diff --git a/.gn b/.gn
index 286e68b8..55f5ee19 100644
--- a/.gn
+++ b/.gn
@@ -71,7 +71,6 @@
   # crbug.com/1158989
   "//headless:headless_renderer",  # 12 errors
   "//headless:headless_shared_sources",  # 2 errors
-  "//headless:headless_shell_browser_lib",  # 1 errors
 
   # //v8, https://crbug.com/v8/7330
   "//v8/src/inspector:inspector",  # 20 errors
diff --git a/DEPS b/DEPS
index 7e427011..71f045b 100644
--- a/DEPS
+++ b/DEPS
@@ -282,7 +282,7 @@
   'dawn_standalone': False,
 
   # reclient CIPD package version
-  'reclient_version': 're_client_version:0.76.0.f4c4bc4-gomaip',
+  'reclient_version': 're_client_version:0.77.2.9cc22cf-gomaip',
 
   # Enable fetching Rust-related packages.
   'use_rust': False,
@@ -300,15 +300,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': 'dbc976b9d2d634e4e9184baa49d831be34495ac8',
+  'skia_revision': 'a556c764152b6db2ffacd835d5f4e0687a1c2782',
   # 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': '3ee8caf74fd7b69aef98a891697e3dfbb9511637',
+  'v8_revision': '3d91f418930a5b6346b8605fb6ce9fbb9b8203f5',
   # 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': '4d182868af4877068cb56fd987c89ba8ff54d523',
+  'angle_revision': '64f41972a9a30a58ca126e28c9f05a926f03b9c6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -316,7 +316,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'e0ea309bac37762ef6772cbc460423a03f658ce6',
+  'pdfium_revision': '5e49f9cccf75b61127eecdcb5f6b3669c125a0c1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -347,11 +347,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '18b243a9a02b3ff964dc92f94af9745029473043',
+  'nacl_revision': 'ff76e4da6740a8466a24877887108522cc4896e7',
   # 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': '4797b2ff22906ce4ff4e6dcee300a70f94dcc43a',
+  'freetype_revision': 'dd91f6e7f5a051818070c49715125fb72074023e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -371,7 +371,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': '2417ba3d0d766848fcd0bc65d6cf2819f68c16e5',
+  'catapult_revision': '6552f9ba7bb598399ca8ace6ed5310bf70bd6ff3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -379,7 +379,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': '88b74fb70d34f0aa51a4b5a15dfd35d400d21602',
+  'devtools_frontend_revision': '0b7a75f07584057dc80c6dd0c9e30a34d165e774',
   # 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.
@@ -415,11 +415,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '6c55c128ec648c4bfbe30b469a3393eb66aefdf8',
+  'dawn_revision': '7143450998c72258f994acea688164f2fa1ff3eb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '31940e410357ffdc890971c7e3f3b6af6e624f0f',
+  'quiche_revision': 'c2576eff37476b17ae780a366ad4e401ce3827f1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -483,7 +483,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       '26e3467ee8494629799408ac63e2bc3a77948aed',
+  'libcxx_revision':       'e5670a0e0e4992f6a120142358b07e49c7d96918',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:5705e56a0e5856621415cfdf444432554e72c9c9',
@@ -776,7 +776,7 @@
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'ec4a10dd84e2f0a73c778902d658ee2eea7c3a66',
+    'url': Var('chromium_git') + '/website.git' + '@' + '987e78eb265555e4afdd072295d23f4e1dd127f5',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -865,7 +865,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'fdVP7sgi-n47PEIlxrBbuiaX6yyzXY4ZjMamM9CRrysC',
+          'version': 'bzOBdzHbwSJDj6VKhuuGWjZHxlCqZe0P7FVsMumVT4oC',
         },
       ],
       'dep_type': 'cipd',
@@ -876,7 +876,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'uHFOKYjRhk0J8636v7rAjexFqH1ibrZJyd-rA1Xw-ZkC',
+          'version': '-V17sKWka-6j0T6tX_EHEZgloORU8xgTqavWyGWzMMIC',
         },
       ],
       'dep_type': 'cipd',
@@ -887,7 +887,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'IUXrWgewP_hXlir7RI4M8bYLFmUQEQ1n3eWfteykMksC',
+          'version': 'A1SJdkoWLvjMoXu6RlSst8CDfm_wVyBdvU1_eC5XRWQC',
         },
       ],
       'dep_type': 'cipd',
@@ -1159,7 +1159,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5613e35a21006fe57b07fc7e287ea4f02e258591',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '43785cbb14c961e05fbca737a43591bb045234e3',
       'condition': 'checkout_chromeos',
   },
 
@@ -1187,7 +1187,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b7ec673cccc42bce346234209dfd194b7911e169',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f41670fdadc9eca7fff99ab8563190dd41d27ee8',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1559,7 +1559,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + 'aff62f245e3ec2a2bc9de4e7c016e376d109e205',
+    Var('chromium_git') + '/openscreen' + '@' + '834a7bbd68f2a8e0186f840320f26fc027ec8d7c',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1707,7 +1707,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@7d94bcff7a00c368f3f1bcd6db3d8a55066254eb',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@db1584efaa9b791256776a628df265ded6edbfc2',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1743,10 +1743,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '44e4c8770158c505b03ee7feafa4859d083b0912',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f7f601d7e9b296b05c0fc1ad886a4f2b11a64ef2',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3c353f872ba7d94c6dd6c672086de6a96e775569',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '4b6819434d6b851b6cfcf211992b12a9793e0bc5',
+    Var('webrtc_git') + '/src.git' + '@' + '8baa453432992297d45a91aad50be09e6a93ed7d',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1819,7 +1819,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@af0bf87ff6738f722b9a0938f0ca6979c263886d',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3f95ce893573ce8badea0517785565c45da8dba9',
     'condition': 'checkout_src_internal',
   },
 
@@ -1838,7 +1838,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': 'JJXXcwB3ER61dMBrjnfPvxV8DfhgpwIE34DUr3optygC',
+        'version': 'vmMtbeoWla3R_jjlJu5JVgSnguGIWpCkU5GgvcYiPuoC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1849,7 +1849,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'v20C9hI9yQpKPg2z79gf78VPZChPFPtP1GSi_iO2aeAC',
+        'version': 'FhsPaA-4wtrcSY33iKNTocII_aorefuLRr9UJncbxzEC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1860,7 +1860,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'r4NwX9q3WGBoRzUhw3Qv-ZJcvxjq7f2iCPjkhPUrSnMC',
+        'version': 'uUlSMBpgmwyfsQdttJjLftYV5rwH8_pPlX9H_XF4UooC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py
index bc35bbf..0ceb050 100644
--- a/PRESUBMIT_test_mocks.py
+++ b/PRESUBMIT_test_mocks.py
@@ -129,7 +129,7 @@
   def PresubmitLocalPath(self):
     return self.presubmit_local_path
 
-  def ReadFile(self, filename, mode='rU'):
+  def ReadFile(self, filename, mode='r'):
     if hasattr(filename, 'AbsoluteLocalPath'):
        filename = filename.AbsoluteLocalPath()
     for file_ in self.files:
diff --git a/WATCHLISTS b/WATCHLISTS
index ff7737b..2e9a54d1 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -120,6 +120,9 @@
       'filepath': 'chrome/browser/resources/settings/chromeos/os_apps_page'\
                   '|chrome/browser/ui/webui/app_management',
     },
+    'app_preload_service': {
+      'filepath': 'chrome/browser/apps/app_preload_service'
+    },
     'app_service': {
       'filepath': 'chrome/browser/apps/app_service/'\
                   '|chrome/browser/ui/app_list/app_service/'\
@@ -2221,6 +2224,7 @@
     'android_webview': ['android-webview-reviews@chromium.org'],
     'android_webview_network_service': [],
     'app_management': ['jshikaram+watch-app_management@chromium.org'],
+    'app_preload_service': ['jshikaram+watch-app_preload_service@chromium.org'],
     'app_service': ['dominickn+watch-app_service@chromium.org',
                     'nancylingwang@chromium.org'],
     'app_shortcuts': ['dominickn+watch-app_shortcuts@chromium.org',
diff --git a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
index 24097ac..99afe3b 100644
--- a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
+++ b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
@@ -80,14 +80,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
@@ -539,7 +540,8 @@
 
 void InterceptedRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // intercept response headers here
   // pause/resume |proxied_client_receiver_| if necessary
 
@@ -573,7 +575,8 @@
     }
   }
 
-  target_client_->OnReceiveResponse(std::move(head), std::move(body));
+  target_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                    std::move(cached_metadata));
 }
 
 void InterceptedRequest::OnReceiveRedirect(
@@ -596,10 +599,6 @@
                                    std::move(callback));
 }
 
-void InterceptedRequest::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  target_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void InterceptedRequest::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   target_client_->OnTransferSizeUpdated(transfer_size_diff);
 }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
index abe9e0e..fb3d2a8 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -53,8 +53,8 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.ScopedSysTraceEvent;
 import org.chromium.base.task.PostTask;
+import org.chromium.base.task.TaskTraits;
 import org.chromium.build.BuildConfig;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.base.ResourceBundle;
@@ -522,7 +522,7 @@
     // Log extra information, for debugging purposes. Do the work asynchronously to avoid blocking
     // startup.
     private void logCommandLineAndActiveTrials() {
-        PostTask.postTask(UiThreadTaskTraits.BEST_EFFORT, () -> {
+        PostTask.postTask(TaskTraits.BEST_EFFORT, () -> {
             // TODO(ntfschr): CommandLine can change at any time. For simplicity, only log it
             // once during startup.
             AwContentsStatics.logCommandLineForDebugging();
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
index ddcb222..78b8e26 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
@@ -16,16 +16,25 @@
     private static final String WEBVIEW_CRASH_PRODUCT_NAME = "AndroidWebView";
     private static final String NONEMBEDDED_WEBVIEW_MINIDUMP_FILE_PREFIX =
             "nonembeded-webview-minidump-";
+    private static boolean sCrashDirMade;
 
     public AwPureJavaExceptionReporter() {
-        super(SystemWideCrashDirectories.getOrCreateWebViewCrashDir(), /*attachLogcat=*/false);
-        // The reporter doesn't create a minidump if the crash dump directory doesn't exist, so make
-        // sure to create it.
-        // TODO(https://crbug.com/1293108): this should be shared with chrome as well and removed
-        // from here.
-        new File(SystemWideCrashDirectories.getOrCreateWebViewCrashDir(),
-                CrashFileManager.CRASH_DUMP_DIR)
-                .mkdirs();
+        super(/*attachLogcat=*/false);
+    }
+
+    @Override
+    protected File getCrashFilesDirectory() {
+        if (!sCrashDirMade) {
+            // The reporter doesn't create a minidump if the crash dump directory doesn't exist, so
+            // make sure to create it.
+            // TODO(https://crbug.com/1293108): this should be shared with chrome as well and
+            // removed from here.
+            new File(SystemWideCrashDirectories.getOrCreateWebViewCrashDir(),
+                    CrashFileManager.CRASH_DUMP_DIR)
+                    .mkdirs();
+            sCrashDirMade = true;
+        }
+        return SystemWideCrashDirectories.getWebViewCrashDir();
     }
 
     @Override
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
index 146c9a8..4d7ecd0 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
@@ -30,6 +30,7 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.build.BuildConfig;
+import org.chromium.components.crash.CustomAssertionHandler;
 import org.chromium.components.crash.PureJavaExceptionHandler;
 import org.chromium.components.embedder_support.application.FontPreloadingWorkaround;
 import org.chromium.components.version_info.VersionConstants;
@@ -97,6 +98,7 @@
             CommandLineUtil.initCommandLine();
 
             PureJavaExceptionHandler.installHandler(() -> new AwPureJavaExceptionReporter());
+            CustomAssertionHandler.installHandler(() -> new AwPureJavaExceptionReporter());
 
             // TODO(crbug.com/1182693): Do set up a native UMA recorder once we support recording
             // metrics from native nonembedded code.
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni
index cad1c5d..3a8057c 100644
--- a/android_webview/system_webview_apk_tmpl.gni
+++ b/android_webview/system_webview_apk_tmpl.gni
@@ -10,6 +10,7 @@
 import("//build/config/locales.gni")
 import("//chrome/android/trichrome.gni")
 import("//chrome/version.gni")
+import("//components/crash/android/silent_java_assert_reporting.gni")
 import("//device/vr/buildflags/buildflags.gni")
 import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
 import("//weblayer/variables.gni")
@@ -277,6 +278,10 @@
       png_to_webp = true
     }
 
+    if (enable_silent_java_assert_reporting && !_omit_dex) {
+      custom_assertion_handler = crash_reporting_assertion_handler
+    }
+
     if (!defined(version_code)) {
       if (_use_trichrome_library) {
         if (android_64bit_target_cpu) {
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index 975fc50..6519f52 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -327,11 +327,6 @@
   // Runs `close_assistant_ui_runner_` when it is non-null.
   void MaybeCloseAssistant();
 
-  // Get updated app list view state after dragging from shelf.
-  AppListViewState CalculateStateAfterShelfDrag(
-      const ui::LocatedEvent& event_in_screen,
-      float launcher_above_shelf_bottom_amount) const;
-
   using StateTransitionAnimationCallback =
       base::RepeatingCallback<void(AppListViewState)>;
 
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc
index f2f9630..f0f1d8f 100644
--- a/ash/app_list/app_list_presenter_unittest.cc
+++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -115,7 +115,6 @@
 namespace ash {
 namespace {
 
-constexpr int kAppListBezelMargin = 50;
 constexpr int kBestMatchContainerIndex = 1;
 
 AppListModel* GetAppListModel() {
@@ -146,19 +145,6 @@
   base::RunLoop().RunUntilIdle();
 }
 
-// Generates a fling.
-void FlingUpOrDown(ui::test::EventGenerator* generator,
-                   AppListView* view,
-                   bool up) {
-  int offset = up ? -100 : 100;
-  gfx::Point start_point = view->GetBoundsInScreen().origin();
-  gfx::Point target_point = start_point;
-  target_point.Offset(0, offset);
-
-  generator->GestureScrollSequence(start_point, target_point,
-                                   base::Milliseconds(10), 2);
-}
-
 std::unique_ptr<TestSearchResult> CreateOmniboxSuggestionResult(
     const std::string& result_id) {
   auto suggestion_result = std::make_unique<TestSearchResult>();
@@ -2086,6 +2072,13 @@
   EXPECT_EQ(*result_location,
             *result_selection_controller->selected_location_details());
 
+  // Make sure that the action view is shown.
+  generator->MoveMouseTo(action_view->GetBoundsInScreen().left_center());
+  EXPECT_TRUE(action_view->GetVisible());
+
+  // Ensure layout after the action view visibility has been updated.
+  result_view->GetWidget()->LayoutRootViewIfNecessary();
+
   // Click remove suggestion action button again.
   generator->MoveMouseTo(action_view->GetBoundsInScreen().CenterPoint());
   generator->ClickLeftButton();
@@ -3618,72 +3611,6 @@
   GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
 }
 
-// Tests that the app list view handles drag properly in laptop mode.
-TEST_P(AppListPresenterNonBubbleTest, AppListViewDragHandler) {
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  // Execute a slow short upwards drag this should fail to transition the app
-  // list.
-  int top_of_app_list =
-      GetAppListView()->GetWidget()->GetWindowBoundsInScreen().y();
-  generator->GestureScrollSequence(gfx::Point(0, top_of_app_list + 20),
-                                   gfx::Point(0, top_of_app_list - 20),
-                                   base::Milliseconds(500), 50);
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Execute a long upwards drag, this should transition the app list.
-  generator->GestureScrollSequence(gfx::Point(10, top_of_app_list + 20),
-                                   gfx::Point(10, 10), base::Milliseconds(100),
-                                   10);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  // Execute a short downward drag, this should fail to transition the app list.
-  gfx::Point start(10, 10);
-  gfx::Point end(10, 100);
-  generator->GestureScrollSequence(
-      start, end,
-      generator->CalculateScrollDurationForFlingVelocity(start, end, 1, 100),
-      100);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  // Execute a long and slow downward drag to switch to peeking.
-  start = gfx::Point(10, 200);
-  end = gfx::Point(10, 650);
-  generator->GestureScrollSequence(
-      start, end,
-      generator->CalculateScrollDurationForFlingVelocity(start, end, 1, 100),
-      100);
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Transition to fullscreen.
-  generator->GestureScrollSequence(gfx::Point(10, top_of_app_list + 20),
-                                   gfx::Point(10, 10), base::Milliseconds(100),
-                                   10);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  // Enter text to transition to |FULLSCREEN_SEARCH|.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-
-  // Execute a short downward drag, this should fail to close the app list.
-  start = gfx::Point(10, 10);
-  end = gfx::Point(10, 100);
-  generator->GestureScrollSequence(
-      start, end,
-      generator->CalculateScrollDurationForFlingVelocity(start, end, 1, 100),
-      100);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-
-  // Execute a long downward drag, this should close the app list.
-  generator->GestureScrollSequence(gfx::Point(10, 10), gfx::Point(10, 900),
-                                   base::Milliseconds(100), 10);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
 // Tests the shelf background type is as expected when a window is created after
 // going to tablet mode.
 TEST_F(AppListPresenterTest, ShelfBackgroundWithHomeLauncher) {
@@ -3795,146 +3722,6 @@
   EXPECT_TRUE(search_box_view->is_search_box_active());
 }
 
-// Tests that a tap/click on the AppListView from half launcher returns the
-// AppListView to Peeking, and that a tap/click on the AppListView from
-// Peeking closes the app list.
-TEST_P(AppListPresenterNonBubbleTest,
-       StateTransitionsByTapAndClickingAppListBodyFromHalf) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* app_list_view = GetAppListView();
-  SearchBoxView* search_box_view = app_list_view->search_box_view();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Press a key, the AppListView should transition to half.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
-  EXPECT_TRUE(search_box_view->is_search_box_active());
-
-  // Tap outside the search box, the AppListView should transition to Peeking
-  // and the search box should be inactive.
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointOutsideSearchbox());
-    generator->ClickLeftButton();
-    generator->ReleaseLeftButton();
-  } else {
-    generator->GestureTapDownAndUp(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  EXPECT_FALSE(search_box_view->is_search_box_active());
-
-  // Tap outside the search box again, the AppListView should hide.
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointOutsideSearchbox());
-    generator->ClickLeftButton();
-    generator->ReleaseLeftButton();
-  } else {
-    generator->GestureTapDownAndUp(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
-// Tests that a tap/click on the AppListView from Fullscreen search returns
-// the AppListView to fullscreen all apps, and that a tap/click on the
-// AppListView from fullscreen all apps closes the app list.
-TEST_P(AppListPresenterNonBubbleTest,
-       StateTransitionsByTappingAppListBodyFromFullscreen) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* app_list_view = GetAppListView();
-  SearchBoxView* search_box_view = app_list_view->search_box_view();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-
-  // Execute a long upwards drag, this should transition the app list to
-  // fullscreen.
-  const int top_of_app_list =
-      app_list_view->GetWidget()->GetWindowBoundsInScreen().y();
-  generator->GestureScrollSequence(gfx::Point(10, top_of_app_list + 20),
-                                   gfx::Point(10, 10), base::Milliseconds(100),
-                                   10);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  // Press a key, this should activate the searchbox and transition to
-  // fullscreen search.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-  EXPECT_TRUE(search_box_view->is_search_box_active());
-
-  // Tap outside the searchbox, this should deactivate the searchbox and the
-  // applistview should return to fullscreen all apps.
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointOutsideSearchbox());
-    generator->ClickLeftButton();
-  } else {
-    generator->GestureTapDownAndUp(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-  EXPECT_FALSE(search_box_view->is_search_box_active());
-
-  // Tap outside the searchbox again, this should close the applistview.
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointOutsideSearchbox());
-    generator->ClickLeftButton();
-  } else {
-    generator->GestureTapDownAndUp(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
-// Tests that the searchbox activates when it is tapped and that the widget is
-// closed after tapping outside the searchbox.
-TEST_P(AppListPresenterNonBubbleTest, TapAndClickEnablesSearchBox) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  SearchBoxView* search_box_view = GetAppListView()->search_box_view();
-
-  // Tap/Click the search box, it should activate.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointInsideSearchbox());
-    generator->PressLeftButton();
-    generator->ReleaseLeftButton();
-  } else {
-    generator->GestureTapAt(GetPointInsideSearchbox());
-  }
-
-  EXPECT_TRUE(search_box_view->is_search_box_active());
-
-  // Tap on the body of the app list, the search box should deactivate.
-  if (test_mouse_event) {
-    generator->MoveMouseTo(GetPointOutsideSearchbox());
-    generator->PressLeftButton();
-    generator->ReleaseLeftButton();
-  } else {
-    generator->GestureTapAt(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  EXPECT_FALSE(search_box_view->is_search_box_active());
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  // Tap on the body of the app list again, the app list should hide.
-  if (test_mouse_event) {
-    generator->PressLeftButton();
-    generator->ReleaseLeftButton();
-  } else {
-    generator->GestureTapAt(GetPointOutsideSearchbox());
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
 // Tests that search box gets deactivated if the active search model gets
 // switched. Does not apply to ProductivityLauncher, where the search box is
 // always active.
@@ -4057,64 +3844,6 @@
 }
 
 // Tests that the result selection will reset after closing the search box by
-// clicking somewhere outside the search box.
-TEST_P(AppListPresenterNonBubbleTest,
-       ClosingSearchBoxByClickingOutsideResetsResultSelection) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  SearchBoxView* search_box_view = GetAppListView()->search_box_view();
-  ResultSelectionController* result_selection_controller =
-      search_result_page()->result_selection_controller();
-
-  // Mark the suggested content info as dismissed so that it does not interfere
-  // with the layout for the selection traversal.
-  Shell::Get()->app_list_controller()->MarkSuggestedContentInfoDismissed();
-
-  // Add search results to the search model.
-  SearchModel* search_model = GetSearchModel();
-  search_model->results()->Add(CreateOmniboxSuggestionResult("Suggestion1"));
-  search_model->results()->Add(CreateOmniboxSuggestionResult("Suggestion2"));
-  // The results are updated asynchronously. Wait until the update is finished.
-  base::RunLoop().RunUntilIdle();
-
-  // Click the search box, the result selection should be the first one in
-  // default.
-  ShowZeroStateSearchInHalfState();
-
-  EXPECT_TRUE(search_box_view->is_search_box_active());
-  ASSERT_TRUE(result_selection_controller->selected_result());
-  EXPECT_TRUE(result_selection_controller->selected_result()->selected());
-  EXPECT_TRUE(result_selection_controller->selected_location_details()
-                  ->is_first_result());
-
-  // Move the selection to the second result.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_DOWN);
-  ASSERT_TRUE(result_selection_controller->selected_result());
-  EXPECT_TRUE(result_selection_controller->selected_result()->selected());
-  EXPECT_FALSE(result_selection_controller->selected_location_details()
-                   ->is_first_result());
-
-  // Tap on the body of the app list, the search box should deactivate.
-  if (test_mouse_event) {
-    ClickMouseAt(GetPointOutsideSearchbox());
-  } else {
-    GetEventGenerator()->GestureTapAt(GetPointOutsideSearchbox());
-  }
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(search_box_view->is_search_box_active());
-
-  // Tap/Click the search box again, the result selection should be reset to the
-  // first one.
-  ShowZeroStateSearchInHalfState();
-
-  EXPECT_TRUE(search_box_view->is_search_box_active());
-  ASSERT_TRUE(result_selection_controller->selected_result());
-  EXPECT_TRUE(result_selection_controller->selected_result()->selected());
-  EXPECT_TRUE(result_selection_controller->selected_location_details()
-                  ->is_first_result());
-}
-
-// Tests that the result selection will reset after closing the search box by
 // clicking the close button.
 TEST_P(AppListPresenterNonBubbleTest,
        ClosingSearchBoxByClickingCloseButtonResetsResultSelection) {
@@ -4235,121 +3964,6 @@
   GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
 }
 
-// Tests that an unhandled two finger tap/right click does not close the app
-// list, and an unhandled one finger tap/left click closes the app list in
-// Peeking mode.
-TEST_P(AppListPresenterNonBubbleTest, UnhandledEventOnPeeking) {
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Two finger tap or right click in the empty space below the searchbox. The
-  // app list should not close.
-  gfx::Point empty_space =
-      GetAppListView()->search_box_view()->GetBoundsInScreen().bottom_left();
-  empty_space.Offset(0, 10);
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  if (TestMouseEventParam()) {
-    generator->MoveMouseTo(empty_space);
-    generator->PressRightButton();
-    generator->ReleaseRightButton();
-  } else {
-    ui::GestureEvent two_finger_tap(
-        empty_space.x(), empty_space.y(), 0, base::TimeTicks(),
-        ui::GestureEventDetails(ui::ET_GESTURE_TWO_FINGER_TAP));
-    generator->Dispatch(&two_finger_tap);
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  // One finger tap or left click in the empty space below the searchbox. The
-  // app list should close.
-  if (TestMouseEventParam()) {
-    generator->MoveMouseTo(empty_space);
-    generator->ClickLeftButton();
-  } else {
-    generator->GestureTapAt(empty_space);
-  }
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
-// Tests that a drag to the bezel from Fullscreen/Peeking will close the app
-// list.
-// TODO(crbug.com/1281927): Figure out if ProductivityLauncher needs to
-// support swipe to open and close.
-TEST_P(AppListPresenterNonBubbleTest,
-       DragToBezelClosesAppListFromFullscreenAndPeeking) {
-  const bool test_fullscreen = TestFullscreenParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* view = GetAppListView();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  if (test_fullscreen) {
-    FlingUpOrDown(GetEventGenerator(), view, true /* up */);
-    GetAppListTestHelper()->WaitUntilIdle();
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-  }
-
-  // Drag the app list to 50 DIPs from the bottom bezel.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  const int bezel_y = display::Screen::GetScreen()
-                          ->GetDisplayNearestView(view->parent_window())
-                          .bounds()
-                          .bottom();
-  generator->GestureScrollSequence(
-      gfx::Point(0, bezel_y - (kAppListBezelMargin + 100)),
-      gfx::Point(0, bezel_y - (kAppListBezelMargin)), base::Milliseconds(1500),
-      100);
-
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
-// Tests that a drag to the bezel from Fullscreen/Peeking will close the app
-// list even on external display with non zero y origin.
-// TODO(crbug.com/1281927): Figure out if ProductivityLauncher needs to
-// support swipe to open and close.
-TEST_P(AppListPresenterNonBubbleTest,
-       DragToBezelClosesAppListFromFullscreenAndPeekingOnExternal) {
-  UpdateDisplay("800x600,1000x768");
-
-  const bool test_fullscreen = TestFullscreenParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetSecondaryDisplay().id());
-  AppListView* view = GetAppListView();
-  {
-    SCOPED_TRACE("Peeking");
-    GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  }
-  EXPECT_EQ(Shell::GetAllRootWindows()[1],
-            view->GetWidget()->GetNativeWindow()->GetRootWindow());
-
-  if (test_fullscreen) {
-    FlingUpOrDown(GetEventGenerator(), view, true /* up */);
-    GetAppListTestHelper()->WaitUntilIdle();
-    SCOPED_TRACE("FullscreenAllApps");
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-  }
-
-  // Drag the app list to 50 DIPs from the bottom bezel.
-  display::Display display =
-      display::Screen::GetScreen()->GetDisplayNearestView(
-          view->GetWidget()->GetNativeWindow());
-  const int bezel_y = display.bounds().bottom();
-  const int drag_x = display.bounds().x() + 10;
-  GetEventGenerator()->GestureScrollSequence(
-      gfx::Point(drag_x, bezel_y - (kAppListBezelMargin + 100)),
-      gfx::Point(drag_x, bezel_y - (kAppListBezelMargin)),
-      base::Milliseconds(1500), 100);
-
-  GetAppListTestHelper()->WaitUntilIdle();
-  SCOPED_TRACE("Closed");
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
 // Regression test for crash due to use-after-free. https://crbug.com/1163332
 TEST_P(AppListPresenterTest, ShouldNotCrashOnItemClickAfterMonitorDisconnect) {
   // Set up two displays.
@@ -4504,69 +4118,6 @@
   }
 }
 
-// Tests that a fling from Fullscreen/Peeking closes the app list.
-TEST_P(AppListPresenterNonBubbleTest,
-       FlingDownClosesAppListFromFullscreenAndPeeking) {
-  const bool test_fullscreen = TestFullscreenParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* view = GetAppListView();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  if (test_fullscreen) {
-    FlingUpOrDown(GetEventGenerator(), view, true /* up */);
-    GetAppListTestHelper()->WaitUntilIdle();
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-  }
-
-  // Fling down, the app list should close.
-  FlingUpOrDown(GetEventGenerator(), view, false /* down */);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  GetAppListTestHelper()->CheckVisibility(false);
-}
-
-// Tests that drag using a mouse does not always close the app list if the app
-// list was previously closed using a fling gesture.
-TEST_P(AppListPresenterNonBubbleTest, MouseDragAfterDownwardFliing) {
-  const bool test_fullscreen = TestFullscreenParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-
-  AppListView* view = GetAppListView();
-  const views::View* expand_arrow =
-      view->app_list_main_view()->contents_view()->expand_arrow_view();
-
-  if (test_fullscreen)
-    GestureTapOn(expand_arrow);
-  GetAppListTestHelper()->CheckState(test_fullscreen
-                                         ? AppListViewState::kFullscreenAllApps
-                                         : AppListViewState::kPeeking);
-
-  // Fling down, the app list should close.
-  FlingUpOrDown(GetEventGenerator(), view, false /* down */);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-
-  // Show the app list again, and perform mouse drag that ends up at the same
-  // position.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  if (test_fullscreen)
-    GestureTapOn(expand_arrow);
-  GetAppListTestHelper()->CheckState(test_fullscreen
-                                         ? AppListViewState::kFullscreenAllApps
-                                         : AppListViewState::kPeeking);
-
-  GetEventGenerator()->MoveMouseTo(GetPointOutsideSearchbox());
-  GetEventGenerator()->PressLeftButton();
-  GetEventGenerator()->MoveMouseBy(0, -10);
-  GetEventGenerator()->MoveMouseBy(0, 10);
-  GetEventGenerator()->ReleaseLeftButton();
-
-  // Verify the app list state has not changed.
-  GetAppListTestHelper()->CheckState(test_fullscreen
-                                         ? AppListViewState::kFullscreenAllApps
-                                         : AppListViewState::kPeeking);
-}
-
 TEST_F(AppListPresenterNonBubbleTest,
        MouseWheelFromAppListPresenterImplTransitionsAppListState) {
   GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
@@ -4578,137 +4129,6 @@
   GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
 }
 
-TEST_P(AppListPresenterNonBubbleTest,
-       LongUpwardDragInFullscreenShouldNotClose) {
-  const bool test_fullscreen_search = TestFullscreenParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* view = GetAppListView();
-  FlingUpOrDown(GetEventGenerator(), view, true);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  if (test_fullscreen_search) {
-    // Enter a character into the searchbox to transition to FULLSCREEN_SEARCH.
-    PressAndReleaseKey(ui::VKEY_0);
-    GetAppListTestHelper()->WaitUntilIdle();
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-  }
-
-  // Drag from the center of the applist to the top of the screen very slowly.
-  // This should not trigger a state transition.
-  gfx::Point drag_start = view->GetBoundsInScreen().CenterPoint();
-  drag_start.set_x(15);
-  gfx::Point drag_end = view->GetBoundsInScreen().top_right();
-  drag_end.set_x(15);
-  GetEventGenerator()->GestureScrollSequence(
-      drag_start, drag_end,
-      GetEventGenerator()->CalculateScrollDurationForFlingVelocity(
-          drag_start, drag_end, 1, 1000),
-      1000);
-  GetAppListTestHelper()->WaitUntilIdle();
-  if (test_fullscreen_search)
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-  else
-    GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-}
-
-// Tests closing the app list during drag, and verifies the bounds get properly
-// updated when the app list is shown again..
-TEST_P(AppListPresenterNonBubbleTest, CloseAppListDuringDrag) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  const gfx::Point drag_start = GetAppListView()->GetBoundsInScreen().origin();
-
-  // Start drag and press escape to close the app list view.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  if (test_mouse_event) {
-    generator->MoveMouseTo(drag_start);
-    generator->PressLeftButton();
-    generator->MoveMouseBy(0, -10);
-  } else {
-    generator->MoveTouch(drag_start);
-    generator->PressTouch();
-    generator->MoveTouch(drag_start + gfx::Vector2d(0, -10));
-  }
-
-  EXPECT_TRUE(GetAppListView()->is_in_drag());
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_ESCAPE);
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  EXPECT_FALSE(GetAppListView()->is_in_drag());
-
-  // Show the app list and verify the app list returns to peeking position.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  EXPECT_EQ(drag_start, GetAppListView()->GetBoundsInScreen().origin());
-}
-
-// Tests closing the app list during drag, and verifies that drag updates are
-// ignored while the app list is closing.
-// TODO(crbug.com/1281927): Figure out if ProductivityLauncher needs to
-// support swipe to open and close.
-TEST_P(AppListPresenterNonBubbleTest, DragUpdateWhileAppListClosing) {
-  const bool test_mouse_event = TestMouseEventParam();
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  const gfx::Point drag_start = GetAppListView()->GetBoundsInScreen().origin();
-
-  // Set up non zero animation duration to ensure app list is not closed
-  // immediately.
-  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
-      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
-
-  // Start drag and press escape to close the app list view.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  if (test_mouse_event) {
-    generator->MoveMouseTo(drag_start);
-    generator->PressLeftButton();
-    generator->MoveMouseBy(0, -10);
-  } else {
-    generator->MoveTouch(drag_start);
-    generator->PressTouch();
-    generator->MoveTouch(drag_start + gfx::Vector2d(0, -10));
-  }
-  EXPECT_TRUE(GetAppListView()->is_in_drag());
-
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_ESCAPE);
-
-  // Update the drag before running the loop that waits for the close animation
-  // to finish,
-  if (test_mouse_event) {
-    generator->MoveMouseBy(0, -10);
-  } else {
-    generator->MoveTouch(drag_start + gfx::Vector2d(0, -20));
-  }
-
-  base::RunLoop().RunUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
-  EXPECT_FALSE(GetAppListView()->is_in_drag());
-
-  // Show the app list and verify the app list returns to peeking position.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  EXPECT_EQ(drag_start, GetAppListView()->GetBoundsInScreen().origin());
-}
-
-// Tests that a drag can not make the app list smaller than the shelf height.
-TEST_F(AppListPresenterNonBubbleTest, LauncherCannotGetSmallerThanShelf) {
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  AppListView* view = GetAppListView();
-
-  // Try to place the app list 1 px below the shelf, it should stay at shelf
-  // height.
-  int target_y = GetPrimaryShelf()
-                     ->GetShelfViewForTesting()
-                     ->GetBoundsInScreen()
-                     .top_right()
-                     .y();
-  const int expected_app_list_y = target_y;
-  target_y += 1;
-  view->UpdateYPositionAndOpacity(target_y, 1);
-
-  EXPECT_EQ(expected_app_list_y, view->GetBoundsInScreen().top_right().y());
-}
-
 // Tests that the AppListView is on screen on a small display.
 TEST_F(AppListPresenterNonBubbleTest, SearchBoxShownOnSmallDisplay) {
   // Update the display to a small scale factor.
@@ -4895,46 +4315,6 @@
   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
 }
 
-// Verifies that in clamshell mode, AppList has the expected state based on the
-// drag distance after dragging from Peeking state.
-TEST_F(AppListPresenterNonBubbleTest, DragAppListViewFromPeeking) {
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Calculate |threshold| in the same way with AppListView::EndDrag.
-  const int threshold = GetPeekingHeight() / kAppListThresholdDenominator;
-
-  // Drag AppListView downward by |threshold| then release the gesture.
-  // Check the final state should be Peeking.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  AppListView* view = GetAppListView();
-  const int drag_to_peeking_distance = threshold;
-  gfx::Point drag_start = view->GetBoundsInScreen().top_center();
-  gfx::Point drag_end(drag_start.x(),
-                      drag_start.y() + drag_to_peeking_distance);
-  generator->GestureScrollSequence(
-      drag_start, drag_end,
-      generator->CalculateScrollDurationForFlingVelocity(drag_start, drag_end,
-                                                         2, 1000),
-      1000);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Drag AppListView upward by bigger distance then release the gesture.
-  // Check the final state should be kFullscreenAllApps.
-  const int drag_to_fullscreen_distance = threshold + 1;
-  drag_start = view->GetBoundsInScreen().top_center();
-  drag_end =
-      gfx::Point(drag_start.x(), drag_start.y() - drag_to_fullscreen_distance);
-
-  generator->GestureScrollSequence(
-      drag_start, drag_end,
-      generator->CalculateScrollDurationForFlingVelocity(drag_start, drag_end,
-                                                         2, 1000),
-      1000);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-}
-
 // Tests that the app list background corner radius remains constant during app
 // list drag if the shelf is not in maximized state.
 TEST_F(AppListPresenterNonBubbleTest, BackgroundCornerRadiusDuringDrag) {
@@ -5009,93 +4389,6 @@
             background_shield->layer()->rounded_corner_radii());
 }
 
-// Tests how app list background rounded corners are changed during a drag while
-// the shelf is in a maximized state (i.e. while a maximized window is shown).
-TEST_F(AppListPresenterNonBubbleTest,
-       BackgroundCornerRadiusDuringDragWithMaximizedShelf) {
-  auto window = CreateTestWindow();
-  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
-
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  const gfx::Point shelf_top = GetPrimaryShelf()
-                                   ->GetShelfViewForTesting()
-                                   ->GetBoundsInScreen()
-                                   .top_center();
-  const int background_radius = ShelfConfig::Get()->shelf_size() / 2;
-
-  AppListView* view = GetAppListView();
-  const views::View* const background_shield =
-      view->GetAppListBackgroundShieldForTest();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-
-  // Start drag at the peeking app list top.
-  const gfx::Point peeking_top = view->GetBoundsInScreen().top_center();
-  generator->MoveTouch(peeking_top);
-  generator->PressTouch();
-
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-
-  // Move above the shelf, with an offset less than the background radius.
-  // Verify that current background corner radius matches the offset from the
-  // shelf.
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius / 5));
-  EXPECT_EQ(
-      gfx::RoundedCornersF(background_radius / 5, background_radius / 5, 0, 0),
-      background_shield->layer()->rounded_corner_radii());
-
-  // Move to the shelf top - background should have no rounded corners.
-  generator->MoveTouch(shelf_top);
-  EXPECT_EQ(gfx::RoundedCornersF(),
-            background_shield->layer()->rounded_corner_radii());
-
-  // Move to half background radius height - the background corner radius should
-  // match the offset from the shelf.
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius / 2));
-  EXPECT_EQ(
-      gfx::RoundedCornersF(background_radius / 2, background_radius / 2, 0, 0),
-      background_shield->layer()->rounded_corner_radii());
-
-  // Move to the height just under the background radius - the current
-  // background corners should be equal to the offset from the shelf.
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius - 1));
-  EXPECT_EQ(
-      gfx::RoundedCornersF(background_radius - 1, background_radius - 1, 0, 0),
-      background_shield->layer()->rounded_corner_radii());
-
-  // Move to the height that equals the background radius - the current
-  // background corners should be equal to the offset from the shelf.
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius));
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-
-  // Move to the height just over the background radius - the background corner
-  // radius value should stay at the |background_radius| value.
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius + 1));
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-  generator->MoveTouch(shelf_top - gfx::Vector2d(0, background_radius + 5));
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-
-  // Move above the peeking height - the background radius should remain the
-  // same.
-  generator->MoveTouch(gfx::Point(peeking_top.x(), peeking_top.y() + 5));
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-
-  // Move back to peeking height, and end drag.
-  generator->MoveTouch(peeking_top);
-  generator->ReleaseTouch();
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  EXPECT_EQ(gfx::RoundedCornersF(background_radius, background_radius, 0, 0),
-            background_shield->layer()->rounded_corner_radii());
-}
-
 // Tests that the touch selection menu created when tapping an open folder's
 // folder name view be interacted with.
 TEST_P(PopulatedAppListTest, TouchSelectionMenu) {
@@ -5147,489 +4440,13 @@
   ASSERT_EQ("", GetFolderName());
 }
 
-// Tests how app list is laid out during different state transitions and app
-// list drag. All these tests can be deleted when ProductivityLauncher ships to
-// stable.
-class AppListPresenterLayoutTest : public AppListPresenterTest {
- public:
-  AppListPresenterLayoutTest() = default;
-  ~AppListPresenterLayoutTest() override = default;
-
-  void SetUp() override {
-    AppListPresenterTest::SetUp();
-    scoped_feature_list_.InitWithFeatures(
-        /*enabled_features=*/{features::kEnableBackgroundBlur},
-        /*disabled_features=*/{features::kProductivityLauncher});
-
-    UpdateDisplay("1080x900");
-    GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  }
-
-  int ExpectedSuggestionChipContainerTop(const gfx::Rect& search_box_bounds) {
-    return search_box_bounds.bottom() + 16 /*suggesion chip top margin*/;
-  }
-
-  // Calculates expected apps grid position based on display height and the
-  // search box in-screen bounds.
-  // NOTE: This assumes that the display size is such that the preferred apps
-  // grid size is within min and max apps grid height (in which case the margin
-  // when scalable app list is not enabled is 1 / 16 of the available height).
-  int ExpectedAppsGridTop(int display_height,
-                          const gfx::Rect& search_box_bounds) {
-    return ExpectedSuggestionChipContainerTop(search_box_bounds) +
-           32 /*suggestion chip container height*/ +
-           24 /*grid fadeout zone height*/ - 16 /*grid fadeout mask height*/;
-  }
-
-  // Calculates expected apps grid position on the search results page based on
-  // the display height and the search box in-screen bounds.
-  int ExpectedAppsGridTopForSearchResults(int display_height,
-                                          const gfx::Rect& search_box_bounds) {
-    const int top = ExpectedAppsGridTop(display_height, search_box_bounds);
-    // In the search results page, the apps grid is shown 24 dip below where
-    // they'd be shown in the apps page. The |top| was calculated relative to
-    // search box bounds in the search results page, so it has to be further
-    // offset by the difference between search box bottom bounds in the apps and
-    // search results page.
-    const int search_box_diff =
-        contents_view()->GetSearchBoxBounds(AppListState::kStateApps).bottom() -
-        contents_view()
-            ->GetSearchBoxBounds(AppListState::kStateSearchResults)
-            .bottom();
-    return top + search_box_diff +
-           24 /*apps grid offset in fullscreen search state*/;
-  }
-
-  ContentsView* contents_view() {
-    return GetAppListView()->app_list_main_view()->contents_view();
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// Instantiate the values in the parameterized tests. Used to
-// toggle mouse and touch events and in some tests to toggle fullscreen mode
-// tests.
-INSTANTIATE_TEST_SUITE_P(All, AppListPresenterLayoutTest, testing::Bool());
-
-// Tests that the app list contents top margin is gradually updated during drag
-// between peeking and fullscreen view state while showing apps page.
-// This test can be deleted when ProductivityLauncher ships to stable.
-TEST_P(AppListPresenterLayoutTest, AppsPagePositionDuringDrag) {
-  const int shelf_height = ShelfConfig::Get()->shelf_size();
-  const int fullscreen_y = 0;
-  const int closed_y = 900 - shelf_height;
-  const int fullscreen_search_box_padding = (900 - shelf_height) / 16;
-
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  const gfx::Point peeking_top =
-      GetAppListView()->GetBoundsInScreen().top_center();
-
-  // Drag AppListView upwards half way to the top of the screen, and check the
-  // search box padding has been updated to a value half-way between peeking and
-  // fullscreen values.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveTouch(peeking_top);
-  generator->PressTouch();
-  generator->MoveTouch(
-      gfx::Point(peeking_top.x(), (peeking_top.y() + fullscreen_y) / 2));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  gfx::Rect search_box_bounds =
-      GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  float progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagNone);
-  EXPECT_LE(std::abs(progress - 1.5f), 0.01f);
-
-  EXPECT_EQ((peeking_top.y() + fullscreen_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress - 1,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateApps),
-                    fullscreen_search_box_padding),
-            search_box_bounds.y());
-
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  // In apps state, search results page should be hidden behind the search
-  // box.
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-
-  // Move to the fullscreen position, and verify the search box padding is
-  // equal to the expected fullscreen value.
-  generator->MoveTouch(gfx::Point(peeking_top.x(), fullscreen_y));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  EXPECT_EQ(2.0f, GetAppListView()->GetAppListTransitionProgress(
-                      AppListView::kProgressFlagNone));
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(fullscreen_search_box_padding, search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-
-  // Move half way between peeking and closed state - the search box padding
-  // should be half distance between closed and peeking padding.
-  generator->MoveTouch(
-      gfx::Point(peeking_top.x(), (peeking_top.y() + closed_y) / 2));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagNone);
-  EXPECT_LE(std::abs(progress - 0.5f), 0.01f);
-
-  EXPECT_EQ((peeking_top.y() + closed_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateApps),
-                    0),
-            search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-
-  // Move to the closed state height, and verify the search box padding matches
-  // the state.
-  generator->MoveTouch(gfx::Point(peeking_top.x(), closed_y));
-  GetAppListTestHelper()->WaitUntilIdle();
-  EXPECT_EQ(0.0f, GetAppListView()->GetAppListTransitionProgress(
-                      AppListView::kProgressFlagNone));
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(closed_y, search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-}
-
-// Tests that the app list contents top margin is gradually updated during drag
-// between half and fullscreen state while showing search results.
-// This test can be deleted when ProductivityLauncher ships to stable.
-TEST_P(AppListPresenterLayoutTest, SearchResultsPagePositionDuringDrag) {
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Enter text in the search box to transition to half app list.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
-
-  const int shelf_height = ShelfConfig::Get()->shelf_size();
-  const int search_results_height = 440;
-  const int fullscreen_y = 0;
-  const int closed_y = 900 - shelf_height;
-  const int fullscreen_search_box_padding = (900 - shelf_height) / 16;
-
-  const gfx::Point half_top =
-      GetAppListView()->GetBoundsInScreen().top_center();
-
-  // Drag AppListView upwards half way to the top of the screen, and check the
-  // search box padding has been updated to a value half-way between peeking and
-  // fullscreen values.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveTouch(half_top);
-  generator->PressTouch();
-  generator->MoveTouch(
-      gfx::Point(half_top.x(), (half_top.y() + fullscreen_y) / 2));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  gfx::Rect search_box_bounds =
-      GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  float progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagSearchResults);
-  EXPECT_LE(std::abs(progress - 1.5f), 0.01f);
-
-  EXPECT_EQ((half_top.y() + fullscreen_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress - 1,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateSearchResults),
-                    fullscreen_search_box_padding),
-            search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-
-  // Move to the fullscreen position, and verify the search box padding is
-  // equal to the expected fullscreen value.
-  generator->MoveTouch(gfx::Point(half_top.x(), fullscreen_y));
-  GetAppListTestHelper()->WaitUntilIdle();
-  EXPECT_EQ(2.0f, GetAppListView()->GetAppListTransitionProgress(
-                      AppListView::kProgressFlagSearchResults));
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(fullscreen_search_box_padding, search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-
-  // Move half way between peeking and closed state - the search box padding
-  // should be half distance between closed and peeking padding.
-  generator->MoveTouch(gfx::Point(half_top.x(), (half_top.y() + closed_y) / 2));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagSearchResults);
-  EXPECT_LE(std::abs(progress - 0.5f), 0.01f);
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ((half_top.y() + closed_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateSearchResults),
-                    0),
-            search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-
-  // Move to the closed state height, and verify the search box padding matches
-  // the state.
-  generator->MoveTouch(gfx::Point(half_top.x(), closed_y));
-  GetAppListTestHelper()->WaitUntilIdle();
-  EXPECT_EQ(0.0f, GetAppListView()->GetAppListTransitionProgress(
-                      AppListView::kProgressFlagSearchResults));
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(closed_y, search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-}
-
-// Tests changing the active app list page while drag is in progress.
-// This test can be deleted when ProductivityLauncher ships to stable.
-TEST_P(AppListPresenterLayoutTest, SwitchPageDuringDrag) {
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  const gfx::Point peeking_top =
-      GetAppListView()->GetBoundsInScreen().top_center();
-
-  // Enter text in the search box to transition to half app list.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
-
-  const gfx::Point half_top =
-      GetAppListView()->GetBoundsInScreen().top_center();
-
-  const int shelf_height = ShelfConfig::Get()->shelf_size();
-  const int search_results_height = 440;
-  const int fullscreen_y = 0;
-  const int fullscreen_search_box_padding = (900 - shelf_height) / 16;
-
-  // Drag AppListView upwards half way to the top of the screen, and check the
-  // search box padding has been updated to a value half-way between peeking and
-  // fullscreen values.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveTouch(half_top);
-  generator->PressTouch();
-  generator->MoveTouch(
-      gfx::Point(half_top.x(), (half_top.y() + fullscreen_y) / 2));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  gfx::Rect search_box_bounds =
-      GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  float progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagSearchResults);
-  EXPECT_LE(std::abs(progress - 1.5f), 0.01f);
-  EXPECT_EQ((half_top.y() + fullscreen_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress - 1,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateSearchResults),
-                    fullscreen_search_box_padding),
-            search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-
-  const gfx::Rect apps_grid_bounds_in_results_page =
-      apps_grid_view()->GetBoundsInScreen();
-  const gfx::Rect app_list_bounds = GetAppListView()->GetBoundsInScreen();
-
-  // Press ESC key - this should move the UI back to the app list.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_ESCAPE);
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // The app list position should remain the same.
-  EXPECT_EQ(app_list_bounds, GetAppListView()->GetBoundsInScreen());
-
-  // The search box should be moved so drag progress for peeking state matches
-  // the current height.
-  float new_progress = (0.5 * half_top.y()) / peeking_top.y();
-  int expected_search_box_top =
-      new_progress * peeking_top.y() +
-      (1 - new_progress) * fullscreen_search_box_padding +
-      new_progress * ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                         AppListState::kStateApps);
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(expected_search_box_top, search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(apps_grid_bounds_in_results_page.y() - 24,
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_EQ(apps_grid_bounds_in_results_page.size(),
-            apps_grid_view()->GetBoundsInScreen().size());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-
-  // Enter text in the search box to transition back to search results page.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  progress = GetAppListView()->GetAppListTransitionProgress(
-      AppListView::kProgressFlagSearchResults);
-  EXPECT_LE(std::abs(progress - 1.5f), 0.01f);
-  EXPECT_EQ((half_top.y() + fullscreen_y) / 2 +
-                gfx::Tween::IntValueBetween(
-                    progress - 1,
-                    ContentsView::GetPeekingSearchBoxTopMarginOnPage(
-                        AppListState::kStateSearchResults),
-                    fullscreen_search_box_padding),
-            search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-}
-
-// Tests changing the active app list page in fullscreen state.
-// This test can be deleted when ProductivityLauncher ships to stable.
-TEST_P(AppListPresenterLayoutTest, SwitchPageInFullscreen) {
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-  FlingUpOrDown(GetEventGenerator(), GetAppListView(), true);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  const int shelf_height = ShelfConfig::Get()->shelf_size();
-  const int search_results_height = 440;
-  const int fullscreen_y = 0;
-  const int fullscreen_search_box_padding = (900 - shelf_height) / 16;
-
-  gfx::Rect search_box_bounds =
-      GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(fullscreen_y + fullscreen_search_box_padding,
-            search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-
-  const gfx::Rect app_list_bounds = GetAppListView()->GetBoundsInScreen();
-
-  // Enter text in the search box to transition to half app list.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(app_list_bounds, GetAppListView()->GetBoundsInScreen());
-  EXPECT_EQ(fullscreen_y + fullscreen_search_box_padding,
-            search_box_bounds.y());
-  EXPECT_EQ(search_box_bounds.y(),
-            search_result_page()->GetBoundsInScreen().y());
-  EXPECT_EQ(search_results_height,
-            search_result_page()->GetBoundsInScreen().height());
-  EXPECT_EQ(ExpectedAppsGridTopForSearchResults(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  const gfx::Rect apps_grid_bounds_in_results_page =
-      apps_grid_view()->GetBoundsInScreen();
-
-  // Press ESC key - this should move the UI back to the app list.
-  PressAndReleaseKey(ui::KeyboardCode::VKEY_ESCAPE);
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-
-  search_box_bounds = GetAppListView()->search_box_view()->GetBoundsInScreen();
-  search_box_bounds.Inset(GetAppListView()->search_box_view()->GetInsets());
-
-  EXPECT_EQ(app_list_bounds, GetAppListView()->GetBoundsInScreen());
-  EXPECT_EQ(fullscreen_y + fullscreen_search_box_padding,
-            search_box_bounds.y());
-  EXPECT_EQ(ExpectedAppsGridTop(900, search_box_bounds),
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_TRUE(apps_grid_view()->GetVisible());
-  EXPECT_EQ(apps_grid_bounds_in_results_page.y() - 24,
-            apps_grid_view()->GetBoundsInScreen().y());
-  EXPECT_EQ(apps_grid_bounds_in_results_page.size(),
-            apps_grid_view()->GetBoundsInScreen().size());
-  EXPECT_EQ(search_box_bounds, search_result_page()->GetBoundsInScreen());
-}
-
 // Test a variety of behaviors for home launcher (app list in tablet mode).
-// Parameterized by ProductivityLauncher.
+// Parameterized by Mouse or touch parameter.
 class AppListPresenterHomeLauncherTest
     : public AshTestBase,
       public testing::WithParamInterface<bool> {
  public:
-  AppListPresenterHomeLauncherTest() {
-    const bool enable_productivity_launcher = GetParam();
-    if (enable_productivity_launcher) {
-      scoped_feature_list_.InitWithFeatures(
-          /*enabled_features=*/{features::kEnableBackgroundBlur,
-                                features::kProductivityLauncher},
-          /*disabled_features=*/{});
-    } else {
-      scoped_feature_list_.InitWithFeatures(
-          /*enabled_features=*/{features::kEnableBackgroundBlur},
-          /*disabled_features=*/{features::kProductivityLauncher});
-    }
-  }
+  AppListPresenterHomeLauncherTest() = default;
   AppListPresenterHomeLauncherTest(const AppListPresenterHomeLauncherTest&) =
       delete;
   AppListPresenterHomeLauncherTest& operator=(
@@ -5649,6 +4466,8 @@
     AshTestBase::TearDown();
   }
 
+  bool TestMouseEventParam() const { return GetParam(); }
+
   void TapHomeButton(int64_t display_id) {
     HomeButton* const home_button =
         Shell::GetRootWindowControllerWithDisplayId(display_id)
@@ -5693,6 +4512,12 @@
         .bottom_right();
   }
 
+  gfx::Point GetPointInsideSearchbox() {
+    return GetSearchBoxViewFromHelper(GetAppListTestHelper())
+        ->GetBoundsInScreen()
+        .CenterPoint();
+  }
+
   void ShowAppList() {
     GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
   }
@@ -5704,196 +4529,16 @@
   }
 
  protected:
-  base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<WallpaperControllerTestApi> wallpaper_test_api_;
 };
 
-INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
+INSTANTIATE_TEST_SUITE_P(MouseTouchEvent,
                          AppListPresenterHomeLauncherTest,
                          testing::Bool());
 
-// Verifies that mouse dragging AppListView is enabled.
-TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppList) {
-  // ProductivityLauncher doesn't use peeking state or app list dragging.
-  if (features::IsProductivityLauncherEnabled())
-    return;
-
-  std::unique_ptr<AppListItem> item(new AppListItem("fake id"));
-  GetAppListModel()->AddItem(std::move(item));
-
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Drag AppListView upward by mouse. Before moving the mouse, AppsGridView
-  // should be invisible.
-  const gfx::Point start_point = GetAppListView()->GetBoundsInScreen().origin();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveMouseTo(start_point);
-  generator->PressLeftButton();
-  AppsGridView* apps_grid_view = GetAppListView()
-                                     ->app_list_main_view()
-                                     ->contents_view()
-                                     ->apps_container_view()
-                                     ->apps_grid_view();
-  EXPECT_FALSE(apps_grid_view->GetVisible());
-
-  // Verifies that the AppListView state after mouse drag should be
-  // FullscreenAllApps.
-  generator->MoveMouseBy(0, -start_point.y());
-  generator->ReleaseLeftButton();
-  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
-  EXPECT_TRUE(apps_grid_view->GetVisible());
-}
-
-// Verifies that mouse dragging AppListView creates layers, causes to change the
-// opacity, and destroys the layers when done.
-TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppListItemOpacity) {
-  // ProductivityLauncher doesn't use peeking state or app list dragging.
-  if (features::IsProductivityLauncherEnabled())
-    return;
-
-  const int items_in_page =
-      SharedAppListConfig::instance().GetMaxNumOfItemsPerPage();
-  for (int i = 0; i < items_in_page; ++i) {
-    std::unique_ptr<AppListItem> item(
-        new AppListItem(base::StringPrintf("fake id %d", i)));
-    GetAppListModel()->AddItem(std::move(item));
-  }
-
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  // Drag AppListView by mouse. Before moving the mouse, each AppListItem
-  // doesn't have its own layer.
-  const gfx::Point start_point = GetAppListView()->GetBoundsInScreen().origin();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveMouseTo(start_point);
-  generator->PressLeftButton();
-  AppsGridView* apps_grid_view = GetAppListView()
-                                     ->app_list_main_view()
-                                     ->contents_view()
-                                     ->apps_container_view()
-                                     ->apps_grid_view();
-  // No items have layer.
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_FALSE(item_view->layer()) << "at " << i;
-  }
-
-  // Drags the mouse a bit above (twice as shelf's height). This should show the
-  // item vaguely.
-  const int shelf_height =
-      GetPrimaryShelf()->GetShelfViewForTesting()->height();
-  generator->MoveMouseBy(0, -shelf_height * 2);
-  // All of the item should have the layer at this point.
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_TRUE(item_view->layer()) << "at " << i;
-    EXPECT_LE(0.f, item_view->layer()->opacity()) << "at " << i;
-    EXPECT_GE(1.f, item_view->layer()->opacity()) << "at " << i;
-  }
-
-  // Moves the mouse to the top edge of the screen; now all app-list items are
-  // fully visible, but stays to keep layer. The opacity should be almost 1.0.
-  generator->MoveMouseTo(start_point.x(), 0);
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_TRUE(item_view->layer()) << "at " << i;
-    EXPECT_LE(0.f, item_view->layer()->opacity()) << "at " << i;
-    EXPECT_GE(1.f, item_view->layer()->opacity()) << "at " << i;
-  }
-
-  // Finishes the drag. It should destruct the layer.
-  generator->ReleaseLeftButton();
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_FALSE(item_view->layer()) << "at " << i;
-  }
-}
-
-// Tests that ending of the mouse dragging of app-list destroys the layers for
-// the items which are in the second page. See https://crbug.com/990529.
-TEST_P(AppListPresenterHomeLauncherTest, LayerOnSecondPage) {
-  // ProductivityLauncher doesn't use peeking state or app list dragging.
-  if (features::IsProductivityLauncherEnabled())
-    return;
-
-  const int items_in_page =
-      SharedAppListConfig::instance().GetMaxNumOfItemsPerPage();
-  AppListModel* model = GetAppListModel();
-  for (int i = 0; i < items_in_page; ++i) {
-    std::unique_ptr<AppListItem> item(
-        new AppListItem(base::StringPrintf("fake id %02d", i)));
-    model->AddItem(std::move(item));
-  }
-
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
-
-  const gfx::Point start_point = GetAppListView()->GetBoundsInScreen().origin();
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  generator->MoveMouseTo(start_point);
-  generator->PressLeftButton();
-  PagedAppsGridView* apps_grid_view = GetAppListView()
-                                          ->app_list_main_view()
-                                          ->contents_view()
-                                          ->apps_container_view()
-                                          ->apps_grid_view();
-
-  // Drags the mouse a bit above (twice as shelf's height). This should show the
-  // item vaguely.
-  const int shelf_height =
-      GetPrimaryShelf()->GetShelfViewForTesting()->height();
-  generator->MoveMouseBy(0, -shelf_height * 2);
-  // All of the item should have the layer at this point.
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_TRUE(item_view->layer()) << "at " << i;
-    EXPECT_LE(0.f, item_view->layer()->opacity()) << "at " << i;
-    EXPECT_GE(1.f, item_view->layer()->opacity()) << "at " << i;
-  }
-
-  // Add items at the front of the items.
-  const int additional_items = 10;
-  syncer::StringOrdinal prev_position =
-      model->top_level_item_list()->item_at(0)->position();
-  for (int i = 0; i < additional_items; ++i) {
-    std::unique_ptr<AppListItem> item(
-        new AppListItem(base::StringPrintf("fake id %02d", i + items_in_page)));
-    // Update the position so that the item is added at the front of the list.
-    auto metadata = item->CloneMetadata();
-    metadata->position = prev_position.CreateBefore();
-    prev_position = metadata->position;
-    item->SetMetadata(std::move(metadata));
-    model->AddItem(std::move(item));
-  }
-
-  generator->MoveMouseBy(0, -1);
-
-  // At this point, some items move out from the first page.
-  EXPECT_LT(1, apps_grid_view->pagination_model()->total_pages());
-
-  // The items on the first page should have layers.
-  for (int i = 0; i < items_in_page; ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_TRUE(item_view->layer()) << "at " << i;
-    EXPECT_LE(0.f, item_view->layer()->opacity()) << "at " << i;
-    EXPECT_GE(1.f, item_view->layer()->opacity()) << "at " << i;
-  }
-
-  // Drag to the top of the screen and finish the drag. It should destroy all
-  // of the layers, including items on the second page.
-  generator->MoveMouseTo(start_point.x(), 0);
-  generator->ReleaseLeftButton();
-  for (size_t i = 0; i < apps_grid_view->view_model()->view_size(); ++i) {
-    views::View* item_view = apps_grid_view->view_model()->view_at(i);
-    EXPECT_FALSE(item_view->layer()) << "at " << i;
-  }
-}
-
 // Tests that the app list is shown automatically when the tablet mode is on.
 // The app list is dismissed when the tablet mode is off.
-TEST_P(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) {
+TEST_F(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) {
   GetAppListTestHelper()->CheckVisibility(false);
 
   // Turns on tablet mode.
@@ -5907,7 +4552,7 @@
 
 // Tests that the app list window's parent is changed after entering tablet
 // mode.
-TEST_P(AppListPresenterHomeLauncherTest, ParentWindowContainer) {
+TEST_F(AppListPresenterHomeLauncherTest, ParentWindowContainer) {
   // Show app list in non-tablet mode. The window container should be
   // kShellWindowId_AppListContainer.
   GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
@@ -5925,29 +4570,7 @@
 }
 
 // Tests that the background opacity change for app list.
-TEST_P(AppListPresenterHomeLauncherTest, BackgroundOpacity) {
-  // ProductivityLauncher uses a different widget for clamshell mode.
-  if (!features::IsProductivityLauncherEnabled()) {
-    // Show app list in non-tablet mode. The background shield opacity should be
-    // 70%.
-    GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-
-    // The opacity should be set on the color, not the layer. Setting opacity on
-    // the layer will change the opacity of the blur effect, which is not
-    // desired.
-    const U8CPU clamshell_background_opacity = static_cast<U8CPU>(255 * 0.8);
-    EXPECT_EQ(
-        SkColorSetA(AppListColorProvider::Get()->GetAppListBackgroundColor(
-                        /*is_tablet_mode*/
-                        false, /*default_color*/ gfx::kGoogleGrey900),
-                    clamshell_background_opacity),
-        GetAppListView()->GetAppListBackgroundShieldColorForTest());
-    EXPECT_EQ(1, GetAppListView()
-                     ->GetAppListBackgroundShieldForTest()
-                     ->layer()
-                     ->opacity());
-  }
-
+TEST_F(AppListPresenterHomeLauncherTest, BackgroundOpacity) {
   // Turn on tablet mode. The background shield should be transparent.
   EnableTabletMode(true);
 
@@ -5965,18 +4588,7 @@
 
 // Tests that the background blur which is present in clamshell mode does not
 // show in tablet mode.
-TEST_P(AppListPresenterHomeLauncherTest, BackgroundBlur) {
-  // ProductivityLauncher uses a different widget for clamshell mode.
-  if (!features::IsProductivityLauncherEnabled()) {
-    // Show app list in non-tablet mode. The background blur should be enabled.
-    GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-    EXPECT_GT(GetAppListView()
-                  ->GetAppListBackgroundShieldForTest()
-                  ->layer()
-                  ->background_blur(),
-              0.0f);
-  }
-
+TEST_F(AppListPresenterHomeLauncherTest, BackgroundBlur) {
   // Turn on tablet mode. The background blur should be disabled.
   EnableTabletMode(true);
   EXPECT_EQ(0.0f, GetAppListView()
@@ -5986,7 +4598,7 @@
 }
 
 // Tests that tapping or clicking on background cannot dismiss the app list.
-TEST_P(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) {
+TEST_F(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) {
   // Show app list in non-tablet mode. Click outside search box.
   GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6018,7 +4630,7 @@
   EXPECT_TRUE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        EscapeKeyInNonTabletModeClosesLauncher) {
   ShowAppList();
   EXPECT_TRUE(IsAppListVisible());
@@ -6028,7 +4640,7 @@
   EXPECT_FALSE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) {
+TEST_F(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) {
   ShowAppList();
   EXPECT_TRUE(IsAppListVisible());
 
@@ -6037,7 +4649,7 @@
   EXPECT_FALSE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        SearchKeyInNonTabletModeClosesLauncher) {
   ShowAppList();
   EXPECT_TRUE(IsAppListVisible());
@@ -6047,7 +4659,7 @@
   EXPECT_FALSE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        EscapeKeyInTabletModeDoesNotCloseLauncher) {
   EnableTabletMode(true);
   EXPECT_TRUE(IsAppListVisible());
@@ -6057,7 +4669,7 @@
   EXPECT_TRUE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        BackKeyInTabletModeDoesNotCloseLauncher) {
   EnableTabletMode(true);
   EXPECT_TRUE(IsAppListVisible());
@@ -6067,7 +4679,7 @@
   EXPECT_TRUE(IsAppListVisible());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        SearchKeyInTabletModeDoesNotCloseLauncher) {
   EnableTabletMode(true);
   EXPECT_TRUE(IsAppListVisible());
@@ -6078,7 +4690,7 @@
 }
 
 // Tests that moving focus outside app list window can dismiss it.
-TEST_P(AppListPresenterHomeLauncherTest, FocusOutToDismiss) {
+TEST_F(AppListPresenterHomeLauncherTest, FocusOutToDismiss) {
   // Show app list in non-tablet mode. Move focus to another window.
   GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6106,23 +4718,6 @@
   GetAppListTestHelper()->CheckVisibility(true);
 }
 
-// Tests that the gesture-scroll cannot dismiss the app list.
-TEST_F(AppListPresenterNonBubbleTest, GestureScrollToDismiss) {
-  // Show app list in non-tablet mode. Fling down.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckVisibility(true);
-  FlingUpOrDown(GetEventGenerator(), GetAppListView(), false /* up */);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckVisibility(false);
-
-  // Show app list in tablet mode. Fling down.
-  EnableTabletMode(true);
-  GetAppListTestHelper()->CheckVisibility(true);
-  FlingUpOrDown(GetEventGenerator(), GetAppListView(), false /* up */);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckVisibility(true);
-}
-
 TEST_F(AppListPresenterNonBubbleTest,
        MouseScrollUpFromPeekingShowsFullscreenLauncher) {
   // Show app list in non-tablet mode.
@@ -6182,37 +4777,9 @@
   GetAppListTestHelper()->CheckVisibility(false);
 }
 
-// Test that the AppListView opacity is reset after it is hidden during the
-// overview mode animation.
-TEST_P(AppListPresenterHomeLauncherTest, LauncherShowsAfterOverviewMode) {
-  // ProductivityLauncher closes itself in overview in clamshell mode.
-  if (features::IsProductivityLauncherEnabled())
-    return;
-
-  // Show the AppList in clamshell mode.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  // Enable overview mode.
-  EnterOverview();
-
-  // Test that the AppListView is transparent.
-  EXPECT_EQ(0.0f, GetAppListView()->GetWidget()->GetLayer()->opacity());
-
-  // Disable overview mode.
-  ExitOverview();
-
-  // Show the launcher, test that the opacity is restored.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  EXPECT_EQ(1.0f, GetAppListView()->GetWidget()->GetLayer()->opacity());
-  EXPECT_TRUE(GetAppListView()->GetWidget()->IsVisible());
-}
-
 // Tests that tapping home button while home screen is visible and showing
 // search results moves the home screen to apps container page.
-TEST_P(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) {
+TEST_F(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) {
   // Show app list in tablet mode.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6237,7 +4804,7 @@
 }
 
 // Tests the app list opacity in overview mode.
-TEST_P(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) {
+TEST_F(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) {
   // Show app list in tablet mode.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6255,13 +4822,13 @@
   EXPECT_EQ(1.0f, layer->opacity());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) {
+TEST_F(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) {
   EnableTabletMode(true);
   wallpaper_test_api_->StartWallpaperPreview();
   GetAppListTestHelper()->CheckVisibility(false);
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        AppListShownAfterWallpaperPreviewConfirmed) {
   EnableTabletMode(true);
   wallpaper_test_api_->StartWallpaperPreview();
@@ -6269,7 +4836,7 @@
   GetAppListTestHelper()->CheckVisibility(true);
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        AppListShownAfterWallpaperPreviewCanceled) {
   EnableTabletMode(true);
   wallpaper_test_api_->StartWallpaperPreview();
@@ -6277,7 +4844,7 @@
   GetAppListTestHelper()->CheckVisibility(true);
 }
 
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        AppListShownAfterWallpaperPreviewAndExitOverviewMode) {
   EnableTabletMode(true);
   wallpaper_test_api_->StartWallpaperPreview();
@@ -6290,7 +4857,7 @@
 }
 
 // Tests that going home will minimize all windows.
-TEST_P(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) {
+TEST_F(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) {
   // Show app list in tablet mode. Maximize all windows.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6327,7 +4894,7 @@
 }
 
 // Tests that going home will end split view mode.
-TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) {
+TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) {
   // Show app list in tablet mode. Enter split view mode.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6341,7 +4908,7 @@
 }
 
 // Tests that going home will end overview mode.
-TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) {
+TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) {
   // Show app list in tablet mode. Enter overview mode.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6357,7 +4924,7 @@
 
 // Tests that going home will end overview and split view mode if both are
 // active (e.g. one side of the split view contains overview).
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        GoingHomeEndsSplitViewModeWithOverview) {
   // Show app list in tablet mode. Enter split view mode.
   EnableTabletMode(true);
@@ -6383,7 +4950,7 @@
 
 // Tests that the context menu is triggered in the same way as if we are on
 // the wallpaper.
-TEST_P(AppListPresenterHomeLauncherTest, WallpaperContextMenu) {
+TEST_F(AppListPresenterHomeLauncherTest, WallpaperContextMenu) {
   // Show app list in tablet mode.
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6424,50 +4991,8 @@
   EXPECT_FALSE(root_window_controller->IsContextMenuShown());
 }
 
-// Tests app list visibility when switching to tablet mode during dragging to
-// close app list.
-TEST_P(AppListPresenterHomeLauncherTest,
-       SwitchToTabletModeDuringDraggingToClose) {
-  // ProductivityLauncher doesn't use peeking state or app list dragging.
-  if (features::IsProductivityLauncherEnabled())
-    return;
-
-  UpdateDisplay("1080x900");
-
-  // Open app list.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  // Drag to shelf to close app list.
-  ui::test::EventGenerator* generator = GetEventGenerator();
-  const int x = 540;
-  const int peeking_height =
-      900 - GetAppListView()->GetHeightForState(AppListViewState::kPeeking);
-  const int closed_y = 890;
-  generator->MoveTouch(gfx::Point(x, peeking_height));
-  generator->PressTouch();
-  generator->MoveTouch(gfx::Point(x, closed_y));
-  generator->ReleaseTouch();
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckVisibility(false);
-
-  // Open app list.
-  GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
-  GetAppListTestHelper()->CheckVisibility(true);
-
-  // Drag to shelf to close app list, meanwhile switch to tablet mode.
-  generator->MoveTouch(gfx::Point(x, peeking_height));
-  generator->PressTouch();
-  generator->MoveTouch(gfx::Point(x, peeking_height + 10));
-  EnableTabletMode(true);
-  generator->MoveTouch(gfx::Point(x, closed_y));
-  generator->ReleaseTouch();
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckVisibility(true);
-}
-
 // Test backdrop exists for active non-fullscreen window in tablet mode.
-TEST_P(AppListPresenterHomeLauncherTest, BackdropTest) {
+TEST_F(AppListPresenterHomeLauncherTest, BackdropTest) {
   WorkspaceControllerTestApi test_helper(ShellTestApi().workspace_controller());
   EnableTabletMode(true);
   GetAppListTestHelper()->CheckVisibility(true);
@@ -6482,7 +5007,7 @@
 
 // Tests that app list is not active when switching to tablet mode if an active
 // window exists.
-TEST_P(AppListPresenterHomeLauncherTest,
+TEST_F(AppListPresenterHomeLauncherTest,
        NotActivateAppListWindowWhenActiveWindowExists) {
   // No window is active.
   EXPECT_EQ(nullptr, window_util::GetActiveWindow());
@@ -6602,26 +5127,87 @@
   EXPECT_FALSE(GetSearchBoxView()->is_search_box_active());
 }
 
-TEST_P(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) {
+TEST_F(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) {
   UpdateDisplay("800x600,1000x768");
 
   TapHomeButton(GetSecondaryDisplay().id());
   {
     SCOPED_TRACE("1st tap");
     GetAppListTestHelper()->CheckVisibility(true);
-    if (!features::IsProductivityLauncherEnabled())
-      GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
   }
 
   TapHomeButton(GetSecondaryDisplay().id());
   {
     SCOPED_TRACE("2nd tap");
     GetAppListTestHelper()->CheckVisibility(false);
-    if (!features::IsProductivityLauncherEnabled())
-      GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
   }
 }
 
+// Tests that a tap/click on the AppListView from Fullscreen search returns
+// the AppListView to fullscreen all apps, and that a tap/click on the
+// AppListView from fullscreen all apps closes the app list.
+TEST_P(AppListPresenterHomeLauncherTest,
+       StateTransitionsByTappingAppListBodyFromFullscreen) {
+  EnableTabletMode(true);
+  GetAppListTestHelper()->CheckVisibility(true);
+
+  SearchBoxView* search_box_view = GetAppListView()->search_box_view();
+  ui::test::EventGenerator* generator = GetEventGenerator();
+  const bool test_mouse_event = TestMouseEventParam();
+
+  // Press a key, this should activate the searchbox and transition to
+  // fullscreen search.
+  PressAndReleaseKey(ui::KeyboardCode::VKEY_0);
+  GetAppListTestHelper()->WaitUntilIdle();
+  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
+  EXPECT_TRUE(search_box_view->is_search_box_active());
+
+  // Tap outside the searchbox, this should deactivate the searchbox and the
+  // applistview should return to fullscreen all apps.
+  if (test_mouse_event) {
+    generator->MoveMouseTo(GetPointOutsideSearchbox());
+    generator->ClickLeftButton();
+  } else {
+    generator->GestureTapDownAndUp(GetPointOutsideSearchbox());
+  }
+  GetAppListTestHelper()->WaitUntilIdle();
+  GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
+  EXPECT_FALSE(search_box_view->is_search_box_active());
+}
+
+// Tests that the searchbox activates when it is tapped and that the widget is
+// closed after tapping outside the searchbox.
+TEST_P(AppListPresenterHomeLauncherTest, TapAndClickEnablesSearchBox) {
+  EnableTabletMode(true);
+  GetAppListTestHelper()->CheckVisibility(true);
+
+  SearchBoxView* search_box_view = GetAppListView()->search_box_view();
+  ui::test::EventGenerator* generator = GetEventGenerator();
+  const bool test_mouse_event = TestMouseEventParam();
+
+  if (test_mouse_event) {
+    generator->MoveMouseTo(GetPointInsideSearchbox());
+    generator->PressLeftButton();
+    generator->ReleaseLeftButton();
+  } else {
+    generator->GestureTapAt(GetPointInsideSearchbox());
+  }
+
+  EXPECT_TRUE(search_box_view->is_search_box_active());
+
+  // Tap on the body of the app list, the search box should deactivate.
+  if (test_mouse_event) {
+    generator->MoveMouseTo(GetPointOutsideSearchbox());
+    generator->PressLeftButton();
+    generator->ReleaseLeftButton();
+  } else {
+    generator->GestureTapAt(GetPointOutsideSearchbox());
+  }
+  GetAppListTestHelper()->WaitUntilIdle();
+  EXPECT_FALSE(search_box_view->is_search_box_active());
+  GetAppListTestHelper()->CheckVisibility(true);
+}
+
 // Test that gesture tapping the app list search box correctly handles the event
 // by moving the textfield's cursor to the tapped position within the text.
 TEST_P(AppListPresenterTest, SearchBoxTextfieldGestureTap) {
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc
index 0452064d..335bd49 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -695,11 +695,9 @@
       continue_label_container_->AddChildView(std::make_unique<IconButton>(
           base::BindRepeating(&AppListBubbleAppsPage::OnToggleContinueSection,
                               base::Unretained(this)),
-          IconButton::Type::kTinyFloating, &kChevronUpIcon,
+          IconButton::Type::kXSmallFloating, &kChevronUpIcon,
           /*is_togglable=*/false,
           /*has_border=*/false));
-  // The icon is scaled down since the button is tiny.
-  toggle_continue_section_button_->SetIconSize(16);
   // See ButtonFocusSkipper in app_list_bubble_view.cc for focus handling.
 }
 
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc
index 1f5ce4de..7e9fb99 100644
--- a/ash/app_list/views/app_list_bubble_view.cc
+++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -607,6 +607,7 @@
     // NOTE: Folder view bounds are also modified during reparent drag when the
     // view is "visible" but hidden offscreen. See app_list_folder_view.cc.
     folder_view_->SetBoundsRect(folder_view_->preferred_bounds());
+    folder_view_->UpdateShadowBounds();
   }
 }
 
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc
index 668b2797..764b753 100644
--- a/ash/app_list/views/app_list_folder_view.cc
+++ b/ash/app_list/views/app_list_folder_view.cc
@@ -1102,7 +1102,7 @@
   }
 }
 
-void AppListFolderView::UpdateShadowForVirtualKeyboard() {
+void AppListFolderView::UpdateShadowBounds() {
   shadow_->SetContentBounds(background_view_->layer()->bounds());
 }
 
diff --git a/ash/app_list/views/app_list_folder_view.h b/ash/app_list/views/app_list_folder_view.h
index 4da8a5dc..78b3e412 100644
--- a/ash/app_list/views/app_list_folder_view.h
+++ b/ash/app_list/views/app_list_folder_view.h
@@ -137,9 +137,8 @@
   // Virtual keyboard
   int GetYOffsetForFolder();
 
-  // Force the folder `shadow_` to recalculate bounds after a virtual keyboard
-  // repositioned the view.
-  void UpdateShadowForVirtualKeyboard();
+  // Recalculates and updates the bounds of the folder `shadow_`  .
+  void UpdateShadowBounds();
 
   // Returns true if this view's child views are in animation for opening or
   // closing the folder.
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index 5bf8862..2abddf74 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -81,10 +81,6 @@
 // The height of the half app list, measured from the bottom of the screen.
 constexpr int kHalfHeight = 545;
 
-// The DIP distance from the bezel in which a gesture drag end results in a
-// closed app list.
-constexpr int kAppListBezelMargin = 50;
-
 // The size of app info dialog in fullscreen app list.
 constexpr int kAppInfoDialogWidth = 512;
 constexpr int kAppInfoDialogHeight = 384;
@@ -92,12 +88,6 @@
 // The duration of app list animations when they should run immediately.
 constexpr int kAppListAnimationDurationImmediateMs = 0;
 
-// Histogram for the app list dragging in clamshell mode.
-constexpr char kAppListDragInClamshellHistogram[] =
-    "Apps.StateTransition.Drag.PresentationTime.ClamshellMode";
-constexpr char kAppListDragInClamshellMaxLatencyHistogram[] =
-    "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode";
-
 // The number of minutes that must pass for the current app list page to reset
 // to the first page.
 constexpr int kAppListPageResetTimeLimitMinutes = 20;
@@ -180,19 +170,6 @@
                      sk_opacity_value);
 }
 
-// Gets radius for app list background corners when the app list has the
-// provided height. The rounded corner should match the current app list height
-// (so the rounded corners bottom edge matches the shelf top), until it reaches
-// the app list background radius (i.e. background radius in peeking app list
-// state).
-// |height|: App list view height, relative to the shelf top (i.e. distance
-//           between app list top and shelf top edge).
-double GetBackgroundRadiusForAppListHeight(double height,
-                                           int shelf_background_corner_radius) {
-  return std::min(static_cast<double>(shelf_background_corner_radius),
-                  std::max(height, 0.));
-}
-
 float ComputeSubpixelOffset(const display::Display& display, float value) {
   float pixel_position = std::round(display.device_scale_factor() * value);
   float dp_position = pixel_position / display.device_scale_factor();
@@ -984,127 +961,6 @@
   search_box_view_->ClearSearchAndDeactivateSearchBox();
 }
 
-void AppListView::StartDrag(const gfx::PointF& location_in_root) {
-  initial_drag_point_ = location_in_root;
-
-  drag_offset_ =
-      initial_drag_point_.y() - GetWidget()->GetNativeWindow()->bounds().y();
-}
-
-void AppListView::UpdateDrag(const gfx::PointF& location_in_root) {
-  float new_y_position_in_root = location_in_root.y() - drag_offset_;
-
-  UpdateYPositionAndOpacity(new_y_position_in_root,
-                            GetAppListBackgroundOpacityDuringDragging());
-}
-
-void AppListView::EndDrag(const gfx::PointF& location_in_root) {
-  // |is_in_drag_| might have been cleared if the app list was dismissed while
-  // drag was still in progress. Nothing to do here in that case.
-  if (!is_in_drag_) {
-    DCHECK_EQ(AppListViewState::kClosed, app_list_state_);
-    return;
-  }
-
-  // Remember the last fling velocity, as the value gets reset in SetIsInDrag.
-  const int last_fling_velocity = last_fling_velocity_;
-  SetIsInDrag(false);
-
-  // Change the app list state based on where the drag ended. If fling velocity
-  // was over the threshold, snap to the next state in the direction of the
-  // fling.
-  if (std::abs(last_fling_velocity) >= kDragVelocityThreshold) {
-    // If the user releases drag with velocity over the threshold, snap to
-    // the next state, ignoring the drag release position.
-
-    if (last_fling_velocity > 0) {
-      switch (app_list_state_) {
-        case AppListViewState::kPeeking:
-        case AppListViewState::kHalf:
-        case AppListViewState::kFullscreenSearch:
-        case AppListViewState::kFullscreenAllApps:
-          Dismiss();
-          break;
-        case AppListViewState::kClosed:
-          NOTREACHED();
-          break;
-      }
-    } else {
-      switch (app_list_state_) {
-        case AppListViewState::kFullscreenAllApps:
-        case AppListViewState::kFullscreenSearch:
-          SetState(app_list_state_);
-          break;
-        case AppListViewState::kHalf:
-          SetState(AppListViewState::kFullscreenSearch);
-          break;
-        case AppListViewState::kPeeking:
-          UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram,
-                                    kSwipe, kMaxPeekingToFullscreen);
-          SetState(AppListViewState::kFullscreenAllApps);
-          break;
-        case AppListViewState::kClosed:
-          NOTREACHED();
-          break;
-      }
-    }
-  } else {
-    int app_list_height = GetHeightForState(app_list_state_);
-
-    const int app_list_threshold =
-        app_list_height / kAppListThresholdDenominator;
-    const int drag_delta = initial_drag_point_.y() - location_in_root.y();
-    int display_bottom_in_root = GetDisplayNearestView().bounds().height();
-    // If the drag ended near the bezel, close the app list.
-    if (location_in_root.y() >=
-        (display_bottom_in_root - kAppListBezelMargin)) {
-      Dismiss();
-    } else {
-      switch (app_list_state_) {
-        case AppListViewState::kFullscreenAllApps:
-          if (drag_delta < -app_list_threshold) {
-            if (delegate_->IsInTabletMode() || is_side_shelf_)
-              Dismiss();
-            else
-              SetState(AppListViewState::kPeeking);
-          } else {
-            SetState(app_list_state_);
-          }
-          break;
-        case AppListViewState::kFullscreenSearch:
-          if (drag_delta < -app_list_threshold)
-            Dismiss();
-          else
-            SetState(app_list_state_);
-          break;
-        case AppListViewState::kHalf:
-          if (drag_delta > app_list_threshold)
-            SetState(AppListViewState::kFullscreenSearch);
-          else if (drag_delta < -app_list_threshold)
-            Dismiss();
-          else
-            SetState(app_list_state_);
-          break;
-        case AppListViewState::kPeeking:
-          if (drag_delta > app_list_threshold) {
-            SetState(AppListViewState::kFullscreenAllApps);
-            UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram,
-                                      kSwipe, kMaxPeekingToFullscreen);
-          } else if (drag_delta < -app_list_threshold) {
-            Dismiss();
-          } else {
-            SetState(app_list_state_);
-          }
-          break;
-        case AppListViewState::kClosed:
-          NOTREACHED();
-          break;
-      }
-    }
-  }
-  initial_drag_point_ = gfx::PointF();
-}
-
 void AppListView::SetChildViewsForStateTransition(
     AppListViewState target_state) {
   if (target_state == AppListViewState::kHalf ||
@@ -1359,43 +1215,15 @@
     return;
 
   switch (event->type()) {
+    // TODO(https://crbug.com/1356661): Consider not marking ET_MOUSE_DRAGGED as
+    // handled here.
     case ui::ET_MOUSE_PRESSED:
-      event->SetHandled();
-      if (is_in_drag_)
-        return;
-      initial_mouse_drag_point_ = event->root_location_f();
-      break;
     case ui::ET_MOUSE_DRAGGED:
       event->SetHandled();
-      if (is_side_shelf_ || delegate_->IsInTabletMode())
-        return;
-      if (!is_in_drag_ && event->IsOnlyLeftMouseButton()) {
-        // Calculate the mouse drag offset to determine whether AppListView is
-        // in drag.
-        gfx::Vector2dF drag_distance =
-            event->root_location_f() - initial_mouse_drag_point_;
-        if (std::abs(drag_distance.y()) < kMouseDragThreshold)
-          return;
-
-        StartDrag(initial_mouse_drag_point_);
-        SetIsInDrag(true);
-        app_list_main_view_->contents_view()->UpdateYPositionAndOpacity();
-      }
-
-      if (!is_in_drag_)
-        return;
-      UpdateDrag(event->root_location_f());
       break;
     case ui::ET_MOUSE_RELEASED:
       event->SetHandled();
-      initial_mouse_drag_point_ = gfx::PointF();
-      if (!is_in_drag_) {
-        HandleClickOrTap(event);
-        return;
-      }
-      EndDrag(event->root_location_f());
-      CloseKeyboardIfVisible();
-      SetIsInDrag(false);
+      HandleClickOrTap(event);
       break;
     case ui::ET_MOUSEWHEEL:
       if (HandleScroll(event->location(), event->AsMouseWheelEvent()->offset(),
@@ -1418,49 +1246,9 @@
     case ui::ET_GESTURE_LONG_PRESS:
     case ui::ET_GESTURE_LONG_TAP:
     case ui::ET_GESTURE_TWO_FINGER_TAP:
-      SetIsInDrag(false);
       event->SetHandled();
       HandleClickOrTap(event);
       break;
-    case ui::ET_SCROLL_FLING_START:
-    case ui::ET_GESTURE_SCROLL_BEGIN: {
-      // If the search box is active when we start our drag, let it know.
-      if (search_box_view_->is_search_box_active())
-        search_box_view_->NotifyGestureEvent();
-
-      // Avoid scrolling events for the app list in tablet mode.
-      if (is_side_shelf_ || delegate_->IsInTabletMode())
-        return;
-      // There may be multiple scroll begin events in one drag because the
-      // relative location of the finger and widget is almost unchanged and
-      // scroll begin event occurs when the relative location changes beyond a
-      // threshold. So avoid resetting the initial drag point in drag.
-      if (!is_in_drag_)
-        StartDrag(event->root_location_f());
-      SetIsInDrag(true);
-      event->SetHandled();
-      break;
-    }
-    case ui::ET_GESTURE_SCROLL_UPDATE: {
-      // Avoid scrolling events for the app list in tablet mode.
-      if (is_side_shelf_ || delegate_->IsInTabletMode())
-        return;
-      SetIsInDrag(true);
-      last_fling_velocity_ = event->details().scroll_y();
-      UpdateDrag(event->root_location_f());
-      event->SetHandled();
-      break;
-    }
-    case ui::ET_GESTURE_END: {
-      if (!is_in_drag_)
-        break;
-      // Avoid scrolling events for the app list in tablet mode.
-      if (is_side_shelf_ || delegate_->IsInTabletMode())
-        return;
-      EndDrag(event->root_location_f());
-      event->SetHandled();
-      break;
-    }
     default:
       break;
   }
@@ -1474,11 +1262,6 @@
   search_box_view_->OnTabletModeChanged(started);
   app_list_main_view_->contents_view()->OnTabletModeChanged(started);
 
-  if (is_in_drag_) {
-    SetIsInDrag(false);
-    UpdateChildViewsYPositionAndOpacity();
-  }
-
   // Refresh the state if the view is not in a fullscreen state.
   if (started && !is_fullscreen())
     SetState(app_list_state_);
@@ -1615,10 +1398,6 @@
   base::WeakPtr<AppListView> set_state_request =
       set_state_weak_factory_.GetWeakPtr();
 
-  // Clear the drag state before closing the view.
-  if (new_state_override == AppListViewState::kClosed)
-    SetIsInDrag(false);
-
   SetChildViewsForStateTransition(new_state_override);
 
   // Bail out if `SetChildViewForStateTransition()` caused another call to
@@ -1648,9 +1427,6 @@
   if (delegate_)
     delegate_->OnViewStateChanged(new_state_override);
 
-  if (is_in_drag_ && app_list_state_ != AppListViewState::kClosed)
-    app_list_main_view_->contents_view()->UpdateYPositionAndOpacity();
-
   if (GetWidget()->IsActive()) {
     // Reset the focus to initially focused view. This should be
     // done before updating visibility of views, because setting
@@ -1670,7 +1446,7 @@
 
   // Updates the visibility of app list items according to the change of
   // |app_list_state_|.
-  GetAppsContainerView()->UpdateControlVisibility(app_list_state_, is_in_drag_);
+  GetAppsContainerView()->UpdateControlVisibility(app_list_state_, false);
 }
 
 void AppListView::UpdateWindowTitle() {
@@ -1734,15 +1510,13 @@
   ApplyBoundsAnimation(target_state, animation_duration);
   app_list_main_view_->contents_view()->OnAppListViewTargetStateChanged(
       target_state);
-  if (!is_in_drag_) {
-    app_list_main_view_->contents_view()->AnimateToViewState(
-        target_state, animation_duration);
-  }
+  app_list_main_view_->contents_view()->AnimateToViewState(target_state,
+                                                           animation_duration);
 }
 
 void AppListView::ApplyBoundsAnimation(AppListViewState target_state,
                                        base::TimeDelta duration_ms) {
-  if (is_side_shelf_ || is_in_drag_) {
+  if (is_side_shelf_) {
     // There is no animation in side shelf.
     UpdateAppListBackgroundYPosition(target_state);
     // Mark the state transition as complete directly, as no animations that
@@ -1781,8 +1555,6 @@
   // state transitions - for example
   // *   When interrupting another state transition half-way, in which case the
   //     layer has non-identity ransform.
-  // *   Starting an animation after drag gesture, in which case bounds may not
-  //     match the expected app list bounds in the current state.
   bool report_animation_throughput =
       layer->transform() == gfx::Transform() &&
       layer->bounds() == GetPreferredWidgetBoundsForState(app_list_state_);
@@ -1889,40 +1661,6 @@
   }
 }
 
-void AppListView::UpdateYPositionAndOpacity(float y_position_in_root,
-                                            float background_opacity) {
-  DCHECK(!is_side_shelf_);
-  if (app_list_state_ == AppListViewState::kClosed)
-    return;
-
-  if (GetWidget()->GetLayer()->GetAnimator()->IsAnimatingProperty(
-          ui::LayerAnimationElement::TRANSFORM)) {
-    GetWidget()->GetLayer()->GetAnimator()->StopAnimatingProperty(
-        ui::LayerAnimationElement::TRANSFORM);
-  }
-
-  SetIsInDrag(true);
-
-  presentation_time_recorder_->RequestNext();
-
-  background_opacity_in_drag_ = background_opacity;
-  gfx::Rect new_window_bounds = GetWidget()->GetNativeWindow()->bounds();
-  display::Display display = GetDisplayNearestView();
-  float app_list_y_position_in_root = std::min(
-      std::max(y_position_in_root,
-               static_cast<float>(display.GetWorkAreaInsets().top())),
-      static_cast<float>(display.size().height() - delegate_->GetShelfSize()));
-
-  gfx::NativeView native_view = GetWidget()->GetNativeView();
-  new_window_bounds.set_y(static_cast<int>(app_list_y_position_in_root));
-  native_view->SetBounds(new_window_bounds);
-  native_view->layer()->SetSubpixelPositionOffset(gfx::Vector2dF(
-      ComputeSubpixelOffset(display, new_window_bounds.x()),
-      ComputeSubpixelOffset(display, app_list_y_position_in_root)));
-
-  UpdateChildViewsYPositionAndOpacity();
-}
-
 void AppListView::OffsetYPositionOfAppList(int offset) {
   gfx::NativeView native_view = GetWidget()->GetNativeView();
   gfx::Transform transform;
@@ -1941,35 +1679,6 @@
   return app_info_bounds;
 }
 
-void AppListView::SetIsInDrag(bool is_in_drag) {
-  if (!is_in_drag && !delegate_->IsInTabletMode())
-    presentation_time_recorder_.reset();
-
-  if (is_in_drag == is_in_drag_)
-    return;
-
-  // Reset |last_fling_velocity_| if it was set during the drag.
-  if (!is_in_drag)
-    last_fling_velocity_ = 0;
-
-  // Don't allow dragging to interrupt the close animation, it probably is not
-  // intentional.
-  if (app_list_state_ == AppListViewState::kClosed)
-    return;
-
-  is_in_drag_ = is_in_drag;
-
-  if (is_in_drag && !delegate_->IsInTabletMode()) {
-    presentation_time_recorder_.reset();
-    presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
-        GetWidget()->GetCompositor(), kAppListDragInClamshellHistogram,
-        kAppListDragInClamshellMaxLatencyHistogram);
-  }
-
-  GetAppsContainerView()->UpdateControlVisibility(target_app_list_state_,
-                                                  is_in_drag_);
-}
-
 void AppListView::OnHomeLauncherGainingFocusWithoutAnimation() {
   if (GetFocusManager()->GetFocusedView() != GetInitiallyFocusedView())
     GetInitiallyFocusedView()->RequestFocus();
@@ -2133,7 +1842,7 @@
 
   // NOTE: `target_state` may not match `app_list_state_` if
   // `OnBoundsAnimationCompleted()` gets called synchronously - for example,
-  // for state changes during drag, and with side shelf.
+  // for state changes with side shelf.
   delegate_->OnStateTransitionAnimationCompleted(target_state,
                                                  was_animation_interrupted);
 }
@@ -2151,18 +1860,6 @@
       animation_end_timestamp);
 }
 
-void AppListView::UpdateChildViewsYPositionAndOpacity() {
-  if (target_app_list_state_ == AppListViewState::kClosed)
-    return;
-
-  UpdateAppListBackgroundYPosition(target_app_list_state_);
-
-  // Update the opacity of the background shield.
-  SetBackgroundShieldColor();
-
-  app_list_main_view_->contents_view()->UpdateYPositionAndOpacity();
-}
-
 void AppListView::RedirectKeyEventToSearchBox(ui::KeyEvent* event) {
   if (event->handled())
     return;
@@ -2210,18 +1907,14 @@
         GetAppsContainerView()->app_list_folder_view()->GetYOffsetForFolder();
     if (folder_offset != 0) {
       OffsetYPositionOfAppList(folder_offset);
-      GetAppsContainerView()
-          ->app_list_folder_view()
-          ->UpdateShadowForVirtualKeyboard();
+      GetAppsContainerView()->app_list_folder_view()->UpdateShadowBounds();
       offset_to_show_folder_with_onscreen_keyboard_ = true;
     }
   } else if (offset_to_show_folder_with_onscreen_keyboard_) {
     // If the keyboard is closing or a folder isn't being shown, reset
     // the app list's position
     OffsetYPositionOfAppList(0);
-    GetAppsContainerView()
-        ->app_list_folder_view()
-        ->UpdateShadowForVirtualKeyboard();
+    GetAppsContainerView()->app_list_folder_view()->UpdateShadowBounds();
     offset_to_show_folder_with_onscreen_keyboard_ = false;
   }
 
@@ -2254,20 +1947,6 @@
   EnsureWidgetBoundsMatchCurrentState();
 }
 
-float AppListView::GetAppListBackgroundOpacityDuringDragging() {
-  float top_of_applist = GetWidget()->GetWindowBoundsInScreen().y();
-  const int shelf_height = delegate_->GetShelfSize();
-  float dragging_height =
-      std::max((GetScreenBottom() - shelf_height - top_of_applist), 0.f);
-  float coefficient =
-      std::min(dragging_height / (kNumOfShelfSize * shelf_height), 1.0f);
-  float shield_opacity =
-      is_background_blur_enabled_ ? kAppListOpacityWithBlur : kAppListOpacity;
-  // Assume shelf is opaque when start to drag down the launcher.
-  const float shelf_opacity = 1.0f;
-  return coefficient * shield_opacity + (1 - coefficient) * shelf_opacity;
-}
-
 void AppListView::SetBackgroundShieldColor() {
   // There is a chance when AppListView::OnWallpaperColorsChanged is called
   // from AppListViewDelegate, the |app_list_background_shield_| is not
@@ -2282,10 +1961,6 @@
   if (delegate_->IsInTabletMode()) {
     // The Homecher background should have an opacity of 0.
     color_opacity = 0;
-  } else if (is_in_drag_) {
-    // Allow a custom opacity while the AppListView is dragging to show a
-    // gradual opacity change when dragging from the shelf.
-    color_opacity = background_opacity_in_drag_;
   } else if (is_background_blur_enabled_) {
     color_opacity = kAppListOpacityWithBlur;
   }
@@ -2296,11 +1971,6 @@
 }
 
 bool AppListView::ShouldIgnoreScrollEvents() {
-  // When the app list is doing state change animation or the apps grid view is
-  // in transition, ignore the scroll events to prevent triggering extra state
-  // changes or transitions.
-  if (is_in_drag())
-    return true;
   if (app_list_state_ != AppListViewState::kPeeking &&
       app_list_state_ != AppListViewState::kFullscreenAllApps)
     return true;
@@ -2360,29 +2030,7 @@
 
   // Update the y position of the background shield.
   gfx::Transform transform;
-  if (is_in_drag_) {
-    // For the purpose of determining background shield offset, use progress
-    // with kHalf baseline so the background shield does not start translating
-    // up before it reaches kHalf height (which is larger than kPeeking height).
-    // If the shield transform started at kPeeking height, the app list view
-    // background would jump up when starting drag from the kHalf state.
-    float app_list_transition_progress =
-        GetAppListTransitionProgress(kProgressFlagSearchResults);
-    if (app_list_transition_progress < 1 && !shelf_has_rounded_corners()) {
-      const float shelf_height =
-          GetScreenBottom() - GetDisplayNearestView().work_area().bottom();
-      app_list_background_shield_->SetBackgroundRadius(
-          GetBackgroundRadiusForAppListHeight(
-              GetCurrentAppListHeight() - shelf_height,
-              app_list_background_corner_radius));
-    } else if (app_list_transition_progress >= 1 &&
-               app_list_transition_progress <= 2) {
-      // Translate background shield so that it ends drag at a y position
-      // according to the background radius in peeking and fullscreen.
-      transform.Translate(0, -app_list_background_corner_radius *
-                                 (app_list_transition_progress - 1));
-    }
-  } else if (ShouldHideRoundedCorners(state, GetBoundsInScreen())) {
+  if (ShouldHideRoundedCorners(state, GetBoundsInScreen())) {
     transform.Translate(0, -app_list_background_corner_radius);
   }
 
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h
index 3dcff9f..a38c610 100644
--- a/ash/app_list/views/app_list_view.h
+++ b/ash/app_list/views/app_list_view.h
@@ -54,8 +54,6 @@
                      CheckAppListViewBoundsWhenVKeyboardEnabled);
 FORWARD_DECLARE_TEST(AppListControllerImplTest,
                      CheckAppListViewBoundsWhenDismissVKeyboard);
-FORWARD_DECLARE_TEST(AppListControllerImplMetricsTest,
-                     PresentationTimeRecordedForDragInTabletMode);
 
 // The fraction of app list height that the app list must be released at in
 // order to transition to the next state.
@@ -114,10 +112,6 @@
     AppListView* const view_;
   };
 
-  // Number of the size of shelf. Used to determine the opacity of items in the
-  // app list during dragging.
-  static constexpr float kNumOfShelfSize = 2.0;
-
   // The opacity of the app list background.
   static constexpr float kAppListOpacity = 0.95;
 
@@ -131,23 +125,6 @@
   // its state.
   static constexpr int kScrollIgnoreTimeMs = 500;
 
-  // The snapping threshold for dragging app list from shelf in tablet mode,
-  // measured in DIPs.
-  static constexpr int kDragSnapToFullscreenThreshold = 320;
-
-  // The snapping thresholds for dragging app list from shelf in laptop mode,
-  // measured in DIPs.
-  static constexpr int kDragSnapToClosedThreshold = 120;
-  static constexpr int kDragSnapToPeekingThreshold = 561;
-
-  // The velocity the app list must be dragged from the shelf in order to
-  // transition to the next state, measured in DIPs/event.
-  static constexpr int kDragVelocityFromShelfThreshold = 120;
-
-  // The velocity the app list must be dragged in order to transition to the
-  // next state, measured in DIPs/event.
-  static constexpr int kDragVelocityThreshold = 6;
-
   // The animation duration for app list movement.
   static constexpr int kAppListAnimationDurationMs = 200;
   static constexpr int kAppListAnimationDurationFromFullscreenMs = 250;
@@ -248,16 +225,9 @@
   void SetStateFromSearchBoxView(bool search_box_is_empty,
                                  bool triggered_by_contents_change);
 
-  // Updates y position and opacity of app list during dragging.
-  void UpdateYPositionAndOpacity(float y_position_in_screen,
-                                 float background_opacity);
-
   // Offsets the y position of the app list (above the screen)
   void OffsetYPositionOfAppList(int offset);
 
-  // Update Y position and opacity of this view's child views during dragging.
-  void UpdateChildViewsYPositionAndOpacity();
-
   // The search box cannot actively listen to all key events. To control and
   // input into the search box when it does not have focus, we need to redirect
   // necessary key events to the search box.
@@ -273,9 +243,6 @@
   // hidden
   bool CloseKeyboardIfVisible();
 
-  // Sets |is_in_drag_| and updates the visibility of app list items.
-  void SetIsInDrag(bool is_in_drag);
-
   // Home launcher can become the focused window without being reset when all
   // open windows are closed in tablet mode. Ensures that correct initial view
   // is focused in this case.
@@ -334,11 +301,6 @@
   // Returns a animation metrics reporting callback  for state transition.
   metrics_util::SmoothnessCallback GetStateTransitionMetricsReportCallback();
 
-  // Called when drag in tablet mode starts/proceeds/ends.
-  void OnHomeLauncherDragStart();
-  void OnHomeLauncherDragInProgress();
-  void OnHomeLauncherDragEnd();
-
   // Resets the animation metrics reporter for state transition.
   void ResetTransitionMetricsReporter();
 
@@ -378,8 +340,6 @@
 
   bool shelf_has_rounded_corners() const { return shelf_has_rounded_corners_; }
 
-  bool is_in_drag() const { return is_in_drag_; }
-
   void set_onscreen_keyboard_shown(bool onscreen_keyboard_shown) {
     onscreen_keyboard_shown_ = onscreen_keyboard_shown;
   }
@@ -426,17 +386,6 @@
   // AppListView.
   void HandleClickOrTap(ui::LocatedEvent* event);
 
-  // Initializes |initial_drag_point_|.
-  void StartDrag(const gfx::PointF& location_in_root);
-
-  // Updates the bounds of the widget while maintaining the relative position
-  // of the top of the widget and the gesture.
-  void UpdateDrag(const gfx::PointF& location_in_root);
-
-  // Handles app list state transfers. If the drag was fast enough, ignore the
-  // release position and snap to the next state.
-  void EndDrag(const gfx::PointF& location_in_root);
-
   // Set child views for |target_state|.
   void SetChildViewsForStateTransition(AppListViewState target_state);
 
@@ -494,9 +443,6 @@
   // Overridden from views::WidgetDelegateView:
   views::View* GetInitiallyFocusedView() override;
 
-  // Gets app list background opacity during dragging.
-  float GetAppListBackgroundOpacityDuringDragging();
-
   const std::vector<SkColor>& GetWallpaperProminentColors();
   void SetBackgroundShieldColor();
 
@@ -522,7 +468,7 @@
   gfx::Rect GetPreferredWidgetBoundsForState(AppListViewState state);
 
   // Updates y position of |app_list_background_shield_| based on the
-  // |state| and |is_in_drag_|.
+  // |state|.
   void UpdateAppListBackgroundYPosition(AppListViewState state);
 
   // Reset the subpixel position offset of the |layer| so that it's DP origin
@@ -552,27 +498,9 @@
   // Whether the shelf has rounded corners.
   bool shelf_has_rounded_corners_ = false;
 
-  // True if the user is in the process of gesture-dragging on opened app list,
-  // or dragging the app list from shelf.
-  bool is_in_drag_ = false;
-
   // Whether the view is being built.
   bool is_building_ = false;
 
-  // The opacity of app list background during dragging. This ensures a gradual
-  // opacity shift from the shelf opacity while dragging to show the AppListView
-  // from the shelf.
-  float background_opacity_in_drag_ = 0.f;
-
-  // The location of initial gesture event in root window coordinates.
-  gfx::PointF initial_drag_point_;
-
-  // The offset to the widget from dragging location.
-  float drag_offset_;
-
-  // The location of the initial mouse event in root window coordinates.
-  gfx::PointF initial_mouse_drag_point_;
-
   // The velocity of the gesture event.
   float last_fling_velocity_ = 0;
   // Whether the background blur is enabled.
@@ -605,9 +533,6 @@
   // If true, the contents view is not reset when showing the app list.
   bool disable_contents_reset_when_showing_ = false;
 
-  // Records the presentation time for app launcher dragging.
-  std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
-
   // A timer which will reset the app list to the initial page. This timer only
   // goes off when the app list is not visible after a set amount of time.
   base::OneShotTimer page_reset_timer_;
diff --git a/ash/app_list/views/app_list_view_pixeltest.cc b/ash/app_list/views/app_list_view_pixeltest.cc
index 434b3a25..84794074 100644
--- a/ash/app_list/views/app_list_view_pixeltest.cc
+++ b/ash/app_list/views/app_list_view_pixeltest.cc
@@ -3,11 +3,13 @@
 // found in the LICENSE file.
 
 #include "ash/app_list/test/app_list_test_helper.h"
+#include "ash/app_list/views/app_list_bubble_apps_page.h"
 #include "ash/app_list/views/search_box_view.h"
 #include "ash/shell.h"
 #include "ash/test/ash_pixel_diff_test_helper.h"
 #include "ash/test/ash_pixel_test_init_params.h"
 #include "ash/test/ash_test_base.h"
+#include "ui/views/controls/scroll_view.h"
 #include "ui/views/controls/textfield/textfield_test_api.h"
 
 namespace ash {
@@ -56,11 +58,30 @@
 // Verifies the app list view under the clamshell mode.
 TEST_P(AppListViewPixelRTLTest, Basics) {
   GetAppListTestHelper()->AddAppItemsWithColorAndName(
-      2, AppListTestHelper::IconColorType::kAlternativeColor,
+      /*num_apps=*/2, AppListTestHelper::IconColorType::kAlternativeColor,
       /*set_name=*/true);
   ShowAppListAndHideCursor();
   EXPECT_TRUE(pixel_test_helper_.ComparePrimaryFullScreen(
       GetParam() ? "bubble_launcher_basics_rtl" : "bubble_launcher_basics"));
 }
 
+// Verifies that the app list gradient zones work as expected.
+TEST_P(AppListViewPixelRTLTest, GradientZone) {
+  GetAppListTestHelper()->AddAppItemsWithColorAndName(
+      /*num_apps=*/22, AppListTestHelper::IconColorType::kAlternativeColor,
+      /*set_name=*/true);
+  ShowAppListAndHideCursor();
+  views::ScrollView* scroll_view =
+      GetAppListTestHelper()->GetBubbleAppsPage()->scroll_view();
+
+  // Scroll the bubble app list so that some app list icons are beneath the
+  // gradient zones.
+  scroll_view->ScrollToPosition(scroll_view->vertical_scroll_bar(),
+                                /*position=*/20);
+
+  EXPECT_TRUE(pixel_test_helper_.ComparePrimaryFullScreen(
+      GetParam() ? "bubble_launcher_gradient_zone_rtl"
+                 : "bubble_launcher_gradient_zone"));
+}
+
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc
index 8216c65..20f5d1c 100644
--- a/ash/app_list/views/app_list_view_unittest.cc
+++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -2377,76 +2377,6 @@
   ASSERT_EQ(2, delegate_->dismiss_count());
 }
 
-// Tests that search box should not become a rectangle during drag.
-TEST_F(AppListViewPeekingTest, SearchBoxCornerRadiusDuringDragging) {
-  base::HistogramTester histogram_tester;
-  Initialize(false /*is_tablet_mode*/);
-  delegate_->GetTestModel()->PopulateApps(kInitialItems);
-  Show();
-  view_->SetState(ash::AppListViewState::kFullscreenAllApps);
-  EXPECT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state());
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);
-
-  // Send SCROLL_START and SCROLL_UPDATE events, simulating dragging the
-  // launcher.
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  gfx::Point start = view_->GetWidget()->GetWindowBoundsInScreen().top_right();
-  int delta_y = 1;
-  ui::GestureEvent start_event = ui::GestureEvent(
-      start.x(), start.y(), ui::EF_NONE, timestamp,
-      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, delta_y));
-  view_->OnGestureEvent(&start_event);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);
-
-  // Drag down the launcher.
-  timestamp += base::Milliseconds(25);
-  delta_y += 10;
-  start.Offset(0, 1);
-  ui::GestureEvent update_event = ui::GestureEvent(
-      start.x(), start.y(), ui::EF_NONE, timestamp,
-      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, delta_y));
-  view_->OnGestureEvent(&update_event);
-
-  EXPECT_TRUE(IsStateShown(ash::AppListState::kStateApps));
-  EXPECT_EQ(kSearchBoxBorderCornerRadius,
-            search_box_view()->GetSearchBoxBorderCornerRadiusForState(
-                ash::AppListState::kStateApps));
-
-  // Search box should keep |kSearchBoxCornerRadiusFullscreen| corner radius
-  // during drag.
-  EXPECT_TRUE(SetAppListState(ash::AppListState::kStateSearchResults));
-  EXPECT_TRUE(view_->is_in_drag());
-  EXPECT_EQ(kSearchBoxBorderCornerRadius,
-            search_box_view()->GetSearchBoxBorderCornerRadiusForState(
-                ash::AppListState::kStateSearchResults));
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);
-
-  // Ends to drag the launcher.
-  EXPECT_TRUE(SetAppListState(ash::AppListState::kStateApps));
-  timestamp += base::Milliseconds(25);
-  start.Offset(0, 1);
-  ui::GestureEvent end_event =
-      ui::GestureEvent(start.x(), start.y() + delta_y, ui::EF_NONE, timestamp,
-                       ui::GestureEventDetails(ui::ET_GESTURE_END));
-  view_->OnGestureEvent(&end_event);
-
-  // Search box should keep |kSearchBoxCornerRadiusFullscreen| corner radius
-  // if launcher drag finished.
-  EXPECT_FALSE(view_->is_in_drag());
-  EXPECT_EQ(kSearchBoxBorderCornerRadius,
-            search_box_view()->GetSearchBoxBorderCornerRadiusForState(
-                ash::AppListState::kStateApps));
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 1);
-}
-
 // Tests displaying the app list and performs a standard set of checks on its
 // top level views.
 TEST_F(AppListViewPeekingTest, DisplayTest) {
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc
index 726a3ac8..d73f15f 100644
--- a/ash/app_list/views/apps_container_view.cc
+++ b/ash/app_list/views/apps_container_view.cc
@@ -1552,15 +1552,6 @@
   scrollable_container_->SetY(current_suggestion_chip_y +
                               chip_grid_y_distance_);
   page_switcher_->SetY(current_suggestion_chip_y + chip_grid_y_distance_);
-
-  // If app list is in drag, reset transforms that might started animating in
-  // AnimateYPosition().
-  if (contents_view_->app_list_view()->is_in_drag()) {
-    if (suggestion_chip_container_view_)
-      suggestion_chip_container_view_->layer()->SetTransform(gfx::Transform());
-    scrollable_container_->layer()->SetTransform(gfx::Transform());
-    page_switcher_->layer()->SetTransform(gfx::Transform());
-  }
 }
 
 void AppsContainerView::DisableFocusForShowingActiveFolder(bool disabled) {
diff --git a/ash/app_list/views/apps_container_view.h b/ash/app_list/views/apps_container_view.h
index 86b2059b..e0ab3df6 100644
--- a/ash/app_list/views/apps_container_view.h
+++ b/ash/app_list/views/apps_container_view.h
@@ -75,6 +75,7 @@
 
   // Updates the visibility of the items in this view according to
   // |app_list_state| and |is_in_drag|.
+  // TODO(crbug.com/1356674): Remove |is_in_drag| from parameters.
   void UpdateControlVisibility(AppListViewState app_list_state,
                                bool is_in_drag);
 
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc
index dc807d7..3ef07c8 100644
--- a/ash/app_list/views/apps_grid_view_unittest.cc
+++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -858,20 +858,17 @@
                          testing::Combine(testing::Bool(), testing::Bool()));
 
 // Test suite for verifying tablet mode apps grid behaviour, parameterized by
-// RTL locale and ProductivityLauncher feature.
-class AppsGridViewTabletTest
-    : public AppsGridViewTest,
-      public testing::WithParamInterface<std::tuple<bool, bool>> {
+// RTL locale.
+class AppsGridViewTabletTest : public AppsGridViewTest,
+                               public testing::WithParamInterface<bool> {
  public:
   AppsGridViewTabletTest() {
-    is_rtl_ = std::get<0>(GetParam());
-    is_productivity_launcher_enabled_ = std::get<1>(GetParam());
+    is_rtl_ = GetParam();
+    is_productivity_launcher_enabled_ = true;
     create_as_tablet_mode_ = true;
   }
 };
-INSTANTIATE_TEST_SUITE_P(All,
-                         AppsGridViewTabletTest,
-                         testing::Combine(testing::Bool(), testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(All, AppsGridViewTabletTest, testing::Bool());
 
 // Test suite that tests apps sort works on all apps grid, parameterized by
 // RTL locale and clamshell/tablet mode.
@@ -1182,127 +1179,6 @@
   EXPECT_EQ(base::ASCIIToUTF16(title), title_label->GetText());
 }
 
-TEST_P(AppsGridViewRTLTest, ScrollSequenceHandledByAppListView) {
-  base::HistogramTester histogram_tester;
-
-  model_->PopulateApps(GetTilesPerPage(0) + 1);
-  UpdateLayout();
-  EXPECT_EQ(2, GetPaginationModel()->total_pages());
-
-  gfx::Point apps_grid_view_origin =
-      apps_grid_view_->GetBoundsInScreen().origin();
-  ui::GestureEvent scroll_begin(
-      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
-      base::TimeTicks(),
-      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 1));
-  ui::GestureEvent scroll_update(
-      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
-      base::TimeTicks(),
-      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, 10));
-  ui::GestureEvent scroll_end(apps_grid_view_origin.x(),
-                              apps_grid_view_origin.y(), 0, base::TimeTicks(),
-                              ui::GestureEventDetails(ui::ET_GESTURE_END));
-
-  // Drag down on the app grid when on page 1, this should move the AppListView
-  // and not move the AppsGridView.
-  apps_grid_view_->OnGestureEvent(&scroll_begin);
-  EXPECT_FALSE(scroll_begin.handled());
-
-  // Simulate redirecting the event to app list view through views hierarchy.
-  app_list_view_->OnGestureEvent(&scroll_begin);
-  EXPECT_TRUE(scroll_begin.handled());
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);
-
-  // The following scroll update events will be sent to the view that handled
-  // the scroll begin event.
-  app_list_view_->OnGestureEvent(&scroll_update);
-  EXPECT_TRUE(scroll_update.handled());
-  ASSERT_TRUE(app_list_view_->is_in_drag());
-  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);
-
-  app_list_view_->OnGestureEvent(&scroll_end);
-  EXPECT_TRUE(scroll_end.handled());
-
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 1);
-}
-
-TEST_P(AppsGridViewRTLTest, MouseScrollSequenceHandledByAppListView) {
-  base::HistogramTester histogram_tester;
-
-  model_->PopulateApps(GetTilesPerPage(0) + 1);
-  UpdateLayout();
-  EXPECT_EQ(2, GetPaginationModel()->total_pages());
-
-  const gfx::Point apps_grid_view_origin =
-      apps_grid_view_->GetBoundsInScreen().origin();
-  // Pick a point inside the `AppsGridView`, as well as arbitrary points below
-  // and above it to drag to.
-  gfx::Point drag_start_point = apps_grid_view_origin + gfx::Vector2d(0, 10);
-  gfx::Point below_point = apps_grid_view_origin + gfx::Vector2d(0, 20);
-  gfx::Point above_point = apps_grid_view_origin + gfx::Vector2d(0, -20);
-
-  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, apps_grid_view_origin,
-                             apps_grid_view_origin, ui::EventTimeForNow(),
-                             ui::EF_LEFT_MOUSE_BUTTON,
-                             ui::EF_LEFT_MOUSE_BUTTON);
-
-  ui::MouseEvent drag_start(ui::ET_MOUSE_DRAGGED, drag_start_point,
-                            drag_start_point, ui::EventTimeForNow(),
-                            ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
-
-  ui::MouseEvent drag_below(ui::ET_MOUSE_DRAGGED, below_point, below_point,
-                            ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
-                            ui::EF_LEFT_MOUSE_BUTTON);
-
-  ui::MouseEvent drag_above(ui::ET_MOUSE_DRAGGED, above_point, above_point,
-                            ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
-                            ui::EF_LEFT_MOUSE_BUTTON);
-
-  // Send a press event to set the `mouse_drag_start_point_` for scrolling
-  apps_grid_view_->OnMouseEvent(&press_event);
-  EXPECT_TRUE(press_event.handled());
-
-  // Drag down on the app grid when on page 1, this should move the
-  // `AppListView` and not move the `AppsGridView`. We have to send two drag
-  // down events, `drag_start` and `drag_below`, to make sure `AppListView` has
-  // its anchor point and starts dragging down. Event is manually passed to
-  // `AppListview` in `AppsGridView::OnMouseEvent`
-  apps_grid_view_->OnMouseEvent(&drag_start);
-  EXPECT_TRUE(drag_start.handled());
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);
-
-  apps_grid_view_->OnMouseEvent(&drag_below);
-  EXPECT_TRUE(drag_below.handled());
-  ASSERT_TRUE(app_list_view_->is_in_drag());
-  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);
-
-  // Now drag back up. Because we have dragged the launcher down, we want it to
-  // continue dragging to allow the user to fully expand it. If we don't, the
-  // launcher can end up in a "expanded" state with the launcher not reaching
-  // the top of the screen and the app list scrolling.
-  apps_grid_view_->OnMouseEvent(&drag_above);
-  EXPECT_TRUE(drag_above.handled());
-  ASSERT_TRUE(app_list_view_->is_in_drag());
-  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 2);
-  histogram_tester.ExpectTotalCount(
-      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);
-}
-
 TEST_P(AppsGridViewRTLTest,
        OnGestureEventScrollSequenceHandleByPaginationController) {
   base::HistogramTester histogram_tester;
@@ -1334,7 +1210,6 @@
 
   apps_grid_view_->OnGestureEvent(&scroll_update);
   EXPECT_TRUE(scroll_update.handled());
-  ASSERT_FALSE(app_list_view_->is_in_drag());
   ASSERT_NE(0, GetPaginationModel()->transition().progress);
   histogram_tester.ExpectTotalCount(
       "Apps.PaginationTransition.DragScroll.PresentationTime.ClamshellMode", 1);
@@ -4722,7 +4597,6 @@
 
   apps_grid_view_->OnGestureEvent(&scroll_update);
   EXPECT_TRUE(scroll_update.handled());
-  ASSERT_FALSE(app_list_view_->is_in_drag());
   ASSERT_NE(0, GetPaginationModel()->transition().progress);
   histogram_tester.ExpectTotalCount(
       "Apps.PaginationTransition.DragScroll.PresentationTime.TabletMode", 1);
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc
index 2a9cfce..5ff07a4 100644
--- a/ash/app_list/views/contents_view.cc
+++ b/ash/app_list/views/contents_view.cc
@@ -66,11 +66,6 @@
 // The top search box margin (measured from the app list view top bound) when
 // app list view is in peeking state on the apps page.
 constexpr int kSearchBoxTopMarginInPeekingAppsPage = 84;
-
-// The range of app list transition progress in which the expand arrow'
-// opacity changes from 0 to 1.
-constexpr float kExpandArrowOpacityStartProgress = 0.61;
-constexpr float kExpandArrowOpacityEndProgress = 1;
 constexpr int kSearchBarMinWidth = 440;
 
 // Range of the fraction of app list from collapsed to peeking that search box
@@ -478,16 +473,6 @@
       !app_list_view_->is_side_shelf() && !app_list_view_->is_tablet_mode();
 
   float target_opacity = target_visibility ? 1.0f : 0.0f;
-  // Update the target opacity for when the app list view is in drag.
-  if (target_opacity && app_list_view_->is_in_drag()) {
-    // NOTE: The expand arrow is only shown for apps page, so it's OK to use the
-    // app list drag progress for apps page.
-    const float progress = app_list_view_->GetAppListTransitionProgress(
-        AppListView::kProgressFlagNone);
-    target_opacity =
-        GetOpacityForProgress(progress, kExpandArrowOpacityStartProgress,
-                              kExpandArrowOpacityEndProgress);
-  }
 
   ui::Layer* const layer = expand_arrow_view_->layer();
   if (transition_duration.is_zero()) {
@@ -544,13 +529,6 @@
 }
 
 gfx::Rect ContentsView::GetSearchBoxBounds(AppListState state) const {
-  if (app_list_view_->is_in_drag()) {
-    return GetSearchBoxExpectedBoundsForProgress(
-        state, app_list_view_->GetAppListTransitionProgress(
-                   state == AppListState::kStateSearchResults
-                       ? AppListView::kProgressFlagSearchResults
-                       : AppListView::kProgressFlagNone));
-  }
   return GetSearchBoxBoundsForViewState(state, target_view_state());
 }
 
@@ -737,17 +715,9 @@
           ConvertRectToWidgetWithoutTransform(search_box_bounds));
   search_box->GetWidget()->SetBounds(search_rect);
 
-  float progress = 0.0f;
-  if (app_list_view_->is_in_drag()) {
-    progress = app_list_view_->GetAppListTransitionProgress(
-        current_state == AppListState::kStateSearchResults
-            ? AppListView::kProgressFlagSearchResults
-            : AppListView::kProgressFlagNone);
-  } else {
-    progress = AppListView::GetTransitionProgressForState(target_view_state());
-  }
-  const bool restore_opacity = !app_list_view_->is_in_drag() &&
-                               target_view_state() != AppListViewState::kClosed;
+  float progress =
+      AppListView::GetTransitionProgressForState(target_view_state());
+  const bool restore_opacity = target_view_state() != AppListViewState::kClosed;
   const float search_box_opacity =
       restore_opacity
           ? 1.0f
@@ -762,13 +732,6 @@
                                     restore_opacity);
   }
 
-  // If in drag, reset the transforms that might have been set in
-  // AnimateToViewState().
-  if (app_list_view_->is_in_drag()) {
-    search_box->layer()->SetTransform(gfx::Transform());
-    expand_arrow_view_->layer()->SetTransform(gfx::Transform());
-  }
-
   target_page_for_last_view_state_update_ = current_state;
 }
 
diff --git a/ash/app_list/views/contents_view.h b/ash/app_list/views/contents_view.h
index b4254a8..943fb9d 100644
--- a/ash/app_list/views/contents_view.h
+++ b/ash/app_list/views/contents_view.h
@@ -173,6 +173,7 @@
 
   // Returns the expected search box bounds based on the app list transition
   // progress.
+  // TODO(crbug.com/1356674): Remove |progress| from parameters.
   gfx::Rect GetSearchBoxExpectedBoundsForProgress(AppListState state,
                                                   float progress) const;
 
diff --git a/ash/app_list/views/paged_apps_grid_view.cc b/ash/app_list/views/paged_apps_grid_view.cc
index 1b877bd..660828b 100644
--- a/ash/app_list/views/paged_apps_grid_view.cc
+++ b/ash/app_list/views/paged_apps_grid_view.cc
@@ -984,8 +984,7 @@
       (event.IsMouseEvent() || event.type() == ui::ET_GESTURE_SCROLL_BEGIN) &&
       !IsTabletMode() &&
       ((pagination_model_.selected_page() == 0 &&
-        calculate_offset(event) > 0) ||
-       contents_view_->app_list_view()->is_in_drag())) {
+        calculate_offset(event) > 0))) {
     return false;
   }
 
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index 3a74e3d..f650400 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -656,8 +656,7 @@
 
 int SearchBoxView::GetSearchBoxBorderCornerRadiusForState(
     AppListState state) const {
-  if (state == AppListState::kStateSearchResults && app_list_view_ &&
-      !app_list_view_->is_in_drag()) {
+  if (state == AppListState::kStateSearchResults && app_list_view_) {
     return features::IsProductivityLauncherEnabled()
                ? kExpandedSearchBoxCornerRadiusForProductivityLauncher
                : kSearchBoxBorderCornerRadiusSearchResult;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 9ca2038..be725f0 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -1317,6 +1317,9 @@
       <message name="IDS_ASH_HOLDING_SPACE_TITLE" desc="Title of the holding space tray and bubble.">
         Tote
       </message>
+      <message name="IDS_ASH_HOLDING_SPACE_TITLE_REBRAND" desc="Title of the holding space tray and bubble when rebranding is enabled.">
+        Quick Files
+      </message>
       <message name="IDS_ASH_HOLDING_SPACE_PINNED_TITLE" desc="Title of the pinned files area in the holding space bubble.">
         Pinned files
       </message>
@@ -4563,6 +4566,9 @@
       <message name="IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR" desc="Description explaining that there was an error with the speech recognition library download.">
         Can't download speech files. Try again later.
       </message>
+      <message name="IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED" desc="Error message shown when a OS reboot is required to install the Live Caption files.">
+        Restart needed to install speech files.
+      </message>
       <message name="IDS_ASH_ACCESSIBILITY_DICTATION_BUTTON_TOOLTIP_SODA_DOWNLOADING" desc="A tooltip explaining that speech recognition files are downloading." >
         Downloading speech files
       </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1 b/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
new file mode 100644
index 0000000..b834c87
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
@@ -0,0 +1 @@
+57566ae221e8244cd3331693cd7f6063b2136b55
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_HOLDING_SPACE_TITLE_REBRAND.png.sha1 b/ash/ash_strings_grd/IDS_ASH_HOLDING_SPACE_TITLE_REBRAND.png.sha1
new file mode 100644
index 0000000..2fee28b
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_HOLDING_SPACE_TITLE_REBRAND.png.sha1
@@ -0,0 +1 @@
+0efba1b5cba684074d8ca48b4007a3c6ed0db170
\ No newline at end of file
diff --git a/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc b/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc
index da05b73..45fccc75 100644
--- a/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc
+++ b/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc
@@ -45,10 +45,10 @@
 
   void LoginUserSession() {
     auto account_id = AccountId::FromUserEmail(kPublicAccountEmail);
-    user_manager()->AddUser(account_id);
+    auto* user = user_manager()->AddUser(account_id);
 
-    user_manager()->UserLoggedIn(
-        account_id, account_id.GetUserEmail() + "-hash", false, false);
+    user_manager()->UserLoggedIn(account_id, user->username_hash(), false,
+                                 false);
   }
 
   void FastForwardAttempt() {
diff --git a/ash/components/arc/mojom/intent_helper.mojom b/ash/components/arc/mojom/intent_helper.mojom
index 1fd3e044..665a271 100644
--- a/ash/components/arc/mojom/intent_helper.mojom
+++ b/ash/components/arc/mojom/intent_helper.mojom
@@ -249,15 +249,13 @@
   array<LaunchFileInfo>? files;
 };
 
-// Contains information about an app's supported links.
-struct SupportedLinks {
+// Contains information about supported links for an ARC package.
+[RenamedFrom="arc.mojom.SupportedLinks"]
+struct SupportedLinksPackage {
   // Android package name of the app.
   string package_name;
-  // A list of all the link intent filters handled by the app. Should only
-  // include, link intents. That is, filters must have an http/https scheme and
-  // at least one authority. This field can be omitted when deleting supported
-  // links for an app.
-  array<IntentFilter>? filters;
+  // Deprecated and no longer used.
+  array<IntentFilter>? deprecated_filters;
 };
 
 // The source of a change in the supported links setting.
@@ -356,8 +354,8 @@
   // IntentFilters, and removes the apps in |removed_packages| from handling
   // supported links.
   [MinVersion=47] OnSupportedLinksChanged@20(
-      array<SupportedLinks> added_packages,
-      array<SupportedLinks> removed_packages,
+      array<SupportedLinksPackage> added_packages,
+      array<SupportedLinksPackage> removed_packages,
       [MinVersion=48] SupportedLinkChangeSource source);
 
   // Called when a new entry has been added to the MediaStore.Downloads
diff --git a/ash/components/login/auth/stub_authenticator.cc b/ash/components/login/auth/stub_authenticator.cc
index 94cdd645..2f9b850 100644
--- a/ash/components/login/auth/stub_authenticator.cc
+++ b/ash/components/login/auth/stub_authenticator.cc
@@ -14,8 +14,9 @@
 
 namespace {
 
-// As defined in /chromeos/ash/components/dbus/cryptohome/cryptohome_client.cc.
-static const char kUserIdHashSuffix[] = "-hash";
+// As defined in
+// //chromeos/ash/components/dbus/cryptohome/fake_userdataauth_client.cc
+static constexpr char kUserIdHashSuffix[] = "-hash";
 
 }  // anonymous namespace
 
diff --git a/ash/components/policy/OWNERS b/ash/components/policy/OWNERS
index 939a973..793150c7 100644
--- a/ash/components/policy/OWNERS
+++ b/ash/components/policy/OWNERS
@@ -11,4 +11,4 @@
 igorcov@chromium.org
 pmarko@chromium.org
 poromov@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 0e57557..6858c383 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -562,7 +562,7 @@
 
 // Enables duplex native messaging between DriveFS and extensions.
 const base::Feature kDriveFsBidirectionalNativeMessaging{
-    "DriveFsBidirectionalNativeMessaging", base::FEATURE_DISABLED_BY_DEFAULT};
+    "DriveFsBidirectionalNativeMessaging", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables DriveFS' experimental local files mirroring functionality.
 const base::Feature kDriveFsMirroring{"DriveFsMirroring",
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc
index 90fdfd1..2df9932b 100644
--- a/ash/constants/ash_pref_names.cc
+++ b/ash/constants/ash_pref_names.cc
@@ -762,6 +762,9 @@
 // A boolean pref indicating whether the microphone is allowed to be used.
 const char kUserMicrophoneAllowed[] = "ash.user.microphone_allowed";
 
+// A boolean pref indicating whether the geolocation is allowed to be used.
+const char kUserGeolocationAllowed[] = "ash.user.geolocation_allowed";
+
 // A boolean pref which determines whether tap-dragging is enabled.
 const char kTapDraggingEnabled[] = "settings.touchpad.enable_tap_dragging";
 
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index 95142e73..fa6143a 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -343,6 +343,7 @@
 
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kUserCameraAllowed[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kUserMicrophoneAllowed[];
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kUserGeolocationAllowed[];
 
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kTapDraggingEnabled[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kTouchpadEnabled[];
diff --git a/ash/glanceables/glanceables_controller.cc b/ash/glanceables/glanceables_controller.cc
index 9a235634..5709a9ac 100644
--- a/ash/glanceables/glanceables_controller.cc
+++ b/ash/glanceables/glanceables_controller.cc
@@ -103,6 +103,7 @@
 void GlanceablesController::DestroyUi() {
   widget_.reset();
   view_ = nullptr;
+  delegate_->OnGlanceablesClosed();
   window_hider_.reset();  // Show hidden windows.
 }
 
diff --git a/ash/glanceables/glanceables_delegate.h b/ash/glanceables/glanceables_delegate.h
index 7a23d98..308a0d2 100644
--- a/ash/glanceables/glanceables_delegate.h
+++ b/ash/glanceables/glanceables_delegate.h
@@ -18,6 +18,9 @@
 
   // Triggers session restore.
   virtual void RestoreSession() = 0;
+
+  // Called after the glanceables UI is closed.
+  virtual void OnGlanceablesClosed() = 0;
 };
 
 }  // namespace ash
diff --git a/ash/glanceables/glanceables_unittests.cc b/ash/glanceables/glanceables_unittests.cc
index dda57adc..95d2c6dd 100644
--- a/ash/glanceables/glanceables_unittests.cc
+++ b/ash/glanceables/glanceables_unittests.cc
@@ -125,6 +125,8 @@
 };
 
 TEST_F(GlanceablesTest, CreateAndDestroyUi) {
+  ASSERT_EQ(0, GetTestDelegate()->on_glanceables_closed_count());
+
   controller_->CreateUi();
 
   // A fullscreen widget was created.
@@ -146,6 +148,9 @@
   // Widget and glanceables view are destroyed.
   EXPECT_FALSE(GetWidget());
   EXPECT_FALSE(GetGlanceablesView());
+
+  // Delegate was notified that glanceables were closed.
+  EXPECT_EQ(1, GetTestDelegate()->on_glanceables_closed_count());
 }
 
 TEST_F(GlanceablesTest, GlanceablesViewCreatesChildViews) {
diff --git a/ash/glanceables/test_glanceables_delegate.cc b/ash/glanceables/test_glanceables_delegate.cc
index 520d090e..e132a7d 100644
--- a/ash/glanceables/test_glanceables_delegate.cc
+++ b/ash/glanceables/test_glanceables_delegate.cc
@@ -14,4 +14,8 @@
   ++restore_session_count_;
 }
 
+void TestGlanceablesDelegate::OnGlanceablesClosed() {
+  ++on_glanceables_closed_count_;
+}
+
 }  // namespace ash
diff --git a/ash/glanceables/test_glanceables_delegate.h b/ash/glanceables/test_glanceables_delegate.h
index 9b74316..d4473d67 100644
--- a/ash/glanceables/test_glanceables_delegate.h
+++ b/ash/glanceables/test_glanceables_delegate.h
@@ -19,11 +19,14 @@
 
   // GlanceablesDelegate:
   void RestoreSession() override;
+  void OnGlanceablesClosed() override;
 
   int restore_session_count() { return restore_session_count_; }
+  int on_glanceables_closed_count() { return on_glanceables_closed_count_; }
 
  private:
   int restore_session_count_ = 0;
+  int on_glanceables_closed_count_ = 0;
 };
 
 }  // namespace ash
diff --git a/ash/login/LOGIN_LOCK_OWNERS b/ash/login/LOGIN_LOCK_OWNERS
index ec20423..676e4f7 100644
--- a/ash/login/LOGIN_LOCK_OWNERS
+++ b/ash/login/LOGIN_LOCK_OWNERS
@@ -3,7 +3,7 @@
 emaxx@chromium.org
 
 #Secondary (in CET)
-rsorokin@chromium.org
+rsorokin@google.com
 rrsilva@google.com
 
 # Secondary (in PST)
diff --git a/ash/login/OOBE_WEBUI_OWNERS b/ash/login/OOBE_WEBUI_OWNERS
index a4a26dd..2247a45 100644
--- a/ash/login/OOBE_WEBUI_OWNERS
+++ b/ash/login/OOBE_WEBUI_OWNERS
@@ -1,7 +1,7 @@
 # Primary (in CET)
 dkuzmin@google.com
 rrsilva@google.com
-rsorokin@chromium.org
+rsorokin@google.com
 
 #Secondary (in CET)
 antrim@chromium.org
diff --git a/ash/public/cpp/personalization_app/user_display_info.cc b/ash/public/cpp/personalization_app/user_display_info.cc
index 3977acc..ce2e88ba 100644
--- a/ash/public/cpp/personalization_app/user_display_info.cc
+++ b/ash/public/cpp/personalization_app/user_display_info.cc
@@ -4,21 +4,28 @@
 
 #include "ash/public/cpp/personalization_app/user_display_info.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chromeos/strings/grit/chromeos_strings.h"
 #include "components/user_manager/user.h"
+#include "components/user_manager/user_names.h"
+#include "ui/base/l10n/l10n_util.h"
 
-namespace ash {
-namespace personalization_app {
+namespace ash::personalization_app {
 
 UserDisplayInfo::UserDisplayInfo() = default;
 
 UserDisplayInfo::UserDisplayInfo(const user_manager::User& user)
-    : email(user.GetDisplayEmail()),
-      name(base::UTF16ToUTF8(user.GetDisplayName())) {}
+    : email(user.GetDisplayEmail()) {
+  if (user.GetAccountId() == user_manager::GuestAccountId()) {
+    name = base::UTF16ToUTF8(
+        l10n_util::GetStringUTF16(IDS_PERSONALIZATION_APP_GUEST_NAME));
+  } else {
+    name = base::UTF16ToUTF8(user.GetDisplayName());
+  }
+}
 
 UserDisplayInfo::UserDisplayInfo(UserDisplayInfo&&) = default;
 UserDisplayInfo& UserDisplayInfo::operator=(UserDisplayInfo&&) = default;
 
 UserDisplayInfo::~UserDisplayInfo() = default;
 
-}  // namespace personalization_app
-}  // namespace ash
+}  // namespace ash::personalization_app
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.cc b/ash/quick_pair/repository/fast_pair_repository_impl.cc
index c97c06c..9aaa581 100644
--- a/ash/quick_pair/repository/fast_pair_repository_impl.cc
+++ b/ash/quick_pair/repository/fast_pair_repository_impl.cc
@@ -70,13 +70,14 @@
 }
 
 FastPairRepositoryImpl::FastPairRepositoryImpl(
+    scoped_refptr<device::BluetoothAdapter> adapter,
     std::unique_ptr<DeviceMetadataFetcher> device_metadata_fetcher,
     std::unique_ptr<FootprintsFetcher> footprints_fetcher,
     std::unique_ptr<FastPairImageDecoder> image_decoder,
     std::unique_ptr<DeviceIdMap> device_id_map,
     std::unique_ptr<DeviceImageStore> device_image_store,
     std::unique_ptr<SavedDeviceRegistry> saved_device_registry)
-    : FastPairRepository(),
+    : adapter_(adapter),
       device_metadata_fetcher_(std::move(device_metadata_fetcher)),
       footprints_fetcher_(std::move(footprints_fetcher)),
       image_decoder_(std::move(image_decoder)),
@@ -147,6 +148,51 @@
 
 bool FastPairRepositoryImpl::IsAccountKeyPairedLocally(
     const std::vector<uint8_t>& account_key) {
+  // Before we check if the |account_key| matches any of the devices saved in
+  // the Saved Device Registry, we fetch all the devices saved to the user's
+  // account and cross check the SHA256(concat(account_key, mac_address)) of
+  // the saved devices with the SHA256(concat(account_key, mac_address)) of any
+  // devices paired to the adapter using the paired device's mac address and
+  // the given |account_key|. If there are any matches, we should add the
+  // (mac_address, account_key) pair to the Saved Device Registry before
+  // completing our check. This handles the edge case where a user pairs a
+  // device already saved to their account from another platform via classic
+  // BT pairing, and the device still emits a not discoverable advertisement,
+  // and we want to prevent showing a Subsequent pairing notification in this
+  // case.
+  for (device::BluetoothDevice* device : adapter_->GetDevices()) {
+    if (!device->IsPaired())
+      continue;
+
+    // Use the paired device's |mac_address| and the given |account_key| to
+    // generate a SHA256(concat(account_key, mac_address)), and use this
+    // SHA256 hash to check if there are any matches with any saved devices in
+    // Footprints.
+    const std::string& mac_address = device->GetAddress();
+    std::string paired_device_hash = GenerateSha256OfAccountKeyAndMacAddress(
+        std::string(account_key.begin(), account_key.end()), mac_address);
+
+    for (const auto& info : user_devices_cache_.fast_pair_info()) {
+      if (info.has_device() &&
+          info.device().has_sha256_account_key_public_address() &&
+          info.device().sha256_account_key_public_address() ==
+              paired_device_hash) {
+        QP_LOG(VERBOSE)
+            << __func__
+            << ": paired device already saved to account at address = "
+            << mac_address << "; adding to registry";
+        saved_device_registry_->SaveAccountKey(mac_address, account_key);
+
+        // We only expect there to be at most one match with |account_key| in
+        // the devices saved to Footprints. An account key is uniquely written
+        // to one device in the pairing flows. Since we found a match and
+        // saved it locally, we can return "true" since the account key matches
+        // a paired device.
+        return true;
+      }
+    }
+  }
+
   return saved_device_registry_->IsAccountKeySavedToRegistry(account_key);
 }
 
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.h b/ash/quick_pair/repository/fast_pair_repository_impl.h
index 4d0bd43..6cc4aa5 100644
--- a/ash/quick_pair/repository/fast_pair_repository_impl.h
+++ b/ash/quick_pair/repository/fast_pair_repository_impl.h
@@ -47,6 +47,7 @@
  public:
   FastPairRepositoryImpl();
   FastPairRepositoryImpl(
+      scoped_refptr<device::BluetoothAdapter> adapter,
       std::unique_ptr<DeviceMetadataFetcher> device_metadata_fetcher,
       std::unique_ptr<FootprintsFetcher> footprints_fetcher,
       std::unique_ptr<FastPairImageDecoder> image_decoder,
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl_unittest.cc b/ash/quick_pair/repository/fast_pair_repository_impl_unittest.cc
index f3f13ac..47d5b2b 100644
--- a/ash/quick_pair/repository/fast_pair_repository_impl_unittest.cc
+++ b/ash/quick_pair/repository/fast_pair_repository_impl_unittest.cc
@@ -162,9 +162,10 @@
     saved_device_registry_ = saved_device_registry.get();
 
     fast_pair_repository_ = std::make_unique<FastPairRepositoryImpl>(
-        std::move(device_metadata_fetcher), std::move(footprints_fetcher),
-        std::move(image_decoder), std::move(device_id_map),
-        std::move(device_image_store), std::move(saved_device_registry));
+        adapter_, std::move(device_metadata_fetcher),
+        std::move(footprints_fetcher), std::move(image_decoder),
+        std::move(device_id_map), std::move(device_image_store),
+        std::move(saved_device_registry));
 
     pref_service_ = std::make_unique<TestingPrefServiceSimple>();
     ON_CALL(browser_delegate_, GetActivePrefService())
@@ -635,8 +636,49 @@
                                        /*success=*/false, 1);
 }
 
-TEST_F(FastPairRepositoryImplTest, IsAccountKeyPairedLocally) {
+TEST_F(FastPairRepositoryImplTest,
+       IsAccountKeyPairedLocally_SavedLocallyNotPaired) {
+  // Simulate a device already saved to the registry. A Fast Pair device can
+  // be saved in the registry even if it is not paired locally because
+  // the SavedDeviceRegistry  tracks devices that have been Fast paired in the
+  // past.
   saved_device_registry_->SaveAccountKey(kTestClassicAddress1, kAccountKey1);
+  EXPECT_TRUE(
+      saved_device_registry_->IsAccountKeySavedToRegistry(kAccountKey1));
+
+  EXPECT_TRUE(fast_pair_repository_->IsAccountKeyPairedLocally(kAccountKey1));
+  EXPECT_FALSE(fast_pair_repository_->IsAccountKeyPairedLocally(kAccountKey2));
+}
+
+TEST_F(FastPairRepositoryImplTest,
+       IsAccountKeyPairedLocally_PairedNotSavedLocally) {
+  // Simulate a device saved to a user's account that matches a device paired
+  // with devices |adapter_| is loaded with. In the init of the |adapter_|, we
+  // mocked `GetDevices` with |device_list_|.
+  nearby::fastpair::FastPairInfo info;
+  auto* device = info.mutable_device();
+  device->set_account_key(
+      std::string(kAccountKey1.begin(), kAccountKey1.end()));
+  device->set_sha256_account_key_public_address(
+      GenerateSha256AccountKeyMacAddress(
+          std::string(kAccountKey1.begin(), kAccountKey1.end()),
+          kTestClassicAddress1));
+  nearby::fastpair::UserReadDevicesResponse response;
+  *response.add_fast_pair_info() = info;
+  footprints_fetcher_->SetGetUserDevicesResponse(response);
+
+  // We want to simulate the cache being updated when it is parsing a
+  // NotDiscoverableAdv, which happens when it is checking an account key.
+  AccountKeyFilter filter(kFilterBytes1, {salt});
+  auto run_loop = std::make_unique<base::RunLoop>();
+  fast_pair_repository_->CheckAccountKeys(
+      filter, base::BindOnce(&FastPairRepositoryImplTest::VerifyAccountKeyCheck,
+                             base::Unretained(this), run_loop->QuitClosure(),
+                             /*expected_result=*/false));
+  run_loop->Run();
+
+  // At this point the cache will be updated with any devices Saved to
+  // Footprints. We can continue now checking if it matches any paired devices.
   EXPECT_TRUE(fast_pair_repository_->IsAccountKeyPairedLocally(kAccountKey1));
   EXPECT_FALSE(fast_pair_repository_->IsAccountKeyPairedLocally(kAccountKey2));
 }
diff --git a/ash/services/quick_pair/fast_pair_data_parser.cc b/ash/services/quick_pair/fast_pair_data_parser.cc
index 08a9101..3083b4d 100644
--- a/ash/services/quick_pair/fast_pair_data_parser.cc
+++ b/ash/services/quick_pair/fast_pair_data_parser.cc
@@ -274,8 +274,10 @@
     return;
   }
 
-  if (salt_bytes.size() > 1) {
-    QP_LOG(WARNING) << " Parsed a salt field larger than one byte: "
+  // The salt byte requirements need to stay aligned with the Fast Pair Spec:
+  // https://developers.devsite.corp.google.com/nearby/fast-pair/specifications/service/provider#AccountKeyFilter
+  if (salt_bytes.size() > 2) {
+    QP_LOG(WARNING) << " Parsed a salt field larger than two bytes: "
                     << salt_bytes.size();
     std::move(callback).Run(absl::nullopt);
     return;
diff --git a/ash/services/quick_pair/fast_pair_data_parser_unittest.cc b/ash/services/quick_pair/fast_pair_data_parser_unittest.cc
index c1ba9168..ae6bd4c 100644
--- a/ash/services/quick_pair/fast_pair_data_parser_unittest.cc
+++ b/ash/services/quick_pair/fast_pair_data_parser_unittest.cc
@@ -28,8 +28,10 @@
 constexpr int kAccountKeyFilterHeader = 0b01100000;
 constexpr int kAccountKeyFilterNoNotificationHeader = 0b01100010;
 constexpr int kSaltHeader = 0b00010001;
+constexpr int kSaltHeader2Bytes = 0b00100001;
+constexpr int kSaltHeader3Bytes = 0b00110001;
 const std::vector<uint8_t> kSaltBytes = {0x01};
-const std::vector<uint8_t> kInvalidSaltBytes = {0x01, 0x02};
+const std::vector<uint8_t> kLargeSaltBytes = {0xC7, 0xC8};
 const std::vector<uint8_t> kDeviceAddressBytes = {17, 18, 19, 20, 21, 22};
 constexpr int kBatteryHeader = 0b00110011;
 constexpr int kBatterHeaderNoNotification = 0b00110100;
@@ -37,7 +39,8 @@
 const std::string kModelId = "112233";
 const std::string kAccountKeyFilter = "112233445566";
 const std::string kSalt = "01";
-const std::string kInvalidSalt = "01020404050607";
+const std::string kLargeSalt = "C7C8";
+const std::string kInvalidSalt = "C7C8C9";
 const std::string kBattery = "01048F";
 const std::string kDeviceAddress = "11:12:13:14:15:16";
 
@@ -406,13 +409,40 @@
   run_loop.Run();
 }
 
+TEST_F(FastPairDataParserTest, ParseNotDiscoverableAdvertisement_SaltTwoBytes) {
+  std::vector<uint8_t> bytes = FastPairServiceDataCreator::Builder()
+                                   .SetHeader(kNotDiscoverableAdvHeader)
+                                   .SetModelId(kModelId)
+                                   .AddExtraFieldHeader(kAccountKeyFilterHeader)
+                                   .AddExtraField(kAccountKeyFilter)
+                                   .AddExtraFieldHeader(kSaltHeader2Bytes)
+                                   .AddExtraField(kLargeSalt)
+                                   .Build()
+                                   ->CreateServiceData();
+  base::RunLoop run_loop;
+  auto callback = base::BindLambdaForTesting(
+      [&run_loop](
+          const absl::optional<NotDiscoverableAdvertisement>& advertisement) {
+        EXPECT_TRUE(advertisement.has_value());
+        EXPECT_EQ(kAccountKeyFilter,
+                  base::HexEncode(advertisement->account_key_filter));
+        EXPECT_EQ(kLargeSaltBytes, advertisement->salt);
+        run_loop.Quit();
+      });
+
+  data_parser_->ParseNotDiscoverableAdvertisement(bytes, kDeviceAddress,
+                                                  std::move(callback));
+
+  run_loop.Run();
+}
+
 TEST_F(FastPairDataParserTest, ParseNotDiscoverableAdvertisement_SaltTooLarge) {
   std::vector<uint8_t> bytes = FastPairServiceDataCreator::Builder()
                                    .SetHeader(kNotDiscoverableAdvHeader)
                                    .SetModelId(kModelId)
-                                   .AddExtraFieldHeader(0b01100001)
+                                   .AddExtraFieldHeader(kAccountKeyFilterHeader)
                                    .AddExtraField(kAccountKeyFilter)
-                                   .AddExtraFieldHeader(kSaltHeader)
+                                   .AddExtraFieldHeader(kSaltHeader3Bytes)
                                    .AddExtraField(kInvalidSalt)
                                    .Build()
                                    ->CreateServiceData();
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index dd25c9b1..6b6a603 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -1609,48 +1609,6 @@
   RunGestureDragTests(bottom_center, shelf_bounds.top_center());
 }
 
-// TODO(https://crbug.com/1286875): This behavior is broken in production. An
-// auto-hidden shelf will close after a short swipe up that fails to show the
-// app list.
-TEST_F(ShelfLayoutManagerTest,
-       DISABLED_ShortSwipeUpOnAutoHideShelfKeepsShelfOpen) {
-  Shelf* shelf = GetPrimaryShelf();
-  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
-
-  auto* generator = GetEventGenerator();
-  constexpr base::TimeDelta kTimeDelta = base::Milliseconds(100);
-  constexpr int kNumScrollSteps = 4;
-
-  // Starts the drag from the center of the shelf's bottom.
-  gfx::Rect shelf_bounds = GetVisibleShelfWidgetBoundsInScreen();
-  gfx::Point start = shelf_bounds.bottom_center();
-  gfx::Vector2d delta;
-
-  // Create a normal unmaximized window, the auto-hide shelf should be hidden.
-  aura::Window* window = CreateTestWindow();
-  window->SetBounds(gfx::Rect(0, 0, 100, 100));
-  window->Show();
-  GetAppListTestHelper()->CheckVisibility(false);
-  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
-  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
-
-  // Swiping up to show the auto-hide shelf.
-  gfx::Point end = shelf_bounds.top_center();
-  generator->GestureScrollSequence(start, end, kTimeDelta, kNumScrollSteps);
-  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
-
-  // Swiping up on the auto-hide shelf to drag up the app list. Close the app
-  // list on drag ended since the short drag distance but keep the previous
-  // shown auto-hide shelf still visible.
-  delta.set_y(AppListView::kDragSnapToClosedThreshold - 10);
-  end = start - delta;
-  generator->GestureScrollSequence(start, end, kTimeDelta, kNumScrollSteps);
-  GetAppListTestHelper()->WaitUntilIdle();
-  GetAppListTestHelper()->CheckVisibility(false);
-  // This line fails, see https://crbug.com/1286875.
-  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
-}
-
 // Swiping on shelf when fullscreen app list is opened should have no effect.
 TEST_F(ShelfLayoutManagerTest, SwipingOnShelfIfAppListOpened) {
   Shelf* shelf = GetPrimaryShelf();
@@ -3031,28 +2989,6 @@
   EXPECT_EQ(shelf_background_type, GetShelfWidget()->GetBackgroundType());
 }
 
-TEST_F(ShelfLayoutManagerTest, SwipeUpOnShelfDoesNotShowAppList) {
-  Shelf* shelf = GetPrimaryShelf();
-  ASSERT_EQ(ShelfAlignment::kBottom, shelf->alignment());
-  ASSERT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
-  ASSERT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
-
-  // Start the drag from the center of the shelf's bottom.
-  gfx::Rect shelf_widget_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
-  gfx::Point start = shelf_widget_bounds.bottom_center();
-
-  // Fling up with velocity about the threshold that would show the historical
-  // peeking launcher.
-  StartScroll(start);
-  UpdateScroll(-AppListView::kDragSnapToPeekingThreshold);
-  EndScroll(/*is_fling=*/true,
-            -(AppListView::kDragVelocityFromShelfThreshold + 10));
-  GetAppListTestHelper()->WaitUntilIdle();
-
-  // Launcher did not show.
-  EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible());
-}
-
 // Tests that tapping the home button is successful on the autohidden shelf.
 TEST_F(ShelfLayoutManagerTest, NoTemporaryAutoHideStateWhileOpeningLauncher) {
   // Enable animations and simulate the zero state search called when showing
@@ -4365,6 +4301,58 @@
   }
 }
 
+// TODO(https://crbug.com/1286875): This behavior is broken in production. An
+// auto-hidden shelf will close after a short swipe up that fails to show the
+// app list.
+TEST_P(QuickActionShowBubbleTest,
+       DISABLED_ShortSwipeUpOnAutoHideShelfKeepsShelfOpen) {
+  Shelf* shelf = GetPrimaryShelf();
+  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
+
+  auto* generator = GetEventGenerator();
+  constexpr base::TimeDelta kTimeDelta = base::Milliseconds(100);
+  constexpr int kNumScrollSteps = 4;
+
+  // Starts the drag from the center of the shelf's bottom.
+  gfx::Rect shelf_bounds = GetVisibleShelfWidgetBoundsInScreen();
+  gfx::Point start = shelf_bounds.bottom_center();
+
+  // Create a normal unmaximized window, the auto-hide shelf should be hidden.
+  aura::Window* window = CreateTestWindow();
+  window->SetBounds(gfx::Rect(0, 0, 100, 100));
+  window->Show();
+  GetAppListTestHelper()->CheckVisibility(false);
+  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
+  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
+
+  // Swiping up to show the auto-hide shelf.
+  gfx::Point end = shelf_bounds.top_center();
+  generator->GestureScrollSequence(start, end, kTimeDelta, kNumScrollSteps);
+  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
+
+  // Swiping up on the auto-hide shelf to drag up the app list. Scroll Velocity
+  // is not enough to show the app list but keep the previous shown auto-hide
+  // shelf still visible. Starts fling from the navigation_widget.
+  start = GetPrimaryShelf()
+              ->navigation_widget()
+              ->GetContentsView()
+              ->GetBoundsInScreen()
+              .CenterPoint();
+  const int scroll_offset_threshold =
+      ShelfConfig::Get()->mousewheel_scroll_offset_threshold() + 10;
+  gfx::Vector2d offset(0, scroll_offset_threshold);
+  end = start - offset;
+  generator->GestureScrollSequence(
+      start, end,
+      generator->CalculateScrollDurationForFlingVelocity(start, end,
+                                                         /*velocity =*/50, 4),
+      4);
+  GetAppListTestHelper()->WaitUntilIdle();
+  GetAppListTestHelper()->CheckVisibility(false);
+  // This line fails, see https://crbug.com/1286875.
+  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
+}
+
 // Tests that the shelf background is opaque in both screens after app list is
 // dismissed in a secondary display. (See https://crbug.com/1060686)
 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundOpaqueAfetrAppListUpdate) {
diff --git a/ash/strings/ash_strings_af.xtb b/ash/strings/ash_strings_af.xtb
index 92dcd29d..d6fc89a 100644
--- a/ash/strings/ash_strings_af.xtb
+++ b/ash/strings/ash_strings_af.xtb
@@ -1255,6 +1255,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, outovoltooi</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Jou administrateur bestuur hierdie instelling.</translation>
 <translation id="8155628902202578800">Maak inligtingdialoog oop vir <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Voorgestel vir jou</translation>
 <translation id="8167567890448493835">Gebruik tans <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Bekyk jou foon se onlangse foto's, media, kennisgewings en programme op jou <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Kennisgewings word versteek.</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index 1afa6c8b..60f4c92 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -1256,6 +1256,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />، الإكمال التلقائي</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> يتولى مشرفك إدارة هذا الإعداد.</translation>
 <translation id="8155628902202578800">فتح مربع حوار المعلومات للبريد الإلكتروني <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">نتائج مقترَحة لك</translation>
 <translation id="8167567890448493835">استخدام <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">يمكنك عرض أحدث الصور والوسائط والإشعارات والتطبيقات في هاتفك على جهاز <ph name="DEVICE_TYPE" />.</translation>
 <translation id="8192202700944119416">يتم إخفاء الإشعارات.</translation>
diff --git a/ash/strings/ash_strings_az.xtb b/ash/strings/ash_strings_az.xtb
index 926fc15..cfb7020 100644
--- a/ash/strings/ash_strings_az.xtb
+++ b/ash/strings/ash_strings_az.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, Avto-tamamlama</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Bu ayar inzibatçınız tərəfindən idarə olunur.</translation>
 <translation id="8155628902202578800"><ph name="USER_EMAIL_ADDRESS" /> üçün məlumat dialoqunu açın</translation>
+<translation id="8157728322324420120">Sizin üçün təklif edilənlər</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> istifadə edilir</translation>
 <translation id="8183592608247778598"><ph name="DEVICE_TYPE" /> cihazında telefonunuzun son fotoları, mediası, bildirişləri və tətbiqlərinə baxın</translation>
 <translation id="8192202700944119416">Bildirişlər gizlədildi.</translation>
diff --git a/ash/strings/ash_strings_cy.xtb b/ash/strings/ash_strings_cy.xtb
index f88eb6f..08716fa3 100644
--- a/ash/strings/ash_strings_cy.xtb
+++ b/ash/strings/ash_strings_cy.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, Awtogwblhau</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Rheolir y weithred hon gan eich gweinyddwr.</translation>
 <translation id="8155628902202578800">Agor y deialog gwybodaeth ar gyfer <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Awgrymir i chi</translation>
 <translation id="8167567890448493835">Yn defnyddio <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Gweld lluniau, cyfryngau, hysbysiadau ac apiau diweddar eich ffôn ar eich <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Mae hysbysiadau wedi'u cuddio.</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb
index f3e7801..3c8247a5 100644
--- a/ash/strings/ash_strings_es-419.xtb
+++ b/ash/strings/ash_strings_es-419.xtb
@@ -1255,6 +1255,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />; autocompletar</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" />: El administrador controla esta configuración.</translation>
 <translation id="8155628902202578800">Abrir el diálogo de información de <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Sugerencias para ti</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> en uso</translation>
 <translation id="8183592608247778598">Mira las apps, las notificaciones, el contenido multimedia y las fotos recientes del teléfono en tu <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Las notificaciones están ocultas.</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb
index 1141c2a..9a616dd 100644
--- a/ash/strings/ash_strings_fa.xtb
+++ b/ash/strings/ash_strings_fa.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />، تکمیل خودکار</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> این تنظیم را سرپرست شما مدیریت می‌کند.</translation>
 <translation id="8155628902202578800">باز کردن کادر گفتگوی اطلاعات برای <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">پیشنهادی برای شما</translation>
 <translation id="8167567890448493835">درحال استفاده از <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">عکس‌ها، رسانه‌ها، اعلان‌ها، و برنامه‌های جدید تلفنتان را در <ph name="DEVICE_TYPE" /> مشاهده کنید</translation>
 <translation id="8192202700944119416">اعلان‌ها پنهان شده است.</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb
index b1887dfc..c3e5bc74 100644
--- a/ash/strings/ash_strings_id.xtb
+++ b/ash/strings/ash_strings_id.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, Dilengkapi otomatis</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Setelan ini dikelola oleh administrator Anda.</translation>
 <translation id="8155628902202578800">Buka dialog info untuk <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Saran untuk Anda</translation>
 <translation id="8167567890448493835">Menggunakan <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Lihat foto, media, notifikasi, dan aplikasi terbaru ponsel Anda di <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Notifikasi disembunyikan.</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb
index 0a125e50..6225a6a5 100644
--- a/ash/strings/ash_strings_it.xtb
+++ b/ash/strings/ash_strings_it.xtb
@@ -1255,6 +1255,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, completamento automatico</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Questa impostazione è gestita dall'amministratore.</translation>
 <translation id="8155628902202578800">Apri la finestra di dialogo delle informazioni per <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Consigliati per te</translation>
 <translation id="8167567890448493835">In uso: <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Visualizza le foto, i contenuti multimediali, le notifiche e le app recenti del tuo telefono su <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Le notifiche sono nascoste.</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb
index 8d3a106..80ee69f 100644
--- a/ash/strings/ash_strings_iw.xtb
+++ b/ash/strings/ash_strings_iw.xtb
@@ -1256,6 +1256,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, השלמה אוטומטית</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> ההגדרה הזו מנוהלת על-ידי מנהל המערכת שלך.</translation>
 <translation id="8155628902202578800">פתיחת תיבת דו-שיח עם מידע על <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">הצעות בשבילך</translation>
 <translation id="8167567890448493835">המיקום הנוכחי הוא<ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">הצגת התמונות, המדיה, ההתראות והאפליקציות שבטלפון מהזמן האחרון ב-<ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">ההתראות מוסתרות.</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb
index 6eceb45..dfb534f 100644
--- a/ash/strings/ash_strings_ko.xtb
+++ b/ash/strings/ash_strings_ko.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, 자동 완성</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> 관리자가 관리하는 설정입니다.</translation>
 <translation id="8155628902202578800"><ph name="USER_EMAIL_ADDRESS" /> 정보 대화상자 열기</translation>
+<translation id="8157728322324420120">추천</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> 사용 중</translation>
 <translation id="8183592608247778598">휴대전화의 최근 사진, 미디어, 알림, 앱을 <ph name="DEVICE_TYPE" />에서 봅니다.</translation>
 <translation id="8192202700944119416">알림이 숨겨져 있음</translation>
diff --git a/ash/strings/ash_strings_lo.xtb b/ash/strings/ash_strings_lo.xtb
index b3bee94..023ee01f 100644
--- a/ash/strings/ash_strings_lo.xtb
+++ b/ash/strings/ash_strings_lo.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, ຕື່ມອັດຕະໂນມັດ</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> ການຕັ້ງຄ່ານີ້ຈັດການໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ.</translation>
 <translation id="8155628902202578800">ເປີດກ່ອງໂຕ້ຕອງຂໍ້ມູນສຳລັບ <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">ແນະ​ນຳ​ສຳ​ລັບ​ທ່ານ</translation>
 <translation id="8167567890448493835">ກຳລັງໃຊ້ <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">ເບິ່ງຮູບພາບ, ມີເດຍ, ການແຈ້ງເຕືອນ ແລະ ແອັບຫຼ້າສຸດຂອງໂທລະສັບທ່ານຢູ່ <ph name="DEVICE_TYPE" /> ຂອງທ່ານ</translation>
 <translation id="8192202700944119416">ເຊື່ອງການແຈ້ງເຕືອນໄວ້ແລ້ວ.</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb
index dbb40690..922a01a 100644
--- a/ash/strings/ash_strings_lt.xtb
+++ b/ash/strings/ash_strings_lt.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, automatinis užbaigimas</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Šį nustatymą tvarko jūsų administratorius.</translation>
 <translation id="8155628902202578800">Atidaryti <ph name="USER_EMAIL_ADDRESS" /> informacijos dialogo langą</translation>
+<translation id="8157728322324420120">Siūloma jums</translation>
 <translation id="8167567890448493835">Naudojama: <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Peržiūrėkite telefono naujausias nuotraukas, mediją, pranešimus ir programas „<ph name="DEVICE_TYPE" />“ įrenginyje</translation>
 <translation id="8192202700944119416">Pranešimai yra paslėpti.</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 477b6b6..103b1df 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -1255,6 +1255,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, Autolengkap</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Tetapan ini diurus oleh pentadbir anda.</translation>
 <translation id="8155628902202578800">Buka dialog maklumat untuk <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Disyorkan untuk anda</translation>
 <translation id="8167567890448493835">Menggunakan <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Lihat foto, media, pemberitahuan dan apl terbaharu telefon anda pada <ph name="DEVICE_TYPE" /> anda</translation>
 <translation id="8192202700944119416">Pemberitahuan disembunyikan.</translation>
diff --git a/ash/strings/ash_strings_my.xtb b/ash/strings/ash_strings_my.xtb
index 9fb1dda5..2b5efa1d 100644
--- a/ash/strings/ash_strings_my.xtb
+++ b/ash/strings/ash_strings_my.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />၊ အလိုအလျောက်ဖြည့်သည်</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> ဤဆက်တင်ကို သင့် 'ကြီးကြပ်သူ' က စီမံသည်။</translation>
 <translation id="8155628902202578800"><ph name="USER_EMAIL_ADDRESS" /> အတွက် အချက်အလက်ဒိုင်ယာလော့ခ် ဖွင့်ပါ</translation>
+<translation id="8157728322324420120">သင့်အတွက် အကြံပြုထားသည်များ</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> အသုံးပြုခြင်း</translation>
 <translation id="8183592608247778598">သင့်ဖုန်းရှိ မကြာသေးမီက ဓာတ်ပုံ၊ မီဒီယာ၊ အကြောင်းကြားချက်နှင့် အက်ပ်များကို သင်၏ <ph name="DEVICE_TYPE" /> ၌ ကြည့်နိုင်သည်</translation>
 <translation id="8192202700944119416">အကြောင်းကြားချက်များကို ဝှက်ထားသည်။</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index c90e5c0..8da29ea 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -1251,6 +1251,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, automatisch aanvullen</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Deze instelling wordt beheerd door je beheerder.</translation>
 <translation id="8155628902202578800">Dialoogvenster met informatie openen voor <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Voorgesteld voor jou</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> in gebruik</translation>
 <translation id="8183592608247778598">Recente foto's, media, meldingen en apps van je telefoon bekijken op je <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Meldingen zijn verborgen.</translation>
diff --git a/ash/strings/ash_strings_or.xtb b/ash/strings/ash_strings_or.xtb
index 7698771..e020ba2 100644
--- a/ash/strings/ash_strings_or.xtb
+++ b/ash/strings/ash_strings_or.xtb
@@ -1253,6 +1253,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, ସ୍ଵତଃ ଶେଷ ହେଉଥିବା</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> ଏହି ସେଟିଂ ଆପଣଙ୍କ ଆଡମିନିଷ୍ଟ୍ରେଟରଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ ହୁଏ।</translation>
 <translation id="8155628902202578800"><ph name="USER_EMAIL_ADDRESS" /> ପାଇଁ ସୂଚନା ଡାଏଲଗ୍ ଖୋଲନ୍ତୁ</translation>
+<translation id="8157728322324420120">ଆପଣଙ୍କ ପାଇଁ ପ୍ରସ୍ତାବିତ</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" />କୁ ବ୍ୟବହାର କରାଯାଉଛି</translation>
 <translation id="8183592608247778598">ଆପଣଙ୍କ ଫୋନରେ ଥିବା ବର୍ତ୍ତମାନର ଫଟୋ, ମିଡିଆ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆପ୍ସକୁ ଆପଣଙ୍କର <ph name="DEVICE_TYPE" />ରେ ଦେଖନ୍ତୁ</translation>
 <translation id="8192202700944119416">ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଲୁଚାଯାଇଛି।</translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb
index 5bc09d8..8b8fb8f 100644
--- a/ash/strings/ash_strings_pl.xtb
+++ b/ash/strings/ash_strings_pl.xtb
@@ -1253,6 +1253,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, autouzupełnianie</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> – tym ustawieniem zarządza Twój administrator.</translation>
 <translation id="8155628902202578800">Otwórz okno informacyjne dla konta <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Proponowane dla Ciebie</translation>
 <translation id="8167567890448493835">W użyciu jest: <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Wyświetlaj najnowsze zdjęcia, pliki multimedialne, powiadomienia i aplikacje z telefonu na urządzeniu <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Powiadomienia są ukryte.</translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb
index 57cd6c2..b3e7dbab 100644
--- a/ash/strings/ash_strings_ru.xtb
+++ b/ash/strings/ash_strings_ru.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, автозаполнение</translation>
 <translation id="8155007568264258537">Функцией "<ph name="FEATURE_NAME" />" управляет администратор.</translation>
 <translation id="8155628902202578800">Открыть диалоговое окно с информацией об аккаунте <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Рекомендуем</translation>
 <translation id="8167567890448493835">Используемый язык: <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Просмотр недавних фотографий, медиафайлов, уведомлений и приложений с телефона на устройстве <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Уведомления скрыты</translation>
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb
index 07a5f92..f6680d9 100644
--- a/ash/strings/ash_strings_si.xtb
+++ b/ash/strings/ash_strings_si.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, ස්වයං සම්පූර්ණය</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> මෙම සැකසුම ඔබේ පරිපාලකයා විසින් කළමනා කෙරේ.</translation>
 <translation id="8155628902202578800"><ph name="USER_EMAIL_ADDRESS" /> සඳහා තතු සංවාදය විවෘත කරන්න</translation>
+<translation id="8157728322324420120">ඔබ වෙනුවෙන් යෝජිත</translation>
 <translation id="8167567890448493835"><ph name="LOCALE_NAME" /> භාවිත කිරීම</translation>
 <translation id="8183592608247778598">ඔබගේ දුරකථනයේ මෑත ඡායාරූප, මාධ්‍ය, දැනුම්දීම් සහ යෙදුම් ඔබගේ <ph name="DEVICE_TYPE" /> හි බලන්න</translation>
 <translation id="8192202700944119416">දැනුම්දීම් සැඟවී ඇත.</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb
index b558ec6e..dc5f3d5 100644
--- a/ash/strings/ash_strings_sk.xtb
+++ b/ash/strings/ash_strings_sk.xtb
@@ -1254,6 +1254,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />, automatické dopĺňanie</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> Toto nastavenie ovláda váš správca.</translation>
 <translation id="8155628902202578800">Otvoriť dialógové okno informácií o používateľovi <ph name="USER_EMAIL_ADDRESS" /></translation>
+<translation id="8157728322324420120">Navrhnuté pre vás</translation>
 <translation id="8167567890448493835">Práve sa používa <ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">Zobrazujte si najnovšie fotky, médiá, upozornenia a aplikácie svojho telefónu v zariadení <ph name="DEVICE_TYPE" /></translation>
 <translation id="8192202700944119416">Upozornenia sú skryté.</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb
index e184d5e..613a56b 100644
--- a/ash/strings/ash_strings_zh-CN.xtb
+++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -1251,6 +1251,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />,自动填充</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" />:此设置由您的管理员管理。</translation>
 <translation id="8155628902202578800">打开与 <ph name="USER_EMAIL_ADDRESS" /> 对应的信息对话框</translation>
+<translation id="8157728322324420120">为您推荐</translation>
 <translation id="8167567890448493835">目前使用的是“<ph name="LOCALE_NAME" />”</translation>
 <translation id="8183592608247778598">在 <ph name="DEVICE_TYPE" /> 上查看手机中近期的照片、媒体、通知和应用</translation>
 <translation id="8192202700944119416">已隐藏通知。</translation>
diff --git a/ash/strings/ash_strings_zh-HK.xtb b/ash/strings/ash_strings_zh-HK.xtb
index 14a8e3af..9074bfb 100644
--- a/ash/strings/ash_strings_zh-HK.xtb
+++ b/ash/strings/ash_strings_zh-HK.xtb
@@ -1252,6 +1252,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />,自動完成</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" />,呢項設定由管理員管理。</translation>
 <translation id="8155628902202578800">打開 <ph name="USER_EMAIL_ADDRESS" /> 嘅資料對話框</translation>
+<translation id="8157728322324420120">個人化建議</translation>
 <translation id="8167567890448493835">正在使用「<ph name="LOCALE_NAME" />」</translation>
 <translation id="8183592608247778598">在 <ph name="DEVICE_TYPE" /> 上查看手機最近的相片、媒體、通知和應用程式</translation>
 <translation id="8192202700944119416">已隱藏通知。</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb
index aa08ec8..b665698 100644
--- a/ash/strings/ash_strings_zh-TW.xtb
+++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -1253,6 +1253,7 @@
 <translation id="8152264887680882389"><ph name="TEXT" />,自動完成</translation>
 <translation id="8155007568264258537"><ph name="FEATURE_NAME" /> 這項設定是由系統管理員管理。</translation>
 <translation id="8155628902202578800">開啟 <ph name="USER_EMAIL_ADDRESS" /> 的資訊對話方塊</translation>
+<translation id="8157728322324420120">個人化建議</translation>
 <translation id="8167567890448493835">使用<ph name="LOCALE_NAME" /></translation>
 <translation id="8183592608247778598">透過 <ph name="DEVICE_TYPE" /> 查看手機上最近的相片、媒體、通知和應用程式</translation>
 <translation id="8192202700944119416">已隱藏通知。</translation>
diff --git a/ash/style/ash_color_provider_unittest.cc b/ash/style/ash_color_provider_unittest.cc
index 8787940..4eb4ef0 100644
--- a/ash/style/ash_color_provider_unittest.cc
+++ b/ash/style/ash_color_provider_unittest.cc
@@ -204,7 +204,7 @@
           SkColorSetRGB(0xE3, 0x74, 0x0)},
          {ColorMode::kLight,
           ColorProvider::ControlsLayerType::kControlBackgroundColorPositive,
-          SkColorSetRGB(0x1E, 0x8E, 0x3E)},
+          SkColorSetRGB(0x18, 0x80, 0x38)},
          {ColorMode::kLight, ColorProvider::ControlsLayerType::kFocusAuraColor,
           SkColorSetARGB(0x3D, 0x1A, 0x73, 0xE8)},
          {ColorMode::kLight, ColorProvider::ControlsLayerType::kFocusRingColor,
@@ -259,7 +259,7 @@
           SkColorSetRGB(0xE3, 0x74, 0x0)},
          {ColorMode::kLight,
           ColorProvider::ContentLayerType::kTextColorPositive,
-          SkColorSetRGB(0x1E, 0x8E, 0x3E)},
+          SkColorSetRGB(0x18, 0x80, 0x38)},
          {ColorMode::kLight, ColorProvider::ContentLayerType::kTextColorURL,
           SkColorSetRGB(0x1A, 0x73, 0xE8)},
 
@@ -274,7 +274,7 @@
           SkColorSetRGB(0xE3, 0x74, 0x0)},
          {ColorMode::kLight,
           ColorProvider::ContentLayerType::kIconColorPositive,
-          SkColorSetRGB(0x1E, 0x8E, 0x3E)},
+          SkColorSetRGB(0x18, 0x80, 0x38)},
          {ColorMode::kLight,
           ColorProvider::ContentLayerType::kIconColorProminent,
           SkColorSetRGB(0x1A, 0x73, 0xE8)},
@@ -365,7 +365,7 @@
 
          {ColorMode::kLight,
           ColorProvider::ContentLayerType::kBatterySystemInfoBackgroundColor,
-          SkColorSetRGB(0x1E, 0x8E, 0x3E)},
+          SkColorSetRGB(0x18, 0x80, 0x38)},
 
          {ColorMode::kLight,
           ColorProvider::ContentLayerType::kBatterySystemInfoIconColor,
diff --git a/ash/style/icon_button.cc b/ash/style/icon_button.cc
index 151a8bda..71d9d260 100644
--- a/ash/style/icon_button.cc
+++ b/ash/style/icon_button.cc
@@ -4,6 +4,8 @@
 
 #include "ash/style/icon_button.h"
 
+#include "ash/constants/ash_features.h"
+#include "ash/style/ash_color_id.h"
 #include "ash/style/ash_color_provider.h"
 #include "ash/style/style_util.h"
 #include "ash/utility/haptics_util.h"
@@ -11,6 +13,7 @@
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/color/color_id.h"
 #include "ui/events/devices/haptic_touchpad_effects.h"
 #include "ui/events/event.h"
@@ -27,25 +30,26 @@
 namespace ash {
 namespace {
 
-constexpr int kTinyButtonSize = 24;
+constexpr int kXSmallButtonSize = 24;
 constexpr int kSmallButtonSize = 32;
 constexpr int kMediumButtonSize = 36;
 constexpr int kLargeButtonSize = 48;
 
 constexpr int kBorderSize = 4;
 
-// Icon size of the IconButton. Though the button has different sizes, the icon
-// inside will be kept the same size.
+// Icon size of the small, medium and large size buttons.
 constexpr int kIconSize = 20;
+// Icon size of the extra small size button.
+constexpr int kXSmallIconSize = 16;
 
 // The gap between the focus ring and the button's content.
 constexpr gfx::Insets kFocusRingPadding(1);
 
 int GetButtonSizeOnType(IconButton::Type type) {
   switch (type) {
-    case IconButton::Type::kTiny:
-    case IconButton::Type::kTinyFloating:
-      return kTinyButtonSize;
+    case IconButton::Type::kXSmall:
+    case IconButton::Type::kXSmallFloating:
+      return kXSmallButtonSize;
     case IconButton::Type::kSmall:
     case IconButton::Type::kSmallFloating:
       return kSmallButtonSize;
@@ -58,8 +62,16 @@
   }
 }
 
+int GetIconSizeOnType(IconButton::Type type) {
+  if (type == IconButton::Type::kXSmall ||
+      type == IconButton::Type::kXSmallFloating) {
+    return kXSmallIconSize;
+  }
+  return kIconSize;
+}
+
 bool IsFloatingIconButton(IconButton::Type type) {
-  return type == IconButton::Type::kTinyFloating ||
+  return type == IconButton::Type::kXSmallFloating ||
          type == IconButton::Type::kSmallFloating ||
          type == IconButton::Type::kMediumFloating ||
          type == IconButton::Type::kLargeFloating;
@@ -180,25 +192,34 @@
 }
 
 void IconButton::PaintButtonContents(gfx::Canvas* canvas) {
+  if (!GetWidget())
+    return;
+
   if (!IsFloatingIconButton(type_)) {
     const gfx::Rect rect(GetContentsBounds());
     cc::PaintFlags flags;
     flags.setAntiAlias(true);
 
-    const auto* color_provider = AshColorProvider::Get();
-    SkColor color = color_provider->GetControlsLayerColor(
-        AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive);
+    const bool is_jellyroll_enabled = features::IsJellyrollEnabled();
+
+    ui::ColorId color_id =
+        is_jellyroll_enabled
+            ? cros_tokens::kCrosSysSysOnBase
+            : static_cast<ui::ColorId>(kColorAshControlBackgroundColorInactive);
     bool should_show_button_toggled_on =
         toggled_ &&
         (GetEnabled() ||
          button_behavior_ ==
              DisabledButtonBehavior::kCanDisplayDisabledToggleValue);
     if (should_show_button_toggled_on) {
-      color = color_provider->GetControlsLayerColor(
-          AshColorProvider::ControlsLayerType::kControlBackgroundColorActive);
+      color_id =
+          is_jellyroll_enabled
+              ? cros_tokens::kCrosSysSysPrimaryContainer
+              : static_cast<ui::ColorId>(kColorAshControlBackgroundColorActive);
     }
-    if (background_color_)
-      color = background_color_.value();
+
+    SkColor color =
+        background_color_.value_or(GetColorProvider()->GetColor(color_id));
 
     // If the button is disabled, apply opacity filter to the color.
     if (!GetEnabled())
@@ -248,17 +269,22 @@
 }
 
 void IconButton::UpdateVectorIcon() {
-  if (!icon_)
+  if (!icon_ || !GetWidget())
     return;
 
-  auto* color_provider = AshColorProvider::Get();
+  auto* color_provider = GetColorProvider();
+  const bool is_jellyroll_enabled = features::IsJellyrollEnabled();
   const SkColor normal_icon_color =
-      icon_color_.value_or(color_provider->GetContentLayerColor(
-          AshColorProvider::ContentLayerType::kButtonIconColor));
-  const SkColor toggled_icon_color = color_provider->GetContentLayerColor(
-      AshColorProvider::ContentLayerType::kButtonIconColorPrimary);
+      icon_color_.value_or(color_provider->GetColor(
+          is_jellyroll_enabled
+              ? cros_tokens::kCrosSysOnSurface
+              : static_cast<ui::ColorId>(kColorAshButtonIconColor)));
+  const SkColor toggled_icon_color = color_provider->GetColor(
+      is_jellyroll_enabled
+          ? cros_tokens::kCrosSysSysOnPrimaryContainer
+          : static_cast<ui::ColorId>(kColorAshButtonIconColorPrimary));
   const SkColor icon_color = toggled_ ? toggled_icon_color : normal_icon_color;
-  const int icon_size = icon_size_.value_or(kIconSize);
+  const int icon_size = icon_size_.value_or(GetIconSizeOnType(type_));
 
   // Skip repainting if the incoming icon is the same as the current icon. If
   // the icon has been painted before, |gfx::CreateVectorIcon()| will simply
diff --git a/ash/style/icon_button.h b/ash/style/icon_button.h
index 23ba728c..ae8bc84 100644
--- a/ash/style/icon_button.h
+++ b/ash/style/icon_button.h
@@ -31,11 +31,11 @@
   METADATA_HEADER(IconButton);
 
   enum class Type {
-    kTiny,
+    kXSmall,
     kSmall,
     kMedium,
     kLarge,
-    kTinyFloating,
+    kXSmallFloating,
     kSmallFloating,
     kMediumFloating,
     kLargeFloating
diff --git a/ash/style/pill_button.cc b/ash/style/pill_button.cc
index 8c439c5..ce2e172 100644
--- a/ash/style/pill_button.cc
+++ b/ash/style/pill_button.cc
@@ -13,6 +13,7 @@
 #include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/animation/ink_drop.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/focus_ring.h"
 #include "ui/views/controls/highlight_path_generator.h"
@@ -52,7 +53,7 @@
 
 // Returns true if the button has an icon.
 bool IsIconPillButton(PillButton::Type type) {
-  return type & PillButton::kIconLeading;
+  return type & (PillButton::kIconLeading | PillButton::kIconFollowing);
 }
 
 // Returns the button height according to the given type.
@@ -166,8 +167,11 @@
       rounded_highlight_path_(rounded_highlight_path) {
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
-  SetHorizontalAlignment(gfx::ALIGN_CENTER);
-  InitializeButtonLayout();
+  if (type_ & kIconFollowing)
+    SetHorizontalAlignment(gfx::ALIGN_RIGHT);
+  else
+    SetHorizontalAlignment(gfx::ALIGN_CENTER);
+  InitFocusRingAndBackground();
   label()->SetSubpixelRenderingEnabled(false);
   // TODO: Unify the font size, weight under ash/style as well.
   label()->SetFontList(views::Label::GetDefaultFontList().Derive(
@@ -259,6 +263,21 @@
                AshColorProvider::GetDisabledColor(enabled_text_color));
 }
 
+gfx::Insets PillButton::GetInsets() const {
+  const int height = GetButtonHeight(type_);
+  const int vertical_spacing =
+      std::max((height - GetPreferredSize().height()) / 2, 0);
+  const int icon_padding = IsIconPillButton(type_)
+                               ? GetHorizontalSpacingWithIcon()
+                               : horizontal_spacing_;
+  if (type_ & kIconFollowing) {
+    return gfx::Insets::TLBR(vertical_spacing, horizontal_spacing_,
+                             vertical_spacing, icon_padding);
+  }
+  return gfx::Insets::TLBR(vertical_spacing, icon_padding, vertical_spacing,
+                           horizontal_spacing_);
+}
+
 void PillButton::SetBackgroundColor(const SkColor background_color) {
   if (background_color_ == background_color)
     return;
@@ -296,17 +315,9 @@
   label()->SetFontList(views::Label::GetDefaultFontList());
 }
 
-void PillButton::InitializeButtonLayout() {
+void PillButton::InitFocusRingAndBackground() {
   const int height = GetButtonHeight(type_);
 
-  const int vertical_spacing =
-      std::max((height - GetPreferredSize().height()) / 2, 0);
-  const int left_padding = IsIconPillButton(type_)
-                               ? GetHorizontalSpacingWithIcon()
-                               : horizontal_spacing_;
-  SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
-      vertical_spacing, left_padding, vertical_spacing, horizontal_spacing_)));
-
   if (rounded_highlight_path_) {
     if ((type_ & kButtonColorVariant) == kPrimary) {
       views::InstallRoundRectHighlightPathGenerator(
diff --git a/ash/style/pill_button.h b/ash/style/pill_button.h
index 2f64936..644bc37 100644
--- a/ash/style/pill_button.h
+++ b/ash/style/pill_button.h
@@ -43,6 +43,7 @@
   static constexpr TypeFlag kAccent = 1 << 6;
   static constexpr TypeFlag kLarge = 1 << 7;
   static constexpr TypeFlag kIconLeading = 1 << 8;
+  static constexpr TypeFlag kIconFollowing = 1 << 9;
 
   // Types of the PillButton. Each type is represented as the bitwise OR
   // operation of the feature bit masks. The naming rule of the button type is
@@ -50,9 +51,14 @@
   enum Type {
     // PillButton with default text and background colors, a leading icon.
     kDefaultWithIconLeading = kDefault | kIconLeading,
+    // PillButton with default text and background colors, a following icon.
+    kDefaultWithIconFollowing = kDefault | kIconFollowing,
     // PillButton with default text and background colors, a large button size,
     // a leading icon.
     kDefaultLargeWithIconLeading = kDefault | kLarge | kIconLeading,
+    // PillButton with default text and background colors, a large button size,
+    // a following icon.
+    kDefaultLargeWithIconFollowing = kDefault | kLarge | kIconFollowing,
     // PillButton with default text and background colors, no icon.
     kDefaultWithoutIcon = kDefault,
     // PillButton with default text and background colors, a large button size,
@@ -62,10 +68,15 @@
     // PillButton with default-elevated text and background colors, a leading
     // icon.
     kDefaultElevatedWithIconLeading = kDefault | kIconLeading,
+    // PillButton with default-elevated text and background colors, a following
+    // icon.
+    kDefaultElevatedWithIconFollowing = kDefault | kIconFollowing,
     // PillButton with default-elevated text and background colors, a large
-    // button size,
-    // a leading icon.
+    // button size, a leading icon.
     kDefaultElevatedLargeWithIconLeading = kDefault | kLarge | kIconLeading,
+    // PillButton with default-elevated text and background colors, a large
+    // button size, a following icon.
+    kDefaultElevatedLargeWithIconFollowing = kDefault | kLarge | kIconFollowing,
     // PillButton with default-elevated text and background colors, no icon.
     kDefaultElevatedWithoutIcon = kDefault,
     // PillButton with default-elevated text and background colors, a large
@@ -75,9 +86,14 @@
 
     // PillButton with primary text and background colors, a leading icon.
     kPrimaryWithIconLeading = kPrimary | kIconLeading,
+    // PillButton with primary text and background colors, a following icon.
+    kPrimaryWithIconFollowing = kPrimary | kIconFollowing,
     // PillButton with primary text and background colors, a large button size,
     // a leading icon.
     kPrimaryLargeWithIconLeading = kPrimary | kLarge | kIconLeading,
+    // PillButton with primary text and background colors, a large button size,
+    // a following icon.
+    kPrimaryLargeWithIconFollowing = kPrimary | kLarge | kIconFollowing,
     // PillButton with primary text and background colors, no icon.
     kPrimaryWithoutIcon = kPrimary,
     // PillButton with primary text and background colors, a large button size,
@@ -86,9 +102,14 @@
 
     // PillButton with secondary text and background colors, a leading icon.
     kSecondaryWithIconLeading = kSecondary | kIconLeading,
+    // PillButton with secondary text and background colors, a following icon.
+    kSecondaryWithIconFollowing = kSecondary | kIconFollowing,
     // PillButton with secondary text and background colors, a large button
     // size, a leading icon.
     kSecondaryLargeWithIconLeading = kSecondary | kLarge | kIconLeading,
+    // PillButton with secondary text and background colors, a large button
+    // size, a following icon.
+    kSecondaryLargeWithIconFollowing = kSecondary | kLarge | kIconFollowing,
     // PillButton with secondary text and background colors, no icon.
     kSecondaryWithoutIcon = kSecondary,
     // PillButton with secondary text and background colors, a large button
@@ -97,9 +118,14 @@
 
     // PillButton with floating text colors, no background, a leading icon.
     kFloatingWithIconLeading = kFloating | kIconLeading,
+    // PillButton with floating text colors, no background, a following icon.
+    kFloatingWithIconFollowing = kFloating | kIconFollowing,
     // PillButton with floating text colors, no background, a large button size,
     // a leading icon.
     kFloatingLargeWithIconLeading = kFloating | kLarge | kIconLeading,
+    // PillButton with floating text colors, no background, a large button size,
+    // a following icon.
+    kFloatingLargeWithIconFollowing = kFloating | kLarge | kIconFollowing,
     // PillButton with floating text colors, no background, no icon.
     kFloatingWithoutIcon = kFloating,
     // PillButton with floating text colors, no background, a large button size,
@@ -108,9 +134,14 @@
 
     // PillButton with alert text and background colors, a leading icon.
     kAlertWithIconLeading = kAlert | kIconLeading,
+    // PillButton with alert text and background colors, a following icon.
+    kAlertWithIconFollowing = kAlert | kIconFollowing,
     // PillButton with alert text and background colors, a large button size, a
     // leading icon.
     kAlertLargeWithIconLeading = kAlert | kLarge | kIconLeading,
+    // PillButton with alert text and background colors, a large button size, a
+    // following icon.
+    kAlertLargeWithIconFollowing = kAlert | kLarge | kIconFollowing,
     // PillButton with alert text and background colors, no icon.
     kAlertWithoutIcon = kAlert,
     // PillButton with alert text and background colors, a large button size, no
@@ -146,6 +177,7 @@
   gfx::Size CalculatePreferredSize() const override;
   int GetHeightForWidth(int width) const override;
   void OnThemeChanged() override;
+  gfx::Insets GetInsets() const override;
 
   // Sets the button's background color, text's color or icon's color. Note, do
   // this only when the button wants to have different colors from the default
@@ -160,8 +192,9 @@
   void SetUseDefaultLabelFont();
 
  private:
-  // Initialize the button layout according to the button type.
-  void InitializeButtonLayout();
+  // Initialize the button focus ring and background according to the button
+  // type.
+  void InitFocusRingAndBackground();
 
   // Returns the spacing on the side where the icon locates. The value is set
   // smaller to make the spacing on two sides visually look the same.
diff --git a/ash/system/accessibility/tray_accessibility.cc b/ash/system/accessibility/tray_accessibility.cc
index 7a83079..cf25a12 100644
--- a/ash/system/accessibility/tray_accessibility.cc
+++ b/ash/system/accessibility/tray_accessibility.cc
@@ -629,10 +629,22 @@
 void AccessibilityDetailedView::OnSodaInstallError(
     speech::LanguageCode language_code,
     speech::SodaInstaller::ErrorCode error_code) {
-  std::u16string message = l10n_util::GetStringUTF16(
-      IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR);
-  MaybeShowSodaMessage(SodaFeature::kDictation, language_code, message);
-  MaybeShowSodaMessage(SodaFeature::kLiveCaption, language_code, message);
+  std::u16string error_message;
+  switch (error_code) {
+    case speech::SodaInstaller::ErrorCode::kUnspecifiedError: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR);
+      break;
+    }
+    case speech::SodaInstaller::ErrorCode::kNeedsReboot: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED);
+      break;
+    }
+  }
+
+  MaybeShowSodaMessage(SodaFeature::kDictation, language_code, error_message);
+  MaybeShowSodaMessage(SodaFeature::kLiveCaption, language_code, error_message);
 }
 
 void AccessibilityDetailedView::OnSodaProgress(
diff --git a/ash/system/audio/audio_detailed_view.cc b/ash/system/audio/audio_detailed_view.cc
index 069c5eb..df09c731 100644
--- a/ash/system/audio/audio_detailed_view.cc
+++ b/ash/system/audio/audio_detailed_view.cc
@@ -361,9 +361,21 @@
 void AudioDetailedView::OnSodaInstallError(
     speech::LanguageCode language_code,
     speech::SodaInstaller::ErrorCode error_code) {
-  std::u16string message = l10n_util::GetStringUTF16(
-      IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR);
-  MaybeShowSodaMessage(language_code, message);
+  std::u16string error_message;
+  switch (error_code) {
+    case speech::SodaInstaller::ErrorCode::kUnspecifiedError: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR);
+      break;
+    }
+    case speech::SodaInstaller::ErrorCode::kNeedsReboot: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_ASH_ACCESSIBILITY_SETTING_SUBTITLE_SODA_DOWNLOAD_ERROR_REBOOT_REQUIRED);
+      break;
+    }
+  }
+
+  MaybeShowSodaMessage(language_code, error_message);
 }
 
 void AudioDetailedView::OnSodaProgress(speech::LanguageCode language_code,
diff --git a/ash/system/holding_space/holding_space_tray.cc b/ash/system/holding_space/holding_space_tray.cc
index df61f311..938fc4b3 100644
--- a/ash/system/holding_space/holding_space_tray.cc
+++ b/ash/system/holding_space/holding_space_tray.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "ash/accessibility/accessibility_controller_impl.h"
+#include "ash/constants/ash_features.h"
 #include "ash/drag_drop/scoped_drag_drop_observer.h"
 #include "ash/public/cpp/holding_space/holding_space_client.h"
 #include "ash/public/cpp/holding_space/holding_space_constants.h"
@@ -309,7 +310,9 @@
 }
 
 std::u16string HoldingSpaceTray::GetTooltipText(const gfx::Point& point) const {
-  return l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_TITLE);
+  return features::IsHoldingSpaceRebrandEnabled()
+             ? l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_TITLE_REBRAND)
+             : l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_TITLE);
 }
 
 void HoldingSpaceTray::HandleLocaleChange() {
diff --git a/ash/system/holding_space/holding_space_tray_unittest.cc b/ash/system/holding_space/holding_space_tray_unittest.cc
index 5d55051..4f4c52a 100644
--- a/ash/system/holding_space/holding_space_tray_unittest.cc
+++ b/ash/system/holding_space/holding_space_tray_unittest.cc
@@ -2658,6 +2658,13 @@
            .bitmap()));
 }
 
+TEST_P(HoldingSpaceTrayIconTest, CheckTrayTooltipText) {
+  StartSession(/*pre_mark_time_of_first_add=*/true);
+  GetTray()->FirePreviewsUpdateTimerIfRunningForTesting();
+  EXPECT_EQ(GetTray()->GetTooltipText(gfx::Point()),
+            IsHoldingSpaceRebrandEnabled() ? u"Quick Files" : u"Tote");
+}
+
 // Base class for tests of the holding space downloads section parameterized by:
 // * the set of holding space item types which are expected to appear there.
 class HoldingSpaceTrayDownloadsSectionTest
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc
index b8c194e3..5b980936 100644
--- a/ash/system/ime_menu/ime_menu_tray.cc
+++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -64,6 +64,10 @@
 // Insets for the title view (dp).
 constexpr auto kTitleViewPadding = gfx::Insets::TLBR(0, 0, 0, 16);
 
+// Insets for the bubble view to fix the overlapping
+// between the floating menu and the IME tray in kiosk session (dp).
+constexpr auto kKioskBubbleViewPadding = gfx::Insets::TLBR(-19, 0, -23, 0);
+
 // Returns the height range of ImeListView.
 gfx::Range GetImeListViewRange() {
   const int max_items = 5;
@@ -345,13 +349,16 @@
 }
 
 void ImeMenuTray::ShowImeMenuBubbleInternal() {
+  gfx::Insets bubble_anchor_insets =
+      IsKioskSession() ? kKioskBubbleViewPadding : GetBubbleAnchorInsets();
+
   TrayBubbleView::InitParams init_params;
   init_params.delegate = GetWeakPtr();
   init_params.parent_window = GetBubbleWindowContainer();
   init_params.anchor_view = nullptr;
   init_params.anchor_mode = TrayBubbleView::AnchorMode::kRect;
   init_params.anchor_rect = GetBubbleAnchor()->GetAnchorBoundsInScreen();
-  init_params.anchor_rect.Inset(GetBubbleAnchorInsets());
+  init_params.anchor_rect.Inset(bubble_anchor_insets);
   init_params.shelf_alignment = shelf()->alignment();
   init_params.preferred_width = kTrayMenuWidth;
   init_params.close_on_deactivate = true;
diff --git a/ash/system/message_center/message_center_constants.h b/ash/system/message_center/message_center_constants.h
index d21ad541..a1b022d 100644
--- a/ash/system/message_center/message_center_constants.h
+++ b/ash/system/message_center/message_center_constants.h
@@ -24,8 +24,10 @@
 
 constexpr int kMessagePopupCornerRadius = 16;
 
-constexpr int kMessageCenterNotificationCornerRadius = 2;
+constexpr int kMessageCenterNotificationInnerCornerRadius = 2;
 constexpr int kMessageCenterScrollViewCornerRadius = 12;
+constexpr int kMessageCenterNotificationTopBottomCornerRadius =
+    kMessageCenterScrollViewCornerRadius;
 constexpr int kMessageCenterPadding = 8;
 constexpr int kMessageCenterBottomPadding = 8;
 constexpr int kMessageListNotificationSpacing = 2;
diff --git a/ash/system/message_center/unified_message_list_view.cc b/ash/system/message_center/unified_message_list_view.cc
index 2204dd49f..699692cd 100644
--- a/ash/system/message_center/unified_message_list_view.cc
+++ b/ash/system/message_center/unified_message_list_view.cc
@@ -5,7 +5,6 @@
 #include "ash/system/message_center/unified_message_list_view.h"
 #include <string>
 
-#include "ash/bubble/bubble_constants.h"
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/metrics_util.h"
 #include "ash/system/message_center/ash_notification_view.h"
@@ -138,15 +137,16 @@
                           message_center_style::kSeperatorColor));
     }
 
-    int message_center_notification_corner_radius =
+    const int message_center_notification_corner_radius =
         features::IsNotificationsRefreshEnabled()
-            ? kMessageCenterNotificationCornerRadius
+            ? kMessageCenterNotificationInnerCornerRadius
             : 0;
-    const int top_radius = is_top ? kBubbleCornerRadius
-                                  : message_center_notification_corner_radius;
-    const int bottom_radius = is_bottom
-                                  ? kBubbleCornerRadius
-                                  : message_center_notification_corner_radius;
+    const int top_radius = is_top
+                               ? kMessageCenterNotificationTopBottomCornerRadius
+                               : message_center_notification_corner_radius;
+    const int bottom_radius =
+        is_bottom ? kMessageCenterNotificationTopBottomCornerRadius
+                  : message_center_notification_corner_radius;
     message_view_->UpdateCornerRadius(top_radius, bottom_radius);
     control_view_->UpdateCornerRadius(top_radius, bottom_radius);
   }
@@ -156,7 +156,7 @@
     need_update_corner_radius_ = true;
 
     int corner_radius = features::IsNotificationsRefreshEnabled()
-                            ? kMessageCenterNotificationCornerRadius
+                            ? kMessageCenterNotificationInnerCornerRadius
                             : 0;
     message_view_->UpdateCornerRadius(corner_radius, corner_radius);
   }
@@ -280,7 +280,9 @@
 
     need_update_corner_radius_ = false;
 
-    message_view_->UpdateCornerRadius(kBubbleCornerRadius, kBubbleCornerRadius);
+    message_view_->UpdateCornerRadius(
+        kMessageCenterNotificationTopBottomCornerRadius,
+        kMessageCenterNotificationTopBottomCornerRadius);
 
     // Also update `above_view_`'s bottom and `below_view_`'s top corner radius
     // when sliding.
@@ -290,14 +292,16 @@
     above_view_ = (index == 0) ? nullptr : AsMVC(list_child_views[index - 1]);
     if (above_view_)
       above_view_->message_view()->UpdateCornerRadius(
-          kMessageCenterNotificationCornerRadius, kBubbleCornerRadius);
+          kMessageCenterNotificationInnerCornerRadius,
+          kMessageCenterNotificationTopBottomCornerRadius);
 
     below_view_ = (index == list_child_views.size() - 1)
                       ? nullptr
                       : AsMVC(list_child_views[index + 1]);
     if (below_view_)
       below_view_->message_view()->UpdateCornerRadius(
-          kBubbleCornerRadius, kMessageCenterNotificationCornerRadius);
+          kMessageCenterNotificationTopBottomCornerRadius,
+          kMessageCenterNotificationInnerCornerRadius);
   }
 
   void OnSlideEnded(const std::string& notification_id) override {
diff --git a/ash/system/message_center/unified_message_list_view_unittest.cc b/ash/system/message_center/unified_message_list_view_unittest.cc
index e7e9da5..3516899 100644
--- a/ash/system/message_center/unified_message_list_view_unittest.cc
+++ b/ash/system/message_center/unified_message_list_view_unittest.cc
@@ -279,7 +279,7 @@
 
   int GetMessageCenterNotificationCornerRadius() {
     return IsNotificationsRefreshEnabled()
-               ? kMessageCenterNotificationCornerRadius
+               ? kMessageCenterNotificationInnerCornerRadius
                : 0;
   }
 
@@ -332,9 +332,10 @@
     EXPECT_EQ(GetMessageViewBounds(1).bottom(), GetMessageViewBounds(2).y());
   }
 
-  int top_most_corner_radius = IsNotificationsRefreshEnabled()
-                                   ? kBubbleCornerRadius
-                                   : GetMessageCenterNotificationCornerRadius();
+  int top_most_corner_radius =
+      IsNotificationsRefreshEnabled()
+          ? kMessageCenterNotificationTopBottomCornerRadius
+          : GetMessageCenterNotificationCornerRadius();
   EXPECT_EQ(top_most_corner_radius, GetMessageViewAt(0)->top_radius());
   EXPECT_EQ(GetMessageCenterNotificationCornerRadius(),
             GetMessageViewAt(1)->top_radius());
@@ -346,7 +347,8 @@
   EXPECT_EQ(GetMessageCenterNotificationCornerRadius(),
             GetMessageViewAt(1)->bottom_radius());
 
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(2)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(2)->bottom_radius());
 
   EXPECT_LT(0, message_list_view()->GetPreferredSize().height());
 }
@@ -360,8 +362,10 @@
   EXPECT_EQ(1u, message_list_view()->children().size());
   EXPECT_EQ(id0, GetMessageViewAt(0)->notification_id());
 
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->bottom_radius());
 
   int previous_message_list_view_height =
       message_list_view()->GetPreferredSize().height();
@@ -394,14 +398,16 @@
     EXPECT_EQ(GetMessageViewBounds(0).bottom(), GetMessageViewBounds(1).y());
   }
 
-  int top_most_corner_radius = IsNotificationsRefreshEnabled()
-                                   ? kBubbleCornerRadius
-                                   : GetMessageCenterNotificationCornerRadius();
+  int top_most_corner_radius =
+      IsNotificationsRefreshEnabled()
+          ? kMessageCenterNotificationTopBottomCornerRadius
+          : GetMessageCenterNotificationCornerRadius();
   EXPECT_EQ(top_most_corner_radius, GetMessageViewAt(0)->top_radius());
   EXPECT_EQ(GetMessageCenterNotificationCornerRadius(),
             GetMessageViewAt(1)->top_radius());
 
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->bottom_radius());
 }
 
 TEST_P(ParameterizedUnifiedMessageListViewTest, RemoveNotification) {
@@ -413,9 +419,10 @@
 
   EXPECT_EQ(2u, message_list_view()->children().size());
 
-  int top_most_corner_radius = IsNotificationsRefreshEnabled()
-                                   ? kBubbleCornerRadius
-                                   : GetMessageCenterNotificationCornerRadius();
+  int top_most_corner_radius =
+      IsNotificationsRefreshEnabled()
+          ? kMessageCenterNotificationTopBottomCornerRadius
+          : GetMessageCenterNotificationCornerRadius();
   EXPECT_EQ(top_most_corner_radius, GetMessageViewAt(0)->top_radius());
   EXPECT_EQ(GetMessageCenterNotificationCornerRadius(),
             GetMessageViewAt(0)->bottom_radius());
@@ -429,8 +436,10 @@
   EXPECT_LT(0, message_list_view()->GetPreferredSize().height());
   EXPECT_GT(previous_height, message_list_view()->GetPreferredSize().height());
 
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->bottom_radius());
 
   MessageCenter::Get()->RemoveNotification(id1, true /* by_user */);
   FinishSlideOutAnimation();
@@ -1101,27 +1110,31 @@
 
   // At first, there should be no fully rounded corners for the middle
   // notification.
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(2)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(2)->bottom_radius());
 
   // Start sliding notification 2 away.
   StartSliding(2);
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(2)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(2)->bottom_radius());
 
   // Notification 1's bottom corner and notification 3's top corner should also
   // be rounded.
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(1)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->bottom_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(3)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(3)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(3)->bottom_radius());
 
   // Notification 0 should not change.
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(0)->bottom_radius());
 
   // Slide out notification 2, the 3 notifications left should have no rounded
@@ -1130,55 +1143,65 @@
   FinishSlideOutAnimation();
   AnimateUntilIdle();
 
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(0)->bottom_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(1)->top_radius());
 
   // Test with notification 1. Same behavior should happen.
   StartSliding(1);
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->bottom_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->bottom_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(2)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(2)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(2)->bottom_radius());
 
   // Cancel the slide. Everything goes back to normal.
   GetMessageViewAt(1)->OnSlideChanged(/*in_progress=*/false);
   for (int i = 0; i <= 2; i++) {
-    EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+    EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
               GetMessageViewAt(i)->top_radius());
-    EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+    EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
               GetMessageViewAt(i)->bottom_radius());
   }
 
   // Test with the top notification.
   StartSliding(0);
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(0)->bottom_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(0)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(1)->bottom_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(2)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(2)->bottom_radius());
   GetMessageViewAt(0)->OnSlideChanged(/*in_progress=*/false);
 
   // Test with the bottom notification.
   StartSliding(2);
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(0)->top_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(0)->bottom_radius());
-  EXPECT_EQ(kMessageCenterNotificationCornerRadius,
+  EXPECT_EQ(kMessageCenterNotificationInnerCornerRadius,
             GetMessageViewAt(1)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(1)->bottom_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(2)->top_radius());
-  EXPECT_EQ(kBubbleCornerRadius, GetMessageViewAt(2)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(1)->bottom_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(2)->top_radius());
+  EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
+            GetMessageViewAt(2)->bottom_radius());
   GetMessageViewAt(2)->OnSlideChanged(/*in_progress=*/false);
 }
 
diff --git a/ash/system/privacy_hub/privacy_hub_controller.cc b/ash/system/privacy_hub/privacy_hub_controller.cc
index 52c37ec2..bc9e901 100644
--- a/ash/system/privacy_hub/privacy_hub_controller.cc
+++ b/ash/system/privacy_hub/privacy_hub_controller.cc
@@ -17,6 +17,7 @@
 void PrivacyHubController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(prefs::kUserCameraAllowed, true);
   registry->RegisterBooleanPref(prefs::kUserMicrophoneAllowed, true);
+  registry->RegisterBooleanPref(prefs::kUserGeolocationAllowed, true);
 }
 
 }  // namespace ash
diff --git a/ash/webui/BUILD.gn b/ash/webui/BUILD.gn
index 594e7412..67216b0 100644
--- a/ash/webui/BUILD.gn
+++ b/ash/webui/BUILD.gn
@@ -32,6 +32,7 @@
     "//ash/webui/personalization_app:unit_tests",
     "//ash/webui/projector_app:unit_tests",
     "//ash/webui/scanning:unit_tests",
+    "//ash/webui/scanning/mojom:unit_tests",
     "//ash/webui/shimless_rma/backend:unit_tests",
     "//ash/webui/shimless_rma/mojom:unit_tests",
     "//ash/webui/shortcut_customization_ui/backend:unit_tests",
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_af.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_af.xtb
index 817113e..ba348c6 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_af.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_af.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Vee uit</translation>
 <translation id="8425673304802773841">Kantel af</translation>
 <translation id="8428213095426709021">Instellings</translation>
+<translation id="8629662593426079630">360 p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" /> p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Wissel mikrofoondempknoppie. Demp is aan</translation>
 <translation id="8712637175834984815">Het dit</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_ar.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_ar.xtb
index d7a6c514..ed38a430 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_ar.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_ar.xtb
@@ -161,6 +161,7 @@
 <translation id="8261506727792406068">حذف</translation>
 <translation id="8425673304802773841">إمالة إلى أسفل</translation>
 <translation id="8428213095426709021">الإعدادات</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">دقة عالية <ph name="HEIGHT" />بكسل (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">زر كتم الميكروفون. تم كتم الميكروفون.</translation>
 <translation id="8712637175834984815">تم</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_az.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_az.xtb
index b2231253..7eebd1a8 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_az.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_az.xtb
@@ -158,6 +158,7 @@
 <translation id="8261506727792406068">Silin</translation>
 <translation id="8425673304802773841">Aşağı əyin</translation>
 <translation id="8428213095426709021">Ayarlar</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Mikrofonu səssisə keçirin. Susdurma düyməsi aktivdir</translation>
 <translation id="8712637175834984815">Anladım</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_cy.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_cy.xtb
index 4871e79..663106c 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_cy.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_cy.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Dileu</translation>
 <translation id="8425673304802773841">Gogwyddo i lawr</translation>
 <translation id="8428213095426709021">Gosodiadau</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Toglo distewi'r meicroffon. Mae distewi ymlaen</translation>
 <translation id="8712637175834984815">Iawn</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_es-419.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_es-419.xtb
index 5328e32..425020a 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_es-419.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_es-419.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Borrar</translation>
 <translation id="8425673304802773841">Inclinar hacia abajo</translation>
 <translation id="8428213095426709021">Configuración</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" /> p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Activar o desactivar la función para silenciar el micrófono, la función para silenciar está activada</translation>
 <translation id="8712637175834984815">Entendido</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb
index cbc2271..572cdbe3 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">حذف</translation>
 <translation id="8425673304802773841">پایین کشیدن</translation>
 <translation id="8428213095426709021">تنظیمات</translation>
+<translation id="8629662593426079630">۳۶۰ پیکسل</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">وضعیت بی‌صدا بودن میکروفون را تغییر دهید. میکروفون بی‌صدا است</translation>
 <translation id="8712637175834984815">متوجه شدم</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_id.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_id.xtb
index 6261bd9..2eae51a 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_id.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_id.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Hapus</translation>
 <translation id="8425673304802773841">Miringkan ke bawah</translation>
 <translation id="8428213095426709021">Setelan</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Aktifkan/nonaktifkan tombol bisukan mikrofon. Bisukan aktif</translation>
 <translation id="8712637175834984815">Mengerti</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_it.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_it.xtb
index c94332c3..7702f02 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_it.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_it.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Elimina</translation>
 <translation id="8425673304802773841">Inclinazione verso il basso</translation>
 <translation id="8428213095426709021">Impostazioni</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Attiva/disattiva audio del microfono. Opzione Disattiva audio attiva</translation>
 <translation id="8712637175834984815">Fatto</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_iw.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_iw.xtb
index e07e3a4..503d1462 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_iw.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_iw.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">מחיקה</translation>
 <translation id="8425673304802773841">הטייה מטה</translation>
 <translation id="8428213095426709021">הגדרות</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">‏איכות HD ‏– ‎<ph name="HEIGHT" />p ‏(<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">החלפת המצב של השתקת המיקרופון. ההשתקה פועלת</translation>
 <translation id="8712637175834984815">הבנתי</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_ko.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_ko.xtb
index 253ce18..76f91bb 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_ko.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_ko.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">삭제</translation>
 <translation id="8425673304802773841">아래로 기울이기</translation>
 <translation id="8428213095426709021">설정</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p(<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">마이크 음소거를 전환합니다. 음소거가 사용 설정되었습니다</translation>
 <translation id="8712637175834984815">확인</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
index f2ab4f78..d204568 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">ລຶບ</translation>
 <translation id="8425673304802773841">ອຽງລົງ</translation>
 <translation id="8428213095426709021">ການ​ຕັ້ງຄ່າ</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">ສະຫຼັບການປິດສຽງໄມໂຄຣໂຟນ. ກຳລັງປິດສຽງຢູ່</translation>
 <translation id="8712637175834984815">ເຂົ້າໃຈແລ້ວ</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_lt.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_lt.xtb
index 38c0508..587dd24 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_lt.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_lt.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Ištrinti</translation>
 <translation id="8425673304802773841">Nukreipti žemyn</translation>
 <translation id="8428213095426709021">Nustatymai</translation>
+<translation id="8629662593426079630">360 taškų</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" /> p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Perjungti mikrofono nutildymą. Nutildymas įjungtas</translation>
 <translation id="8712637175834984815">Supratau</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_ms.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_ms.xtb
index 508134f2e..cdceb46 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_ms.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_ms.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Padam</translation>
 <translation id="8425673304802773841">Condongkan ke bawah</translation>
 <translation id="8428213095426709021">Tetapan</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Togol redam mikrofon. Redam dihidupkan</translation>
 <translation id="8712637175834984815">Faham</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_my.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_my.xtb
index 03e5fa1..fbfbfc1 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_my.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_my.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">ဖျက်ရန်</translation>
 <translation id="8425673304802773841">အောက်သို့ စောင်းရန်</translation>
 <translation id="8428213095426709021">ဆက်တင်များ</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">မိုက်ခရိုဖုန်း အသံပိတ် ခလုတ်။ အသံတိတ်ခြင်း ဖွင့်</translation>
 <translation id="8712637175834984815">ရပါပြီ!</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb
index 1896205..24e2ab6 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Verwijderen</translation>
 <translation id="8425673304802773841">Naar beneden kantelen</translation>
 <translation id="8428213095426709021">Instellingen</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Geluid uitzetten voor microfoon schakelen. Geluid uit staat aan</translation>
 <translation id="8712637175834984815">Begrepen</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_or.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_or.xtb
index c74823c..3a0843f 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_or.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_or.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">ବିଲୋପ</translation>
 <translation id="8425673304802773841">ତଳକୁ ଟିଲ୍ଟ କରନ୍ତୁ</translation>
 <translation id="8428213095426709021">ସେଟିଂସ୍</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">ମାଇକ୍ରୋଫୋନ ମ୍ୟୁଟ କରିବା ବଟନକୁ ଟୋଗଲ କରନ୍ତୁ। ମ୍ୟୁଟ ଚାଲୁ ଅଛି</translation>
 <translation id="8712637175834984815">ବୁଝିଗଲି</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_pl.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_pl.xtb
index b36532d..bc3fe94 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_pl.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_pl.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Usuń</translation>
 <translation id="8425673304802773841">Pochyl w dół</translation>
 <translation id="8428213095426709021">Ustawienia</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Przełącz przycisk wyciszenia mikrofonu. Wyciszenie jest włączone</translation>
 <translation id="8712637175834984815">Rozumiem</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_ru.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_ru.xtb
index dd61e8a..c9cce81 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_ru.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_ru.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Удалить</translation>
 <translation id="8425673304802773841">Наклонить вниз</translation>
 <translation id="8428213095426709021">Настройки</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Микрофон отключен.</translation>
 <translation id="8712637175834984815">Готово</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_si.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_si.xtb
index 3356000..e3237c7 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_si.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_si.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">මකන්න</translation>
 <translation id="8425673304802773841">පහළට ඇල කරන්න</translation>
 <translation id="8428213095426709021">සැකසුම්</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">මයික්‍රෆෝනය නිහඬ කිරීම ටොගල කරන්න නිහඬ කිරීම ක්‍රියාත්මකයි</translation>
 <translation id="8712637175834984815">එය ලැබුණා</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_sk.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_sk.xtb
index 8cd202d9..a398ab6 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_sk.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_sk.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">Odstrániť</translation>
 <translation id="8425673304802773841">Naklonenie nadol</translation>
 <translation id="8428213095426709021">Nastavenia</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD <ph name="HEIGHT" /> p (<ph name="WIDTH" /> : <ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">Prepínač vypnutia zvuku mikrofónu. Zvuk je vypnutý.</translation>
 <translation id="8712637175834984815">Dobre</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_sv.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_sv.xtb
index 61d1bf2..4c2208b 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_sv.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_sv.xtb
@@ -91,7 +91,7 @@
 <translation id="4705093842003735294">Hög upplösning</translation>
 <translation id="4890010094662541459">3 × 3</translation>
 <translation id="491895758387112773">Multistream-videoinspelning</translation>
-<translation id="5034763830503483128">Fotots bildproportioner</translation>
+<translation id="5034763830503483128">Fotots bildformat</translation>
 <translation id="5057360777601936059">Kameran är inte tillgänglig.
         Kontrollera kameraanslutningen.</translation>
 <translation id="5163387177077603948">Flyttas åt höger</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-CN.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-CN.xtb
index 488d3d2..ce2c17a73 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-CN.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-CN.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">删除</translation>
 <translation id="8425673304802773841">向下倾斜</translation>
 <translation id="8428213095426709021">设置</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">高清 <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">使用切换开关可将麦克风静音或取消静音。已静音</translation>
 <translation id="8712637175834984815">知道了</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-HK.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-HK.xtb
index cd06740..94864496 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-HK.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-HK.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">刪除</translation>
 <translation id="8425673304802773841">向下傾斜</translation>
 <translation id="8428213095426709021">設定</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">高清畫質 <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">將個咪校去靜音。開咗靜音</translation>
 <translation id="8712637175834984815">我知道了</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-TW.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-TW.xtb
index b3194888..555ec62 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-TW.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_zh-TW.xtb
@@ -160,6 +160,7 @@
 <translation id="8261506727792406068">刪除</translation>
 <translation id="8425673304802773841">向下傾斜</translation>
 <translation id="8428213095426709021">設定</translation>
+<translation id="8629662593426079630">360p</translation>
 <translation id="8687491812650032292">HD 高畫質 <ph name="HEIGHT" />p (<ph name="WIDTH" />:<ph name="HEIGHT" />)</translation>
 <translation id="8711011893539266636">將麥克風切換為靜音。靜音功能已開啟</translation>
 <translation id="8712637175834984815">我瞭解了</translation>
diff --git a/ash/webui/common/resources/BUILD.gn b/ash/webui/common/resources/BUILD.gn
index 48676d1..3edb44b 100644
--- a/ash/webui/common/resources/BUILD.gn
+++ b/ash/webui/common/resources/BUILD.gn
@@ -126,12 +126,12 @@
   root_dir = "$target_gen_dir/$preprocessed_dir"
   out_dir = "$target_gen_dir/$preprocessed_dir"
   js_files = generate_definitions_js_files
+  deps = [ "//ui/webui/resources:library" ]
   extra_deps = [
     ":copy_checked_in_dts_files",
     ":css_wrapper_files",
     ":html_wrapper_files",
     ":preprocess",
-    "//ui/webui/resources:library",
   ]
 }
 
diff --git a/ash/webui/demo_mode_app_ui/demo_mode_app_untrusted_ui.cc b/ash/webui/demo_mode_app_ui/demo_mode_app_untrusted_ui.cc
index ce5a26c9..93015ac5 100644
--- a/ash/webui/demo_mode_app_ui/demo_mode_app_untrusted_ui.cc
+++ b/ash/webui/demo_mode_app_ui/demo_mode_app_untrusted_ui.cc
@@ -105,6 +105,12 @@
   data_source->SetRequestFilter(
       base::BindRepeating(&ShouldSourceFromComponent, webui_resource_paths),
       base::BindRepeating(&SourceDataFromComponent, component_path));
+  data_source->OverrideContentSecurityPolicy(
+      network::mojom::CSPDirectiveName::StyleSrc,
+      "style-src 'self' 'unsafe-inline';");
+  data_source->OverrideContentSecurityPolicy(
+      network::mojom::CSPDirectiveName::TrustedTypes,
+      "trusted-types lit-html;");
 }
 
 DemoModeAppUntrustedUI::~DemoModeAppUntrustedUI() = default;
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller.cc b/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
index 3112e47..9742c34 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
@@ -171,14 +171,14 @@
 
 void SystemRoutineController::BindInterface(
     mojo::PendingReceiver<mojom::SystemRoutineController> pending_receiver) {
-  DCHECK(!ReceiverIsBound());
+  receiver_.reset();
   receiver_.Bind(std::move(pending_receiver));
   receiver_.set_disconnect_handler(
       base::BindOnce(&SystemRoutineController::OnBoundInterfaceDisconnect,
                      base::Unretained(this)));
 }
 
-bool SystemRoutineController::ReceiverIsBound() {
+bool SystemRoutineController::IsReceiverBoundForTesting() {
   return receiver_.is_bound();
 }
 
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller.h b/ash/webui/diagnostics_ui/backend/system_routine_controller.h
index 77ca14cf..5b0df121 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller.h
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller.h
@@ -52,7 +52,7 @@
       mojo::PendingReceiver<mojom::SystemRoutineController> pending_receiver);
   // Handler for when remote attached to |receiver_| disconnects.
   void OnBoundInterfaceDisconnect();
-  bool ReceiverIsBound();
+  bool IsReceiverBoundForTesting();
 
   void SetWakeLockProviderForTesting(
       mojo::Remote<device::mojom::WakeLockProvider> provider) {
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc b/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
index 3ea97d7..6290542 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
@@ -989,23 +989,23 @@
 }
 
 TEST_F(SystemRoutineControllerTest, ResetReceiverOnDisconnect) {
-  ASSERT_FALSE(system_routine_controller_->ReceiverIsBound());
+  ASSERT_FALSE(system_routine_controller_->IsReceiverBoundForTesting());
   mojo::Remote<mojom::SystemRoutineController> remote;
   system_routine_controller_->BindInterface(
       remote.BindNewPipeAndPassReceiver());
-  ASSERT_TRUE(system_routine_controller_->ReceiverIsBound());
+  ASSERT_TRUE(system_routine_controller_->IsReceiverBoundForTesting());
 
   // Unbind remote to trigger disconnect and disconnect handler.
   remote.reset();
   base::RunLoop().RunUntilIdle();
-  ASSERT_FALSE(system_routine_controller_->ReceiverIsBound());
+  ASSERT_FALSE(system_routine_controller_->IsReceiverBoundForTesting());
 
   // Test intent is to ensure interface can be rebound when application is
   // reloaded using |CTRL + R|.  A disconnect should be signaled in which we
   // will reset the receiver to its unbound state.
   system_routine_controller_->BindInterface(
       remote.BindNewPipeAndPassReceiver());
-  ASSERT_TRUE(system_routine_controller_->ReceiverIsBound());
+  ASSERT_TRUE(system_routine_controller_->IsReceiverBoundForTesting());
 }
 
 TEST_F(SystemRoutineControllerTest, SendRoutineResultDoesNotCrash) {
diff --git a/ash/webui/diagnostics_ui/resources/BUILD.gn b/ash/webui/diagnostics_ui/resources/BUILD.gn
index 55e6ed5..c5b082cc 100644
--- a/ash/webui/diagnostics_ui/resources/BUILD.gn
+++ b/ash/webui/diagnostics_ui/resources/BUILD.gn
@@ -160,8 +160,9 @@
 js_library("diagnostics_sticky_banner") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("diagnostics_utils") {
@@ -242,18 +243,20 @@
     ":diagnostics_types",
     ":diagnostics_utils",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("keyboard_tester") {
   deps = [
     "//ash/webui/common/resources:keyboard_diagram",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("memory_card") {
@@ -400,12 +403,13 @@
     ":mojo_interface_provider",
     ":overview_card",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_toast/cr_toast_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_toast/cr_toast_externs.js",
+  ]
 }
 
 js_library("text_badge") {
diff --git a/ash/webui/os_feedback_ui/resources/feedback_flow.html b/ash/webui/os_feedback_ui/resources/feedback_flow.html
index e521240..6ce6981e 100644
--- a/ash/webui/os_feedback_ui/resources/feedback_flow.html
+++ b/ash/webui/os_feedback_ui/resources/feedback_flow.html
@@ -5,6 +5,7 @@
         help-content-search-result-count="{{helpContentSearchResultCount_}}">
     </search-page>
     <share-data-page id="shareDataPage" feedback-context="[[feedbackContext_]]"
+        should-show-bluetooth-checkbox="[[shouldShowBluetoothCheckbox_]]"
         on-continue-click="handleContinueClick_"
         on-go-back-click="handleGoBackClick_">
     </share-data-page>
diff --git a/ash/webui/os_feedback_ui/resources/feedback_flow.js b/ash/webui/os_feedback_ui/resources/feedback_flow.js
index d229954..5ddb863 100644
--- a/ash/webui/os_feedback_ui/resources/feedback_flow.js
+++ b/ash/webui/os_feedback_ui/resources/feedback_flow.js
@@ -47,6 +47,88 @@
 };
 
 /**
+ * Builds a RegExp that matches one of the given words. Each word has to match
+ * at word boundary and is not at the end of the tested string. For example,
+ * the word "SIM" would match the string "I have a sim card issue" but not
+ * "I have a simple issue" nor "I have a sim" (because the user might not have
+ * finished typing yet).
+ * @param {!Array<!string>} words
+ * @return {!RegExp}
+ * @protected
+ */
+export function buildWordMatcher(words) {
+  return new RegExp(
+      words.map((word) => '\\b' + word + '\\b[^$]').join('|'), 'i');
+}
+
+/**
+ * Regular expression to check for all variants of blu[e]toot[h] with or
+ * without space between the words; for BT when used as an individual word,
+ * or as two individual characters, and for BLE, BlueZ, and Floss when used
+ * as an individual word. Case insensitive matching.
+ * @type {!RegExp}
+ * @protected
+ */
+const btRegEx = new RegExp(
+    'blu[e]?[ ]?toot[h]?|\\bb[ ]?t\\b|\\bble\\b|\\bfloss\\b|\\bbluez\\b', 'i');
+
+/**
+ * Regular expression to check for all strings indicating that a user can't
+ * connect to a HID or Audio device.
+ * Sample strings this will match:
+ * "I can't connect the speaker!",
+ * "The keyboard has connection problem."
+ * @type {!RegExp}
+ * @protected
+ */
+const cantConnectRegEx = new RegExp(
+    '((headphone|keyboard|mouse|speaker)((?!(connect|pair)).*)(connect|pair))' +
+        '|((connect|pair).*(headphone|keyboard|mouse|speaker))',
+    'i');
+
+/**
+ * Regular expression to check for "tether" or "tethering". Case insensitive
+ * matching.
+ * @type {!RegExp}
+ * @protected
+ */
+const tetherRegEx = new RegExp('tether(ing)?', 'i');
+
+/**
+ * Regular expression to check for "Smart (Un)lock" or "Easy (Un)lock" with
+ * or without space between the words. Case insensitive matching.
+ * @type {!RegExp}
+ * @protected
+ */
+const smartLockRegEx = new RegExp('(smart|easy)[ ]?(un)?lock', 'i');
+
+/**
+ * Regular expression to check for keywords related to Nearby Share like
+ * "nearby (share)" or "phone (hub)".
+ * Case insensitive matching.
+ * @type {!RegExp}
+ * @protected
+ */
+const nearbyShareRegEx = new RegExp('nearby|phone', 'i');
+
+/**
+ * Regular expression to check for keywords related to Fast Pair like
+ * "fast pair".
+ * Case insensitive matching.
+ * @type {!RegExp}
+ * @protected
+ */
+const fastPairRegEx = new RegExp('fast[ ]?pair', 'i');
+
+/**
+ * Regular expression to check for Bluetooth device specific keywords.
+ * @type {!RegExp}
+ * @protected
+ */
+const btDeviceRegEx =
+    buildWordMatcher(['apple', 'allegro', 'pixelbud', 'microsoft', 'sony']);
+
+/**
  * @fileoverview
  * 'feedback-flow' manages the navigation among the steps to be taken.
  */
@@ -82,6 +164,12 @@
      */
     this.feedbackContext_ = null;
 
+    /**
+     * Whether to show the bluetooth Logs checkbox in share data page.
+     * @type {boolean}
+     */
+    this.shouldShowBluetoothCheckbox_;
+
     /** @private {!FeedbackServiceProviderInterface} */
     this.feedbackServiceProvider_ = getFeedbackServiceProvider();
 
@@ -229,6 +317,9 @@
       case FeedbackFlowState.SEARCH:
         this.currentState_ = FeedbackFlowState.SHARE_DATA;
         this.description_ = event.detail.description;
+        this.shouldShowBluetoothCheckbox_ = this.feedbackContext_ !== null &&
+            this.feedbackContext_.isInternalAccount &&
+            this.isDescriptionRelatedToBluetooth(this.description_);
         this.fetchScreenshot_();
         // TODO(longbowei): Handle NoResultFound case.
         if (!this.helpContentOutcomeMetricEmitted_) {
@@ -341,6 +432,25 @@
   setHelpContentClickedForTesting(helpContentClicked) {
     this.helpContentClicked_ = helpContentClicked;
   }
+
+  /**
+   * Checks if any keywords related to bluetooth have been typed. If they are,
+   * we show the bluetooth logs option, otherwise hide it.
+   * @return {boolean}
+   * @param {!string} textInput The input text for the description textarea.
+   * @protected
+   */
+  isDescriptionRelatedToBluetooth(textInput) {
+    /**
+     * If the user is not signed in with a internal google account, the
+     * bluetooth checkbox should be hidden and skip the relative check.
+     */
+    const isRelatedToBluetooth = btRegEx.test(textInput) ||
+        cantConnectRegEx.test(textInput) || tetherRegEx.test(textInput) ||
+        smartLockRegEx.test(textInput) || nearbyShareRegEx.test(textInput) ||
+        fastPairRegEx.test(textInput) || btDeviceRegEx.test(textInput);
+    return isRelatedToBluetooth;
+  }
 }
 
 customElements.define(FeedbackFlowElement.is, FeedbackFlowElement);
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.html b/ash/webui/os_feedback_ui/resources/share_data_page.html
index 22fc9a9..86b2ad6 100644
--- a/ash/webui/os_feedback_ui/resources/share_data_page.html
+++ b/ash/webui/os_feedback_ui/resources/share_data_page.html
@@ -224,7 +224,7 @@
       </div>
       <!-- Bluetooth Logs (Googler Internal Only) -->
       <div id="bluetoothCheckboxContainer" class="checkbox-field-container"
-          hidden$="[[!shouldShowBluetoothCheckbox_(feedbackContext)]]">
+          hidden="[[!shouldShowBluetoothCheckbox]]">
         <cr-checkbox id="bluetoothLogsCheckbox" aria-labelledby="bluetoothInfoLabel" checked>
         </cr-checkbox>
         <label id="bluetoothInfoLabel" inner-h-t-m-l="[[bluetoothLogsCheckboxLabel_]]"></label>
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.js b/ash/webui/os_feedback_ui/resources/share_data_page.js
index fee9ca4..2bbafe1 100644
--- a/ash/webui/os_feedback_ui/resources/share_data_page.js
+++ b/ash/webui/os_feedback_ui/resources/share_data_page.js
@@ -44,6 +44,8 @@
     return {
       feedbackContext: {type: FeedbackContext, readOnly: false, notify: true},
       screenshotUrl: {type: String, readOnly: false, notify: true},
+      shouldShowBluetoothCheckbox:
+          {type: Boolean, readOnly: false, notify: true},
     };
   }
 
@@ -61,6 +63,11 @@
     this.screenshotUrl;
 
     /**
+     * @type {boolean}
+     */
+    this.shouldShowBluetoothCheckbox;
+
+    /**
      * @type {string}
      * @protected
      */
@@ -116,18 +123,6 @@
    * @return {boolean}
    * @protected
    */
-  shouldShowBluetoothCheckbox_() {
-    // TODO: add an additional logic to hide bluetooth checkbox if user input
-    // is not relevant to bluetooth.
-    return (
-        this.feedbackContext !== null &&
-        this.feedbackContext.isInternalAccount);
-  }
-
-  /**
-   * @return {boolean}
-   * @protected
-   */
   hasScreenshot_() {
     return !!this.screenshotUrl;
   }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html
index fbfe7e9..4de1350 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html
@@ -27,7 +27,6 @@
           index="[[index]]"
           on-click="onAlbumSelected_"
           on-keypress="onAlbumSelected_"
-          placeholder="[[isAlbumPlaceholder_(album)]]"
           primary-text="[[album.title]]"
           role="listitem"
           secondary-text="[[getSecondaryText_(album)]]"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html
index eb6f0050..19e7d40 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html
@@ -24,7 +24,6 @@
           index="[[index]]"
           on-click="onPhotoSelected_"
           on-keypress="onPhotoSelected_"
-          placeholder="[[isPhotoPlaceholder_(photo)]]"
           role="option"
           selected="[[isPhotoSelected_(photo, currentSelected_, pendingSelected_)]]"
           tabindex$="[[tabIndex]]">
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html
index b3182dc..c0654b4f 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html
@@ -79,7 +79,6 @@
                 on-click="onPhotoSelected_"
                 on-keypress="onPhotoSelected_"
                 photoindex$="[[photo.index]]"
-                placeholder="[[isPhotoPlaceholder_(photo)]]"
                 role="option"
                 selected="[[isPhotoSelected_(photo, currentSelected_, pendingSelected_)]]"
                 tabindex="-1">
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
index 18e40844..c01de3b 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
@@ -138,13 +138,15 @@
 
 </style>
 <div class="item" style$="[[getItemPlaceholderAnimationDelay_(index)]]">
-  <img clear-src
-      hidden
-      is-google-photos
+  <img aria-hidden="true"
       auto-src="[[src.url]]"
-      aria-hidden="true"
+      clear-src
+      hidden$="[[isImageHidden_(loading_, error_)]]"
       id="image"
-      is="cr-auto-img">
+      is-google-photos
+      is="cr-auto-img"
+      on-error="onImgError_"
+      on-load="onImgLoad_">
   <div class="wallpaper-grid-item-border"></div>
   <template is="dom-if" if="[[isTextVisible_(primaryText, secondaryText)]]">
     <div class="text">
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts
index 0ffdf88..1171700 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts
+++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts
@@ -44,15 +44,23 @@
         observer: 'onSelectedChanged_',
       },
 
-      placeholder: {
+      loading_: {
+        type: Boolean,
+        value: true,
+        observer: 'onLoadingChanged_',
+      },
+
+      error_: {
         type: Boolean,
         value: false,
-        reflectToAttribute: true,
       },
     };
   }
 
-  /** The source for the image to render for the grid item. */
+  /**
+   * The source for the image to render for the grid item. Will display a
+   * placeholder loading animation if src is undefined.
+   */
   src: Url|undefined;
 
   /** The index of the grid item within its parent grid. */
@@ -70,20 +78,19 @@
    */
   selected: boolean|undefined;
 
-  /**
-   * Whether to show a loading animation instead of the real image. Defaults to
-   * false. Will also set a placeholder html attribute.
-   */
-  placeholder: boolean;
+  // Received a new image that has not been downloaded yet for display.
+  private loading_: boolean;
+
+  // Image failed to download.
+  private error_: boolean;
 
   // Invoked on changes to |imageSrc|.
-  private onImageSrcChanged_(src: WallpaperGridItem['src']) {
-    // Hide the |image| element until it has successfully loaded. Note that it
-    // is intentional that the |image| element remain hidden on failure.
-    this.$.image.setAttribute('hidden', '');
-    this.$.image.onload = (src && src.url.length) ?
-        () => this.$.image.removeAttribute('hidden') :
-        null;
+  private onImageSrcChanged_(_: WallpaperGridItem['src']) {
+    // Set loading status if src has just changed while we wait for new image.
+    this.setProperties({
+      loading_: true,
+      error_: false,
+    });
   }
 
   private onSelectedChanged_(selected: boolean|undefined) {
@@ -94,6 +101,29 @@
     }
   }
 
+  private onLoadingChanged_(loading: boolean) {
+    if (loading) {
+      this.setAttribute('placeholder', '');
+    } else {
+      this.removeAttribute('placeholder');
+    }
+  }
+
+  private onImgError_() {
+    this.setProperties({loading_: false, error_: true});
+  }
+
+  private onImgLoad_() {
+    this.setProperties({loading_: false, error_: false});
+  }
+
+  private isImageHidden_(loading: boolean, error: boolean) {
+    // Do not show the image while loading because it has an ugly white frame.
+    // Do not show the image on error either because it has an ugly broken red
+    // icon symbol.
+    return loading || error;
+  }
+
   /** Returns the delay to use for the grid item's placeholder animation. */
   private getItemPlaceholderAnimationDelay_(index: WallpaperGridItem['index']):
       string {
diff --git a/ash/webui/scanning/mojom/BUILD.gn b/ash/webui/scanning/mojom/BUILD.gn
index 19589722..159a4d3 100644
--- a/ash/webui/scanning/mojom/BUILD.gn
+++ b/ash/webui/scanning/mojom/BUILD.gn
@@ -11,4 +11,39 @@
   sources = [ "scanning.mojom" ]
 
   public_deps = [ "//mojo/public/mojom/base" ]
+
+  cpp_typemaps = [
+    {
+      types = [
+        {
+          mojom = "ash.scanning.mojom.ScanResult"
+          cpp = "::lorgnette::ScanFailureMode"
+        },
+      ]
+      traits_headers = [
+        "scanning_type_converters.h",
+        "//chromeos/ash/components/dbus/lorgnette/lorgnette_service.pb.h",
+      ]
+      traits_sources = [ "scanning_type_converters.cc" ]
+      traits_public_deps =
+          [ "//chromeos/ash/components/dbus/lorgnette_manager:lorgnette_proto" ]
+    },
+  ]
+}
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "scanning_type_converters_unittest.cc" ]
+  deps = [
+    ":mojom",
+    "//base",
+    "//base/test:test_support",
+    "//chromeos/ash/components/dbus/lorgnette_manager:lorgnette_proto",
+    "//content/test:test_support",
+    "//services/data_decoder/public/cpp:test_support",
+    "//services/device/public/cpp:test_support",
+    "//testing/gtest",
+    "//ui/gfx",
+    "//ui/shell_dialogs",
+    "//ui/webui",
+  ]
 }
diff --git a/ash/webui/scanning/mojom/OWNERS b/ash/webui/scanning/mojom/OWNERS
index 08850f4..4249be6 100644
--- a/ash/webui/scanning/mojom/OWNERS
+++ b/ash/webui/scanning/mojom/OWNERS
@@ -1,2 +1,4 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
+per-file *_type_converter*.*=set noparent
+per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
\ No newline at end of file
diff --git a/chrome/browser/ash/scanning/scanning_type_converters.cc b/ash/webui/scanning/mojom/scanning_type_converters.cc
similarity index 71%
rename from chrome/browser/ash/scanning/scanning_type_converters.cc
rename to ash/webui/scanning/mojom/scanning_type_converters.cc
index 9b82d6e..c745fa8 100644
--- a/chrome/browser/ash/scanning/scanning_type_converters.cc
+++ b/ash/webui/scanning/mojom/scanning_type_converters.cc
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/scanning/scanning_type_converters.h"
+#include "ash/webui/scanning/mojom/scanning_type_converters.h"
+#include "ash/webui/scanning/mojom/scanning.mojom.h"
 
 #include <utility>
 
@@ -16,6 +17,9 @@
 
 namespace mojo_ipc = ash::scanning::mojom;
 
+using MojomScanResult = ash::scanning::mojom::ScanResult;
+using ProtoScanFailureMode = lorgnette::ScanFailureMode;
+
 using MojomColorMode = ash::scanning::mojom::ColorMode;
 using ProtoColorMode = lorgnette::ColorMode;
 
@@ -192,6 +196,7 @@
     case ProtoSourceType::SOURCE_DEFAULT:
       return MojomSourceType::kDefault;
     case ProtoSourceType::SOURCE_UNSPECIFIED:
+      return MojomSourceType::kUnknown;
     case ProtoSourceType::SourceType_INT_MIN_SENTINEL_DO_NOT_USE_:
     case ProtoSourceType::SourceType_INT_MAX_SENTINEL_DO_NOT_USE_:
       NOTREACHED();
@@ -200,6 +205,46 @@
 }
 
 // static
+bool EnumTraits<MojomSourceType, ProtoSourceType>::FromMojom(
+    MojomSourceType input,
+    ProtoSourceType* out) {
+  switch (input) {
+    case MojomSourceType::kFlatbed:
+      *out = ProtoSourceType::SOURCE_PLATEN;
+      return true;
+    case MojomSourceType::kAdfSimplex:
+      *out = ProtoSourceType::SOURCE_ADF_SIMPLEX;
+      return true;
+    case MojomSourceType::kAdfDuplex:
+      *out = ProtoSourceType::SOURCE_ADF_DUPLEX;
+      return true;
+    case MojomSourceType::kDefault:
+      *out = ProtoSourceType::SOURCE_DEFAULT;
+      return true;
+    case MojomSourceType::kUnknown:
+      *out = ProtoSourceType::SOURCE_UNSPECIFIED;
+      return true;
+  }
+  NOTREACHED();
+  return false;
+};
+
+// static
+MojomFileType EnumTraits<MojomFileType, ProtoImageFormat>::ToMojom(
+    ProtoImageFormat input) {
+  switch (input) {
+    case ProtoImageFormat::IMAGE_FORMAT_PNG:
+      return MojomFileType::kPng;
+    case ProtoImageFormat::IMAGE_FORMAT_JPEG:
+      return MojomFileType::kJpg;
+    case ProtoImageFormat::ImageFormat_INT_MIN_SENTINEL_DO_NOT_USE_:
+    case ProtoImageFormat::ImageFormat_INT_MAX_SENTINEL_DO_NOT_USE_:
+      NOTREACHED();
+      return MojomFileType::kJpg;
+  }
+}
+
+// static
 bool EnumTraits<MojomFileType, ProtoImageFormat>::FromMojom(
     MojomFileType input,
     ProtoImageFormat* out) {
@@ -219,31 +264,60 @@
 }
 
 // static
-mojo_ipc::ScanResult
-EnumTraits<ash::scanning::mojom::ScanResult, lorgnette::ScanFailureMode>::
-    ToMojom(const lorgnette::ScanFailureMode lorgnette_failure_mode) {
-  switch (lorgnette_failure_mode) {
-    case lorgnette::SCAN_FAILURE_MODE_NO_FAILURE:
-      return mojo_ipc::ScanResult::kSuccess;
-    case lorgnette::SCAN_FAILURE_MODE_UNKNOWN:
-      return mojo_ipc::ScanResult::kUnknownError;
-    case lorgnette::SCAN_FAILURE_MODE_DEVICE_BUSY:
-      return mojo_ipc::ScanResult::kDeviceBusy;
-    case lorgnette::SCAN_FAILURE_MODE_ADF_JAMMED:
-      return mojo_ipc::ScanResult::kAdfJammed;
-    case lorgnette::SCAN_FAILURE_MODE_ADF_EMPTY:
-      return mojo_ipc::ScanResult::kAdfEmpty;
-    case lorgnette::SCAN_FAILURE_MODE_FLATBED_OPEN:
-      return mojo_ipc::ScanResult::kFlatbedOpen;
-    case lorgnette::SCAN_FAILURE_MODE_IO_ERROR:
-      return mojo_ipc::ScanResult::kIoError;
-    case lorgnette::ScanFailureMode_INT_MIN_SENTINEL_DO_NOT_USE_:
-    case lorgnette::ScanFailureMode_INT_MAX_SENTINEL_DO_NOT_USE_:
+MojomScanResult EnumTraits<MojomScanResult, ProtoScanFailureMode>::ToMojom(
+    ProtoScanFailureMode input) {
+  switch (input) {
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE:
+      return MojomScanResult::kSuccess;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN:
+      return MojomScanResult::kUnknownError;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY:
+      return MojomScanResult::kDeviceBusy;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_JAMMED:
+      return MojomScanResult::kAdfJammed;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_EMPTY:
+      return MojomScanResult::kAdfEmpty;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_FLATBED_OPEN:
+      return MojomScanResult::kFlatbedOpen;
+    case ProtoScanFailureMode::SCAN_FAILURE_MODE_IO_ERROR:
+      return MojomScanResult::kIoError;
+    case ProtoScanFailureMode::ScanFailureMode_INT_MIN_SENTINEL_DO_NOT_USE_:
+    case ProtoScanFailureMode::ScanFailureMode_INT_MAX_SENTINEL_DO_NOT_USE_:
       break;
   }
-
   NOTREACHED();
-  return mojo_ipc::ScanResult::kUnknownError;
+  return MojomScanResult::kUnknownError;
+}
+
+// static
+bool EnumTraits<MojomScanResult, ProtoScanFailureMode>::FromMojom(
+    MojomScanResult input,
+    ProtoScanFailureMode* output) {
+  switch (input) {
+    case MojomScanResult::kSuccess:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE;
+      return true;
+    case MojomScanResult::kUnknownError:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN;
+      return true;
+    case MojomScanResult::kDeviceBusy:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY;
+      return true;
+    case MojomScanResult::kAdfJammed:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_JAMMED;
+      return true;
+    case MojomScanResult::kAdfEmpty:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_EMPTY;
+      return true;
+    case MojomScanResult::kFlatbedOpen:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_FLATBED_OPEN;
+      return true;
+    case MojomScanResult::kIoError:
+      *output = ProtoScanFailureMode::SCAN_FAILURE_MODE_IO_ERROR;
+      return true;
+  }
+  NOTREACHED();
+  return false;
 }
 
 // static
diff --git a/chrome/browser/ash/scanning/scanning_type_converters.h b/ash/webui/scanning/mojom/scanning_type_converters.h
similarity index 80%
rename from chrome/browser/ash/scanning/scanning_type_converters.h
rename to ash/webui/scanning/mojom/scanning_type_converters.h
index 6b50b7e..7b504b65 100644
--- a/chrome/browser/ash/scanning/scanning_type_converters.h
+++ b/ash/webui/scanning/mojom/scanning_type_converters.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 CHROME_BROWSER_ASH_SCANNING_SCANNING_TYPE_CONVERTERS_H_
-#define CHROME_BROWSER_ASH_SCANNING_SCANNING_TYPE_CONVERTERS_H_
+#ifndef ASH_WEBUI_SCANNING_MOJOM_SCANNING_TYPE_CONVERTERS_H_
+#define ASH_WEBUI_SCANNING_MOJOM_SCANNING_TYPE_CONVERTERS_H_
 
 #include "ash/webui/scanning/mojom/scanning.mojom.h"
 #include "chromeos/ash/components/dbus/lorgnette/lorgnette_service.pb.h"
@@ -30,6 +30,8 @@
 
 template <>
 struct EnumTraits<ash::scanning::mojom::FileType, lorgnette::ImageFormat> {
+  static ash::scanning::mojom::FileType ToMojom(
+      lorgnette::ImageFormat image_format);
   static bool FromMojom(ash::scanning::mojom::FileType input,
                         lorgnette::ImageFormat* out);
 };
@@ -38,7 +40,9 @@
 struct EnumTraits<ash::scanning::mojom::ScanResult,
                   lorgnette::ScanFailureMode> {
   static ash::scanning::mojom::ScanResult ToMojom(
-      const lorgnette::ScanFailureMode lorgnette_failure_mode);
+      lorgnette::ScanFailureMode lorgnette_failure_mode);
+  static bool FromMojom(ash::scanning::mojom::ScanResult input,
+                        lorgnette::ScanFailureMode* out);
 };
 
 template <>
@@ -57,4 +61,4 @@
 
 }  // namespace mojo
 
-#endif  // CHROME_BROWSER_ASH_SCANNING_SCANNING_TYPE_CONVERTERS_H_
+#endif  // ASH_WEBUI_SCANNING_MOJOM_SCANNING_TYPE_CONVERTERS_H_
diff --git a/chrome/browser/ash/scanning/scanning_type_converters_unittest.cc b/ash/webui/scanning/mojom/scanning_type_converters_unittest.cc
similarity index 66%
rename from chrome/browser/ash/scanning/scanning_type_converters_unittest.cc
rename to ash/webui/scanning/mojom/scanning_type_converters_unittest.cc
index f4a90851..960b5eb 100644
--- a/chrome/browser/ash/scanning/scanning_type_converters_unittest.cc
+++ b/ash/webui/scanning/mojom/scanning_type_converters_unittest.cc
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/scanning/scanning_type_converters.h"
+#include "ash/webui/scanning/mojom/scanning_type_converters.h"
+#include <map>
+#include "base/containers/fixed_flat_map.h"
 
 #include "ash/webui/scanning/mojom/scanning.mojom.h"
 #include "chromeos/ash/components/dbus/lorgnette/lorgnette_service.pb.h"
@@ -17,6 +19,18 @@
 
 using ::testing::ElementsAreArray;
 
+using MojomScanResult = ash::scanning::mojom::ScanResult;
+using ProtoScanFailureMode = lorgnette::ScanFailureMode;
+
+using MojomColorMode = ash::scanning::mojom::ColorMode;
+using ProtoColorMode = lorgnette::ColorMode;
+
+using MojomSourceType = ash::scanning::mojom::SourceType;
+using ProtoSourceType = lorgnette::SourceType;
+
+using MojomFileType = ash::scanning::mojom::FileType;
+using ProtoImageFormat = lorgnette::ImageFormat;
+
 namespace mojo_ipc = scanning::mojom;
 
 // POD struct for ScannerCapabilitiesTest.
@@ -90,6 +104,31 @@
   return settings.Clone();
 }
 
+template <typename MojoEnum, typename SourceEnum, size_t N>
+void TestToMojom(const base::fixed_flat_map<MojoEnum, SourceEnum, N>& enums) {
+  // The mojo enum is not sparse.
+  EXPECT_EQ(enums.size() - 1, static_cast<size_t>(MojoEnum::kMaxValue));
+
+  for (auto enum_pair : enums) {
+    EXPECT_EQ(
+        enum_pair.first,
+        (mojo::EnumTraits<MojoEnum, SourceEnum>::ToMojom(enum_pair.second)));
+  }
+}
+
+template <typename MojoEnum, typename SourceEnum, size_t N>
+void TestFromMojom(const base::fixed_flat_map<MojoEnum, SourceEnum, N>& enums) {
+  // The mojo enum is not sparse.
+  EXPECT_EQ(enums.size() - 1, static_cast<uint32_t>(MojoEnum::kMaxValue));
+
+  for (auto enum_pair : enums) {
+    SourceEnum mojo_to_source;
+    EXPECT_TRUE((mojo::EnumTraits<MojoEnum, SourceEnum>::FromMojom(
+        enum_pair.first, &mojo_to_source)));
+    EXPECT_EQ(mojo_to_source, enum_pair.second);
+  }
+}
+
 }  // namespace
 
 // Tests that each possible lorgnette::ScannerCapabilities proto can be
@@ -214,37 +253,83 @@
                                lorgnette::IMAGE_FORMAT_JPEG,
                                mojo_ipc::PageSize::kMax, 0, 0}));
 
-// Test that each lorgnette::ScanFailureMode is converted into the correct
-// mojo_ipc::ScanResult.
-TEST(ScanResultTest, Convert) {
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_NO_FAILURE)),
-            mojo_ipc::ScanResult::kSuccess);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_UNKNOWN)),
-            mojo_ipc::ScanResult::kUnknownError);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_DEVICE_BUSY)),
-            mojo_ipc::ScanResult::kDeviceBusy);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_ADF_JAMMED)),
-            mojo_ipc::ScanResult::kAdfJammed);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_ADF_EMPTY)),
-            mojo_ipc::ScanResult::kAdfEmpty);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_FLATBED_OPEN)),
-            mojo_ipc::ScanResult::kFlatbedOpen);
-  EXPECT_EQ((mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                              lorgnette::ScanFailureMode>::
-                 ToMojom(lorgnette::SCAN_FAILURE_MODE_IO_ERROR)),
-            mojo_ipc::ScanResult::kIoError);
+// Test that mapping between lorgnette::ColorMode and mojo_ipc::ColorMode
+// behaves as expected.
+TEST(ScanningMojomTraitsTest, ColorMode) {
+  constexpr auto enums =
+      base::MakeFixedFlatMap<MojomColorMode, ProtoColorMode>({
+          {MojomColorMode::kBlackAndWhite, ProtoColorMode::MODE_LINEART},
+          {MojomColorMode::kGrayscale, ProtoColorMode::MODE_GRAYSCALE},
+          {MojomColorMode::kColor, ProtoColorMode::MODE_COLOR},
+      });
+
+  TestToMojom(enums);
+  TestFromMojom(enums);
+}
+
+// Test that mapping between lorgnette::SourceType and mojo_ipc::SourceType
+// behaves as expected.
+TEST(ScanningMojomTraitsTest, SourceType) {
+  constexpr auto enums =
+      base::MakeFixedFlatMap<MojomSourceType, ProtoSourceType>({
+          {MojomSourceType::kFlatbed, ProtoSourceType::SOURCE_PLATEN},
+          {MojomSourceType::kAdfSimplex, ProtoSourceType::SOURCE_ADF_SIMPLEX},
+          {MojomSourceType::kAdfDuplex, ProtoSourceType::SOURCE_ADF_DUPLEX},
+          {MojomSourceType::kDefault, ProtoSourceType::SOURCE_DEFAULT},
+          {MojomSourceType::kUnknown, ProtoSourceType::SOURCE_UNSPECIFIED},
+      });
+
+  TestToMojom(enums);
+  TestFromMojom(enums);
+}
+
+TEST(ScanningMojomTraitsTest, FileType) {
+  constexpr auto enums =
+      base::MakeFixedFlatMap<MojomFileType, ProtoImageFormat>({
+          {MojomFileType::kPng, ProtoImageFormat::IMAGE_FORMAT_PNG},
+          {MojomFileType::kJpg, ProtoImageFormat::IMAGE_FORMAT_JPEG},
+      });
+  // The mojo enum is sparse - there is no pdf format in lorgnette::ImageFormat.
+  // Test without calling TestToMojom(enums), TestFromMojom(enums) functions.
+  // Test ToMojom
+  for (auto enum_pair : enums) {
+    EXPECT_EQ(enum_pair.first,
+              (mojo::EnumTraits<MojomFileType, ProtoImageFormat>::ToMojom(
+                  enum_pair.second)));
+  }
+
+  // Test FromMojom
+  for (auto enum_pair : enums) {
+    ProtoImageFormat mojo_to_source;
+    EXPECT_TRUE((mojo::EnumTraits<MojomFileType, ProtoImageFormat>::FromMojom(
+        enum_pair.first, &mojo_to_source)));
+    EXPECT_EQ(mojo_to_source, enum_pair.second);
+  }
+}
+
+// Test that mapping between lorgnette::ScanFailureMode and mojo_ipc::ScanResult
+// behaves as expected.
+TEST(ScanningMojomTraitsTest, ScanResult) {
+  constexpr auto enums =
+      base::MakeFixedFlatMap<MojomScanResult, ProtoScanFailureMode>({
+          {MojomScanResult::kSuccess,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE},
+          {MojomScanResult::kUnknownError,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN},
+          {MojomScanResult::kDeviceBusy,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY},
+          {MojomScanResult::kAdfJammed,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_JAMMED},
+          {MojomScanResult::kAdfEmpty,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_ADF_EMPTY},
+          {MojomScanResult::kFlatbedOpen,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_FLATBED_OPEN},
+          {MojomScanResult::kIoError,
+           ProtoScanFailureMode::SCAN_FAILURE_MODE_IO_ERROR},
+      });
+
+  TestToMojom(enums);
+  TestFromMojom(enums);
 }
 
 }  // namespace ash
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index 820625f..e7eaa7d 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -1326,6 +1326,9 @@
       state_proto_.state_case() == rmad::RmadState::kWelcome &&
       mojo_state_ == mojom::State::kWelcomeScreen) {
     user_has_seen_network_page_ = false;
+    state_proto_.mutable_welcome()->set_choice(
+        rmad::WelcomeState::RMAD_CHOICE_FINALIZE_REPAIR);
+
     mojo_state_ = mojom::State::kConfigureNetwork;
     std::move(callback).Run(
         CreateStateResult(mojom::State::kConfigureNetwork,
diff --git a/ash/webui/shimless_rma/resources/BUILD.gn b/ash/webui/shimless_rma/resources/BUILD.gn
index be759f4..7f424ab 100644
--- a/ash/webui/shimless_rma/resources/BUILD.gn
+++ b/ash/webui/shimless_rma/resources/BUILD.gn
@@ -162,8 +162,9 @@
     ":wrapup_restock_page",
     ":wrapup_wait_for_manual_wp_enable_page",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("base_page") {
@@ -298,12 +299,14 @@
     "//ui/webui/resources/cr_components/chromeos/network:network_config.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_list.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:util.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("onboarding_update_page") {
@@ -324,8 +327,9 @@
     ":mojo_interface_provider",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("onboarding_wp_disable_complete_page") {
@@ -437,10 +441,12 @@
     ":mojo_interface_provider",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("wrapup_restock_page") {
@@ -449,8 +455,9 @@
     ":mojo_interface_provider",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("wrapup_finalize_page") {
@@ -459,8 +466,10 @@
     ":mojo_interface_provider",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+  ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
   ]
 }
 
@@ -470,8 +479,9 @@
     ":mojo_interface_provider",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("shimless_rma_types") {
diff --git a/ash/webui/shimless_rma/resources/onboarding_network_page.js b/ash/webui/shimless_rma/resources/onboarding_network_page.js
index 039f19b..e2640246 100644
--- a/ash/webui/shimless_rma/resources/onboarding_network_page.js
+++ b/ash/webui/shimless_rma/resources/onboarding_network_page.js
@@ -9,13 +9,13 @@
 import 'chrome://resources/cr_components/chromeos/network/network_config.m.js';
 import 'chrome://resources/cr_components/chromeos/network/network_list.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 
 import {HTMLEscape} from '//resources/js/util.m.js';
 import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/cr_components/chromeos/network/network_listener_behavior.m.js';
 import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js
index b8e1f06..0b907891 100644
--- a/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js
+++ b/ash/webui/shimless_rma/resources/reimaging_provisioning_page.js
@@ -3,13 +3,13 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './shimless_rma_shared_css.js';
 import './base_page.js';
 import './icons.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.js b/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.js
index 46c4533..15f4789 100644
--- a/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.js
+++ b/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.js
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js';
 import './base_page.js';
 import './shimless_rma_fonts_css.js';
 import './shimless_rma_shared_css.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/ash/webui/shortcut_customization_ui/resources/BUILD.gn b/ash/webui/shortcut_customization_ui/resources/BUILD.gn
index 99e8d7e..4d8f25f 100644
--- a/ash/webui/shortcut_customization_ui/resources/BUILD.gn
+++ b/ash/webui/shortcut_customization_ui/resources/BUILD.gn
@@ -92,6 +92,7 @@
 }
 
 ts_library("build_ts") {
+  composite = true
   root_dir = "$target_gen_dir/$preprocess_folder"
   out_dir = "$target_gen_dir/tsc"
   tsconfig_base = "tsconfig_base.json"
diff --git a/ash/webui/shortcut_customization_ui/resources/index.html b/ash/webui/shortcut_customization_ui/resources/index.html
index fc2e22c..4ba571a 100644
--- a/ash/webui/shortcut_customization_ui/resources/index.html
+++ b/ash/webui/shortcut_customization_ui/resources/index.html
@@ -20,8 +20,6 @@
     <shortcut-customization-app></shortcut-customization-app>
 
     <script type="module" src="shortcut_customization_app.js"></script>
-    <!-- Below mojo script required to run browser tests -->
-    <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js">
     </script>
   </body>
 </html>
diff --git a/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc b/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
index eeafe3cb..f8deffb3 100644
--- a/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
+++ b/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
@@ -44,7 +44,9 @@
       kChromeUIShortcutCustomizationAppHost);
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
-      "script-src chrome://resources chrome://test 'self';");
+      "script-src chrome://resources chrome://test chrome://webui-test "
+      "'self';");
+
   source->DisableTrustedTypesCSP();
 
   const auto resources =
diff --git a/ash/wm/desks/templates/saved_desk_unittest.cc b/ash/wm/desks/templates/saved_desk_unittest.cc
index a5869b8e..57cc963 100644
--- a/ash/wm/desks/templates/saved_desk_unittest.cc
+++ b/ash/wm/desks/templates/saved_desk_unittest.cc
@@ -3720,7 +3720,7 @@
   loop.Run();
 
   desks_storage::DeskModel::GetEntryByUuidResult result =
-      desk_model()->GetEntryByUUID(uuid.AsLowercaseString());
+      desk_model()->GetEntryByUUID(uuid);
 
   EXPECT_EQ(desks_storage::DeskModel::GetEntryByUuidStatus::kOk, result.status);
   // `LocalDeskStorage` does not support
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f6238ce6..ac10b53 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -3756,6 +3756,7 @@
     sources += [
       "allocator/partition_allocator/address_pool_manager_unittest.cc",
       "allocator/partition_allocator/address_space_randomization_unittest.cc",
+      "allocator/partition_allocator/freeslot_bitmap_unittest.cc",
       "allocator/partition_allocator/hardening_unittest.cc",
       "allocator/partition_allocator/memory_reclaimer_unittest.cc",
       "allocator/partition_allocator/page_allocator_unittest.cc",
diff --git a/base/allocator/partition_allocator/BUILD.gn b/base/allocator/partition_allocator/BUILD.gn
index 109cda2..946f2ca9 100644
--- a/base/allocator/partition_allocator/BUILD.gn
+++ b/base/allocator/partition_allocator/BUILD.gn
@@ -55,6 +55,7 @@
     "dangling_raw_ptr_checks.cc",
     "dangling_raw_ptr_checks.h",
     "freeslot_bitmap.h",
+    "freeslot_bitmap_constants.h",
     "memory_reclaimer.cc",
     "memory_reclaimer.h",
     "oom.cc",
diff --git a/base/allocator/partition_allocator/freeslot_bitmap.h b/base/allocator/partition_allocator/freeslot_bitmap.h
index 554a0a7..60122bd 100644
--- a/base/allocator/partition_allocator/freeslot_bitmap.h
+++ b/base/allocator/partition_allocator/freeslot_bitmap.h
@@ -7,38 +7,67 @@
 
 #include <climits>
 #include <cstdint>
+#include <utility>
 
-#include "base/allocator/partition_allocator/page_allocator_constants.h"
+#include "base/allocator/partition_allocator/freeslot_bitmap_constants.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/bits.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "base/allocator/partition_allocator/partition_page.h"
+
+#if BUILDFLAG(USE_FREESLOT_BITMAP)
 
 namespace partition_alloc::internal {
 
-using FreeSlotBitmapCellType = uintptr_t;
-constexpr size_t kFreeSlotBitmapBitsPerCell =
-    sizeof(FreeSlotBitmapCellType) * CHAR_BIT;
-
-// The number of bits necessary for the bitmap is equal to the maximum number of
-// slots in a super page. We divide this by kBitsPerCell to get the number of
-// cells in a bitmap.
-constexpr size_t kFreeSlotBitmapSize = (kSuperPageSize / kAlignment) / CHAR_BIT;
-
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
-ReservedFreeSlotBitmapSize() {
-#if BUILDFLAG(USE_FREESLOT_BITMAP)
-  return base::bits::AlignUp(kFreeSlotBitmapSize, PartitionPageSize());
-#else
-  return 0;
-#endif
+PA_ALWAYS_INLINE uintptr_t GetFreeSlotBitmapAddressForPointer(uintptr_t ptr) {
+  uintptr_t super_page = ptr & kSuperPageBaseMask;
+  return SuperPageFreeSlotBitmapAddr(super_page);
 }
 
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
-NumPartitionPagesPerFreeSlotBitmap() {
-  return ReservedFreeSlotBitmapSize() / PartitionPageSize();
+// Calculates the cell address and the offset inside the cell corresponding to
+// the |slot_address|.
+PA_ALWAYS_INLINE std::pair<FreeSlotBitmapCellType*, size_t>
+GetFreeSlotBitmapCellPtrAndBitIndex(uintptr_t slot_address) {
+  uintptr_t slot_superpage_offset = slot_address & kSuperPageOffsetMask;
+  uintptr_t superpage_bitmap_start =
+      GetFreeSlotBitmapAddressForPointer(slot_address);
+  uintptr_t cell_addr = base::bits::AlignDown(
+      superpage_bitmap_start + (slot_superpage_offset / kAlignment) / CHAR_BIT,
+      sizeof(FreeSlotBitmapCellType));
+  PA_DCHECK(cell_addr < superpage_bitmap_start + kFreeSlotBitmapSize);
+  size_t bit_index =
+      (slot_superpage_offset / kAlignment) & kFreeSlotBitmapOffsetMask;
+  PA_DCHECK(bit_index < kFreeSlotBitmapBitsPerCell);
+  return {reinterpret_cast<FreeSlotBitmapCellType*>(cell_addr), bit_index};
+}
+
+// This bitmap marks the used slot as 0 and free one as 1. This is because we
+// would like to set all the slots as "used" by default to prevent allocating a
+// used slot when the freelist entry is overwritten.
+
+// Returns true if the bit corresponding to |address| is used( = 0)
+PA_ALWAYS_INLINE bool FreeSlotBitmapSlotIsUsed(uintptr_t address) {
+  auto [cell, bit_index] = GetFreeSlotBitmapCellPtrAndBitIndex(address);
+  return (*cell & (static_cast<FreeSlotBitmapCellType>(1) << bit_index)) == 0;
+}
+
+// Mark the bit corresponding to |address| as used( = 0).
+PA_ALWAYS_INLINE void FreeSlotBitmapMarkSlotAsUsed(uintptr_t address) {
+  PA_DCHECK(!FreeSlotBitmapSlotIsUsed(address));
+  auto [cell, bit_index] = GetFreeSlotBitmapCellPtrAndBitIndex(address);
+  *cell &= ~(static_cast<FreeSlotBitmapCellType>(1) << bit_index);
+}
+
+// Mark the bit corresponding to |address| as free( = 1).
+PA_ALWAYS_INLINE void FreeSlotBitmapMarkSlotAsFree(uintptr_t address) {
+  PA_DCHECK(FreeSlotBitmapSlotIsUsed(address));
+  auto [cell, bit_index] = GetFreeSlotBitmapCellPtrAndBitIndex(address);
+  *cell |= (static_cast<FreeSlotBitmapCellType>(1) << bit_index);
 }
 
 }  // namespace partition_alloc::internal
 
+#endif  // BUILDFLAG(USE_FREESLOT_BITMAP)
+
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_FREESLOT_BITMAP_H_
\ No newline at end of file
diff --git a/base/allocator/partition_allocator/freeslot_bitmap_constants.h b/base/allocator/partition_allocator/freeslot_bitmap_constants.h
new file mode 100644
index 0000000..bc7fd136
--- /dev/null
+++ b/base/allocator/partition_allocator/freeslot_bitmap_constants.h
@@ -0,0 +1,44 @@
+// Copyright 2022 The Chromium Authors.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_FREESLOT_BITMAP_CONSTANTS_H_
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_FREESLOT_BITMAP_CONSTANTS_H_
+
+#include <cstdint>
+
+#include "base/allocator/partition_allocator/partition_alloc_base/bits.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
+#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "base/allocator/partition_allocator/partition_alloc_forward.h"
+
+namespace partition_alloc::internal {
+
+using FreeSlotBitmapCellType = uintptr_t;
+constexpr size_t kFreeSlotBitmapBitsPerCell =
+    sizeof(FreeSlotBitmapCellType) * CHAR_BIT;
+constexpr size_t kFreeSlotBitmapOffsetMask = kFreeSlotBitmapBitsPerCell - 1;
+
+// The number of bits necessary for the bitmap is equal to the maximum number of
+// slots in a super page. We divide this by kBitsPerCell to get the number of
+// cells in a bitmap.
+constexpr size_t kFreeSlotBitmapSize = (kSuperPageSize / kAlignment) / CHAR_BIT;
+
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
+ReservedFreeSlotBitmapSize() {
+#if BUILDFLAG(USE_FREESLOT_BITMAP)
+  return base::bits::AlignUp(kFreeSlotBitmapSize, PartitionPageSize());
+#else
+  return 0;
+#endif
+}
+
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
+NumPartitionPagesPerFreeSlotBitmap() {
+  return ReservedFreeSlotBitmapSize() / PartitionPageSize();
+}
+
+}  // namespace partition_alloc::internal
+
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_FREESLOT_BITMAP_CONSTANTS_H_
\ No newline at end of file
diff --git a/base/allocator/partition_allocator/freeslot_bitmap_unittest.cc b/base/allocator/partition_allocator/freeslot_bitmap_unittest.cc
new file mode 100644
index 0000000..a25c4a8
--- /dev/null
+++ b/base/allocator/partition_allocator/freeslot_bitmap_unittest.cc
@@ -0,0 +1,141 @@
+// Copyright 2022 The Chromium Authors.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/allocator/partition_allocator/freeslot_bitmap.h"
+
+#include <cstdint>
+#include <limits>
+
+#include "base/allocator/partition_allocator/freeslot_bitmap_constants.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "base/allocator/partition_allocator/partition_alloc_forward.h"
+#include "base/allocator/partition_allocator/partition_page.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// This test is disabled when MEMORY_TOOL_REPLACES_ALLOCATOR is defined because
+// we cannot locate the freeslot bitmap address in that case.
+#if BUILDFLAG(USE_FREESLOT_BITMAP) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
+
+namespace partition_alloc::internal {
+
+namespace {
+
+class PartitionAllocFreeSlotBitmapTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    // Allocates memory and creates a pseudo superpage in it. We need to
+    // allocate |2 * kSuperPageSize| so that a whole superpage is contained in
+    // the allocated region.
+    allocator_.init({
+        PartitionOptions::AlignedAlloc::kDisallowed,
+        PartitionOptions::ThreadCache::kDisabled,
+        PartitionOptions::Quarantine::kDisallowed,
+        PartitionOptions::Cookie::kAllowed,
+        PartitionOptions::BackupRefPtr::kDisabled,
+        PartitionOptions::BackupRefPtrZapping::kDisabled,
+        PartitionOptions::UseConfigurablePool::kNo,
+    });
+    allocated_ptr_ = reinterpret_cast<uintptr_t>(
+        allocator_.root()->Alloc(2 * kSuperPageSize, ""));
+    super_page_ = (allocated_ptr_ + kSuperPageSize) & kSuperPageBaseMask;
+
+    // Checks that the whole superpage is in the allocated region.
+    PA_DCHECK(super_page_ + kSuperPageSize <=
+              allocated_ptr_ + 2 * kSuperPageSize);
+  }
+
+  void TearDown() override {
+    allocator_.root()->Free(reinterpret_cast<void*>(allocated_ptr_));
+  }
+
+  // Returns the |index|-th slot address in the virtual superpage. It assumes
+  // that there are no slot spans and the superpage is only filled with the slot
+  // of size |kAlignment|.
+  uintptr_t SlotAddr(size_t index) {
+    return SuperPagePayloadBegin(super_page_, false) + index * kAlignment;
+  }
+
+  // Returns the last slot address in the virtual superpage. It assumes that
+  // there are no slot spans but the superpage is only filled with the slot of
+  // size |kAlignment|.
+  uintptr_t LastSlotAddr() {
+    return super_page_ + kSuperPageSize - PartitionPageSize() - kAlignment;
+  }
+
+ private:
+  uintptr_t allocated_ptr_;
+  uintptr_t super_page_;
+  PartitionAllocator<ThreadSafe> allocator_;
+};
+
+}  // namespace
+
+TEST_F(PartitionAllocFreeSlotBitmapTest, MarkFirstSlotAsUsed) {
+  uintptr_t slot_addr = SlotAddr(0);
+  FreeSlotBitmapMarkSlotAsFree(slot_addr);
+  EXPECT_FALSE(FreeSlotBitmapSlotIsUsed(slot_addr));
+
+  FreeSlotBitmapMarkSlotAsUsed(slot_addr);
+  EXPECT_TRUE(FreeSlotBitmapSlotIsUsed(slot_addr));
+}
+
+TEST_F(PartitionAllocFreeSlotBitmapTest, MarkFirstSlotAsFree) {
+  uintptr_t slot_addr = SlotAddr(0);
+  // All slots are set to "used" by default.
+  EXPECT_TRUE(FreeSlotBitmapSlotIsUsed(slot_addr));
+
+  FreeSlotBitmapMarkSlotAsFree(slot_addr);
+  EXPECT_FALSE(FreeSlotBitmapSlotIsUsed(slot_addr));
+}
+
+TEST_F(PartitionAllocFreeSlotBitmapTest, MarkAllBitsInCellAsUsed) {
+  const size_t kFirstSlotAddr = SlotAddr(0);
+  const size_t kLastSlotAddr = SlotAddr(kFreeSlotBitmapBitsPerCell);
+
+  auto [cell_first_slot, bit_index_first_slot] =
+      GetFreeSlotBitmapCellPtrAndBitIndex(kFirstSlotAddr);
+  auto [cell_last_slot, bit_index_last_slot] =
+      GetFreeSlotBitmapCellPtrAndBitIndex(kLastSlotAddr);
+
+  // Check that the bit corresponding to |kFirstSlotAddr| is the first bit in
+  // some cell (= |cell_first_slot|), and the bit for |kLastSlotAddr| is the
+  // first bit in the next cell. This means that we are manipulating all the
+  // bits in |cell_first_slot| in this test.
+  EXPECT_EQ(0u, bit_index_first_slot);
+  EXPECT_EQ(0u, bit_index_last_slot);
+  EXPECT_NE(cell_first_slot, cell_last_slot);
+
+  for (size_t slot_addr = kFirstSlotAddr; slot_addr < kLastSlotAddr;
+       slot_addr += kAlignment) {
+    FreeSlotBitmapMarkSlotAsFree(slot_addr);
+  }
+
+  // Check all the bits in |cell_first_slot| are 1 (= free).
+  EXPECT_EQ(std::numeric_limits<FreeSlotBitmapCellType>::max(),
+            *cell_first_slot);
+
+  for (size_t slot_addr = kFirstSlotAddr; slot_addr < kLastSlotAddr;
+       slot_addr += kAlignment) {
+    FreeSlotBitmapMarkSlotAsUsed(slot_addr);
+  }
+
+  // Check all the bits in |cell_first_slot| are 0 (= used).
+  EXPECT_EQ(0u, *cell_first_slot);
+}
+
+TEST_F(PartitionAllocFreeSlotBitmapTest, MarkLastSlotAsUsed) {
+  uintptr_t last_slot_addr = LastSlotAddr();
+  FreeSlotBitmapMarkSlotAsFree(last_slot_addr);
+  EXPECT_FALSE(FreeSlotBitmapSlotIsUsed(last_slot_addr));
+
+  FreeSlotBitmapMarkSlotAsUsed(last_slot_addr);
+  EXPECT_TRUE(FreeSlotBitmapSlotIsUsed(last_slot_addr));
+}
+
+}  // namespace partition_alloc::internal
+
+#endif  // BUILDFLAG(USE_FREESLOT_BITMAP) &&
+        // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h
index eeb36d7..1fbd18e 100644
--- a/base/allocator/partition_allocator/partition_page.h
+++ b/base/allocator/partition_allocator/partition_page.h
@@ -12,7 +12,7 @@
 
 #include "base/allocator/partition_allocator/address_pool_manager.h"
 #include "base/allocator/partition_allocator/address_pool_manager_types.h"
-#include "base/allocator/partition_allocator/freeslot_bitmap.h"
+#include "base/allocator/partition_allocator/freeslot_bitmap_constants.h"
 #include "base/allocator/partition_allocator/partition_address_space.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/bits.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
diff --git a/base/allocator/partition_allocator/partition_tag_bitmap.h b/base/allocator/partition_allocator/partition_tag_bitmap.h
index 679158b..a1f0fa8f 100644
--- a/base/allocator/partition_allocator/partition_tag_bitmap.h
+++ b/base/allocator/partition_allocator/partition_tag_bitmap.h
@@ -5,7 +5,7 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_BITMAP_H_
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_BITMAP_H_
 
-#include "base/allocator/partition_allocator/freeslot_bitmap.h"
+#include "base/allocator/partition_allocator/freeslot_bitmap_constants.h"
 #include "base/allocator/partition_allocator/page_allocator_constants.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
diff --git a/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java b/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java
index 2a166a6..8843d735 100644
--- a/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java
+++ b/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java
@@ -4,6 +4,8 @@
 
 package org.chromium.base.jank_tracker;
 
+import androidx.annotation.VisibleForTesting;
+
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 
@@ -47,7 +49,8 @@
     }
 
     @NativeMethods
-    interface Natives {
+    @VisibleForTesting
+    public interface Natives {
         void recordJankMetrics(String scenarioName, long[] timestampsNs, long[] durationsNs,
                 long[] jankBurstsNs, int missedFrames);
     }
diff --git a/base/check.h b/base/check.h
index 55339b2..e97ec0d 100644
--- a/base/check.h
+++ b/base/check.h
@@ -88,7 +88,7 @@
   // Stream for adding optional details to the error message.
   std::ostream& stream();
 
-  NOMERGE ~CheckError();
+  NOMERGE NOT_TAIL_CALLED ~CheckError();
 
   CheckError(const CheckError&) = delete;
   CheckError& operator=(const CheckError&) = delete;
diff --git a/base/feature_list.cc b/base/feature_list.cc
index 857322c..19963ba2 100644
--- a/base/feature_list.cc
+++ b/base/feature_list.cc
@@ -307,8 +307,7 @@
                                              OverrideState override_state,
                                              FieldTrial* field_trial) {
   DCHECK(field_trial);
-  DCHECK(!Contains(overrides_, feature_name) ||
-         !overrides_.find(feature_name)->second.field_trial)
+  DCHECK(!HasAssociatedFieldTrialByFeatureName(feature_name))
       << "Feature " << feature_name << " is overriden multiple times in these "
       << "trials: "
       << overrides_.find(feature_name)->second.field_trial->trial_name()
@@ -644,6 +643,12 @@
   return nullptr;
 }
 
+bool FeatureList::HasAssociatedFieldTrialByFeatureName(StringPiece name) const {
+  DCHECK(!initialized_);
+  auto entry = overrides_.find(name);
+  return entry != overrides_.end() && entry->second.field_trial != nullptr;
+}
+
 FieldTrial* FeatureList::GetEnabledFieldTrialByFeatureName(
     StringPiece name) const {
   DCHECK(initialized_);
diff --git a/base/feature_list.h b/base/feature_list.h
index 432586b..f3f7635 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -294,6 +294,17 @@
   base::FieldTrial* GetAssociatedFieldTrialByFeatureName(
       StringPiece name) const;
 
+  // DO NOT USE outside of internal field trial implementation code. Instead use
+  // GetAssociatedFieldTrialByFeatureName(), which performs some additional
+  // validation.
+  //
+  // Returns whether the given feature |name| is associated with a field trial.
+  // If the given feature |name| does not exist, return false. Unlike
+  // GetAssociatedFieldTrialByFeatureName(), this function must be called during
+  // |FeatureList| initialization; the returned value will report whether the
+  // provided |name| has been used so far.
+  bool HasAssociatedFieldTrialByFeatureName(StringPiece name) const;
+
   // Get associated field trial for the given feature |name| only if override
   // enables it.
   FieldTrial* GetEnabledFieldTrialByFeatureName(StringPiece name) const;
diff --git a/build/android/adb_gdb b/build/android/adb_gdb
index 0923210..2edf4c0 100755
--- a/build/android/adb_gdb
+++ b/build/android/adb_gdb
@@ -355,8 +355,8 @@
 fi
 
 if [ -z "$NDK_DIR" ]; then
-  ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python -c \
-'from pylib.constants import ANDROID_NDK_ROOT; print ANDROID_NDK_ROOT,')
+  ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python3 -c \
+    'from pylib.constants import ANDROID_NDK_ROOT; print(ANDROID_NDK_ROOT,)')
 else
   if [ ! -d "$NDK_DIR" ]; then
     panic "Invalid directory: $NDK_DIR"
diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py
index 6cee06f722..b893e51 100755
--- a/build/android/gyp/dex.py
+++ b/build/android/gyp/dex.py
@@ -124,6 +124,8 @@
   parser.add_argument('--force-enable-assertions',
                       action='store_true',
                       help='Forcefully enable javac generated assertion code.')
+  parser.add_argument('--assertion-handler',
+                      help='The class name of the assertion handler class.')
   parser.add_argument('--warnings-as-errors',
                       action='store_true',
                       help='Treat all warnings as errors.')
@@ -136,6 +138,10 @@
   if options.main_dex_rules_path and not options.multi_dex:
     parser.error('--main-dex-rules-path is unused if multidex is not enabled')
 
+  if options.force_enable_assertions and options.assertion_handler:
+    parser.error('Cannot use both --force-enable-assertions and '
+                 '--assertion-handler')
+
   options.class_inputs = build_utils.ParseGnList(options.class_inputs)
   options.class_inputs_filearg = build_utils.ParseGnList(
       options.class_inputs_filearg)
@@ -518,6 +524,8 @@
   if options.desugar_jdk_libs_json:
     dex_cmd += ['--desugared-lib', options.desugar_jdk_libs_json]
     input_paths += [options.desugar_jdk_libs_json]
+  if options.assertion_handler:
+    dex_cmd += ['--force-assertions-handler:' + options.assertion_handler]
   if options.force_enable_assertions:
     dex_cmd += ['--force-enable-assertions']
 
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py
index 070afc3..753d44d 100755
--- a/build/android/gyp/proguard.py
+++ b/build/android/gyp/proguard.py
@@ -79,6 +79,8 @@
       '--force-enable-assertions',
       action='store_true',
       help='Forcefully enable javac generated assertion code.')
+  parser.add_argument('--assertion-handler',
+                      help='The class name of the assertion handler class.')
   parser.add_argument(
       '--feature-jars',
       action='append',
@@ -136,8 +138,12 @@
 
   if bool(options.keep_rules_targets_regex) != bool(
       options.keep_rules_output_path):
-    raise Exception('You must path both --keep-rules-targets-regex and '
-                    '--keep-rules-output-path')
+    parser.error('You must path both --keep-rules-targets-regex and '
+                 '--keep-rules-output-path')
+
+  if options.force_enable_assertions and options.assertion_handler:
+    parser.error('Cannot use both --force-enable-assertions and '
+                 '--assertion-handler')
 
   options.classpath = build_utils.ParseGnList(options.classpath)
   options.proguard_configs = build_utils.ParseGnList(options.proguard_configs)
@@ -320,7 +326,9 @@
     if options.min_api:
       cmd += ['--min-api', options.min_api]
 
-    if options.force_enable_assertions:
+    if options.assertion_handler:
+      cmd += ['--force-assertions-handler:' + options.assertion_handler]
+    elif options.force_enable_assertions:
       cmd += ['--force-enable-assertions']
 
     for lib in libraries:
diff --git a/build/android/list_java_targets.py b/build/android/list_java_targets.py
index 323b0a6..99a59b2 100755
--- a/build/android/list_java_targets.py
+++ b/build/android/list_java_targets.py
@@ -62,7 +62,7 @@
   return cmd
 
 
-def _run_ninja(output_dir, args):
+def _run_ninja(output_dir, args, quiet=False):
   cmd = [
       _resolve_ninja('autoninja'),
       '-C',
@@ -70,7 +70,10 @@
   ]
   cmd.extend(args)
   logging.info('Running: %r', cmd)
-  subprocess.run(cmd, check=True, stdout=sys.stderr)
+  if quiet:
+    subprocess.run(cmd, check=True, capture_output=True)
+  else:
+    subprocess.run(cmd, check=True, stdout=sys.stderr)
 
 
 def _query_for_build_config_targets(output_dir):
@@ -174,12 +177,13 @@
                       action='store_true',
                       help='Restrict to targets that have proguard enabled')
   parser.add_argument('-v', '--verbose', default=0, action='count')
+  parser.add_argument('-q', '--quiet', default=0, action='count')
   args = parser.parse_args()
 
   args.build |= bool(args.type or args.proguard_enabled or args.print_types
                      or args.stats)
 
-  logging.basicConfig(level=logging.WARNING - (10 * args.verbose),
+  logging.basicConfig(level=logging.WARNING + 10 * (args.quiet - args.verbose),
                       format='%(levelname).1s %(relativeCreated)6d %(message)s')
 
   if args.output_directory:
@@ -193,7 +197,8 @@
 
   if args.build:
     logging.warning('Building %d .build_config.json files...', len(entries))
-    _run_ninja(output_dir, [e.ninja_build_config_target for e in entries])
+    _run_ninja(output_dir, [e.ninja_build_config_target for e in entries],
+               quiet=args.quiet)
 
   if args.type:
     entries = [e for e in entries if e.get_type() in args.type]
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 1eb1e4d3..82ce4e6e 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1305,7 +1305,12 @@
       _args += [ "--show-desugar-default-interface-warnings" ]
     }
 
-    if (enable_java_asserts) {
+    if (defined(invoker.custom_assertion_handler)) {
+      _args += [
+        "--assertion-handler",
+        invoker.custom_assertion_handler,
+      ]
+    } else if (enable_java_asserts) {
       # The default for generating dex file format is
       # --force-disable-assertions.
       _args += [ "--force-enable-assertions" ]
@@ -1487,6 +1492,10 @@
 
     assert(!(defined(invoker.apply_mapping) && !_proguard_enabled),
            "apply_mapping can only be specified if proguard is enabled.")
+    if (defined(invoker.custom_assertion_handler)) {
+      assert(_proguard_enabled,
+             "Proguard is required to support the custom assertion handler.")
+    }
 
     if (_enable_main_dex_list) {
       _main_dex_rules = "//build/android/main_dex_classes.flags"
@@ -1504,6 +1513,7 @@
                                TESTONLY_AND_VISIBILITY + [
                                      "add_view_trace_events",
                                      "build_config",
+                                     "custom_assertion_handler",
                                      "data",
                                      "data_deps",
                                      "deps",
@@ -1733,7 +1743,12 @@
           not_needed(invoker, [ "desugar_jars_paths" ])
         }
 
-        if (enable_java_asserts) {
+        if (defined(invoker.custom_assertion_handler)) {
+          args += [
+            "--assertion-handler",
+            invoker.custom_assertion_handler,
+          ]
+        } else if (enable_java_asserts) {
           # The default for generating dex file format is
           # --force-disable-assertions.
           args += [ "--force-enable-assertions" ]
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 9b43c9e..effc7b40 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -2138,7 +2138,8 @@
 
       # Set these even when !use_final_fields so that they have correct default
       # values within robolectric_binary(), which ignores jar_excluded_patterns.
-      if (enable_java_asserts) {
+      if ((defined(invoker.use_custom_assertion_handler) &&
+           invoker.use_custom_assertion_handler) || enable_java_asserts) {
         defines += [ "_ENABLE_ASSERTS" ]
       }
       if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) {
@@ -2929,6 +2930,7 @@
         }
         bundles_supported = _bundles_supported
         use_final_fields = true
+        use_custom_assertion_handler = defined(invoker.custom_assertion_handler)
         enable_multidex = _enable_multidex
         is_incremental_install = _incremental_apk
         if (defined(invoker.build_config_include_product_version_resource) &&
@@ -3113,12 +3115,16 @@
 
     if (_uses_static_library_synchronized_proguard) {
       _final_dex_target_dep = "${invoker.static_library_provider}__dexsplitter"
+      not_needed(invoker, [ "custom_assertion_handler" ])
     } else if ((_is_bundle_module && _proguard_enabled) || _omit_dex) {
       # No library dep needed.
+      not_needed(invoker, [ "custom_assertion_handler" ])
     } else if (_incremental_apk) {
-      if (defined(invoker.enable_proguard_checks)) {
-        not_needed(invoker, [ "enable_proguard_checks" ])
-      }
+      not_needed(invoker,
+                 [
+                   "enable_proguard_checks",
+                   "custom_assertion_handler",
+                 ])
     } else {
       # Dex generation for app bundle modules with proguarding enabled takes
       # place later due to synchronized proguarding.
@@ -3127,6 +3133,7 @@
         forward_variables_from(invoker,
                                [
                                  "enable_proguard_checks",
+                                 "custom_assertion_handler",
                                  "proguard_enable_obfuscation",
                                ])
         min_sdk_version = _min_sdk_version
@@ -3631,6 +3638,7 @@
                                "chromium_code",
                                "command_line_flags_file",
                                "create_apk_script",
+                               "custom_assertion_handler",
                                "data",
                                "data_deps",
                                "deps",
@@ -3773,6 +3781,7 @@
                                "build_config_include_product_version_resource",
                                "bundle_target",
                                "chromium_code",
+                               "custom_assertion_handler",
                                "data",
                                "data_deps",
                                "deps",
@@ -5111,6 +5120,7 @@
         dex(_dex_target) {
           forward_variables_from(invoker,
                                  [
+                                   "custom_assertion_handler",
                                    "expected_proguard_config",
                                    "expected_proguard_config_base",
                                    "min_sdk_version",
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index 68ce4ea..1712f8d 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -20,6 +20,12 @@
       "-plugin-arg-find-bad-constructs",
       "-Xclang",
       "raw-ref-template-as-trivial-member",
+
+      # TODO(crbug.com/589969): make this the default in clang and remove the flag
+      "-Xclang",
+      "-plugin-arg-find-bad-constructs",
+      "-Xclang",
+      "check-gmock-objects",
     ]
 
     if (is_linux || is_chromeos || is_android || is_fuchsia) {
diff --git a/build_overrides/pdfium.gni b/build_overrides/pdfium.gni
index f5759bd..280e2b6 100644
--- a/build_overrides/pdfium.gni
+++ b/build_overrides/pdfium.gni
@@ -12,6 +12,9 @@
 # FreeType, configured by the embedder in //build/config/freetype.
 pdf_bundle_freetype_override = false
 
+# Build PDFium with PartitionAlloc as the memory allocator.
+pdf_use_partition_alloc_override = true
+
 # Disable use of Skia backend.
 pdf_use_skia_override = false
 
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index d5e2b56..e52b470 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "26e3467ee8494629799408ac63e2bc3a77948aed"
+  libcxx_revision = "e5670a0e0e4992f6a120142358b07e49c7d96918"
 }
diff --git a/chrome/VERSION b/chrome/VERSION
index 0be009a..13d3790 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=107
 MINOR=0
-BUILD=5269
+BUILD=5271
 PATCH=0
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index fb2490a..92778439 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -14,6 +14,7 @@
 import("//chrome/android/modules/chrome_bundle_tmpl.gni")
 import("//chrome/common/features.gni")
 import("//chrome/version.gni")
+import("//components/crash/android/silent_java_assert_reporting.gni")
 import("//components/optimization_guide/features.gni")
 import("//device/vr/buildflags/buildflags.gni")
 import("//weblayer/variables.gni")
@@ -359,6 +360,10 @@
       data_deps += [ "//chrome/android:android_lint" ]
     }
 
+    if (enable_silent_java_assert_reporting) {
+      custom_assertion_handler = crash_reporting_assertion_handler
+    }
+
     if (!defined(version_code)) {
       if (_is_trichrome) {
         version_code = trichrome_version_code
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
index 064dc6d..69205f5 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartFeedTest.java
@@ -30,14 +30,21 @@
 import org.hamcrest.core.AllOf;
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
+import org.chromium.base.jank_tracker.JankMetricUMARecorder;
+import org.chromium.base.jank_tracker.JankMetricUMARecorderJni;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -72,8 +79,22 @@
     private static final int ARTICLE_SECTION_HEADER_POSITION = 0;
 
     @Rule
+    public JniMocker mJniMocker = new JniMocker();
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
 
+    @Mock
+    JankMetricUMARecorder.Natives mJankRecorderNativeMock;
+
+    @Before
+    public void setUp() {
+        mJniMocker.mock(JankMetricUMARecorderJni.TEST_HOOKS, mJankRecorderNativeMock);
+    }
+
     @After
     public void tearDown() {
         if (mActivityTestRule.getActivity() != null) {
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
index dcb8aaf..80f65f8 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
@@ -41,11 +41,17 @@
 
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.MathUtils;
+import org.chromium.base.jank_tracker.JankMetricUMARecorder;
+import org.chromium.base.jank_tracker.JankMetricUMARecorderJni;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.params.ParameterAnnotations;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
@@ -59,6 +65,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
@@ -119,6 +126,14 @@
                     .setRevision(1)
                     .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_MOBILE_START)
                     .build();
+    @Rule
+    public JniMocker mJniMocker = new JniMocker();
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    JankMetricUMARecorder.Natives mJankRecorderNativeMock;
 
     /**
      * {@link ParameterProvider} used for parameterized test that provides whether it's single tab
@@ -137,6 +152,11 @@
         }
     }
 
+    @Before
+    public void setUp() {
+        mJniMocker.mock(JankMetricUMARecorderJni.TEST_HOOKS, mJankRecorderNativeMock);
+    }
+
     @After
     public void tearDown() {
         if (mActivityTestRule.getActivity() != null) {
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
index 1dfadd5..0952d5b 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -31,15 +31,21 @@
 import org.hamcrest.core.AllOf;
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.Callback;
 import org.chromium.base.NativeLibraryLoadedStatus;
 import org.chromium.base.SysUtils;
+import org.chromium.base.jank_tracker.JankMetricUMARecorder;
+import org.chromium.base.jank_tracker.JankMetricUMARecorderJni;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
@@ -47,6 +53,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.build.BuildConfig;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
@@ -115,6 +122,12 @@
     private int mThumbnailFetchCount;
 
     @Rule
+    public JniMocker mJniMocker = new JniMocker();
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
 
     @Rule
@@ -130,6 +143,14 @@
     @Rule
     public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
 
+    @Mock
+    JankMetricUMARecorder.Natives mJankRecorderNativeMock;
+
+    @Before
+    public void setUp() {
+        mJniMocker.mock(JankMetricUMARecorderJni.TEST_HOOKS, mJankRecorderNativeMock);
+    }
+
     @After
     public void tearDown() {
         if (mActivityTestRule.getActivity() != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
index ffb8249..0c150e22 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
@@ -39,8 +39,10 @@
 import org.chromium.chrome.browser.language.AppLocaleUtils;
 import org.chromium.chrome.browser.language.GlobalAppLocaleController;
 import org.chromium.chrome.browser.metrics.UmaUtils;
+import org.chromium.components.crash.CustomAssertionHandler;
 import org.chromium.components.crash.PureJavaExceptionHandler;
 import org.chromium.components.crash.PureJavaExceptionHandler.JavaExceptionReporter;
+import org.chromium.components.crash.PureJavaExceptionHandler.JavaExceptionReporterFactory;
 import org.chromium.components.embedder_support.application.FontPreloadingWorkaround;
 import org.chromium.components.module_installer.util.ModuleUtil;
 import org.chromium.components.version_info.VersionConstants;
@@ -208,16 +210,21 @@
         BuildInfo.setFirebaseAppId(FirebaseConfig.getFirebaseAppId());
 
         // WebView installs its own PureJavaExceptionHandler.
+        // Incremental install disables process isolation, so things in this block will
+        // actually be run for incremental apks, but not normal apks.
         if (!isIsolatedProcess && !isWebViewProcess()) {
-            // Incremental install disables process isolation, so things in this block will
-            // actually be run for incremental apks, but not normal apks.
-            PureJavaExceptionHandler.installHandler(() -> {
-                // ChromePureJavaExceptionReporter may be in the chrome module, so load by
-                // reflection from there.
-                return (JavaExceptionReporter) BundleUtils.newInstance(
-                        createChromeContext(ContextUtils.getApplicationContext()),
-                        "org.chromium.chrome.browser.crash.ChromePureJavaExceptionReporter");
-            });
+            JavaExceptionReporterFactory factory = new JavaExceptionReporterFactory() {
+                @Override
+                public JavaExceptionReporter createJavaExceptionReporter() {
+                    // ChromePureJavaExceptionReporter may be in the chrome module, so load by
+                    // reflection from there.
+                    return (JavaExceptionReporter) BundleUtils.newInstance(
+                            createChromeContext(ContextUtils.getApplicationContext()),
+                            "org.chromium.chrome.browser.crash.ChromePureJavaExceptionReporter");
+                }
+            };
+            PureJavaExceptionHandler.installHandler(factory);
+            CustomAssertionHandler.installHandler(factory);
         }
 
         TraceEvent.end(ATTACH_BASE_CONTEXT_EVENT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromePureJavaExceptionReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromePureJavaExceptionReporter.java
index 27251dc..1dde194 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromePureJavaExceptionReporter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromePureJavaExceptionReporter.java
@@ -7,8 +7,6 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.annotations.MainDex;
 import org.chromium.base.annotations.UsedByReflection;
-import org.chromium.base.task.PostTask;
-import org.chromium.base.task.TaskTraits;
 import org.chromium.components.crash.PureJavaExceptionReporter;
 
 import java.io.File;
@@ -24,7 +22,12 @@
 
     @UsedByReflection("SplitCompatApplication.java")
     public ChromePureJavaExceptionReporter() {
-        super(ContextUtils.getApplicationContext().getCacheDir(), /*attachLogcat=*/true);
+        super(/*attachLogcat=*/true);
+    }
+
+    @Override
+    protected File getCrashFilesDirectory() {
+        return ContextUtils.getApplicationContext().getCacheDir();
     }
 
     @Override
@@ -59,7 +62,7 @@
      * @param javaException The exception to report.
      */
     public static void postReportJavaException(Throwable javaException) {
-        PostTask.postTask(
-                TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> reportJavaException(javaException));
+        ChromePureJavaExceptionReporter reporter = new ChromePureJavaExceptionReporter();
+        reporter.postCreateAndUploadReport(javaException);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 926d9a0..6d60241 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -525,14 +525,14 @@
     }
 
     @Override
-    public void acceptTermsOfService(boolean allowCrashUpload) {
+    public void acceptTermsOfService(boolean allowMetricsAndCrashUploading) {
         assert mNativeInitializationPromise.isFulfilled();
 
         // If default is true then it corresponds to opt-out and false corresponds to opt-in.
         UmaUtils.recordMetricsReportingDefaultOptIn(!DEFAULT_METRICS_AND_CRASH_REPORTING);
         RecordHistogram.recordMediumTimesHistogram("MobileFre.FromLaunch.TosAccepted",
                 SystemClock.elapsedRealtime() - mIntentCreationElapsedRealtimeMs);
-        FirstRunUtils.acceptTermsOfService(allowCrashUpload);
+        FirstRunUtils.acceptTermsOfService(allowMetricsAndCrashUploading);
         FirstRunStatus.setSkipWelcomePage(true);
         flushPersistentData();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
index 5b98771..2d66d7b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
@@ -61,9 +61,10 @@
      * Notifies all interested parties that the user has accepted Chrome Terms of Service.
      * Must be called only after the delegate has fully initialized.
      * Does not automatically advance to the next page, call {@link #advanceToNextPage()} directly.
-     * @param allowCrashUpload True if the user allows to upload crash dumps and collect stats.
+     * @param allowMetricsAndCrashUploading True if the user allows to upload crash dumps and
+     *         collect stats.
      */
-    void acceptTermsOfService(boolean allowCrashUpload);
+    void acceptTermsOfService(boolean allowMetricsAndCrashUploading);
 
     /**
      * Show an informational web page. The page doesn't show navigation control.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
index c62957c..f8079a4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
@@ -66,10 +66,11 @@
 
     /**
      * Sets the EULA/Terms of Services state as "ACCEPTED".
-     * @param allowCrashUpload True if the user allows to upload crash dumps and collect stats.
+     * @param allowMetricsAndCrashUploading True if the user allows to upload crash dumps and
+     *         collect stats.
      */
-    static void acceptTermsOfService(boolean allowCrashUpload) {
-        UmaSessionStats.changeMetricsReportingConsent(allowCrashUpload);
+    static void acceptTermsOfService(boolean allowMetricsAndCrashUploading) {
+        UmaSessionStats.changeMetricsReportingConsent(allowMetricsAndCrashUploading);
         SharedPreferencesManager.getInstance().writeBoolean(
                 ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED, true);
         setEulaAccepted();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
index 7717399..7c0c9b0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
@@ -58,7 +58,7 @@
     private boolean mNativeInitialized;
     private boolean mPolicyServiceInitialized;
     private boolean mTosButtonClicked;
-    private boolean mAllowCrashUpload;
+    private boolean mAllowMetricsAndCrashUploading;
     private boolean mUserInteractedWithUmaCheckbox;
 
     private Button mAcceptButton;
@@ -95,7 +95,7 @@
         // Register event listeners.
         mAcceptButton.setOnClickListener((v) -> onTosButtonClicked());
         mSendReportCheckBox.setOnCheckedChangeListener(((compoundButton, isChecked) -> {
-            mAllowCrashUpload = isChecked;
+            mAllowMetricsAndCrashUploading = isChecked;
             mUserInteractedWithUmaCheckbox = true;
         }));
 
@@ -166,13 +166,13 @@
         assert !isWaitingForNativeAndPolicyInit();
 
         setSpinnerVisible(false);
-        mSendReportCheckBox.setChecked(mAllowCrashUpload);
+        mSendReportCheckBox.setChecked(mAllowMetricsAndCrashUploading);
     }
 
     /** Implements {@link FreUMADialogCoordinator.Listener} */
     @Override
-    public void onAllowCrashUploadChecked(boolean allowCrashUpload) {
-        mAllowCrashUpload = allowCrashUpload;
+    public void onAllowMetricsAndCrashUploadingChecked(boolean allowMetricsAndCrashUploading) {
+        mAllowMetricsAndCrashUploading = allowMetricsAndCrashUploading;
     }
 
     private void updateView() {
@@ -273,13 +273,14 @@
         // which case a previous call to this method has already checked the checkbox expected
         // initial state.
         if (!mUserInteractedWithUmaCheckbox) {
-            mAllowCrashUpload = getUmaCheckBoxInitialState();
-            mSendReportCheckBox.setChecked(mAllowCrashUpload);
+            mAllowMetricsAndCrashUploading = getUmaCheckBoxInitialState();
+            mSendReportCheckBox.setChecked(mAllowMetricsAndCrashUploading);
         }
 
         if (!canShowUmaCheckBox()) {
             if (!umaDialogMayBeShown) {
-                mAllowCrashUpload = (sShowUmaCheckBoxForTesting || VersionInfo.isOfficialBuild())
+                mAllowMetricsAndCrashUploading =
+                        (sShowUmaCheckBoxForTesting || VersionInfo.isOfficialBuild())
                         && !isMetricsReportingDisabledByPolicy;
             }
             mSendReportCheckBox.setVisibility(View.GONE);
@@ -289,7 +290,7 @@
     private void openUmaDialog() {
         new FreUMADialogCoordinator(requireContext(),
                 ((ModalDialogManagerHolder) getActivity()).getModalDialogManager(), this,
-                mAllowCrashUpload);
+                mAllowMetricsAndCrashUploading);
     }
 
     private void onPolicyServiceInitialized(boolean onDevicePolicyFound) {
@@ -337,7 +338,7 @@
             RecordHistogram.recordTimesHistogram("MobileFre.TosFragment.SpinnerVisibleDuration",
                     SystemClock.elapsedRealtime() - mTosAcceptedTime);
         }
-        getPageDelegate().acceptTermsOfService(mAllowCrashUpload);
+        getPageDelegate().acceptTermsOfService(mAllowMetricsAndCrashUploading);
         getPageDelegate().advanceToNextPage();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
index afa0c68..ad200a6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
@@ -16,7 +16,11 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManagerSupplier;
+import org.chromium.chrome.browser.fullscreen.FullscreenManager;
+import org.chromium.chrome.browser.fullscreen.FullscreenOptions;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
@@ -177,6 +181,20 @@
                 }
             };
 
+    private final FullscreenManager.Observer mFullscreenObserver =
+            new FullscreenManager.Observer() {
+                @Override
+                public void onEnterFullscreen(Tab tab, FullscreenOptions options) {
+                    setIsAllowedToAutoHide(false);
+                    mInfoBarContainerView.setTranslationY(0);
+                }
+
+                @Override
+                public void onExitFullscreen(Tab tab) {
+                    setIsAllowedToAutoHide(true);
+                }
+            };
+
     /** The tab that hosts this infobar container. */
     private final Tab mTab;
 
@@ -381,6 +399,12 @@
     @Override
     public void destroy() {
         destroyContainerView();
+        BrowserControlsManager browserControlsManager =
+                BrowserControlsManagerSupplier.getValueOrNullFrom(mTab.getWindowAndroid());
+        if (browserControlsManager != null
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION)) {
+            browserControlsManager.getFullscreenManager().removeObserver(mFullscreenObserver);
+        }
         mTab.removeObserver(mTabObserver);
         if (mNativeInfoBarContainer != 0) {
             InfoBarContainerJni.get().destroy(mNativeInfoBarContainer, InfoBarContainer.this);
@@ -471,9 +495,14 @@
     }
 
     private void initializeContainerView(Activity activity) {
+        BrowserControlsManager browserControlsManager =
+                BrowserControlsManagerSupplier.getValueOrNullFrom(mTab.getWindowAndroid());
         mInfoBarContainerView = new InfoBarContainerView(activity, mContainerViewObserver,
-                BrowserControlsManagerSupplier.getValueOrNullFrom(mTab.getWindowAndroid()),
-                DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid()));
+                browserControlsManager, DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid()));
+        if (browserControlsManager != null
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION)) {
+            browserControlsManager.getFullscreenManager().addObserver(mFullscreenObserver);
+        }
 
         mInfoBarContainerView.addOnAttachStateChangeListener(
                 new View.OnAttachStateChangeListener() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerView.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerView.java
index d92f495..cbcbff76 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerView.java
@@ -13,10 +13,12 @@
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.components.browser_ui.banners.SwipableOverlayView;
 import org.chromium.components.infobars.InfoBar;
 import org.chromium.components.infobars.InfoBarAnimationListener;
@@ -28,7 +30,8 @@
 /**
  * The {@link View} for the {@link InfoBarContainer}.
  */
-public class InfoBarContainerView extends SwipableOverlayView {
+public class InfoBarContainerView
+        extends SwipableOverlayView implements BrowserControlsStateProvider.Observer {
     /**
      * Observes container view changes.
      */
@@ -77,10 +80,15 @@
      */
     InfoBarContainerView(@NonNull Context context,
             @NonNull ContainerViewObserver containerViewObserver,
-            @NonNull BrowserControlsStateProvider browserControlsStateProvider, boolean isTablet) {
-        super(context, null);
+            @Nullable BrowserControlsStateProvider browserControlsStateProvider, boolean isTablet) {
+        super(context, null,
+                !ChromeFeatureList.isEnabled(ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION));
         mContainerViewObserver = containerViewObserver;
         mBrowserControlsStateProvider = browserControlsStateProvider;
+        if (mBrowserControlsStateProvider != null
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION)) {
+            mBrowserControlsStateProvider.addObserver(this);
+        }
 
         // TODO(newt): move this workaround into the infobar views if/when they're scrollable.
         // Workaround for http://crbug.com/407149. See explanation in onMeasure() below.
@@ -108,6 +116,10 @@
     }
 
     void destroy() {
+        if (mBrowserControlsStateProvider != null
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION)) {
+            mBrowserControlsStateProvider.removeObserver(this);
+        }
         removeFromParentView();
     }
 
@@ -174,6 +186,17 @@
         mContainerViewObserver.onShownRatioChanged(shownFraction);
     }
 
+    // BrowserControlsStateProvider.Observer implementation.
+    @Override
+    public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset,
+            int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) {
+        if (!isAllowedToAutoHide()) {
+            return;
+        }
+        setTranslationY(getTotalHeight() * 1.0f * Math.abs(topOffset)
+                / mBrowserControlsStateProvider.getTopControlsHeight());
+    }
+
     /**
      * Sets whether the InfoBarContainer is allowed to auto-hide when the user scrolls the page.
      * Expected to be called when Touch Exploration is enabled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
index c6023ca..22304e3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
@@ -148,8 +148,8 @@
 
     /** Implements {@link SigninFirstRunCoordinator.Delegate}. */
     @Override
-    public void acceptTermsOfService(boolean allowCrashUpload) {
-        getPageDelegate().acceptTermsOfService(allowCrashUpload);
+    public void acceptTermsOfService(boolean allowMetricsAndCrashUploading) {
+        getPageDelegate().acceptTermsOfService(allowMetricsAndCrashUploading);
     }
 
     /** Implements {@link SigninFirstRunCoordinator.Delegate}. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
index a5baa34..b7ccc3a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
@@ -31,6 +31,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RequiresRestart;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsBridge;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesState;
@@ -40,6 +41,7 @@
 import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.InfoBarUtil;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.components.infobars.InfoBar;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -398,4 +400,26 @@
         // - adb shell dumpsys SurfaceFlinger
         // - Observe that Clank's overlay size changes (or disappears if URLbar is also gone).
     }
+
+    /**
+     * Tests that infobar container view hides when browser control is offset.
+     */
+    @Test
+    @MediumTest
+    @Feature({"Browser"})
+    @EnableFeatures({ChromeFeatureList.INFOBAR_SCROLL_OPTIMIZATION})
+    public void testSyncWithBrowserControl() throws Exception {
+        final TestListener infobarListener = addInfoBarToCurrentTab(false);
+        Assert.assertEquals(1, sActivityTestRule.getInfoBars().size());
+        final InfoBar infoBar = sActivityTestRule.getInfoBars().get(0);
+        Assert.assertEquals(0, infoBar.getView().getTranslationY(), /*delta=*/0.1);
+
+        InfoBarContainer infoBarContainer = sActivityTestRule.getInfoBarContainer();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            infoBarContainer.getContainerViewForTesting().onControlsOffsetChanged(
+                    -100, 100, 0, 0, false);
+        });
+        Assert.assertNotEquals(
+                0, infoBarContainer.getContainerViewForTesting().getTranslationY(), /*delta=*/0.1);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java
index 6b308a9..61c1dc128 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java
@@ -15,6 +15,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.FeatureList;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 import org.chromium.base.test.params.ParameterProvider;
@@ -31,14 +32,18 @@
 import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
 import org.chromium.components.browser_ui.site_settings.ContentSettingException;
 import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings;
+import org.chromium.components.browser_ui.site_settings.SiteSettingsFeatureList;
 import org.chromium.components.browser_ui.site_settings.SiteSettingsUtil;
 import org.chromium.components.browser_ui.site_settings.Website;
 import org.chromium.components.browser_ui.site_settings.WebsiteAddress;
 import org.chromium.components.content_settings.ContentSettingValues;
 import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.content_public.browser.ContentFeatureList;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Tests that exercise functionality when showing details for a single site.
@@ -117,6 +122,42 @@
         settingsActivity.finish();
     }
 
+    @Test
+    @SmallTest
+    public void testDesktopSiteException_DowngradePath() {
+        // Enable RDS exceptions and launch single website settings.
+        Map<String, Boolean> featureMap = new HashMap<>();
+        featureMap.put(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS, true);
+        FeatureList.setTestFeatures(featureMap);
+
+        SettingsActivity settingsActivity1 = SiteSettingsTestUtils.startSingleWebsitePreferences(
+                createWebsiteWithContentSettingException(
+                        ContentSettingsType.REQUEST_DESKTOP_SITE, ContentSettingValues.ALLOW));
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            var websitePreferences = (SingleWebsiteSettings) settingsActivity1.getMainFragment();
+            Assert.assertNotNull("Desktop site preference should be present.",
+                    websitePreferences.findPreference(SingleWebsiteSettings.getPreferenceKey(
+                            ContentSettingsType.REQUEST_DESKTOP_SITE)));
+        });
+        settingsActivity1.finish();
+
+        // Disable RDS exceptions for a downgrade and launch single website settings.
+        featureMap.put(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS, false);
+        featureMap.put(SiteSettingsFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS_DOWNGRADE, true);
+        FeatureList.setTestFeatures(featureMap);
+
+        SettingsActivity settingsActivity2 = SiteSettingsTestUtils.startSingleWebsitePreferences(
+                createWebsiteWithContentSettingException(
+                        ContentSettingsType.REQUEST_DESKTOP_SITE, ContentSettingValues.ALLOW));
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            var websitePreferences = (SingleWebsiteSettings) settingsActivity2.getMainFragment();
+            Assert.assertNull("Desktop site preference should not be present.",
+                    websitePreferences.findPreference(SingleWebsiteSettings.getPreferenceKey(
+                            ContentSettingsType.REQUEST_DESKTOP_SITE)));
+        });
+        settingsActivity2.finish();
+    }
+
     /**
      * Helper function for creating a {@link ParameterSet} for {@link SingleWebsiteSettingsParams}.
      */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
index dbe176f..3c9db5d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -38,6 +38,7 @@
 import org.mockito.MockitoAnnotations;
 
 import org.chromium.base.ContextUtils;
+import org.chromium.base.FeatureList;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
@@ -93,6 +94,7 @@
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.content_public.browser.BrowserContextHandle;
+import org.chromium.content_public.browser.ContentFeatureList;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.common.ContentSwitches;
 import org.chromium.device.geolocation.LocationProviderOverrider;
@@ -102,7 +104,9 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -1597,6 +1601,39 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
+    public void testAllowRequestDesktopSiteDomainSetting_DowngradePath() {
+        // Enable RDS exceptions.
+        Map<String, Boolean> featureMap = new HashMap<>();
+        featureMap.put(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS, true);
+        FeatureList.setTestFeatures(featureMap);
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            WebsitePreferenceBridgeJni.get().setPermissionSettingForOrigin(
+                    getBrowserContextHandle(), ContentSettingsType.REQUEST_DESKTOP_SITE,
+                    "https://example.com", "https://example.com", ContentSettingValues.ALLOW);
+        });
+
+        new TwoStatePermissionTestCase("RequestDesktopSite",
+                SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE,
+                ContentSettingsType.REQUEST_DESKTOP_SITE, true)
+                .withExpectedPrefKeys("allowed_group")
+                .withExpectedPrefKeys(SingleCategorySettings.ADD_EXCEPTION_KEY)
+                .run();
+
+        // Disable RDS exceptions for a downgrade.
+        featureMap.put(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS, false);
+        featureMap.put(SiteSettingsFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS_DOWNGRADE, true);
+        FeatureList.setTestFeatures(featureMap);
+
+        new TwoStatePermissionTestCase("RequestDesktopSite",
+                SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE,
+                ContentSettingsType.REQUEST_DESKTOP_SITE, true)
+                .run();
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Preferences"})
     @EnableFeatures("RequestDesktopSiteExceptions")
     public void testBlockRequestDesktopSiteDomainSetting() {
         new TwoStatePermissionTestCase("RequestDesktopSite",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediatorTest.java
index 3c2ccd11..f6b47fb 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediatorTest.java
@@ -118,6 +118,8 @@
     @Mock
     private GURL mGurl3;
     @Mock
+    private GURL mGurl4;
+    @Mock
     private Tab mTab;
     @Mock
     private Tab mTab2;
@@ -148,9 +150,12 @@
     private ClusterVisit mVisit2;
     private ClusterVisit mVisit3;
     private ClusterVisit mVisit4;
+    private ClusterVisit mVisit5;
+    private ClusterVisit mVisit6;
     private HistoryCluster mCluster1;
     private HistoryCluster mCluster2;
     private HistoryCluster mCluster3;
+    private HistoryCluster mClusterSingle;
     private HistoryClustersResult mHistoryClustersResultWithQuery;
     private HistoryClustersResult mHistoryClustersFollowupResultWithQuery;
     private HistoryClustersResult mHistoryClustersResultEmptyQuery;
@@ -255,6 +260,7 @@
         doReturn("http://spec1.com").when(mGurl1).getSpec();
         doReturn("http://spec2.com").when(mGurl2).getSpec();
         doReturn("http://spec3.com").when(mGurl3).getSpec();
+        doReturn("http://spec3.com").when(mGurl4).getSpec();
 
         mMediator = new HistoryClustersMediator(mBridge, mLargeIconBridge, mContext, mResources,
                 mModelList, mToolbarModel, mHistoryClustersDelegate, mClock, mTemplateUrlService,
@@ -267,11 +273,17 @@
                 new ArrayList<>(), mGurl3, 123L, new ArrayList<>());
         mVisit4 = new ClusterVisit(1.0F, mGurl3, "Title 4", "url3.com/foo", new ArrayList<>(),
                 new ArrayList<>(), mGurl3, 123L, new ArrayList<>());
+        mVisit5 = new ClusterVisit(1.0F, mGurl3, "Title 5", "url5.com/", new ArrayList<>(),
+                new ArrayList<>(), mGurl4, 123L, new ArrayList<>());
+        mVisit6 = new ClusterVisit(1.0F, mGurl4, "Title 6", "url6.com/", new ArrayList<>(),
+                new ArrayList<>(), mGurl4, 123L, new ArrayList<>());
         mCluster1 = new HistoryCluster(Arrays.asList(mVisit1, mVisit2), "\"label1\"", "label1",
                 new ArrayList<>(), 456L, Arrays.asList("search 1", "search 2"));
-        mCluster2 = new HistoryCluster(Arrays.asList(mVisit3), "hostname.com", "hostname.com",
-                new ArrayList<>(), 123L, Collections.emptyList());
-        mCluster3 = new HistoryCluster(Arrays.asList(mVisit4), "\"label3\"", "label3",
+        mCluster2 = new HistoryCluster(Arrays.asList(mVisit3, mVisit4), "hostname.com",
+                "hostname.com", new ArrayList<>(), 123L, Collections.emptyList());
+        mCluster3 = new HistoryCluster(Arrays.asList(mVisit5, mVisit6), "\"label3\"", "label3",
+                new ArrayList<>(), 789L, Collections.EMPTY_LIST);
+        mClusterSingle = new HistoryCluster(Arrays.asList(mVisit1), "\"label1\"", "label1",
                 new ArrayList<>(), 789L, Collections.EMPTY_LIST);
         mHistoryClustersResultWithQuery =
                 new HistoryClustersResult(Arrays.asList(mCluster1, mCluster2),
@@ -305,7 +317,7 @@
 
         fulfillPromise(promise, mHistoryClustersResultWithQuery);
 
-        assertEquals(6, mModelList.size());
+        assertEquals(7, mModelList.size());
         ListItem clusterItem = mModelList.get(0);
         assertEquals(clusterItem.type, ItemType.CLUSTER);
         PropertyModel clusterModel = clusterItem.model;
@@ -685,14 +697,14 @@
                 .when(mResources)
                 .getString(eq(R.string.delete_message), anyString());
 
-        mMediator.deleteVisits(Arrays.asList(mVisit1, mVisit3));
-        assertThat(mVisitsForRemoval, Matchers.containsInAnyOrder(mVisit1, mVisit3));
+        mMediator.deleteVisits(Arrays.asList(mVisit1, mVisit2));
+        assertThat(mVisitsForRemoval, Matchers.containsInAnyOrder(mVisit1, mVisit2));
         verify(mMetricsLogger).recordVisitAction(VisitAction.DELETED, mVisit1);
-        verify(mMetricsLogger).recordVisitAction(VisitAction.DELETED, mVisit3);
+        verify(mMetricsLogger).recordVisitAction(VisitAction.DELETED, mVisit2);
         verify(mAnnounceCallback).onResult("multiple");
         // Deleting all of the visits in a cluster should also delete the ModelList entry for the
         // cluster itself.
-        assertEquals(initialSize - 3, mModelList.size());
+        assertEquals(initialSize - 4, mModelList.size());
 
         ListItem clusterItem = mModelList.get(0);
         assertEquals(clusterItem.type, ItemType.CLUSTER);
@@ -700,20 +712,16 @@
         ListItem visitItem = mModelList.get(1);
         assertEquals(visitItem.type, ItemType.VISIT);
         PropertyModel visitModel = visitItem.model;
-        assertEquals(mMediator.applyBolding(mVisit2.getTitle(), mVisit2.getTitleMatchPositions()),
+        assertEquals(mMediator.applyBolding(mVisit3.getTitle(), mVisit3.getTitleMatchPositions()),
                 visitModel.get(HistoryClustersItemProperties.TITLE));
         assertEquals(
-                mMediator.applyBolding(mVisit2.getUrlForDisplay(), mVisit2.getUrlMatchPositions()),
+                mMediator.applyBolding(mVisit3.getUrlForDisplay(), mVisit3.getUrlMatchPositions()),
                 visitModel.get(HistoryClustersItemProperties.URL));
 
-        ListItem relatedSearchesItem = mModelList.get(2);
-        assertEquals(relatedSearchesItem.type, ItemType.RELATED_SEARCHES);
-        PropertyModel relatedSearchesModel = relatedSearchesItem.model;
-        assertEquals(mCluster1.getRelatedSearches(),
-                relatedSearchesModel.get(HistoryClustersItemProperties.RELATED_SEARCHES));
+        mMediator.deleteVisits(Arrays.asList(mVisit3));
+        verify(mAnnounceCallback).onResult("single " + mVisit3.getTitle());
 
-        mMediator.deleteVisits(Arrays.asList(mVisit2));
-        verify(mAnnounceCallback).onResult("single " + mVisit2.getTitle());
+        mMediator.deleteVisits(Arrays.asList(mVisit4));
         // Deleting the final visit should result in an entirely empty list.
         assertEquals(0, mModelList.size());
     }
@@ -882,9 +890,9 @@
         fulfillPromise(promise, mHistoryClustersResultWithQuery);
 
         // The last cluster shouldn't have a divider.
-        PropertyModel clusterModel = mModelList.get(4).model;
+        PropertyModel clusterModel = mModelList.get(5).model;
         assertFalse(clusterModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
-        PropertyModel visitModel = mModelList.get(5).model;
+        PropertyModel visitModel = mModelList.get(6).model;
         assertFalse(visitModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
 
         Promise<HistoryClustersResult> secondPromise = new Promise();
@@ -896,9 +904,33 @@
         // The previously last cluster should now have a divider.
         assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
         assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_IS_THICK));
+    }
 
-        visitModel = mModelList.get(7).model;
+    @Test
+    public void testDividers_deletedLastItem() {
+        Promise promise = new Promise<>();
+        doReturn(promise).when(mBridge).queryClusters("query");
+
+        mMediator.setQueryState(QueryState.forQuery("query", ""));
+        fulfillPromise(promise, mHistoryClustersResultWithQuery);
+
+        Promise<HistoryClustersResult> secondPromise = new Promise();
+        doReturn(secondPromise).when(mBridge).loadMoreClusters("query");
+        mMediator.onScrolled(mRecyclerView, 1, 1);
+        ShadowLooper.idleMainLooper();
+        fulfillPromise(secondPromise, mHistoryClustersFollowupResultWithQuery);
+
+        PropertyModel visitModel = mModelList.get(5).model;
         assertFalse(visitModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
+        visitModel = mModelList.get(6).model;
+        assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
+        assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_IS_THICK));
+
+        mMediator.deleteVisits(
+                Arrays.asList(visitModel.get(HistoryClustersItemProperties.CLUSTER_VISIT)));
+        visitModel = mModelList.get(5).model;
+        assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_VISIBLE));
+        assertTrue(visitModel.get(HistoryClustersItemProperties.DIVIDER_IS_THICK));
     }
 
     @Test
@@ -922,6 +954,19 @@
         assertFalse(mModelList.get(2).model.get(HistoryClustersItemProperties.END_BUTTON_VISIBLE));
     }
 
+    @Test
+    public void testSingleVisitCluster() {
+        HistoryClustersResult singletonVisitResult = new HistoryClustersResult(
+                Arrays.asList(mClusterSingle), new LinkedHashMap<>(), "query", false, false);
+        Promise<HistoryClustersResult> promise = new Promise<>();
+        doReturn(promise).when(mBridge).queryClusters("query");
+
+        mMediator.setQueryState(QueryState.forQuery("query", ""));
+        mMediator.startQuery("query");
+        fulfillPromise(promise, singletonVisitResult);
+        assertEquals(0, mModelList.size());
+    }
+
     private <T> void fulfillPromise(Promise<T> promise, T result) {
         promise.fulfill(result);
         ShadowLooper.idleMainLooper();
diff --git a/chrome/android/modules/chrome_bundle_tmpl.gni b/chrome/android/modules/chrome_bundle_tmpl.gni
index 6d63008..1754d68 100644
--- a/chrome/android/modules/chrome_bundle_tmpl.gni
+++ b/chrome/android/modules/chrome_bundle_tmpl.gni
@@ -6,6 +6,7 @@
 import("//build/config/android/config.gni")
 import("//chrome/android/modules/chrome_feature_module_tmpl.gni")
 import("//chrome/version.gni")
+import("//components/crash/android/silent_java_assert_reporting.gni")
 import("//components/module_installer/android/module_desc_java.gni")
 
 # Instantiates a Chrome-specific app bundle.
@@ -194,6 +195,9 @@
     system_image_locale_allowlist = platform_pak_locales - extended_locales
     is_multi_abi = _is_multi_abi
     validate_services = _enable_chrome_module
+    if (enable_silent_java_assert_reporting) {
+      custom_assertion_handler = crash_reporting_assertion_handler
+    }
 
     # For this to be respected, it must also be set on the base module target.
     strip_unused_resources = is_official_build
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 4a01b0a..c4028c6e 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -5119,6 +5119,12 @@
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD" desc="The label that explains the location of the fingerprint sensor on the device, when a child account is in use.">
     To set up fingerprint, have your child touch the fingerprint sensor. Your child’s fingerprint data is stored securely and never leaves this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT" desc="The label that explains the location of the fingerprint sensor for devices with fingerprint sensor located left to the power button on the top right corner of the keyboard.">
+    Touch the fingerprint sensor at the top right corner of your keyboard, next to the Power button. Your fingerprint data is stored securely and never leaves your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
+  </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT_CHILD" desc="The label that explains the location of the fingerprint sensor for devices with fingerprint sensor located left to the power button on the top right corner of the keyboard, when a child account is in use.">
+    To set up fingerprint, have your child touch the fingerprint sensor at the top right corner of the keyboard, next to the Power button. Your child’s fingerprint data is stored securely and never leaves this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_PROGRESS_TITLE" desc="The title of the dialog that shows where the fingerprint sensor is.">
     Lift, then touch again
   </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT.png.sha1
new file mode 100644
index 0000000..3abdf0a78
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT.png.sha1
@@ -0,0 +1 @@
+4abce01697265d39c2749035e058d11687f9ffd9
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT_CHILD.png.sha1
new file mode 100644
index 0000000..cda0de149
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT_CHILD.png.sha1
@@ -0,0 +1 @@
+45e40c9e1a14d4d31753a2720aab137c3bd69d45
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 32eae0a..b634f20 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5426,9 +5426,26 @@
       </message>
       <!-- End Extension Settings Overridden Dialog strings. -->
       <!-- Force Installed Deprecated Apps Deletion Dialog strings. -->
-      <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog">
-        Old versions of Chrome Apps won't open after December 2022. Contact your administrator to update to a new version or remove this app.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog">
+          Old versions of Chrome Apps won't open on Mac devices after December 2022. Contact your administrator to update to a new version or remove this app.
+        </message>
+      </if>
+      <if expr="is_win">
+        <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog">
+          Old versions of Chrome Apps won't open on Windows devices after December 2022. Contact your administrator to update to a new version or remove this app.
+        </message>
+      </if>
+      <if expr="is_linux">
+        <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog">
+          Old versions of Chrome Apps won't open on Linux devices after December 2022. Contact your administrator to update to a new version or remove this app.
+        </message>
+      </if>
+      <if expr="is_fuchsia">
+        <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog">
+          Old versions of Chrome Apps won't open after December 2022. Contact your administrator to update to a new version or remove this app.
+        </message>
+      </if>
       <!-- End Force Installed Deprecated Apps Deletion Dialog strings. -->
       <!-- Deprecated Apps Deletion Dialog strings. -->
       <message name="IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL" desc="The title of the deprecated app dialog">
@@ -5437,9 +5454,26 @@
       <message name="IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME" desc="The title of the deprecated app dialog with the app name">
         "<ph name="EXTENSION_NAME">$1<ex>Google Docs</ex></ph>" is no longer supported
       </message>
-      <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch.">
-        Old versions of Chrome apps won't open after December 2022. You can check if there's a new version available.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch.">
+          Old versions of Chrome apps won't open on Mac devices after December 2022. You can check if there's a new version available.
+        </message>
+      </if>
+      <if expr="is_win">
+        <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch.">
+          Old versions of Chrome apps won't open on Windows devices after December 2022. You can check if there's a new version available.
+        </message>
+      </if>
+      <if expr="is_linux">
+        <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch.">
+          Old versions of Chrome apps won't open on Linux devices after December 2022. You can check if there's a new version available.
+        </message>
+      </if>
+      <if expr="is_fuchsia">
+        <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch.">
+          Old versions of Chrome apps won't open after December 2022. You can check if there's a new version available.
+        </message>
+      </if>
       <message name="IDS_DEPRECATED_APPS_LEARN_MORE" desc="Redirects to a link with more information on chrome apps deprecation">
         Learn more
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1
index ae4936a95..a66e733 100644
--- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1
@@ -1 +1 @@
-d5ff0b22ce14fcea1fc49a2c7de9b15f730c131a
\ No newline at end of file
+3959309073c7b8077b04aadabd7356fcf866bffa
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1
index 10790c7b..aef95fd3 100644
--- a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1
@@ -1 +1 @@
-0beafb213eafd8a58fd41a4bbd830a216cc85cbe
\ No newline at end of file
+ed3c571b1a4e8dc26e809d25c63815d35371bedd
\ No newline at end of file
diff --git a/chrome/app/gmc_strings.grdp b/chrome/app/gmc_strings.grdp
index c4c0f57..7a7498e 100644
--- a/chrome/app/gmc_strings.grdp
+++ b/chrome/app/gmc_strings.grdp
@@ -25,9 +25,12 @@
   <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_PROGRESS" desc="Download progress indicator after Live Caption is enabled. The user needs to download certain files for the feature to work.">
    Downloading... <ph name="PERCENT">$1<ex>17</ex></ph>%
   </message>
-  <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR" desc="Download progress indicator after Live Caption is enabled. The user needs to download certain files for the feature to work.">
+  <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR" desc="Generic message when Live Caption files can’t be downloaded.">
    Can't download speech files. Try again later.
   </message>
+  <message name="IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED" desc="Error message shown when a OS reboot is required to install the Live Caption files.">
+    Restart needed to install speech files.
+  </message>
   <message name="IDS_GLOBAL_MEDIA_CONTROLS_DIALOG_NAME" desc="A11y name for the Global Media Controls dialog.">
    Global Media Controls
   </message>
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
new file mode 100644
index 0000000..27d9278d
--- /dev/null
+++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
@@ -0,0 +1 @@
+d7bb9121c6f1e9a04481b09ee4ed428277501e1f
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 9a090fb..65607c29 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -4466,6 +4466,9 @@
   <message name="IDS_OS_SETTINGS_PRIVACY_HUB_MICROPHONE_HARDWARE_TOGGLE_ACTIVE_SUBTEXT" desc="Sub-label on the privacy page that indicates that the hardware microphone toggle is active.">
     All microphones disabled by devices hardware switch
   </message>
+  <message name="IDS_OS_SETTINGS_GEOLOCATION_TOGGLE_TITLE" desc="The title of the toggle to enable/disable geolocation from the privacy hub.">
+    Geolocation
+  </message>
   <message name="IDS_OS_SETTINGS_HW_DATA_USAGE_TOGGLE_TITLE" desc="The label of the checkbox to enable/disable device hardware data collection and usage in ChromeOS Flex.">
     <ph name="DEVICE_OS">$1<ex>ChromeOS Flex</ex></ph> hardware support and stability
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_GEOLOCATION_TOGGLE_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_GEOLOCATION_TOGGLE_TITLE.png.sha1
new file mode 100644
index 0000000..e3e13d3ab
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_GEOLOCATION_TOGGLE_TITLE.png.sha1
@@ -0,0 +1 @@
+ca4c89866664243b5f9d95b71414941f13164610
\ No newline at end of file
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb
index 809655f..3bafab5 100644
--- a/chrome/app/resources/generated_resources_af.xtb
+++ b/chrome/app/resources/generated_resources_af.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">Verstek</translation>
 <translation id="1252987234827889034">Profielfout het voorgekom</translation>
 <translation id="1254593899333212300">Direkte internetverbinding</translation>
+<translation id="1257336506558170607">Voer gekose sertifikaat uit</translation>
 <translation id="1258491128795710625">Wat's nuut</translation>
 <translation id="1259152067760398571">Veiligheidskontrole het gister plaasgevind</translation>
 <translation id="1260451001046713751">Laat altyd opspringers en herleidings van <ph name="HOST" /> af toe</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index df19f08e..0a974fa4 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -326,6 +326,7 @@
 <translation id="1307165550267142340">የእርስዎ ፒን ተፈጥሯል</translation>
 <translation id="1307431692088049276">ዳግም አትጠይቀኝ</translation>
 <translation id="1307559529304613120">ውይ!  ስርዓቱ የዚህ መሣሪያ የረጅም ጊዜ ኤ ፒ አይ መዳረሻ ማስመሰያ ማከማቸት አልቻለም።</translation>
+<translation id="1312811472299082263">ከAnsible የመመሪያ ደብተር ወይም ከCrostini ምትኬ ፋይል ይፍጠሩ</translation>
 <translation id="1313405956111467313">ራስ-ሰር የተኪ ውቅር</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">በክፍት ትሮች ውስጥ ጨምሮ ከሁሉም ጣቢያዎች ዘግተው እንዲወጡ ይደረጋሉ</translation>
@@ -1106,6 +1107,7 @@
 <translation id="2028449514182362831">የእንቅስቃሴ ዳሳሾችን የሚፈልጉ ባህሪዎች አይሰሩም</translation>
 <translation id="202918510990975568">ደህንነትን እና የመለያ መግቢያን ለማዋቀር የይለፍ ቃልዎን ያስገቡ</translation>
 <translation id="2030455719695904263">የመከታተያ ፓድ</translation>
+<translation id="2031385797619033640"><ph name="EXTENSIONS_REQUESTING_ACCESS" /> <ph name="ORIGIN" />ን እንዲያነብ እና እንዲቀይር ለመፍቀድ ጠቅ ያድርጉ፦</translation>
 <translation id="2031639749079821948">የይለፍ ቃልዎ በGoogle መለያዎ ውስጥ ይቀመጣል</translation>
 <translation id="2031914984822377766">የእርስዎን ተመራጭ <ph name="LINK_BEGIN" />የድር ጣቢያ ቋንቋዎች<ph name="LINK_END" /> ያክሉ። ከዝርዝሩ ውስጥ ያለው ከፍተኛው ቋንቋ ለትርጉሞች ስራ ላይ ይውላል።</translation>
 <translation id="2033758234986231162">ከስልክዎ ጋር ያለውን ግንኙነት ማስጠበቅ አልተቻለም። ስልክዎ በቅርብ ርቀት መኖሩን፣ የተከፈተ መሆኑን፣ እንዲሁም ብሉቱዝ እና Wi-Fi የበሩ መሆናቸውን ያረጋግጡ።</translation>
@@ -1463,6 +1465,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" />ን ለመጠቀም እባክዎ የእርስዎን መሣሪያ ዳግም ያስነሱት።</translation>
 <translation id="2328636661627946415">ማንነትን የማያሳውቅ ሁነታ ላይ ሲሆኑ፣ ጣቢያዎች የአሰሳ እንቅስቃሴዎን በራሳቸው ጣቢያ ላይ ለማየት ኩኪዎችን ብቻ መጠቀም ይችላሉ። ኩኪዎች የሚሰረዙት ማንነትን የማያሳውቅ ክፍለ ጊዜ መጨረሻ ላይ ነው።</translation>
 <translation id="2329597144923131178">የእርስዎን ዕልባቶች፣ ታሪክ፣ የይለፍ ቃላት እና ሌሎች ቅንብሮች በሁሉም መሣሪያዎችዎ ላይ ለማግኘት ወደ መለያ ይግቡ።</translation>
+<translation id="2332115969598251205"><ph name="PRIMARY_EMAIL" /> ላይ የተቀመጡ መሣሪያዎችን መጫን አልተቻለም። የእርስዎን የበይነመረብ ግንኙነት ይፈትሹ እና እንደገና ይሞክሩ።</translation>
 <translation id="2332131598580221120">በመደብር ውስጥ ይመልከቱ</translation>
 <translation id="2332192922827071008">ምርጫዎችን ክፈት</translation>
 <translation id="2332515770639153015">የተሻሻለ የደህንነት አሰሳ በርቷል</translation>
@@ -1906,6 +1909,7 @@
 <translation id="2749836841884031656">ሲም</translation>
 <translation id="2749881179542288782">ሰዋሰው እና ሆሄ አርም</translation>
 <translation id="2753677631968972007">የጣቢያ ፈቃዶችን ራስዎ ይቆጣጠሩ።</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" /> ላይ የተቀመጡ የፈጣን ጥምረት መሣሪያዎችን በመፈለግ ላይ</translation>
 <translation id="2754825024506485820">በGoogle Play መደብር ላይ ከምርታማነት እስከ መዝናኛ ያሉ የሚያስፈልጉዎትን መተግበሪያዎች ያግኙ። መተግበሪያዎችን በማንኛውም ጊዜ መጫን ይችላሉ።</translation>
 <translation id="2755349111255270002">ይህን <ph name="DEVICE_TYPE" /> ዳግም አቀናብር</translation>
 <translation id="2755367719610958252">የተደራሽነት ባህሪያትን ያቀናብሩ</translation>
@@ -2121,6 +2125,7 @@
 <translation id="2942279350258725020">የAndroid መልዕክቶች</translation>
 <translation id="2942560570858569904">በመጠበቅ ላይ...</translation>
 <translation id="2942581856830209953">ይህን ገጽ ብጁ ያድርጉ</translation>
+<translation id="2943268899142471972">የAnsible የመመሪያ ደብተር ወይም የCrostini ምትኬ ፋይል ይምረጡ</translation>
 <translation id="2944060181911631861">የአጠቃቀም እና የምርመራ ውሂብ ይላኩ። የምርመራ፣ የመሣሪያ እና የመተግበሪያ አጠቃቀም ውሂብ በራስ-ሰር ወደ በራስ-ሰር ወደ Google በመላክ የAndroid ተሞክሮዎ እንዲሻሻል ያግዙ። ይህ የስርዓት እና የመተግበሪያ እርጋታን እና ሌሎች ማሻሻያዎችን ያግዛል። አንዳንድ ውሑድ ውሂብ እንዲሁም የGoogle መተግበሪያዎችን እና እንደ የAndroid ገንቢዎች ያሉ አጋሮችን ያግዛሉ። የእርስዎ የተጨማሪ ድር እና መተግበሪያ እንቅስቃሴ ቅንብር በርቶ ከሆነ ይህ ውሂብ በGoogle መለያዎ ላይ ሊቀመጥ ይችላል። <ph name="BEGIN_LINK1" />የበለጠ ለመረዳት<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">ወደ ፋይሎች ሂድ</translation>
 <translation id="2946119680249604491">ግንኑነት ያክሉ</translation>
@@ -2961,6 +2966,7 @@
 <translation id="3784472333786002075">ኩኪዎች በድርጣቢያዎች የተፈጠሩ ፋይሎች ናቸው። ሁለት ዓይነት ኩኪዎች አሉ፦ የመጀመሪያ ወገን ኩኪዎች እርስዎ በሚጎበኙት ጣቢያ የሚፈጠሩ ናቸው። ይህ ጣቢያ በአድራሻ አሞሌው ላይ ይታያል። የሦስተኛ ወገን ኩኪዎች በሌሎች ጣቢያዎች የሚፈጠሩ ናቸው። እነዚህ ጣቢያዎች እንደ ማስታወቂያዎች ወይም ምስሎች የመሳሰሉ እርስዎ በሚጎበኙት ጣቢያ ላይ ያለ ይዘትን በባለቤትነት የያዙ ናቸው።</translation>
 <translation id="3785308913036335955">የመተግበሪያዎች አቋራጮችን አሳይ</translation>
 <translation id="3785727820640310185">የተቀመጡ የዚህ ጣቢያ የይለፍ ቃላት</translation>
+<translation id="3787434344076711519">ትርጉምን በመጠበቅ ላይ</translation>
 <translation id="3788301286821743879">የኪዮስክ መተግበሪያውን ማስጀመር አልተቻለም።</translation>
 <translation id="3788331399335602504">እነዚህ ፋይሎች</translation>
 <translation id="3788401245189148511">ይህንን ሊያደርግ ይችላል፦</translation>
@@ -3244,6 +3250,7 @@
 <translation id="4036778507053569103">ከአገልጋዩ የወረደው መመሪያ ልክ ያልኾነ ነው።</translation>
 <translation id="4037084878352560732">ፈረስ</translation>
 <translation id="403725336528835653">መጀመሪያ ይሞክሩት</translation>
+<translation id="4040041015953651705">የሚተረጎመው ቋንቋ</translation>
 <translation id="4040105702484676956">ለ<ph name="SITE_NAME" /> እና ለተጫነው መተግበሪያው የጣቢያ ውሂብ እና ፈቃዶች ይጽዱ?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{ከገጽ ውጣ}one{ከገጾች ውጣ}other{ከገጾች ውጣ}}</translation>
 <translation id="4043267180218562935">የጠቋሚ መጠን</translation>
@@ -4047,6 +4054,7 @@
 <translation id="4838170306476614339">የስልክዎን ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ይመልከቱ</translation>
 <translation id="4838836835474292213">የቅንጥብ ሰሌዳ ንባብ መዳረሻ ተፈቅዷል</translation>
 <translation id="4838907349371614303">የይለፍ ቃል ተዘምኗል</translation>
+<translation id="4838958829619609362">ምርጫው በ<ph name="LANGUAGE" /> አይደለም</translation>
 <translation id="4839303808932127586">ቪዲዮ አስ&amp;ቀምጥ እንደ…</translation>
 <translation id="4840096453115567876">ለማንኛውም ማንነት ከማያሳውቅ ሁነታ ይውጡ?</translation>
 <translation id="4841741146571978176">ተፈላጊ ምናባዊ ማሽን የለም። ለመቀጠል እባክዎ <ph name="VM_TYPE" />ን ለማቀናበር ይሞክሩ</translation>
@@ -4818,6 +4826,7 @@
 <translation id="558918721941304263">መተግበሪያዎችን በመጫን ላይ...</translation>
 <translation id="5590418976913374224">በመሣሪያ ጅምር ላይ ድምጽ አጫውት</translation>
 <translation id="5592595402373377407">ገና ምንም በቂ ውሂብ የለም።</translation>
+<translation id="5594899180331219722">ፋይል ምረጥ</translation>
 <translation id="5595307023264033512">በጣቢያዎች ስራ ላይ የዋለው ጠቅላላ ማከማቻ፦<ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">አድራሻ አርትዕ</translation>
 <translation id="5596627076506792578">ተጨማሪ አማራጮች</translation>
@@ -5050,6 +5059,7 @@
 <translation id="5834581999798853053"><ph name="TIME" /> ደቂቃዎች አካባቢ ቀርቷል</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - ካሜራ ወይም ማይክራፎን በመቅረጽ ላይ ነው</translation>
 <translation id="583673505367439042">ጣቢያዎች በመሣሪያዎ ላይ ያሉ ፋይሎችን እና አቃፊዎችን ለማርትዕ መጠየቅ ይችላሉ</translation>
+<translation id="5836999627049108525">የሚተረጎመው ቋንቋ</translation>
 <translation id="583756221537636748">መያዣ</translation>
 <translation id="5840658767386246331">በGoogle ፈልግ</translation>
 <translation id="5840680448799937675">ፋይሎች ሁልጊዜ ከመስመር ውጭ ይጋራሉ</translation>
@@ -5560,6 +5570,7 @@
 <translation id="6318944945640833942">አታሚን ፈልጎ ማግኘት አልተቻለም። እባክዎ የአታሚ አድራሻን እንደገና ያስገቡ።</translation>
 <translation id="6322370287306604163">በጣት አሻራዎ በፍጥነት ይክፈቱ</translation>
 <translation id="6322559670748154781">ይህ ፋይል በተለምዶ የሚወርድ አይደለም እና በላቀ ጥበቃ ታግዷል</translation>
+<translation id="6324083483652497048">እነዚህ ቅጥያዎች <ph name="ORIGIN" />ን እንዲያነቡ እና እንዲቀይሩ ለመፍቀድ ጠቅ ያድርጉ፦</translation>
 <translation id="6324916366299863871">አቋራጭን ያርትዑ</translation>
 <translation id="6325191661371220117">ራስ-አስጀምርን አሰናክል</translation>
 <translation id="6326175484149238433">ከChrome አስወግድ</translation>
@@ -6592,6 +6603,7 @@
 <translation id="7343372807593926528">እባክዎ ግብረመልስ ከመላክዎ በፊት ችግሩን ይግለጹ።</translation>
 <translation id="7344585835349671209">በመሣሪያዎ ላይ የኤችቲቲፒኤስ/ኤስኤስኤል የእውቅና ማረጋገጫዎችን ያስተዳድሩ</translation>
 <translation id="7345706641791090287">የይለፍ ቃልዎን ያረጋግጡ</translation>
+<translation id="7345919885156673810">ምርጫው በ<ph name="LANGUAGE" /> አይደለም</translation>
 <translation id="7346909386216857016">እሺ፣ ገባኝ</translation>
 <translation id="7347452120014970266">ይህ በ<ph name="ORIGIN_NAME" /> እና የተጫኑ መተግበሪያዎች የተከማቹ ሁሉንም ውሂብ እና ኩኪዎች ያጠፋል።</translation>
 <translation id="7347751611463936647">ይህንን ቅጥያ ለመጠቀም «<ph name="EXTENSION_KEYWORD" />» ብለው፣ ከዚያ TAB፣ ከዚያ ትዕዛዝዎን ወይም ፍለጋዎን ይተይቡ።</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index 2bb1c72..0eb462c 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -279,6 +279,7 @@
 <translation id="125220115284141797">تلقائي</translation>
 <translation id="1252987234827889034">حدث خطأ في الملف الشخصي</translation>
 <translation id="1254593899333212300">اتصال مباشر بالإنترنت</translation>
+<translation id="1257336506558170607">تصدير الشهادة التي تم اختيارها</translation>
 <translation id="1258491128795710625">الميزات الجديدة</translation>
 <translation id="1259152067760398571">تم تفعيل ميزة "تأكيد السلامة" أمس.</translation>
 <translation id="1260451001046713751">السماح دائمًا بعرض النوافذ المنبثقة وعمليات إعادة التوجيه من الموقع <ph name="HOST" /></translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb
index 5195086..51dcdfd3 100644
--- a/chrome/app/resources/generated_resources_az.xtb
+++ b/chrome/app/resources/generated_resources_az.xtb
@@ -273,6 +273,7 @@
 <translation id="125220115284141797">Defolt</translation>
 <translation id="1252987234827889034">Profil xətası baş verdi</translation>
 <translation id="1254593899333212300">Birbaşa İnternet bağlantısı</translation>
+<translation id="1257336506558170607">Seçilmiş sertifikatı eksport edin</translation>
 <translation id="1258491128795710625">Yeniliklər</translation>
 <translation id="1259152067760398571">Təhlükəsizlik yoxlanışı dünən icra olunub</translation>
 <translation id="1260451001046713751"><ph name="HOST" /> popap və yönləndirmələrinə daima icazə verin</translation>
@@ -322,6 +323,7 @@
 <translation id="1307165550267142340">PIN yaradıldı</translation>
 <translation id="1307431692088049276">Daha məndən soruşmayın</translation>
 <translation id="1307559529304613120">Sistem bu cihaz üçün uzunmüddətli API girişini saxlaya bilmədi.</translation>
+<translation id="1312811472299082263">Ansible Təlimat Kitabçası və ya Crostini yedək faylından yaradın</translation>
 <translation id="1313405956111467313">Avtomatik proksi sazlama</translation>
 <translation id="131364520783682672">Böyük Hərf rejimi</translation>
 <translation id="1313660246522271310">Açıq tablardakılar daxil olmaqla, bütün saytlardan çıxacaqsınız</translation>
@@ -1093,6 +1095,7 @@
 <translation id="2028449514182362831">Hərəkət sensoru tələb edən xüsusiyyətlər işləməyəcək</translation>
 <translation id="202918510990975568">Təhlükəsizliyi və girişi konfiqurasiya etmək üçün parolunuzu daxil edin</translation>
 <translation id="2030455719695904263">Trekped</translation>
+<translation id="2031385797619033640"><ph name="EXTENSIONS_REQUESTING_ACCESS" /> artırmalarına <ph name="ORIGIN" /> saytını oxumaq və ya dəyişmək icazəsi vermək üçün klikləyin:</translation>
 <translation id="2031639749079821948">Parolunuz Google Hesabınızda saxlanılıb</translation>
 <translation id="2031914984822377766">Tərcih etdiyiniz <ph name="LINK_BEGIN" />vebsayt dillərini<ph name="LINK_END" /> əlavə edin. Siyahıda ilk sıradakı dil tərcümələr üçün istifadə olunacaq.</translation>
 <translation id="2033758234986231162">Telefonunuzla bağlantı qurmaq mümkün deyil. Telefonunuzun yaxınlıqda olduğuna, kiliddən çıxarılmış olduğuna, Bluetooth və Wi-Fi'ın aktiv olduğuna əmin olun.</translation>
@@ -1452,6 +1455,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" /> tətbiqindən istifadə etmək üçün cihazı yenidən başladın.</translation>
 <translation id="2328636661627946415">Anonim rejimdə olduğunuz zaman saytlar öz saytlarında baxış fəaliyyətinizi görmək üçün yalnız kukilərdən istifadə edə bilər. Kukilər Anonim sessiyanın sonunda silinir.</translation>
 <translation id="2329597144923131178">Bütün cihazlarınızda əlfəcin, tarixçə, parol və digər ayarları əldə etmək üçün daxil olun.</translation>
+<translation id="2332115969598251205"><ph name="PRIMARY_EMAIL" /> hesabında saxlanmış cihazları yükləmək olmur. İnternet bağlantınızı yoxlayın və yenidən cəhd edin.</translation>
 <translation id="2332131598580221120">Marketdə baxın</translation>
 <translation id="2332192922827071008">Tərcihləri Açın</translation>
 <translation id="2332515770639153015">Qabaqcıl Güvənli Baxış aktivdir</translation>
@@ -1895,6 +1899,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Qrammatikanı Orfoqrafiya ilə yoxlayın</translation>
 <translation id="2753677631968972007">Sayt icazələrini əl ilə idarə edin.</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" /> hesabında saxlanmış Sürətli Birləşdirmə cihazları axtarılır</translation>
 <translation id="2754825024506485820">Məhsuldarlıqdan tutmuş əyləncəyə qədər sizə lazım olan tətbiqləri Google Play Marketdə tapa bilərsiniz. İstənilən vaxt tətbiqləri quraşdıra bilərsiniz.</translation>
 <translation id="2755349111255270002">Bu <ph name="DEVICE_TYPE" /> cihazını sıfırlayın</translation>
 <translation id="2755367719610958252">Əlçatımlılıq funksiyalarını idarə edin</translation>
@@ -2110,6 +2115,7 @@
 <translation id="2942279350258725020">Android Mesaj</translation>
 <translation id="2942560570858569904">Gözlənilir...</translation>
 <translation id="2942581856830209953">Bu səhifəni fərdiləşdirin</translation>
+<translation id="2943268899142471972">Ansible Təlimat Kitabçası və ya Crostini yedək faylını seçin</translation>
 <translation id="2944060181911631861">İstifadə və diaqnostika datasını göndərin. Google'a diaqnostika, cihaz və tətbiq istifadə datasını avtomatik göndərməklə Android təcrübəsini təkmilləşdirin. Bu, sistem və tətbiq sabitliyi və digər təkmilləşdirmələrə kömək edəcək. Ümumi data, həmçinin, Google tətbiqləri və Android developerləri kimi partnyorlara kömək edəcək. Əlavə Veb və Tətbiq Fəaliyyəti ayarı aktiv edilərsə, bu data Google hesabında yadda saxlana bilər. <ph name="BEGIN_LINK1" />Ətraflı Məlumat<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Fayllara keçin</translation>
 <translation id="2946119680249604491">Bağlantı əlavə edin</translation>
@@ -2950,6 +2956,7 @@
 <translation id="3784472333786002075">Kukilər vebsaytların yaratdığı fayllardır. İki növ kuki var: Birinci tərəf kukilər ziyarət etdiyiniz sayt tərəfindən yaradılır. Sayt ünvan panelində göstərilir. Üçüncü tərəf kukilər başqa saytlar tərəfindən yaradılır. Bu saytlar ziyarət etdiyiniz vebsaytda gördüyünüz reklam və ya şəkillər kimi bəzi məzmunun sahibidir.</translation>
 <translation id="3785308913036335955">Tətbiqlərin qısayollarını göstərin</translation>
 <translation id="3785727820640310185">Bu sayt üçün yadda saxlanmış parollar</translation>
+<translation id="3787434344076711519">Tərcümə gözlənilir</translation>
 <translation id="3788301286821743879">Köşk tətbiqini işə salmaq mümkün olmadı.</translation>
 <translation id="3788331399335602504">bu fayllar</translation>
 <translation id="3788401245189148511">Edə bilərdi:</translation>
@@ -3233,6 +3240,7 @@
 <translation id="4036778507053569103">Serverdən endirilmiş qayda yanlışdır.</translation>
 <translation id="4037084878352560732">At</translation>
 <translation id="403725336528835653">Bunu birinci sınayın</translation>
+<translation id="4040041015953651705">Bu dildən tərcümə edin:</translation>
 <translation id="4040105702484676956"><ph name="SITE_NAME" /> və ona bağlı quraşdırılmış tətbiq üçün sayt datası və icazələr silinsin?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Səhifədən Çıxın}other{Səhifələrdən Çıxın}}</translation>
 <translation id="4043267180218562935">Kursor ölçüsü</translation>
@@ -4036,6 +4044,7 @@
 <translation id="4838170306476614339">Telefonunuzun fotolarına, mediasına və bildirişlərinə baxın</translation>
 <translation id="4838836835474292213">Buferdəki konteti oxumaq üçün girişə icazə verildi</translation>
 <translation id="4838907349371614303">Parol yeniləndi</translation>
+<translation id="4838958829619609362">Seçim <ph name="LANGUAGE" /> dilində deyil</translation>
 <translation id="4839303808932127586">Videonun saxlanma formatı:</translation>
 <translation id="4840096453115567876">İstənilən halda Anonim rejimdən çıxılsın?</translation>
 <translation id="4841741146571978176">Tələb edilən virtual cihaz mövcud deyil. Davam etmək üçün <ph name="VM_TYPE" /> ayarlayın</translation>
@@ -4807,6 +4816,7 @@
 <translation id="558918721941304263">Tətbiqlər yüklənir...</translation>
 <translation id="5590418976913374224">Cihaz işə salındıqda səs oxudulsun</translation>
 <translation id="5592595402373377407">Kifayət qədər əlçatan məlumat hələ yoxdur.</translation>
+<translation id="5594899180331219722">Fayl seçin</translation>
 <translation id="5595307023264033512">Saytlar tərəfindən istifadə olunan cəmi yaddaş: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Ünvana düzəliş edin</translation>
 <translation id="5596627076506792578">Əlavə seçimlər</translation>
@@ -5039,6 +5049,7 @@
 <translation id="5834581999798853053">Təxminən <ph name="TIME" /> dəqiqə qaldı</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - Kamera və ya mikrofon qeydə alması</translation>
 <translation id="583673505367439042">Saytlar cihazınızdakı faylları və qovluqları redaktə etmək üçün icazə istəyə bilər</translation>
+<translation id="5836999627049108525">Bu Dildən Tərcümə edin:</translation>
 <translation id="583756221537636748">Qutu</translation>
 <translation id="5840658767386246331">Google ilə axtarış</translation>
 <translation id="5840680448799937675">Fayllar həmişə oflayn paylaşılacaq</translation>
@@ -5547,6 +5558,7 @@
 <translation id="6318944945640833942">Printer aşkarlanmadı. Printer ünvanını yenidən daxil edin.</translation>
 <translation id="6322370287306604163">Barmaq izi ilə daha sürətli kiliddən çıxarın</translation>
 <translation id="6322559670748154781">Bu fayl tez-tez endirilmədiyinə görə Qabaqcıl Qoruma tərəfindən bloklanıb.</translation>
+<translation id="6324083483652497048">Bu artırmalara <ph name="ORIGIN" /> saytını oxumaq və ya dəyişmək icazəsi vermək üçün klikləyin:</translation>
 <translation id="6324916366299863871">Qısayola düzəliş edin</translation>
 <translation id="6325191661371220117">Avtomatik başlatmanı deaktiv edin</translation>
 <translation id="6326175484149238433">Chrome'dan silin</translation>
@@ -6577,6 +6589,7 @@
 <translation id="7343372807593926528">Rəy göndərməzdən əvvəl problemi təsvir edin.</translation>
 <translation id="7344585835349671209">Cihazınızda HTTPS/SSL sertifikatlarını idarə edin</translation>
 <translation id="7345706641791090287">Parolunuzu təsdiq edin</translation>
+<translation id="7345919885156673810">Seçim <ph name="LANGUAGE" /> Dilində Deyil</translation>
 <translation id="7346909386216857016">Ok, anladım</translation>
 <translation id="7347452120014970266">Bununla <ph name="ORIGIN_NAME" /> tərəfindən saxlanılan bütün data, kukilər və orada quraşdırılmış tətbiqlər silinəcək</translation>
 <translation id="7347751611463936647">Bu artırmanı istifadə etmək üçün "<ph name="EXTENSION_KEYWORD" />", sonra TAB, daha sonra isə əmr və ya axtarışınızı daxil edin.</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index f45ed22..c28c746 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -326,6 +326,7 @@
 <translation id="1307165550267142340">ПИН кодът ви бе създаден</translation>
 <translation id="1307431692088049276">Не ме питайте отново</translation>
 <translation id="1307559529304613120">Ами сега!  Системата не успя да съхрани дългосрочното означение за достъп на това устройство до приложния програмен интерфейс (API).</translation>
+<translation id="1312811472299082263">Създаване от наръчник за Ansible или файл с резервно копие в Crostini</translation>
 <translation id="1313405956111467313">Автоматична конфигурация на прокси сървър</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Ще излезете от профила си във всички сайтове, включително в отворените раздели</translation>
@@ -1105,6 +1106,7 @@
 <translation id="2028449514182362831">Функциите, които изискват достъп до сензорите за движение, няма да работят</translation>
 <translation id="202918510990975568">Въведете паролата си, за да конфигурирате функциите за сигурност и влизане в профила</translation>
 <translation id="2030455719695904263">Тракпад</translation>
+<translation id="2031385797619033640">Кликнете, за да разрешите на <ph name="EXTENSIONS_REQUESTING_ACCESS" /> да чете и променя данните на <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Паролата ви е запазена в профила ви в Google</translation>
 <translation id="2031914984822377766">Добавете предпочитаните от вас <ph name="LINK_BEGIN" />езици за уебсайтове<ph name="LINK_END" />. Най-горният език в списъка ще се използва за преводи.</translation>
 <translation id="2033758234986231162">Не може да се поддържа връзка с телефона ви. Той трябва да е наблизо, да е отключен и с включени функции за Bluetooth и Wi-Fi.</translation>
@@ -1464,6 +1466,7 @@
 <translation id="2328561734797404498">Рестартирайте устройството си, за да използвате <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Когато сте в режим „инкогнито“, сайтовете могат да ползват „бисквитки“, за да следят активността ви при сърфиране само в собствените си уеб страници. „Бисквитките“ ще се изтриват в края на сесията в режим „инкогнито“.</translation>
 <translation id="2329597144923131178">Влезте в профила си и получете своите отметки, история, пароли и др. настройки на всички у-ва.</translation>
+<translation id="2332115969598251205">Устройствата, запазени в(ъв) <ph name="PRIMARY_EMAIL" />, не могат да се заредят. Проверете връзката си с интернет и опитайте отново.</translation>
 <translation id="2332131598580221120">Преглед в магазина</translation>
 <translation id="2332192922827071008">Отваряне на предпочитанията</translation>
 <translation id="2332515770639153015">Функцията за подобрена защита от Безопасно сърфиране е включена</translation>
@@ -1907,6 +1910,7 @@
 <translation id="2749836841884031656">SIM карта</translation>
 <translation id="2749881179542288782">Проверка на граматиката заедно с правописа</translation>
 <translation id="2753677631968972007">Ръчно контролиране на разрешенията за сайтовете.</translation>
+<translation id="2754226775788136540">Търсят се устройства за бързо сдвояване, запазени в(ъв) <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">От приложения за продуктивност до такива за развлечение – намерете тези, от които имате нужда, в Google Play Магазин. Можете да инсталирате приложения по всяко време.</translation>
 <translation id="2755349111255270002">Нулирайте настройките на <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Управление на функциите за достъпност</translation>
@@ -2122,6 +2126,7 @@
 <translation id="2942279350258725020">Android Messages</translation>
 <translation id="2942560570858569904">Изчаква се...</translation>
 <translation id="2942581856830209953">Персонализиране на тази страница</translation>
+<translation id="2943268899142471972">Избиране на наръчник за Ansible или файл с резервно копие в Crostini</translation>
 <translation id="2944060181911631861">Изпращане на данни за употребата и диагностиката. Помогнете за подобряването на работата си с Android, като автоматично изпращате до Google диагностична информация и данни за употребата на устройството и приложенията. Това ще послужи за подобряване на стабилността на системата и приложенията и др. Някои обобщени данни също така ще подпомогнат приложенията и партньорите на Google, напр. програмистите за Android. Ако настройката „Допълнителна активност в мрежата и приложенията“ е включена за вас, тези данни може да се запазват в профила ви в Google. <ph name="BEGIN_LINK1" />Научете повече<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Към файловете</translation>
 <translation id="2946119680249604491">Добавяне на връзка</translation>
@@ -2962,6 +2967,7 @@
 <translation id="3784472333786002075">„Бисквитките“ са файлове, създавани от уебсайтовете. Има два типа „бисквитки“: тези на посещавания домейн се създават от сайта, който преглеждате. Той се показва в адресната лента. „Бисквитките“ на трети страни се създават от други сайтове. Те притежават част от съдържанието, като например реклами или изображения, което виждате на посетения от вас уебсайт.</translation>
 <translation id="3785308913036335955">Показване на прекия път към приложенията</translation>
 <translation id="3785727820640310185">Запазени пароли за този сайт</translation>
+<translation id="3787434344076711519">Изчаква се превод</translation>
 <translation id="3788301286821743879">Неуспешно стартиране на павилионното приложение.</translation>
 <translation id="3788331399335602504">тези файлове</translation>
 <translation id="3788401245189148511">То би имало възможност за:</translation>
@@ -3246,6 +3252,7 @@
 <translation id="4036778507053569103">Изтегленото от сървъра правило е невалидно.</translation>
 <translation id="4037084878352560732">Кон</translation>
 <translation id="403725336528835653">Изпробване</translation>
+<translation id="4040041015953651705">Изходен език</translation>
 <translation id="4040105702484676956">Да се изчистят ли данните за сайтовете и разрешенията за <ph name="SITE_NAME" /> и инсталираното за този сайт приложение?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Изход от страницата}other{Изход от страниците}}</translation>
 <translation id="4043267180218562935">Размер на курсора</translation>
@@ -4052,6 +4059,7 @@
 <translation id="4838170306476614339">Преглед на снимките, мултимедийните файлове и известията на телефона ви</translation>
 <translation id="4838836835474292213">Разрешен е достъп за четене на съдържанието на буферната памет</translation>
 <translation id="4838907349371614303">Паролата е актуализирана</translation>
+<translation id="4838958829619609362">Избраното не е на <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">&amp;Запазване на видеоклипа като...</translation>
 <translation id="4840096453115567876">Да се излезе ли от режим „инкогнито“ въпреки това?</translation>
 <translation id="4841741146571978176">Не съществува задължителна виртуална машина. За да продължите, настройте <ph name="VM_TYPE" /></translation>
@@ -4823,6 +4831,7 @@
 <translation id="558918721941304263">Приложенията се зареждат...</translation>
 <translation id="5590418976913374224">Възпроизвеждане на звук при стартиране на устройството</translation>
 <translation id="5592595402373377407">Още не са налице достатъчно данни.</translation>
+<translation id="5594899180331219722">Избиране на файл</translation>
 <translation id="5595307023264033512">Общо хранилище, използвано от сайтовете: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Редактиране на адреса</translation>
 <translation id="5596627076506792578">Още опции</translation>
@@ -5056,6 +5065,7 @@
 <translation id="5834581999798853053">Остават около <ph name="TIME" /> минути</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – записва се чрез камерата или микрофона</translation>
 <translation id="583673505367439042">Сайтовете могат да извеждат запитвания за редактиране на файловете и папките на устройството ви</translation>
+<translation id="5836999627049108525">Изходен език</translation>
 <translation id="583756221537636748">Кутия</translation>
 <translation id="5840658767386246331">Търсене с Google</translation>
 <translation id="5840680448799937675">Файловете винаги ще се споделят офлайн</translation>
@@ -5566,6 +5576,7 @@
 <translation id="6318944945640833942">Принтерът не бе открит. Моля, въведете отново адреса му.</translation>
 <translation id="6322370287306604163">По-бързо отключване с отпечатък</translation>
 <translation id="6322559670748154781">Този файл обикновено не се изтегля и бе блокиран от „Разширена защита“</translation>
+<translation id="6324083483652497048">Кликнете, за да разрешите на тези разширения да четат и променят данните на <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Редактиране на прекия път</translation>
 <translation id="6325191661371220117">Деактивиране на автоматичното стартиране</translation>
 <translation id="6326175484149238433">Премахване от Chrome</translation>
@@ -6596,6 +6607,7 @@
 <translation id="7343372807593926528">Моля, опишете проблема, преди да изпратите отзивите</translation>
 <translation id="7344585835349671209">Управление на HTTPS/SSL сертификатите на устройството ви</translation>
 <translation id="7345706641791090287">Потвърждаване на паролата</translation>
+<translation id="7345919885156673810">Избраното не е на <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Добре, разбрах</translation>
 <translation id="7347452120014970266">Всички данни и „бисквитки“, съхранявани от <ph name="ORIGIN_NAME" /> и инсталираните приложения, ще бъдат изчистени</translation>
 <translation id="7347751611463936647">За да използвате това разширение, въведете „<ph name="EXTENSION_KEYWORD" />“, след това натиснете „Tab“, след което въведете своята команда или търсене.</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb
index cc959afe..d791d98 100644
--- a/chrome/app/resources/generated_resources_bs.xtb
+++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Nešto nije uredu. Moguće da je Linux samo djelimično nadograđen. Više informacija potražite u zapisnicima. Zapisnici su sačuvani u Fajlovima &gt; Moji fajlovi &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Obrisati i podatke iz ovih aplikacija?</translation>
 <translation id="1043824690776631483">Treba vam odobrenje da posjetite ovu web lokaciju. Može imati neprimjeren sadržaj.</translation>
+<translation id="104419033123549300">Stil karte tipkovnice</translation>
 <translation id="104710386808485638">Ponovno pokrenuti Linux?</translation>
 <translation id="1047431265488717055">Kopiraj tekst linka</translation>
 <translation id="1048286738600630630">Ekrani</translation>
@@ -782,6 +783,7 @@
 <translation id="1721312023322545264">Da pristupite ovoj web lokaciji potrebna vam je dozvola osobe <ph name="NAME" /></translation>
 <translation id="1722460139690167654">Uređajem <ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" /> upravlja<ph name="END_LINK" /> <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Novi prozor</translation>
+<translation id="1724801751621173132">Način unosa</translation>
 <translation id="1725562816265788801">Klizanje po karticama</translation>
 <translation id="1729533290416704613">Također kontrolira koja stranica se prikazuje prilikom pretraživanja iz višenamjenskog okvira.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Da uklonite aplikacije, idite u Postavke &gt; Google Play trgovina &gt; Upravljanje postavkama za Android &gt; Aplikacije ili Upravitelj aplikacija. Zatim dodirnite aplikaciju koju želite deinstalirati (možda ćete morati prevući desno ili lijevo kako biste pronašli aplikaciju). Zatim dodirnite Deinstaliraj ili Onemogući.<ph name="END_PARAGRAPH1" /></translation>
@@ -1966,6 +1968,7 @@
 <translation id="2796740370559399562">Nastavi dopuštati kolačiće</translation>
 <translation id="2798347533012571708">Zadrži ažuriranja</translation>
 <translation id="2799223571221894425">Ponovo pokreni</translation>
+<translation id="2800309299477632167">Prilagođena karta tipkovnice</translation>
 <translation id="2800760947029405028">Otpremite sliku</translation>
 <translation id="2801954693771979815">Veličina ekrana</translation>
 <translation id="2802557211515765772">Nema upravljanih štampača.</translation>
@@ -2027,6 +2030,7 @@
 <translation id="2849767214114481738">PIN je dodan</translation>
 <translation id="2849936225196189499">Kritična</translation>
 <translation id="2850541429955027218">Dodaj temu</translation>
+<translation id="2850672011315104382">Stil interpunkcije</translation>
 <translation id="2851634818064021665">Treba vam odobrenje za posjetu ovoj web lokaciji</translation>
 <translation id="2851728849045278002">Nešto nije uredu. Kliknite za više detalja.</translation>
 <translation id="2852385257476173980">Lista lokacija koje posjećujete se može pojaviti ovdje dok pregledate web</translation>
@@ -2523,6 +2527,7 @@
 <translation id="3359256513598016054">Ograničenja pravila za potvrdu</translation>
 <translation id="3360297538363969800">Štampanje nije uspjelo. Provjerite štampač i pokušajte ponovo.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}one{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}few{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" />s vama.}other{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}}</translation>
+<translation id="3361954577771524115">Iz aplikacije</translation>
 <translation id="3363202073972776113">Ovim novim profilom će upravljati vaša organizacija. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Od vašeg administratora: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Koristite Ctrl ili Alt</translation>
@@ -3047,6 +3052,7 @@
 <translation id="3848547754896969219">Otvori u &amp;anonimnom prozoru</translation>
 <translation id="385051799172605136">Nazad</translation>
 <translation id="3851428669031642514">Učitaj nesigurne skripte</translation>
+<translation id="3852215160863921508">Pomoć prilikom unosa</translation>
 <translation id="3854599674806204102">Izaberite opciju</translation>
 <translation id="3854967233147778866">Ponudi prevođenje web lokacija na drugim jezicima</translation>
 <translation id="3854976556788175030">Ladica za izlaz papira je puna</translation>
@@ -3283,6 +3289,7 @@
 <translation id="4062561150282203854">Sinhronizirajte aplikacije, postavke i ostali sadržaj uređaja <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Mreža koju koristite (<ph name="NETWORK_ID" />) može zahtijevati da posjetite stranicu za prijavu.</translation>
 <translation id="4066207411788646768">Provjerite vezu da vidite dostupne štampače na svojoj mreži</translation>
+<translation id="4066945815577305767">Zaporke su istekle</translation>
 <translation id="4068776064906523561">Sačuvani otisci prstiju</translation>
 <translation id="407173827865827707">Na klik</translation>
 <translation id="4072701974556190758">Lozinka će se sačuvati na vaš Google račun, <ph name="ACCOUNT" />. Nećete je morati zapamtiti.</translation>
@@ -3804,6 +3811,7 @@
 <translation id="4579453506923101210">Zaboravite povezani telefon</translation>
 <translation id="4579581181964204535">Nije moguće emitirati host računar <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Obavještenja preglednika potražite u <ph name="LINK_BEGIN" />Postavkama preglednika Chrome<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Ponovo se prijavite na Google upravitelj zaporki</translation>
 <translation id="4580596421317071374">Lozinke se pohranjuju u aplikaciji <ph name="GOOGLE_PASSWORD_MANAGER" /> na ovom uređaju.</translation>
 <translation id="4580626299762849806">Nije moguće uvesti lozinke. Provjerite fajl <ph name="FILENAME" /> i provjerite je li pravilno formatiran.</translation>
 <translation id="4581774856936278355">Greška prilikom vraćanja Linuxa</translation>
@@ -4485,6 +4493,7 @@
 <translation id="5268373933383932086">Vaša stranica, na vaš način</translation>
 <translation id="5269977353971873915">Štampanje nije uspjelo</translation>
 <translation id="5273806377963980154">Uredite URL web lokacije</translation>
+<translation id="5275084684151588738">Korisnički rječnici</translation>
 <translation id="5275338516105640560">Dugme sačuvane grupe kartica</translation>
 <translation id="5275352920323889391">Pas</translation>
 <translation id="527605719918376753">Isključi zvuk kartice</translation>
@@ -4700,6 +4709,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN mora sadržavati najmanje jedan znak.}one{PIN mora sadržavati najmanje # znak.}few{PIN mora sadržavati najmanje # znaka.}other{PIN mora sadržavati najmanje # znakova.}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> zahtijeva da se sada povežete s WiFi mrežom i preuzmete ažuriranje. Možete ga preuzeti i putem veze s naplatom (mogu nastati troškovi).</translation>
 <translation id="5481273127572794904">Nije dozvoljeno automatsko preuzimanje više fajlova</translation>
+<translation id="5481755802440890178">Trenutačno nije moguće prevesti odabir</translation>
 <translation id="5481941284378890518">Dodaj štampače u blizini</translation>
 <translation id="5483785310822538350">Opozovi pristup fajlu i uređaju</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{Domena <ph name="MANAGER" /> zahtijeva da napravite sigurnosnu kopiju podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> danas. <ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}one{Domena <ph name="MANAGER" /> zahtijeva da napravite sigurnosnu kopiju podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana. <ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}few{Domena <ph name="MANAGER" /> zahtijeva da napravite sigurnosnu kopiju podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana. <ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}other{Domena <ph name="MANAGER" /> zahtijeva da napravite sigurnosnu kopiju podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana. <ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}}</translation>
@@ -4932,6 +4942,7 @@
 <translation id="5696143504434933566">Prijavi zloupotrebu s ekstenzije "<ph name="EXTENSION_NAME" />"</translation>
 <translation id="5696679855467848181">Trenutno se koristi PPD fajl: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Izbornik emoji sličica</translation>
+<translation id="5698462638680260399">Prijavite se da biste upotrebljavali zaporke</translation>
 <translation id="570043786759263127">Aplikacije i usluge Google Playa</translation>
 <translation id="5700836101007545240">Administrator je onemogućio opciju Dodaj vezu</translation>
 <translation id="5701080607174488915">Greška pri preuzimanju pravila sa servera.</translation>
@@ -4949,6 +4960,7 @@
 <translation id="5712153969432126546">Web lokacije ponekad objavljuju PDF-ove, kao što su dokumenti, ugovori i obrasci</translation>
 <translation id="571222594670061844">Web lokacije vam mogu prikazati upite za prijavu koji potiču od usluga identiteta</translation>
 <translation id="5713158217420111469">Povezano je s uređajem <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Stil unosa razmaka</translation>
 <translation id="5715711091495208045">Posrednik dodatka: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Zadani pretraživači</translation>
 <translation id="5719854774000914513">Web lokacije mogu tražiti da se povežu s HID uređajima</translation>
@@ -5590,6 +5602,7 @@
 <translation id="6335920438823100346">Da pokrenete Linux, <ph name="MANAGER" /> zahtijeva da napravite sigurnosnu kopiju podataka i vratite ovaj Chromebook na fabričke postavke.</translation>
 <translation id="6336038146639916978">Domena <ph name="MANAGER" /> je onemogućila otklanjanje grešaka putem ADB-a. Ovim će se <ph name="DEVICE_TYPE" /> vratiti na zadano za 24 sata. Napravite kopiju svih fajlova koje želite sačuvati.</translation>
 <translation id="6338402296920404442">Razmislite o brisanju <ph name="FILENAME" />, tako da drugi koji koriste ovaj uređaj ne mogu vidjeti vaše lozinke.</translation>
+<translation id="6338968693068997776">Dodavanje USB uređaja</translation>
 <translation id="6338981933082930623">Sve web lokacije vam mogu prikazivati bilo koje oglase</translation>
 <translation id="6339668969738228384">Kreirajte novi profil za <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Internetski protokol za štampanje (IPPP)</translation>
@@ -6191,6 +6204,7 @@
 <translation id="6903907808598579934">Uključi sinhronizaciju</translation>
 <translation id="6904344821472985372">Opozovi pristup fajlu</translation>
 <translation id="6904655473976120856">Pritisnite dugme za aplikaciju da izađete</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon jedne minute neaktivnosti}one{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}few{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}other{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}}</translation>
 <translation id="6909422577741440844">Primati s ovog uređaja?</translation>
 <translation id="6910211073230771657">Izbrisano</translation>
 <translation id="691106080621596509">Ovim će se obrisati svi podaci i kolačići koje je pohranila web lokacija <ph name="SITE_GROUP_NAME" />, sve povezane web lokacije i njena instalirana aplikacija</translation>
@@ -6375,6 +6389,7 @@
 <translation id="7069811530847688087">Web lokacija <ph name="WEBSITE" /> može tražiti noviju ili drugačiju vrstu sigurnosnog ključa</translation>
 <translation id="7070484045139057854">Ovo može čitati i mijenjati podatke na web lokaciji</translation>
 <translation id="7072010813301522126">Naziv prečice</translation>
+<translation id="7074066049407662839">Prijavite se da biste spremili zaporke</translation>
 <translation id="7075513071073410194">PKCS br. 1 MD5 sa RSA šifriranjem</translation>
 <translation id="7075625805486468288">Upravljajte HTTPS/SSL potvrdama i postavkama</translation>
 <translation id="7076875098323397992">Nije moguće pokrenuti nadogradnju</translation>
@@ -6906,6 +6921,7 @@
 <translation id="7625568159987162309">Pregledajte dopuštenja i podatke pohranjene na web-lokacijama</translation>
 <translation id="7625823789272218216">Nova kartica s lijeve strane</translation>
 <translation id="7628201176665550262">Brzina osvježavanja</translation>
+<translation id="7628392600831846024">Stil simbola</translation>
 <translation id="7629827748548208700">Kartica: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">Ovim uređajem upravlja <ph name="MANAGER" /> i morate se prijaviti svaki put.</translation>
 <translation id="7631014249255418691">Sigurnosna kopija za Linux aplikacije i fajlove je uspješno kreirana</translation>
@@ -8032,6 +8048,7 @@
 <translation id="8688672835843460752">Dostupno</translation>
 <translation id="8690129572193755009">Web lokacije mogu zatražiti da upravljaju protokolima</translation>
 <translation id="8692107307702113268">Lozinka sadržava više od 1000 znakova</translation>
+<translation id="8694596275649352090">Zaključaj tijekom mirovanja ili kad je poklopac zatvoren</translation>
 <translation id="8695139659682234808">Dodajte roditeljski nadzor nakon pokretanja</translation>
 <translation id="8695825812785969222">Otvori &amp;lokaciju...</translation>
 <translation id="8698269656364382265">Da se vratite na prethodni ekran, prevucite prstom slijeva nadesno.</translation>
@@ -8080,6 +8097,7 @@
 <translation id="8732844209475700754">Više postavki koje se odnose na privatnost, sigurnost i prikupljanje podataka</translation>
 <translation id="8734073480934656039">Ako omogućite ovu postavku, dozvolit ćete aplikacijama za kisok da se pokrenu automatski pri pokretanju uređaja.</translation>
 <translation id="8734674662128056360">Blokiranje kolačića trećih strana</translation>
+<translation id="8734755021067981851">Nije priključen nijedan USB uređaj.</translation>
 <translation id="873545264931343897">Kada <ph name="PLUGIN_NAME" /> završi ažuriranje, ponovo učitajte stranicu da ga aktivirate</translation>
 <translation id="8736288397686080465">Ova web lokacija je ažurirana u pozadini.</translation>
 <translation id="8737709691285775803">Shill</translation>
@@ -8206,6 +8224,7 @@
 <translation id="8850251000316748990">Pogledajte više...</translation>
 <translation id="885246833287407341">Argumenti API funkcije</translation>
 <translation id="8853586775156634952">Ova kartica će se sačuvati samo na ovaj uređaj</translation>
+<translation id="8854745870658584490">Prečac odabira</translation>
 <translation id="8855977033756560989">Ovaj Chromebook poslovni uređaj se isporučuje u paketu s nadogradnjom na poslovnu verziju Chromea. Da iskoristite prednosti poslovnih mogućnosti, prijavite uređaj pomoću računa Google administratora.</translation>
 <translation id="8856028055086294840">Vrati aplikacije i stranice</translation>
 <translation id="885701979325669005">Pohrana</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb
index c9b8ba0..114a59e 100644
--- a/chrome/app/resources/generated_resources_ca.xtb
+++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -324,6 +324,7 @@
 <translation id="1307165550267142340">El PIN s'ha creat</translation>
 <translation id="1307431692088049276">No m'ho tornis a preguntar</translation>
 <translation id="1307559529304613120">El sistema no ha pogut emmagatzemar un testimoni d'accés a l'API de llarg termini per a aquest dispositiu.</translation>
+<translation id="1312811472299082263">Crea a partir d'un manual d'estratègia d'Ansible o d'un fitxer de còpia de seguretat de Crostini</translation>
 <translation id="1313405956111467313">Configuració automàtica del servidor intermediari</translation>
 <translation id="131364520783682672">Bloq Maj</translation>
 <translation id="1313660246522271310">Se't tancarà la sessió de tots els llocs web, també de les pestanyes obertes</translation>
@@ -1097,6 +1098,7 @@
 <translation id="2028449514182362831">Les funcions que necessiten un sensor de moviment no funcionaran</translation>
 <translation id="202918510990975568">Introdueix la contrasenya per configurar la seguretat i l'inici de sessió</translation>
 <translation id="2030455719695904263">Ratolí tàctil</translation>
+<translation id="2031385797619033640">Fes clic per permetre que <ph name="EXTENSIONS_REQUESTING_ACCESS" /> llegeixi i canviï <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">S'ha desat la contrasenya al teu Compte de Google</translation>
 <translation id="2031914984822377766">Afegeix els teus <ph name="LINK_BEGIN" />idiomes preferits per als llocs web<ph name="LINK_END" />. S'utilitzarà el primer idioma de la llista per a les traduccions.</translation>
 <translation id="2033758234986231162">No es pot mantenir la connexió amb el teu telèfon. Comprova que sigui a prop teu, que estigui desbloquejat i que tingui el Bluetooth i la Wi-Fi activats.</translation>
@@ -1453,6 +1455,7 @@
 <translation id="2328561734797404498">Reinicia el dispositiu per utilitzar <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Quan estàs en mode d'incògnit, els llocs web només poden fer servir les galetes per veure la teva activitat de navegació en aquests mateixos llocs web. Les galetes se suprimeixen en finalitzar la sessió d'incògnit.</translation>
 <translation id="2329597144923131178">Inicieu la sessió per tenir adreces d'interès, historial, contrasenyes i altres opcions de configuració en tots els dispositius.</translation>
+<translation id="2332115969598251205">No es poden carregar els dispositius desats a <ph name="PRIMARY_EMAIL" />. Comprova la connexió a Internet i torna-ho a provar.</translation>
 <translation id="2332131598580221120">Mostra a la botiga</translation>
 <translation id="2332192922827071008">Obre les preferències</translation>
 <translation id="2332515770639153015">La funció Navegació segura millorada està activada</translation>
@@ -1896,6 +1899,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Comprova la gramàtica amb l'ortografia</translation>
 <translation id="2753677631968972007">Controla manualment els permisos dels llocs webs.</translation>
+<translation id="2754226775788136540">S'estan cercant els dispositius amb Vinculació ràpida desats a <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Troba a Google Play Store les aplicacions que necessites, des de solucions de productivitat fins a aplicacions d'entreteniment. Pots instal·lar-les en qualsevol moment.</translation>
 <translation id="2755349111255270002">Restableix aquest dispositiu <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Gestiona les funcions d'accessibilitat</translation>
@@ -2111,6 +2115,7 @@
 <translation id="2942279350258725020">Missatges Android</translation>
 <translation id="2942560570858569904">S'està esperant...</translation>
 <translation id="2942581856830209953">Personalitza aquesta pàgina</translation>
+<translation id="2943268899142471972">Selecciona un manual d'estratègia d'Ansible o un fitxer de còpia de seguretat de Crostini</translation>
 <translation id="2944060181911631861">Envia dades d'ús i de diagnòstic. Ajuda a millorar la teva experiència a Android enviant automàticament a Google dades de diagnòstic, del dispositiu i d'ús d'aplicacions. Aquestes dades ajudaran a millorar l'estabilitat del sistema i de les aplicacions, entre altres característiques. Una part de les dades agregades també serà útil per a les aplicacions i per als partners de Google, com ara els desenvolupadors d'Android. Si tens activada l'opció Activitat al web i en aplicacions addicional, és possible que aquestes dades es desin al teu Compte de Google. <ph name="BEGIN_LINK1" />Més informació<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Ves a Fitxers</translation>
 <translation id="2946119680249604491">Afegeix una connexió</translation>
@@ -2951,6 +2956,7 @@
 <translation id="3784472333786002075">Les galetes són fitxers que creen els llocs web. N'hi ha de dos tipus: les galetes pròpies són les que crea el lloc web que visites. El lloc web es mostra a la barra d'adreces. Les galetes de tercers són les que creen altres llocs web. Aquests llocs web són els propietaris de part del contingut que es mostra al lloc web que visites, com ara els anuncis o les imatges.</translation>
 <translation id="3785308913036335955">Mostra la drecera d'aplicacions</translation>
 <translation id="3785727820640310185">Contrasenyes desades per a aquest lloc web</translation>
+<translation id="3787434344076711519">S'està esperant la traducció</translation>
 <translation id="3788301286821743879">No s'ha pogut iniciar l'aplicació de quiosc.</translation>
 <translation id="3788331399335602504">aquests fitxers</translation>
 <translation id="3788401245189148511">Podria:</translation>
@@ -3233,6 +3239,7 @@
 <translation id="4036778507053569103">La política que s'ha baixat del servidor no és vàlida.</translation>
 <translation id="4037084878352560732">Cavall</translation>
 <translation id="403725336528835653">Prova-ho primer</translation>
+<translation id="4040041015953651705">Idioma de partida de la traducció</translation>
 <translation id="4040105702484676956">Vols esborrar les dades i els permisos del lloc web <ph name="SITE_NAME" /> i la seva aplicació instal·lada?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Surt de la pàgina}other{Surt de les pàgines}}</translation>
 <translation id="4043267180218562935">Mida del cursor</translation>
@@ -4038,6 +4045,7 @@
 <translation id="4838170306476614339">Mostra les fotos, els fitxers multimèdia i les notificacions del telèfon</translation>
 <translation id="4838836835474292213">S'ha permès l'accés de lectura al porta-retalls</translation>
 <translation id="4838907349371614303">S'ha actualitzat la contrasenya</translation>
+<translation id="4838958829619609362">La selecció no està en <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">De&amp;sa el vídeo com a...</translation>
 <translation id="4840096453115567876">Vols sortir del mode d'incògnit de totes maneres?</translation>
 <translation id="4841741146571978176">La màquina virtual necessària no existeix. Prova de configurar <ph name="VM_TYPE" /> per continuar.</translation>
@@ -4810,6 +4818,7 @@
 <translation id="558918721941304263">S'estan carregant les aplicacions...</translation>
 <translation id="5590418976913374224">Reprodueix un so en iniciar el dispositiu</translation>
 <translation id="5592595402373377407">Encara no hi ha prou dades disponibles.</translation>
+<translation id="5594899180331219722">Selecciona un fitxer</translation>
 <translation id="5595307023264033512">Emmagatzematge total utilitzat pels llocs web: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Edita l'adreça</translation>
 <translation id="5596627076506792578">Més opcions</translation>
@@ -5041,6 +5050,7 @@
 <translation id="5834581999798853053">Queda cosa de <ph name="TIME" /> minuts</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" />: la càmera o el micròfon estan enregistrant contingut</translation>
 <translation id="583673505367439042">Els llocs web poden demanar permís per editar fitxers i carpetes del dispositiu</translation>
+<translation id="5836999627049108525">Idioma de partida de la traducció</translation>
 <translation id="583756221537636748">Cas</translation>
 <translation id="5840658767386246331">Cerca amb Google</translation>
 <translation id="5840680448799937675">Els fitxers es compartiran sempre sense connexió</translation>
@@ -5550,6 +5560,7 @@
 <translation id="6318944945640833942">No es detecta cap impressora. Torna a introduir-ne l'adreça.</translation>
 <translation id="6322370287306604163">Desbloqueja el dispositiu més ràpidament amb l'empremta digital</translation>
 <translation id="6322559670748154781">Aquest fitxer no se sol baixar i la Protecció avançada l'ha bloquejat</translation>
+<translation id="6324083483652497048">Fes clic per permetre que aquestes extensions llegeixin i canviïn <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Edita la drecera</translation>
 <translation id="6325191661371220117">Desactiva l'inici automàtic</translation>
 <translation id="6326175484149238433">Suprimeix de Chrome</translation>
@@ -6580,6 +6591,7 @@
 <translation id="7343372807593926528">Descriu el problema abans d'enviar suggeriments.</translation>
 <translation id="7344585835349671209">Gestiona els certificats HTTPS/SSL al dispositiu</translation>
 <translation id="7345706641791090287">Confirma la contrasenya</translation>
+<translation id="7345919885156673810">La selecció no està en <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">D'acord</translation>
 <translation id="7347452120014970266">Amb aquesta acció s'esborraran totes les dades i galetes emmagatzemades per <ph name="ORIGIN_NAME" /> i per les seves aplicacions instal·lades</translation>
 <translation id="7347751611463936647">Per utilitzar aquesta extensió, escriviu "<ph name="EXTENSION_KEYWORD" />", premeu la tecla de tabulació i indiqueu l'ordre o la cerca.</translation>
diff --git a/chrome/app/resources/generated_resources_cy.xtb b/chrome/app/resources/generated_resources_cy.xtb
index c50d1bba..b05b8a61 100644
--- a/chrome/app/resources/generated_resources_cy.xtb
+++ b/chrome/app/resources/generated_resources_cy.xtb
@@ -281,6 +281,7 @@
 <translation id="125220115284141797">Diofyn</translation>
 <translation id="1252987234827889034">Bu gwall proffil</translation>
 <translation id="1254593899333212300">Cysylltiad Rhyngrwyd uniongyrchol</translation>
+<translation id="1257336506558170607">Allforio tystysgrif a ddewiswyd</translation>
 <translation id="1258491128795710625">Beth sy'n newydd</translation>
 <translation id="1259152067760398571">Cynhaliwyd gwiriad diogelwch ddoe</translation>
 <translation id="1260451001046713751">Caniatáu ffenestri naid ac ailgyfeiriadau gan <ph name="HOST" /> bob amser</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index 56350d8..bf2c8f8 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -328,6 +328,7 @@
 <translation id="1307165550267142340">Din pinkode blev oprettet</translation>
 <translation id="1307431692088049276">Spørg mig ikke igen</translation>
 <translation id="1307559529304613120">Ups! Systemet kunne ikke gemme det langfristede API-adgangstoken for denne enhed.</translation>
+<translation id="1312811472299082263">Opret via en Ansible Playbook eller en Crostini-backupfil</translation>
 <translation id="1313405956111467313">Automatisk proxykonfiguration</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Du logges ud af alle websites, også i åbne faner</translation>
@@ -1111,6 +1112,7 @@
 <translation id="2028449514182362831">Funktioner, der skal bruge bevægelsessensorer, fungerer ikke</translation>
 <translation id="202918510990975568">Angiv din adgangskode for at konfigurere sikkerhed og login</translation>
 <translation id="2030455719695904263">Touchplade</translation>
+<translation id="2031385797619033640">Klik for at tillade, at <ph name="EXTENSIONS_REQUESTING_ACCESS" /> læser og ændrer <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Din adgangskode er gemt på din Google-konto</translation>
 <translation id="2031914984822377766">Tilføj dine foretrukne <ph name="LINK_BEGIN" />sprog for websites<ph name="LINK_END" />. De øverste sprog på listen anvendes til oversættelser.</translation>
 <translation id="2033758234986231162">Forbindelsen til din telefon kan ikke opretholdes. Sørg for, at din telefon er i nærheden og låst op, og at Bluetooth og Wi-Fi er aktiveret.</translation>
@@ -1470,6 +1472,7 @@
 <translation id="2328561734797404498">Genstart enheden for at bruge <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Når du er i inkognitotilstand, kan websites kun bruge cookies til at se din browseraktivitet på deres eget website. Cookies slettes, når inkognitosessionen afsluttes.</translation>
 <translation id="2329597144923131178">Log ind for at hente bogmærker, historik, adgangskoder og andre indstillinger på alle dine enheder.</translation>
+<translation id="2332115969598251205">Enheder, som er gemt på <ph name="PRIMARY_EMAIL" />, kan ikke indlæses. Tjek din internetforbindelse, og prøv igen.</translation>
 <translation id="2332131598580221120">Vis i Webshop</translation>
 <translation id="2332192922827071008">Åbn præferencer</translation>
 <translation id="2332515770639153015">Udvidet beskyttet browsing er aktiveret</translation>
@@ -1913,6 +1916,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Kontrollér grammatik med stavning</translation>
 <translation id="2753677631968972007">Styr websitetilladelser manuelt</translation>
+<translation id="2754226775788136540">Søger efter enheder med Hurtig parring, der er gemt på <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Find de apps, du skal bruge, f.eks. produktivitetsapps eller apps til underholdning, i Google Play Butik. Du kan til enhver tid installere apps.</translation>
 <translation id="2755349111255270002">Nulstil denne <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Administrer hjælpefunktioner</translation>
@@ -2128,6 +2132,7 @@
 <translation id="2942279350258725020">Beskeder i Android</translation>
 <translation id="2942560570858569904">Venter...</translation>
 <translation id="2942581856830209953">Tilpas denne side</translation>
+<translation id="2943268899142471972">Vælg en Ansible Playbook eller Crostini-backupfil</translation>
 <translation id="2944060181911631861">Send brugs- og diagnosticeringsdata. Hjælp med at forbedre din Android-oplevelse ved automatisk at sende diagnosticerings- og enhedsdata samt data om brug af apps til Google. Dataene bruges til forbedring af bl.a. systemets og appens stabilitet. Visse samlede data hjælper også Google-apps og -partnere, f.eks. Android-udviklere. Hvis indstillingen til yderligere web- og appaktivitet er aktiveret, gemmes disse data muligvis på din Google-konto. <ph name="BEGIN_LINK1" />Få flere oplysninger<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Gå til filer</translation>
 <translation id="2946119680249604491">Tilføj forbindelse</translation>
@@ -2968,6 +2973,7 @@
 <translation id="3784472333786002075">Cookies er filer, som oprettes af websites. Der findes to slags cookies: Førstepartscookies oprettes af det website, du besøger. Websitet vises i adresselinjen. Tredjepartscookies oprettes af andre websites. Disse websites ejer noget af indholdet, f.eks. de annoncer eller billeder, der vises på det website, du besøger.</translation>
 <translation id="3785308913036335955">Vis genveje for Apps</translation>
 <translation id="3785727820640310185">Gemte adgangskoder til dette website</translation>
+<translation id="3787434344076711519">Venter på oversættelse</translation>
 <translation id="3788301286821743879">Terminalappen kunne ikke startes.</translation>
 <translation id="3788331399335602504">disse filer</translation>
 <translation id="3788401245189148511">Den vil kunne:</translation>
@@ -3251,6 +3257,7 @@
 <translation id="4036778507053569103">Den politik, der er downloadet fra serveren, er ugyldig.</translation>
 <translation id="4037084878352560732">Hest</translation>
 <translation id="403725336528835653">Prøv det først</translation>
+<translation id="4040041015953651705">Sprog, der skal oversættes fra</translation>
 <translation id="4040105702484676956">Vil du rydde websitedata og tilladelser for <ph name="SITE_NAME" /> samt websitets installerede apps?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Forlad side}one{Forlad side}other{Forlad sider}}</translation>
 <translation id="4043267180218562935">Markørens størrelse</translation>
@@ -4057,6 +4064,7 @@
 <translation id="4838170306476614339">Se din telefons billeder, mediefiler og notifikationer</translation>
 <translation id="4838836835474292213">Der blev givet læseadgang til udklipsholderen</translation>
 <translation id="4838907349371614303">Adgangskoden er opdateret</translation>
+<translation id="4838958829619609362">Fås ikke på <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">&amp;Gem video som ...</translation>
 <translation id="4840096453115567876">Vil du afslutte inkognitotilstand alligevel?</translation>
 <translation id="4841741146571978176">En påkrævet virtuel maskine findes ikke. Prøv at konfigurere <ph name="VM_TYPE" /> for at fortsætte</translation>
@@ -4828,6 +4836,7 @@
 <translation id="558918721941304263">Indlæser apps...</translation>
 <translation id="5590418976913374224">Afspil lyd ved opstart af enheden</translation>
 <translation id="5592595402373377407">Der er ikke nok data til rådighed endnu.</translation>
+<translation id="5594899180331219722">Vælg en fil</translation>
 <translation id="5595307023264033512">Samlet lagerplads, der anvendes af websites: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Rediger adresse</translation>
 <translation id="5596627076506792578">Flere valgmuligheder</translation>
@@ -5060,6 +5069,7 @@
 <translation id="5834581999798853053">Omkring <ph name="TIME" /> minutter tilbage</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – kameraet eller mikrofonen optager</translation>
 <translation id="583673505367439042">Websites kan anmode om tilladelse til at redigere filer og mapper på din enhed</translation>
+<translation id="5836999627049108525">Sprog, der skal oversættes fra</translation>
 <translation id="583756221537636748">Etui</translation>
 <translation id="5840658767386246331">Søg med Google</translation>
 <translation id="5840680448799937675">Filer deles altid offline</translation>
@@ -5570,6 +5580,7 @@
 <translation id="6318944945640833942">Der blev ikke registreret en printer. Angiv adressen til printeren igen.</translation>
 <translation id="6322370287306604163">Lås op hurtigere med fingeraftryk</translation>
 <translation id="6322559670748154781">Denne fil er ikke downloadet på normal vis og er blevet blokeret af Avanceret beskyttelse</translation>
+<translation id="6324083483652497048">Klik for at tillade, at disse udvidelser læser og ændrer <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Rediger genvej</translation>
 <translation id="6325191661371220117">Deaktiver Automatisk opstart</translation>
 <translation id="6326175484149238433">Fjern fra Chrome</translation>
@@ -6602,6 +6613,7 @@
 <translation id="7343372807593926528">Beskriv problemet, før du sender feedback</translation>
 <translation id="7344585835349671209">Administrer HTTPS-/SSL-certifikater på din enhed</translation>
 <translation id="7345706641791090287">Bekræft din adgangskode</translation>
+<translation id="7345919885156673810">Fås ikke på <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">OK</translation>
 <translation id="7347452120014970266">Denne handling rydder alle de data og cookies, der er gemt af <ph name="ORIGIN_NAME" /> og de apps, den har installeret</translation>
 <translation id="7347751611463936647">Hvis du vil bruge denne udvidelse, skal du indtaste "<ph name="EXTENSION_KEYWORD" />" og derefter TAB. Herefter skal du indtaste din kommando eller søgning.</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index ea86010..11aec33 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -600,7 +600,7 @@
 <translation id="1571738973904005196">Προβολή καρτέλας: <ph name="TAB_ORIGIN" /></translation>
 <translation id="1572139610531470719"><ph name="WINDOW_TITLE" /> (Επισκέπτης)</translation>
 <translation id="1572266655485775982">Ενεργοποίηση Wi-Fi</translation>
-<translation id="1572876035008611720">Εισαγάγετε τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας</translation>
+<translation id="1572876035008611720">Εισαγάγετε το email σας</translation>
 <translation id="1573117025466282241">Χρήση τηλεφώνου με κωδικό QR</translation>
 <translation id="1575741822946219011">Γλώσσες και μέθοδοι εισαγωγής</translation>
 <translation id="1576594961618857597">Προεπιλεγμένο λευκό avatar</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index 5f90e12..2967a329 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -275,6 +275,7 @@
 <translation id="125220115284141797">Predeterminado</translation>
 <translation id="1252987234827889034">Se produjo un error en el perfil</translation>
 <translation id="1254593899333212300">Conexión directa a Internet</translation>
+<translation id="1257336506558170607">Exportar el certificado seleccionado</translation>
 <translation id="1258491128795710625">Novedades</translation>
 <translation id="1259152067760398571">Ayer se ejecutó la verificación de seguridad</translation>
 <translation id="1260451001046713751">Siempre permitir ventanas emergentes y redireccionamientos de <ph name="HOST" /></translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index cc14f592..88521ff0 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -278,6 +278,7 @@
 <translation id="125220115284141797">پیش‌فرض</translation>
 <translation id="1252987234827889034">خطای نمایه رخ داد</translation>
 <translation id="1254593899333212300">اتصال اینترنتی مستقیم</translation>
+<translation id="1257336506558170607">صادر کردن گواهینامه انتخاب‌شده</translation>
 <translation id="1258491128795710625">ویژگی‌های جدید</translation>
 <translation id="1259152067760398571">«بررسی ایمنی» دیروز اجرا شد</translation>
 <translation id="1260451001046713751">همیشه پنجره‌های بازشو و هدایت‌ها از <ph name="HOST" /> مجاز باشد</translation>
@@ -327,6 +328,7 @@
 <translation id="1307165550267142340">پین ایجاد شد</translation>
 <translation id="1307431692088049276">دوباره از من پرسیده نشود</translation>
 <translation id="1307559529304613120">‏متأسفیم! سیستم نتوانست کد دسترسی دراز مدت به API را برای این دستگاه ذخیره کند.</translation>
+<translation id="1312811472299082263">‏ایجاد ازطریق فایل پشتیبان Crostini یا «دفترچه Ansible»</translation>
 <translation id="1313405956111467313">پیکربندی پراکسی خودکار</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">از سیستم همه سایت‌ها، ازجمله برگه‌هایی که اکنون باز هستند خارج خواهید شد</translation>
@@ -1106,6 +1108,7 @@
 <translation id="2028449514182362831">ویژگی‌هایی که به حسگرهای حرکتی نیاز دارند کار نخواهند کرد</translation>
 <translation id="202918510990975568">برای پیکربندی امنیت و ورود به سیستم، گذرواژه‌تان را وارد کنید</translation>
 <translation id="2030455719695904263">پد لمسی</translation>
+<translation id="2031385797619033640">با کلیک کردن، به <ph name="EXTENSIONS_REQUESTING_ACCESS" /> اجازه دهید <ph name="ORIGIN" /> را بخواند و تغییر دهد:</translation>
 <translation id="2031639749079821948">‏گذرواژه‌تان در «حساب Google» شما ذخیره می‌شود</translation>
 <translation id="2031914984822377766"><ph name="LINK_BEGIN" />زبان‌های وب‌سایت<ph name="LINK_END" /> ترجیحی‌تان را اضافه کنید. زبان اول در فهرست برای ترجمه‌ها استفاده خواهد شد.</translation>
 <translation id="2033758234986231162">‏اتصال به تلفن قطع می‌شود. مطمئن شوید تلفنتان نزدیک باشد، قفل آن باز باشد، و بلوتوث و Wi-Fi روشن باشند.</translation>
@@ -1465,6 +1468,7 @@
 <translation id="2328561734797404498">لطفاً برای استفاده از <ph name="APP_NAME" />، دستگاه را بازراه‌اندازی کنید.</translation>
 <translation id="2328636661627946415">وقتی در «حالت ناشناس» هستید، سایت‌ها فقط می‌توانند از کوکی‌ها برای دیدن فعالیت مرور در سایت خودشان استفاده کنند. کوکی‌ها در انتهای «جلسه ناشناس» حذف می‌شود.</translation>
 <translation id="2329597144923131178">برای دریافت نشانک‌ها، سابقه، گذرواژه‌ها و سایر تنظیماتتان در همه دستگاه‌ها، وارد سیستم شوید.</translation>
+<translation id="2332115969598251205">دستگاه‌های ذخیره‌شده در <ph name="PRIMARY_EMAIL" /> بار نشد. اتصال اینترنت را بررسی کرده و دوباره امتحان کنید.</translation>
 <translation id="2332131598580221120">مشاهده در فروشگاه</translation>
 <translation id="2332192922827071008">باز کردن اولویت‌ها</translation>
 <translation id="2332515770639153015">«مرور ایمن پیشرفته» روشن است</translation>
@@ -1908,6 +1912,7 @@
 <translation id="2749836841884031656">سیم‌کارت</translation>
 <translation id="2749881179542288782">بررسی گرامر با املا</translation>
 <translation id="2753677631968972007">اجازه‌های سایت را به‌طور دستی کنترل کنید.</translation>
+<translation id="2754226775788136540">درحال جستجوی دستگاه‌های مجهز به «مرتبط‌سازی سریع» که در <ph name="PRIMARY_EMAIL" /> ذخیره شده است</translation>
 <translation id="2754825024506485820">‏برنامه‌های موردنیازتان را، از بهره‌وری گرفته تا سرگرمی، در «فروشگاه Google Play» پیدا کنید. هر زمانی بخواهید می‌توانید برنامه‌ها را نصب کنید.</translation>
 <translation id="2755349111255270002">بازنشانی این <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">مدیریت قابلیت‌های دسترس‌پذیری</translation>
@@ -2123,6 +2128,7 @@
 <translation id="2942279350258725020">‏پیام‌های Android</translation>
 <translation id="2942560570858569904">درحال انتظار…</translation>
 <translation id="2942581856830209953">سفارشی کردن این صفحه</translation>
+<translation id="2943268899142471972">‏فایل پشتیبان Crostini یا «دفترچه Ansible» را انتخاب کنید</translation>
 <translation id="2944060181911631861">‏داده‌های استفاده و عیب‌یابی را ارسال کنید. با ارسال خودکار داده‌های تشخیص عیب و داده‌های استفاده از دستگاه و برنامه به Google، به بهبود تجربه استفاده از Android کمک کنید. این داده‌ها به بهبود پایداری سیستم و برنامه و موارد دیگر کمک خواهد کرد. بعضی داده‌های انبوهشی نیز به برنامه‌ها و شرکای Google (مانند برنامه‌نویس‌های Android) کمک می‌کند. اگر تنظیم «فعالیت وب و برنامه» تکمیلی روشن باشد، ممکن است این داده‌ها در حساب Google شما ذخیره شود. <ph name="BEGIN_LINK1" />بیشتر بدانید<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">رفتن به فایل‌ها</translation>
 <translation id="2946119680249604491">افزودن اتصال</translation>
@@ -2963,6 +2969,7 @@
 <translation id="3784472333786002075">کوکی‌ها فایل‌هایی هستند که توسط وبسایت‌ها ایجاد می‌شوند. دو نوع کوکی وجود دارد: کوکی‌های شخص اول که توسط سایتی که بازدید می‌کنید ایجاد می‌شوند. این سایت در نوار نشانی نشان داده می‌شود. کوکی‌های شخص ثالث که توسط سایت‌های دیگر ایجاد می‌شوند. برخی از محتواها، مثل آگهی‌ها یا تصاویر موجود در وبسایتی که بازدید می‌کنید، متعلق به این سایت‌ها هستند.</translation>
 <translation id="3785308913036335955">نمایش میان‌بر «برنامه‌ها»</translation>
 <translation id="3785727820640310185">گذرواژه‌های ذخیره‌شده برای این سایت</translation>
+<translation id="3787434344076711519">درانتظار ترجمه</translation>
 <translation id="3788301286821743879">برنامه «کیوسک» راه‌اندازی نشد.</translation>
 <translation id="3788331399335602504">این فایل‌ها</translation>
 <translation id="3788401245189148511">این می‌توانست:</translation>
@@ -3246,6 +3253,7 @@
 <translation id="4036778507053569103">خط‌مشی بارگیری‌شده از سرور نامعتبر است.</translation>
 <translation id="4037084878352560732">اسب</translation>
 <translation id="403725336528835653">امتحان کردن</translation>
+<translation id="4040041015953651705">زبانی که می‌خواهید از آن ترجمه کنید</translation>
 <translation id="4040105702484676956">داده‌ها و اجازه‌های سایت <ph name="SITE_NAME" /> و برنامه‌های نصب‌شده‌اش پاک شود؟</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{خروج از صفحه}one{خروج از صفحه‌ها}other{خروج از صفحه‌ها}}</translation>
 <translation id="4043267180218562935">اندازه نشانگر</translation>
@@ -4052,6 +4060,7 @@
 <translation id="4838170306476614339">مشاهده کردن عکس‌ها، رسانه، و اعلان‌های تلفن شما</translation>
 <translation id="4838836835474292213">دسترسی برای خواندن محتوای بریده‌دان مجاز شد</translation>
 <translation id="4838907349371614303">گذرواژه به‌روزرسانی شد</translation>
+<translation id="4838958829619609362">مورد انتخاب‌شده به زبان <ph name="LANGUAGE" /> نیست</translation>
 <translation id="4839303808932127586">ذ&amp;خیره فایل ویدیوی به‌عنوان...</translation>
 <translation id="4840096453115567876">درهرصورت از «حالت ناشناس» خارج می‌شوید؟</translation>
 <translation id="4841741146571978176">یکی از ماشین‌های مجازی ضروری موجود نیست. برای ادامه، لطفاً <ph name="VM_TYPE" /> را راه‌اندازی کنید</translation>
@@ -4823,6 +4832,7 @@
 <translation id="558918721941304263">درحال بار کردن برنامه...</translation>
 <translation id="5590418976913374224">پخش صدا هنگام راه‌اندازی دستگاه</translation>
 <translation id="5592595402373377407">هنوز داده کافی در دسترس نیست.</translation>
+<translation id="5594899180331219722">انتخاب فایل</translation>
 <translation id="5595307023264033512">مجموع فضای ذخیره‌سازی که سایت‌ها استفاده کرده‌اند: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">ویرایش آدرس</translation>
 <translation id="5596627076506792578">گزینه‌های بیشتر</translation>
@@ -5055,6 +5065,7 @@
 <translation id="5834581999798853053">حدود <ph name="TIME" /> دقیقه باقی مانده است</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - دوربین یا میکروفون درحال ضبط کردن است</translation>
 <translation id="583673505367439042">سایت‌ها می‌توانند برای ویرایش فایل‌ها و پوشه‌های موجود در دستگاهتان درخواست دهند</translation>
+<translation id="5836999627049108525">زبانی که می‌خواهید از آن ترجمه کنید</translation>
 <translation id="583756221537636748">قاب</translation>
 <translation id="5840658767386246331">‏جستجو با Google</translation>
 <translation id="5840680448799937675">فایل‌ها همیشه درحالت آفلاین هم‌رسانی می‌شود</translation>
@@ -5565,6 +5576,7 @@
 <translation id="6318944945640833942">چاپگر شناسایی نشد لطفاً نشانی چاپگر را دوباره وارد کنید.</translation>
 <translation id="6322370287306604163">باز کردن سریع‌تر قفل با اثر انگشت</translation>
 <translation id="6322559670748154781">این فایل معمولاً بارگیری نمی‌شود و «محافظت پیشرفته» آن را مسدود کرده است</translation>
+<translation id="6324083483652497048">با کلیک کردن، به این افزونه‌ها اجازه دهید <ph name="ORIGIN" /> را بخوانند و تغییر دهند:</translation>
 <translation id="6324916366299863871">ویرایش میان‌بر</translation>
 <translation id="6325191661371220117">از کار انداختن اجرای خودکار</translation>
 <translation id="6326175484149238433">‏حذف از Chrome</translation>
@@ -6597,6 +6609,7 @@
 <translation id="7343372807593926528">لطفاً قبل‌از ارسال بازخورد، مشکل را شرح دهید.</translation>
 <translation id="7344585835349671209">‏مدیریت گواهینامه‌های HTTPS/SSL در دستگاه</translation>
 <translation id="7345706641791090287">گذرواژه‌تان را تأیید کنید</translation>
+<translation id="7345919885156673810">مورد انتخاب‌شده به زبان <ph name="LANGUAGE" /> نیست</translation>
 <translation id="7346909386216857016">بله متوجه شدم.</translation>
 <translation id="7347452120014970266">با این کار همه داده‌ها و کوکی‌های ذخیره‌شده توسط <ph name="ORIGIN_NAME" /> و برنامه‌های نصب‌شده آن پاک می‌شود</translation>
 <translation id="7347751611463936647">‏برای استفاده از این برنامهٔ افزودنی، "<ph name="EXTENSION_KEYWORD" />"، سپس TAB و نظر یا جستجوی خود را تایپ کنید.</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index 311f612..4acb603cd 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -328,6 +328,7 @@
 <translation id="1307165550267142340">Nagawa ang iyong PIN</translation>
 <translation id="1307431692088049276">Huwag akong tanungin ulit</translation>
 <translation id="1307559529304613120">Oops!  Nabigo ang system na i-imbak ang pangmatagalang token sa pag-access sa API para sa device na ito.</translation>
+<translation id="1312811472299082263">Gumawa mula sa isang Ansible Playbook o Crostini na backup file</translation>
 <translation id="1313405956111467313">Awtomatikong proxy configuration</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Masa-sign out ka sa lahat ng site, pati na rin sa mga nakabukas na tab</translation>
@@ -1111,6 +1112,7 @@
 <translation id="2028449514182362831">Hindi gagana ang mga feature na nangangailangan ng mga sensor ng paggalaw</translation>
 <translation id="202918510990975568">Ilagay ang iyong password para i-configure ang seguridad at pag-sign in</translation>
 <translation id="2030455719695904263">Trackpad</translation>
+<translation id="2031385797619033640">I-click para payagan ang <ph name="EXTENSIONS_REQUESTING_ACCESS" /> na bashin at baguhin ang <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Naka-save ang iyong password sa Google Account mo</translation>
 <translation id="2031914984822377766">Idagdag ang iyong mga gustong <ph name="LINK_BEGIN" />wika ng website<ph name="LINK_END" />. Gagamitin ang wika sa itaas mula sa listahan para sa mga pagsasalin.</translation>
 <translation id="2033758234986231162">Hindi makapagpanatili ng koneksyon sa iyong telepono. Tiyaking ang iyong telepono ay nasa malapit, naka-unlock, at naka-on ang Bluetooth at Wi-Fi.</translation>
@@ -1470,6 +1472,7 @@
 <translation id="2328561734797404498">Paki-restart ang iyong device para magamit ang <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Kapag nasa Incognito mode ka, puwede lang gumamit ng mga cookie ang mga site para tingnan ang iyong aktibidad sa pag-browse sa sarili nilang site. Ide-delete ang mga cookie sa pagtatapos ng Incognito session.</translation>
 <translation id="2329597144923131178">Mag-sign in upang makuha ang iyong mga bookmark, history, password at ibang mga setting sa lahat ng iyong device.</translation>
+<translation id="2332115969598251205">Hindi ma-load ang mga device na naka-save sa <ph name="PRIMARY_EMAIL" />. Tingnan ang iyong koneksyon sa internet at subukan ulit.</translation>
 <translation id="2332131598580221120">Tingnan sa store</translation>
 <translation id="2332192922827071008">Buksan ang Mga Kagustuhan</translation>
 <translation id="2332515770639153015">Naka-on ang Pinahusay na Ligtas na Pag-browse</translation>
@@ -1913,6 +1916,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Check Grammar With Spelling</translation>
 <translation id="2753677631968972007">Manual na kontrolin ang mga pahintulot sa site.</translation>
+<translation id="2754226775788136540">Naghahanap ng device ng Mabilis na Pagpares na naka-save sa <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Hanapin ang mga app na kailangan mo, mula sa pagiging produktibo hanggang entertainment, sa Google Play Store. Puwede kang mag-install ng mga app anumang oras.</translation>
 <translation id="2755349111255270002">I-reset ang <ph name="DEVICE_TYPE" /> na ito</translation>
 <translation id="2755367719610958252">Pamahalaan ang mga feature sa accessibility</translation>
@@ -2128,6 +2132,7 @@
 <translation id="2942279350258725020">Mga mensahe sa Android</translation>
 <translation id="2942560570858569904">Naghihintay...</translation>
 <translation id="2942581856830209953">I-customize ang page na ito</translation>
+<translation id="2943268899142471972">Pumili ng Ansible Playbook o Crostini na backup file</translation>
 <translation id="2944060181911631861">Magpadala ng data ng paggamit at diagnostic na data. Tumulong sa pagpapaganda ng iyong karanasan sa Android sa pamamagitan ng awtomatikong pagpapadala ng diagnostic na data, data ng device, at data ng paggamit sa app sa Google. Makakatulong ito sa stability ng system at ng app, at sa iba pang pagpapahusay. Makakatulong din ang ilang pinagsama-samang data sa mga app at partner ng Google, gaya ng mga developer ng Android. Kung naka-on ang iyong karagdagang setting ng Aktibidad sa Web at App, maaaring ma-save ang data na ito sa Google account mo. <ph name="BEGIN_LINK1" />Matuto Pa<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Pumunta sa mga file</translation>
 <translation id="2946119680249604491">Magdagdag ng koneksyon</translation>
@@ -2968,6 +2973,7 @@
 <translation id="3784472333786002075">Ang cookies ay mga file na ginawa ng mga website. May dalawang uri ng cookies: Ginagawa ng site na iyong binibisita ang cookies ng first-party. Ipinapakita ang site sa address bar. Ginagawa ng iba pang site ang third-party na cookies. Pagmamay-ari ng mga site na ito ang ilan sa content, tulad ng mga ad o larawan, na nakikita mo sa website na iyong binibisita.</translation>
 <translation id="3785308913036335955">Ipakita ang Shortcut ng Apps</translation>
 <translation id="3785727820640310185">Mga naka-save na password para sa site na ito</translation>
+<translation id="3787434344076711519">Naghihintay na isalin</translation>
 <translation id="3788301286821743879">Hindi mailunsad ang kiosk application.</translation>
 <translation id="3788331399335602504">ang mga file na ito</translation>
 <translation id="3788401245189148511">Maaari itong:</translation>
@@ -3251,6 +3257,7 @@
 <translation id="4036778507053569103">Invalid ang patakarang na-download mula sa server.</translation>
 <translation id="4037084878352560732">Kabayo</translation>
 <translation id="403725336528835653">Subukan muna ito</translation>
+<translation id="4040041015953651705">Wikang pagmumulan ng pagsalin</translation>
 <translation id="4040105702484676956">I-clear ang data ng site at mga pahintulot para sa <ph name="SITE_NAME" /> at naka-install na app nito?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Umalis sa Page}one{Umalis sa Mga Page}other{Umalis sa Mga Page}}</translation>
 <translation id="4043267180218562935">Laki ng cursor</translation>
@@ -4057,6 +4064,7 @@
 <translation id="4838170306476614339">Tingnan ang mga larawan, media, at notification</translation>
 <translation id="4838836835474292213">Pinapayagan ang read access sa clipboard</translation>
 <translation id="4838907349371614303">Na-update ang password</translation>
+<translation id="4838958829619609362">Wala ang pinili sa <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">I-sa&amp;ve ang video bilang...</translation>
 <translation id="4840096453115567876">Umalis pa rin sa Incognito mode?</translation>
 <translation id="4841741146571978176">Wala ang kinakailangang virtual machine. Pakisubukang i-set up ang <ph name="VM_TYPE" /> para magpatuloy</translation>
@@ -4828,6 +4836,7 @@
 <translation id="558918721941304263">Nilo-load ang mga app...</translation>
 <translation id="5590418976913374224">I-play ang tunog sa pagsisimula ng device</translation>
 <translation id="5592595402373377407">Wala pang available na sapat na data.</translation>
+<translation id="5594899180331219722">Pumili ng file</translation>
 <translation id="5595307023264033512">Kabuuang storage na ginagamit ng mga site: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Mag-edit ng address</translation>
 <translation id="5596627076506792578">Higit pang opsyon</translation>
@@ -5060,6 +5069,7 @@
 <translation id="5834581999798853053">Mga <ph name="TIME" /> (na) minuto ang natitira</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - Nagre-record ang camera o mikropono</translation>
 <translation id="583673505367439042">Puwedeng hilingin ng mga site na mag-edit ng mga file at folder sa iyong device</translation>
+<translation id="5836999627049108525">Wikang pagmumulan ng Pagsalin</translation>
 <translation id="583756221537636748">Case</translation>
 <translation id="5840658767386246331">Maghanap gamit ang Google</translation>
 <translation id="5840680448799937675">Palaging ibabahagi offline ang mga file</translation>
@@ -5570,6 +5580,7 @@
 <translation id="6318944945640833942">Walang matukoy na printer. Pakilagay ulit ang address ng printer.</translation>
 <translation id="6322370287306604163">I-unlock nang mas mabilis gamit ang fingerprint</translation>
 <translation id="6322559670748154781">Hindi karaniwang dina-download ang file na ito at na-block ito ng Advanced na Proteksyon.</translation>
+<translation id="6324083483652497048">I-click para payagan ang mga extension na ito na basahin at baguhin ang <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">I-edit ang shortcut</translation>
 <translation id="6325191661371220117">I-disable ang awtomatikong paglulunsad</translation>
 <translation id="6326175484149238433">Alisin sa Chrome</translation>
@@ -6602,6 +6613,7 @@
 <translation id="7343372807593926528">Pakilarawan ang problema bago ipadala ang feedback.</translation>
 <translation id="7344585835349671209">Pamahalaan ang mga HTTPS/SSL certificate sa iyong device</translation>
 <translation id="7345706641791090287">Kumpirmahin ang iyong password</translation>
+<translation id="7345919885156673810">Wala ang pinili sa <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Ok, nakuha ko</translation>
 <translation id="7347452120014970266">Iki-clear nito ang lahat ng data at cookies na na-store ng <ph name="ORIGIN_NAME" /> at ang mga na-install na app nito</translation>
 <translation id="7347751611463936647">Upang gamitin ang extension na ito, i-type ang "<ph name="EXTENSION_KEYWORD" />", pagkatapos ay ang TAB, pagkatapos ay ang iyong command o paghahanap.</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index ec3f6bf..7a6bdee 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">કંઈક ખોટું થયું. શક્ય છે કે Linux માત્ર આંશિક રીતે જ અપગ્રેડ થાય. વધુ માહિતી માટે લૉગનો રિવ્યૂ કરો. ફાઇલો &gt; મારી ફાઇલો &gt; <ph name="LOG_FILE" />માં લૉગ સાચવવામાં આવ્યા છે</translation>
 <translation id="1043818413152647937">આ ઍપમાંથી પણ ડેટા સાફ કરીએ?</translation>
 <translation id="1043824690776631483">આ સાઇટની મુલાકાત લેવા માટે તમને પરવાનગીની જરૂર છે. તેમાં અનુચિત કન્ટેન્ટ હોઈ શકે છે.</translation>
+<translation id="104419033123549300">કીમેપની શૈલી</translation>
 <translation id="104710386808485638">Linux ફરી ચાલુ કરીએ?</translation>
 <translation id="1047431265488717055">લિંક ટે&amp;ક્સ્ટને કૉપિ કરો</translation>
 <translation id="1048286738600630630">પ્રદર્શન</translation>
@@ -769,6 +770,7 @@
 <translation id="1721312023322545264">આ સાઇટની મુલાકાત લેવા માટે તમને <ph name="NAME" /> ની પરવાનગીની જરૂર છે</translation>
 <translation id="1722460139690167654"><ph name="ENROLLMENT_DOMAIN" /> તમારા <ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" />ને મેનેજ કરે છે<ph name="END_LINK" /></translation>
 <translation id="1723824996674794290">&amp;નવી વિંડો</translation>
+<translation id="1724801751621173132">ઇનપુટ મોડ</translation>
 <translation id="1725562816265788801">ટૅબ સ્ક્રોલિંગ</translation>
 <translation id="1729533290416704613">જ્યારે તમે ઑમ્નિબૉક્સ પરથી શોધ કરો ત્યારે કયું પેજ બતાવવામાં આવે તે તેનું પણ નિયંત્રણ કરે છે.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ઍપ કાઢી નાખવા માટે, સેટિંગ &gt; Google Play Store &gt; Android પસંદગીઓ મેનેજ કરો &gt; ઍપ અથવા ઍપ્લિકેશન મેનેજર પર જાઓ. પછી તમે અનઇન્સ્ટૉલ કરવા માગો છો તે ઍપ પર ટૅપ કરો (ઍપ શોધવા માટે તમારે જમણે અથવા ડાબે સ્વાઇપ કરવું જરૂરી હોઈ શકે છે). પછી 'અનઇન્સ્ટૉલ કરો' અથવા 'બંધ કરો' પર ટૅપ કરો.<ph name="END_PARAGRAPH1" /></translation>
@@ -1950,6 +1952,7 @@
 <translation id="2796740370559399562">કુકીઝને મંજૂરી આપવાનું ચાલુ રાખો</translation>
 <translation id="2798347533012571708">અપડેટ મેળવતા રહો</translation>
 <translation id="2799223571221894425">ફરીથી લોંચ કરો</translation>
+<translation id="2800309299477632167">કસ્ટમ કીમેપ</translation>
 <translation id="2800760947029405028">છબી અપલોડ કરો</translation>
 <translation id="2801954693771979815">સ્ક્રીનનું કદ</translation>
 <translation id="2802557211515765772">અહીં મેનેજ કરેલા કોઈ પ્રિન્ટર ઉપલબ્ધ નથી.</translation>
@@ -2011,6 +2014,7 @@
 <translation id="2849767214114481738">તમારો પિન ઉમેરવામાં આવ્યો છે</translation>
 <translation id="2849936225196189499">ટીકાત્મક</translation>
 <translation id="2850541429955027218">થીમ ઉમેરો</translation>
+<translation id="2850672011315104382">વિરામ ચિહ્નની શૈલી</translation>
 <translation id="2851634818064021665">આ સાઇટની મુલાકાત લેવા માટે તમને પરનાવગીની જરૂર છે</translation>
 <translation id="2851728849045278002">કંઈક ખોટું થયું. વધુ વિગતો માટે ક્લિક કરો.</translation>
 <translation id="2852385257476173980">જ્યારે તમે વેબ બ્રાઉઝ કરશો, ત્યારે તમે મુલાકાત લો છો તે સાઇટની સૂચિ અહીં દેખાઈ શકે છે</translation>
@@ -2507,6 +2511,7 @@
 <translation id="3359256513598016054">પ્રમાણપત્ર નીતિની મર્યાદાઓ</translation>
 <translation id="3360297538363969800">છાપવાનું નિષ્ફળ થયું. કૃપા કરીને તમારું પ્રિન્ટર તપાસો અને ફરી પ્રયાસ કરો.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> તમારી સાથે <ph name="ATTACHMENTS" /> શેર કરી રહ્યું છે.}one{<ph name="DEVICE_NAME" /> તમારી સાથે <ph name="ATTACHMENTS" /> શેર કરી રહ્યું છે.}other{<ph name="DEVICE_NAME" /> તમારી સાથે <ph name="ATTACHMENTS" /> શેર કરી રહ્યું છે.}}</translation>
+<translation id="3361954577771524115">ઍપમાંથી</translation>
 <translation id="3363202073972776113">આ નવી પ્રોફાઇલ તમારી સંસ્થા દ્વારા મેનેજ કરવામાં આવશે. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">તમારા વ્યવસ્થાપક તરફથી: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Ctrl અથવા Altનો ઉપયોગ કરો</translation>
@@ -3031,6 +3036,7 @@
 <translation id="3848547754896969219">&amp;છૂપી વિન્ડોમાં ખોલો</translation>
 <translation id="385051799172605136">પાછળ</translation>
 <translation id="3851428669031642514">અસુરક્ષિત સ્ક્રિપ્ટ્સ લોડ કરો</translation>
+<translation id="3852215160863921508">ઇનપુટ સહાય</translation>
 <translation id="3854599674806204102">વિકલ્પ પસંદ કરો</translation>
 <translation id="3854967233147778866">વેબસાઇટનો અન્ય ભાષાઓમાં અનુવાદ કરવાનું ઑફર કરો</translation>
 <translation id="3854976556788175030">નાપસંદગી ટ્રે પૂરી ભરાઈ ગઈ છે</translation>
@@ -3787,6 +3793,7 @@
 <translation id="4579453506923101210">કનેક્ટ કરેલા ફોનથી છૂટા પડો</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> કાસ્ટ કરવામાં અસમર્થ.</translation>
 <translation id="4579876313423027742">બ્રાઉઝરના નોટિફિકેશન માટે, <ph name="LINK_BEGIN" />Chrome બ્રાઉઝર સેટિંગ<ph name="LINK_END" /> પર જાઓ</translation>
+<translation id="4580587929153007251">Google Password Managerમાં ફરી સાઈન ઇન કરો</translation>
 <translation id="4580596421317071374">પાસવર્ડ આ ડિવાઇસ પરના <ph name="GOOGLE_PASSWORD_MANAGER" />માં સાચવવામાં આવે છે.</translation>
 <translation id="4580626299762849806">પાસવર્ડ આયાત કરી શકાતા નથી. <ph name="FILENAME" /> ચેક કરો અને તે યોગ્ય રીતે ફૉર્મેટ કરેલું હોય તેની ખાતરી કરો.</translation>
 <translation id="4581774856936278355">Linuxની પુનઃસ્થાપના કરતી વખતે ભૂલ આવી</translation>
@@ -4468,6 +4475,7 @@
 <translation id="5268373933383932086">તમારું પેજ, તમારી રીતે</translation>
 <translation id="5269977353971873915">પ્રિન્ટ કાઢવામાં નિષ્ફળ</translation>
 <translation id="5273806377963980154">સાઇટના URLમાં ફેરફાર કરો</translation>
+<translation id="5275084684151588738">વપરાશકર્તા શબ્દકોશો</translation>
 <translation id="5275338516105640560">સાચવેલા ટૅબ ગ્રૂપનું બટન</translation>
 <translation id="5275352920323889391">કૂતરું</translation>
 <translation id="527605719918376753">ટૅબ મ્યૂટ કરો</translation>
@@ -4683,6 +4691,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{પિન ઓછામાં ઓછો એક અક્ષરનો હોવો આવશ્યક છે}one{પિન ઓછામાં ઓછો # અક્ષરનો હોવો આવશ્યક છે}other{પિન ઓછામાં ઓછો # અક્ષરનો હોવો આવશ્યક છે}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> માટે જરૂરી છે કે તમે હમણાં વાઇ-ફાઇથી કનેક્ટ થાઓ અને અપડેટ ડાઉનલોડ કરો. અથવા મીટર્ડ (ડેટા નિયંત્રણ) કનેક્શન પરથી ડાઉનલોડ કરો (શુલ્ક લાગુ થઈ શકે છે).</translation>
 <translation id="5481273127572794904">એકથી વધારે ફાઇલો ઑટોમૅટિક રીતે ડાઉનલોડ કરવાની મંજૂરી નથી</translation>
+<translation id="5481755802440890178">આ સમયે પસંદગીનો અનુવાદ કરી શકાયો નથી</translation>
 <translation id="5481941284378890518">નજીકના પ્રિન્ટર્સ ઉમેરો</translation>
 <translation id="5483785310822538350">ફાઇલ અને ઉપકરણ ઍક્સેસને રદબાતલ કરો</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> માટે જરૂરી છે કે તમે આજે તમારા ડેટાનું બૅકઅપ લો અને આ <ph name="DEVICE_TYPE" /> પરત કરો. <ph name="LINK_BEGIN" />વિગતો જુઓ<ph name="LINK_END" />}one{<ph name="MANAGER" /> માટે જરૂરી છે કે તમે તમારા ડેટાનું બૅકઅપ લો અને આ <ph name="DEVICE_TYPE" /> {NUM_DAYS} દિવસમાં પરત કરો. <ph name="LINK_BEGIN" />વિગતો જુઓ<ph name="LINK_END" />}other{<ph name="MANAGER" /> માટે જરૂરી છે કે તમે તમારા ડેટાનું બૅકઅપ લો અને આ <ph name="DEVICE_TYPE" /> {NUM_DAYS} દિવસમાં પરત કરો. <ph name="LINK_BEGIN" />વિગતો જુઓ<ph name="LINK_END" />}}</translation>
@@ -4916,6 +4925,7 @@
 <translation id="5696143504434933566">"<ph name="EXTENSION_NAME" />" તરફથી દુરુપયોગની જાણ કરો</translation>
 <translation id="5696679855467848181">ઉપયોગમાં છે તે વર્તમાન PPD ફાઇલ: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">ઇમોજી પિકર</translation>
+<translation id="5698462638680260399">પાસવર્ડનો ઉપયોગ કરવા માટે સાઇન ઇન કરો</translation>
 <translation id="570043786759263127">Google Play ઍપ અને સેવાઓ</translation>
 <translation id="5700836101007545240">કનેક્શન ઉમેરો, તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરવામાં આવ્યું છે</translation>
 <translation id="5701080607174488915">સર્વરમાંથી પૉલિસી લાવતી વખતે ભૂલ.</translation>
@@ -4933,6 +4943,7 @@
 <translation id="5712153969432126546">સાઇટ અમુક વખતે PDFs પ્રકાશિત કરે છે, જેમ કે દસ્તાવેજો, કરારો અને ફોર્મ</translation>
 <translation id="571222594670061844">સાઇટ ઓળખ સેવાઓના સાઇન ઇન કરવાના સંકેતો બતાવી શકે છે</translation>
 <translation id="5713158217420111469"><ph name="DEVICE" />થી કનેક્ટેડ છે</translation>
+<translation id="5713960379473463904">સ્પેસ ઇનપુટની શૈલી</translation>
 <translation id="5715711091495208045">પ્લગિન બ્રોકર: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">ડિફૉલ્ટ શોધ એન્જિન</translation>
 <translation id="5719854774000914513">સાઇટ HID ડિવાઇસ સાથે કનેક્ટ કરવાનું પૂછી શકે છે</translation>
@@ -6358,6 +6369,7 @@
 <translation id="7069811530847688087"><ph name="WEBSITE" /> માટે વધુ નવો અથવા જુદા પ્રકારનો સુરક્ષા કોડ જરૂરી હોઈ શકે છે</translation>
 <translation id="7070484045139057854">આ સાઇટ ડેટા વાંચી અને તેમાં ફેરફાર કરી શકે છે</translation>
 <translation id="7072010813301522126">શોર્ટકટ નામ</translation>
+<translation id="7074066049407662839">પાસવર્ડ સાચવવા માટે સાઇન ઇન કરો</translation>
 <translation id="7075513071073410194">RSA એન્ક્રિપ્શનવાળું PKCS #1 MD5</translation>
 <translation id="7075625805486468288">HTTPS/SSL પ્રમાણપત્રો અને સેટિંગ મેનેજ કરો</translation>
 <translation id="7076875098323397992">અપગ્રેડની પ્રક્રિયા શરૂ કરી શકાતી નથી</translation>
@@ -6889,6 +6901,7 @@
 <translation id="7625568159987162309">પરવાનગીઓ અને બધી સાઇટ પર સ્ટોર કરેલો ડેટા જુઓ</translation>
 <translation id="7625823789272218216">ડાબી બાજુએ નવી ટૅબ</translation>
 <translation id="7628201176665550262">રિફ્રેશ થવાનો રેટ</translation>
+<translation id="7628392600831846024">પ્રતીકની શૈલી</translation>
 <translation id="7629827748548208700">ટૅબ: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">આ ડિવાઇસ <ph name="MANAGER" /> દ્વારા મેનેજ કરવામાં આવે છે અને તમારે દર વખતે સાઇન ઇન કરવું જરૂરી છે.</translation>
 <translation id="7631014249255418691">Linux ઍપ અને ફાઇલોનો સફળતાપૂર્વક બૅકઅપ લીધો</translation>
@@ -8182,6 +8195,7 @@
 <translation id="8850251000316748990">વધુ જુઓ...</translation>
 <translation id="885246833287407341">API કાર્યના તર્ક</translation>
 <translation id="8853586775156634952">આ કાર્ડ માત્ર આ ડિવાઇસમાં સચવાશે</translation>
+<translation id="8854745870658584490">શૉર્ટકટ માટે પસંદગી</translation>
 <translation id="8855977033756560989">આ Chromebook Enterprise ડિવાઇસ Chrome Enterprise અપગ્રેડ સાથેના બંડલમાં આવે છે. એન્ટરપ્રાઇઝની ક્ષમતાઓનો લાભ લેવા માટે, આ ડિવાઇસની Google વ્યવસ્થાપક એકાઉન્ટ સાથે નોંધણી કરાવો.</translation>
 <translation id="8856028055086294840">ઍપ અને પેજ રિસ્ટોર કરો</translation>
 <translation id="885701979325669005">સ્ટોરેજ</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index 7740e2b..3376b5c 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Nešto nije u redu. Linux je možda samo djelomično nadograđen. Pregledajte zapisnike za više informacija. Zapisnici su spremljeni u mapu Datoteke &gt; Moje datoteke &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Želite li izbrisati podatke i iz ovih aplikacija?</translation>
 <translation id="1043824690776631483">Potrebno ti je dopuštenje za posjet toj web-lokaciji. Sadržaj možda nije primjeren.</translation>
+<translation id="104419033123549300">Stil karte tipkovnice</translation>
 <translation id="104710386808485638">Ponovno pokrenuti Linux?</translation>
 <translation id="1047431265488717055">Kopiraj te&amp;kst veze</translation>
 <translation id="1048286738600630630">Zasloni</translation>
@@ -327,6 +328,7 @@
 <translation id="1307165550267142340">Vaš je PIN izrađen</translation>
 <translation id="1307431692088049276">Nemoj me pitati ponovno</translation>
 <translation id="1307559529304613120">Ups! Sustav nije uspio pohraniti token za dugotrajni pristup API-ju za ovaj uređaj.</translation>
+<translation id="1312811472299082263">Izrada pomoću Ansible Playbooka ili datoteke sigurnosne kopije na Crostiniju</translation>
 <translation id="1313405956111467313">Automatska konfiguracija proxyja</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Odjavit ćete se sa svih web-lokacija, uključujući otvorene kartice</translation>
@@ -773,6 +775,7 @@
 <translation id="1721312023322545264"><ph name="NAME" /> mora dopustiti da posjetiš tu web-lokaciju</translation>
 <translation id="1722460139690167654">Vašim uređajem <ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" /> upravlja<ph name="END_LINK" /> <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Novi prozor</translation>
+<translation id="1724801751621173132">Način unosa</translation>
 <translation id="1725562816265788801">Pomicanje kartica</translation>
 <translation id="1729533290416704613">Upravlja i time koja se stranica prikazuje prilikom pretraživanja putem višenamjenskog okvira.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Za uklanjanje aplikacija idite na Postavke &gt; Trgovina Play &gt; Upravljanje postavkama Androida &gt; Aplikacije ili Upravitelj aplikacija. Zatim dodirnite aplikaciju koju želite deinstalirati (možda ćete morati prijeći prstom udesno ili ulijevo kako biste pronašli aplikaciju). Zatim dodirnite Deinstaliraj ili Onemogući.<ph name="END_PARAGRAPH1" /></translation>
@@ -1100,6 +1103,7 @@
 <translation id="2028449514182362831">Značajke kojima su potrebni senzori kretanja neće raditi</translation>
 <translation id="202918510990975568">Unesite zaporku da biste konfigurirali sigurnost i prijavu</translation>
 <translation id="2030455719695904263">Dodirna površina</translation>
+<translation id="2031385797619033640">Kliknite da biste dopustili da <ph name="EXTENSIONS_REQUESTING_ACCESS" /> čita i mijenja <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Zaporka je spremljena na vaš Google račun</translation>
 <translation id="2031914984822377766">Dodajte željene <ph name="LINK_BEGIN" />jezike web-lokacije<ph name="LINK_END" />. Za prijevode će se upotrebljavati prvi jezik na popisu.</translation>
 <translation id="2033758234986231162">Održavanje veze s vašim telefonom nije uspjelo. Provjerite je li telefon u blizini, je li otključan i jesu li Bluetooth i Wi-Fi uključeni.</translation>
@@ -1457,6 +1461,7 @@
 <translation id="2328561734797404498">Ponovo pokrenite uređaj da biste koristili <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Kad ste u anonimnom načinu rada, web-lokacija može upotrebljavati kolačiće samo kako bi vidjela vašu aktivnost pregledavanja na toj web-lokaciji. Kolačići se brišu na kraju anonimne sesije.</translation>
 <translation id="2329597144923131178">Prijavite se da biste imali svoje oznake, povijest, zaporke i druge postavke na svim svojim uređajima.</translation>
+<translation id="2332115969598251205">Nije moguće učitati uređaje spremljene na e-adresi <ph name="PRIMARY_EMAIL" />. Provjerite internetsku vezu i pokušajte ponovo.</translation>
 <translation id="2332131598580221120">Pogledaj u web-trgovini</translation>
 <translation id="2332192922827071008">Otvori Postavke</translation>
 <translation id="2332515770639153015">Uključeno je poboljšano sigurno pregledavanje</translation>
@@ -1900,6 +1905,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Uz pravopis provjeri i gramatiku</translation>
 <translation id="2753677631968972007">Ručno upravljajte dopuštenjima za web-lokacije.</translation>
+<translation id="2754226775788136540">Traženje uređaja za brzo uparivanje spremljenih na e-adresi <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Pronađite aplikacije koje su vam potrebne, za sve od rada do zabave, u Trgovini Google Play. Aplikacije možete instalirati kad god želite.</translation>
 <translation id="2755349111255270002">Vratite <ph name="DEVICE_TYPE" /> na zadano</translation>
 <translation id="2755367719610958252">Upravljajte značajkama pristupačnosti</translation>
@@ -1951,6 +1957,7 @@
 <translation id="2796740370559399562">Nastavi dopuštati kolačiće</translation>
 <translation id="2798347533012571708">Zadrži ažuriranja</translation>
 <translation id="2799223571221894425">Pokreni ponovo</translation>
+<translation id="2800309299477632167">Prilagođena karta tipkovnice</translation>
 <translation id="2800760947029405028">Prenesite sliku</translation>
 <translation id="2801954693771979815">Veličina zaslona</translation>
 <translation id="2802557211515765772">Nema upravljanih pisača.</translation>
@@ -2012,6 +2019,7 @@
 <translation id="2849767214114481738">PIN je dodan</translation>
 <translation id="2849936225196189499">Kritično</translation>
 <translation id="2850541429955027218">Dodaj temu</translation>
+<translation id="2850672011315104382">Stil interpunkcije</translation>
 <translation id="2851634818064021665">Potrebno ti je dopuštenje za posjet toj web-lokaciji</translation>
 <translation id="2851728849045278002">Nešto nije u redu. Kliknite za više pojedinosti.</translation>
 <translation id="2852385257476173980">Popis web-lokacija koje posjetite može se pojaviti ovdje kad budete pregledavali na webu.</translation>
@@ -2115,6 +2123,7 @@
 <translation id="2942279350258725020">Android poruke</translation>
 <translation id="2942560570858569904">Čekanje...</translation>
 <translation id="2942581856830209953">Prilagodba stranice</translation>
+<translation id="2943268899142471972">Odaberite datoteku sigurnosne kopije za Ansible Playbook ili Crostini</translation>
 <translation id="2944060181911631861">Slanje podataka o upotrebi i dijagnostici. Pomognite poboljšati Android automatskim slanjem dijagnostičkih podataka te podataka o upotrebi uređaja i aplikacija Googleu. Ti podaci pomoći će poboljšati stabilnost sustava, aplikacija i drugo. Neki skupni podaci pomoći će i Googleovim aplikacijama i partnerima, na primjer razvojnim programerima za Android. Ako je uključena dodatna postavka Aktivnost na webu i u aplikacijama, ti se podaci mogu spremati na vaš Google račun. <ph name="BEGIN_LINK1" />Saznajte više<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Idi na datoteke</translation>
 <translation id="2946119680249604491">Dodaj vezu</translation>
@@ -2507,6 +2516,7 @@
 <translation id="3359256513598016054">Ograničenja pravila certifikata</translation>
 <translation id="3360297538363969800">Ispis nije uspio. Provjerite svoj pisač i pokušajte ponovo.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}one{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}few{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}other{<ph name="DEVICE_NAME" /> dijeli <ph name="ATTACHMENTS" /> s vama.}}</translation>
+<translation id="3361954577771524115">Iz aplikacije</translation>
 <translation id="3363202073972776113">Ovim novim profilom upravljat će vaša organizacija. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Od vašeg administratora: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Upotrijebite Ctrl ili Alt</translation>
@@ -2955,6 +2965,7 @@
 <translation id="3784472333786002075">Kolačići su datoteke web-lokacija. Postoje dvije vrste kolačića: kolačiće prve strane izrađuje web-lokacija koju posjetite. Ta je web-lokacija navedena u adresnoj traci. Kolačiće trećih strana izrađuju ostale web-lokacije. Te web-lokacije posjeduju dio sadržaja prikazanog na web-lokaciji koju ste posjetili, primjerice oglase ili slike.</translation>
 <translation id="3785308913036335955">Prikaži prečac za Aplikacije</translation>
 <translation id="3785727820640310185">Spremljene zaporke za tu web-lokaciju</translation>
+<translation id="3787434344076711519">Čekanje na prijevod</translation>
 <translation id="3788301286821743879">Aplikacija kioska ne može se pokrenuti.</translation>
 <translation id="3788331399335602504">ove datoteke</translation>
 <translation id="3788401245189148511">Proširenje ili aplikacija mogli bi:</translation>
@@ -3030,6 +3041,7 @@
 <translation id="3848547754896969219">Otvori u &amp;anonimnom prozoru</translation>
 <translation id="385051799172605136">Natrag</translation>
 <translation id="3851428669031642514">Učitaj nesigurne skripte</translation>
+<translation id="3852215160863921508">Pomoć prilikom unosa</translation>
 <translation id="3854599674806204102">Odaberite opciju</translation>
 <translation id="3854967233147778866">Ponudi prevođenje web-lokacija na druge jezike</translation>
 <translation id="3854976556788175030">Izlazna je ladica puna</translation>
@@ -3238,6 +3250,7 @@
 <translation id="4036778507053569103">Pravilo preuzeto s poslužitelja nije važeće.</translation>
 <translation id="4037084878352560732">Konj</translation>
 <translation id="403725336528835653">Najprije isprobajte</translation>
+<translation id="4040041015953651705">Jezik s kojega se prevodi</translation>
 <translation id="4040105702484676956">Želite li izbrisati podatke web-lokacije i dopuštenja za web-lokaciju <ph name="SITE_NAME" /> i njezinu instaliranu aplikaciju?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Zatvori stranicu}one{Zatvori stranicu}few{Zatvori stranice}other{Zatvori stranica}}</translation>
 <translation id="4043267180218562935">Veličina pokazivača</translation>
@@ -3265,6 +3278,7 @@
 <translation id="4062561150282203854">Sinkronizirajte aplikacije, postavke i druge podatke s uređaja <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Mreža koju upotrebljavate (<ph name="NETWORK_ID" />) može zahtijevati posjet stranici za prijavu.</translation>
 <translation id="4066207411788646768">Provjerite svoju vezu da biste vidjeli dostupne pisače u mreži</translation>
+<translation id="4066945815577305767">Zaporke su istekle</translation>
 <translation id="4068776064906523561">Spremljeni otisci prstiju</translation>
 <translation id="407173827865827707">Na klik</translation>
 <translation id="4072701974556190758">Zaporka će se spremiti na vaš Google račun, <ph name="ACCOUNT" />. Ne morate je pamtiti.</translation>
@@ -3785,6 +3799,7 @@
 <translation id="4579453506923101210">Zaboravljanje povezanog telefona</translation>
 <translation id="4579581181964204535">Ne može se emitirati <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Za obavijesti preglednika otvorite <ph name="LINK_BEGIN" />postavke preglednika Chrome<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Ponovo se prijavite na Google upravitelj zaporki</translation>
 <translation id="4580596421317071374">Zaporke se spremaju u <ph name="GOOGLE_PASSWORD_MANAGER" /> na ovom uređaju.</translation>
 <translation id="4580626299762849806">Zaporke se ne mogu uvesti. Provjerite je li datoteka <ph name="FILENAME" /> pravilno formatirana.</translation>
 <translation id="4581774856936278355">Došlo je do pogreške prilikom vraćanja Linuxa</translation>
@@ -4043,6 +4058,7 @@
 <translation id="4838170306476614339">Pregled fotografija, medija i obavijesti s vašeg telefona</translation>
 <translation id="4838836835474292213">Dopušten pristup za čitanje međuspremnika</translation>
 <translation id="4838907349371614303">Zaporka je ažurirana</translation>
+<translation id="4838958829619609362">Odabir nije na jeziku <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Sp&amp;remi videozapis kao...</translation>
 <translation id="4840096453115567876">Želite li ipak napustiti anonimni način?</translation>
 <translation id="4841741146571978176">Obavezno virtualno računalo ne postoji. Pokušajte postaviti <ph name="VM_TYPE" /> da biste nastavili</translation>
@@ -4465,6 +4481,7 @@
 <translation id="5268373933383932086">Vaša stranica, vaš izbor</translation>
 <translation id="5269977353971873915">Ispis nije uspio</translation>
 <translation id="5273806377963980154">Uredite URL web-lokacije</translation>
+<translation id="5275084684151588738">Korisnički rječnici</translation>
 <translation id="5275338516105640560">Gumb spremljene grupe kartica</translation>
 <translation id="5275352920323889391">Pas</translation>
 <translation id="527605719918376753">Isključi zvuk kartice</translation>
@@ -4680,6 +4697,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN mora imati najmanje jedan znak}one{PIN mora imati najmanje # znak}few{PIN mora imati najmanje # znaka}other{PIN mora imati najmanje # znakova}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> zahtijeva da se odmah povežete s Wi-Fijem i preuzmete ažuriranje. Možete ga preuzeti i putem veze s ograničenim prometom (moguća je naplata naknada).</translation>
 <translation id="5481273127572794904">Nije dopušteno automatsko preuzimanje više datoteka</translation>
+<translation id="5481755802440890178">Trenutačno nije moguće prevesti odabir</translation>
 <translation id="5481941284378890518">Dodaj pisače u blizini</translation>
 <translation id="5483785310822538350">Opozovi pristup datotekama i uređaju</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> traži da stvorite sigurnosnu kopiju svojih podataka i danas vratite ovaj uređaj <ph name="DEVICE_TYPE" />. <ph name="LINK_BEGIN" />Pogledajte pojedinosti<ph name="LINK_END" />}one{<ph name="MANAGER" /> traži da stvorite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte pojedinosti<ph name="LINK_END" />}few{<ph name="MANAGER" /> traži da stvorite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte pojedinosti<ph name="LINK_END" />}other{<ph name="MANAGER" /> traži da stvorite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte pojedinosti<ph name="LINK_END" />}}</translation>
@@ -4814,6 +4832,7 @@
 <translation id="558918721941304263">Učitavanje aplikacija...</translation>
 <translation id="5590418976913374224">Reprodukcija zvuka pri pokretanju uređaja</translation>
 <translation id="5592595402373377407">Još nije dostupno dovoljno podataka.</translation>
+<translation id="5594899180331219722">Odaberite datoteku</translation>
 <translation id="5595307023264033512">Ukupna pohrana koju upotrebljavaju web-lokacije: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Uređivanje adrese</translation>
 <translation id="5596627076506792578">Više opcija</translation>
@@ -4909,6 +4928,7 @@
 <translation id="5696143504434933566">Prijavi zloupotrebu za proširenje "<ph name="EXTENSION_NAME" />"</translation>
 <translation id="5696679855467848181">Trenutačna PPD datoteka u upotrebi: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Alat za odabir emojija</translation>
+<translation id="5698462638680260399">Prijavite se da biste upotrebljavali zaporke</translation>
 <translation id="570043786759263127">Aplikacije i usluge Google Playa</translation>
 <translation id="5700836101007545240">Dodavanje veze onemogućio je administrator</translation>
 <translation id="5701080607174488915">Pogreška pri dohvaćanju pravila s poslužitelja.</translation>
@@ -4926,6 +4946,7 @@
 <translation id="5712153969432126546">Web-lokacije ponekad objavljuju PDF-ove, primjerice dokumente, ugovore i obrasce</translation>
 <translation id="571222594670061844">Web-lokacije mogu prikazivati upite za prijavu usluga za identitet</translation>
 <translation id="5713158217420111469">Povezano s uređajem <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Stil unosa razmaka</translation>
 <translation id="5715711091495208045">Broker dodatka: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Zadane tražilice</translation>
 <translation id="5719854774000914513">Web-lokacije mogu tražiti dopuštenje za povezivanje s HID uređajima</translation>
@@ -5044,6 +5065,7 @@
 <translation id="5834581999798853053">Preostalo je oko <ph name="TIME" /> min</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – kamera ili mikrofon snimaju</translation>
 <translation id="583673505367439042">Web-lokacije mogu tražiti dopuštenje za uređivanje datoteka i mapa na vašem uređaju</translation>
+<translation id="5836999627049108525">Jezik s kojega se prevodi</translation>
 <translation id="583756221537636748">Kutijica</translation>
 <translation id="5840658767386246331">Pretražuj koristeći Google</translation>
 <translation id="5840680448799937675">Datoteke će se uvijek dijeliti izvanmrežno</translation>
@@ -5553,6 +5575,7 @@
 <translation id="6318944945640833942">Pisač nije otkriven. Ponovo unesite adresu pisača.</translation>
 <translation id="6322370287306604163">Brže otključavanje otiskom prsta</translation>
 <translation id="6322559670748154781">Ova se datoteka rijetko preuzima te ju je Napredna zaštita blokirala</translation>
+<translation id="6324083483652497048">Kliknite da biste ovim proširenjima omogućili čitanje i promjenu web-lokacije <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Uređivanje prečaca</translation>
 <translation id="6325191661371220117">Onemogući automatsko pokretanje</translation>
 <translation id="6326175484149238433">Ukloni iz programa Chrome</translation>
@@ -5564,6 +5587,7 @@
 <translation id="6335920438823100346">Da biste pokrenuli Linux, <ph name="MANAGER" /> zahtijeva da sigurnosno kopirate svoje podatke i vratite ovaj Chromebook na tvorničke postavke.</translation>
 <translation id="6336038146639916978">Domena <ph name="MANAGER" /> onemogućila je ADB otklanjanje pogrešaka. Zbog toga će se uređaj <ph name="DEVICE_TYPE" /> vratiti na zadano za 24 sata. Sigurnosno kopirajte sve datoteke koje želite zadržati.</translation>
 <translation id="6338402296920404442">Razmislite o brisanju datoteke <ph name="FILENAME" /> kako osobe koje upotrebljavaju ovaj uređaj ne mogu vidjeti vaše zaporke.</translation>
+<translation id="6338968693068997776">Dodavanje USB uređaja</translation>
 <translation id="6338981933082930623">Sve vam web-lokacije mogu prikazivati bilo kakve oglase</translation>
 <translation id="6339668969738228384">Izradi novi profil za <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Internet Printing Protocol (IPPS)</translation>
@@ -6165,6 +6189,7 @@
 <translation id="6903907808598579934">Uključi sinkronizaciju</translation>
 <translation id="6904344821472985372">Opozovi pristup datoteci</translation>
 <translation id="6904655473976120856">Pritisnite gumb aplikacije za izlazak</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon jedne minute neaktivnosti}one{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}few{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}other{Radi zaštite vaših zaporki, Google upravitelj zaporki zaključava se nakon {NUM_MINS} min neaktivnosti}}</translation>
 <translation id="6909422577741440844">Primati s ovog uređaja?</translation>
 <translation id="6910211073230771657">Izbrisano</translation>
 <translation id="691106080621596509">Izbrisat će se svi podaci i kolačići koje je spremila web-lokacija <ph name="SITE_GROUP_NAME" /> te sve njezine pripadajuće web-lokacije i instalirana aplikacija</translation>
@@ -6349,6 +6374,7 @@
 <translation id="7069811530847688087"><ph name="WEBSITE" /> može zahtijevati noviju ili neku drugu vrstu sigurnosnog ključa</translation>
 <translation id="7070484045139057854">Može čitati i mijenjati podatke web-lokacije</translation>
 <translation id="7072010813301522126">Naziv prečaca</translation>
+<translation id="7074066049407662839">Prijavite se da biste spremili zaporke</translation>
 <translation id="7075513071073410194">PKCS br. 1 MD5 s RSA enkripcijom</translation>
 <translation id="7075625805486468288">Upravljanje HTTPS/SSL certifikatima i postavkama</translation>
 <translation id="7076875098323397992">Nije moguće započeti nadogradnju</translation>
@@ -6587,6 +6613,7 @@
 <translation id="7343372807593926528">Prije slanja povratnih informacija opišite problem.</translation>
 <translation id="7344585835349671209">Upravljanje HTTPS/SSL certifikatima na uređaju</translation>
 <translation id="7345706641791090287">Potvrdite zaporku</translation>
+<translation id="7345919885156673810">Odabir nije na jeziku <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Dobro, shvaćam</translation>
 <translation id="7347452120014970266">Izbrisat će se svi podaci i kolačići koje je spremila web-lokacija <ph name="ORIGIN_NAME" /> i njezine instalirane aplikacije</translation>
 <translation id="7347751611463936647">Da biste upotrijebili to proširenje, upišite "<ph name="EXTENSION_KEYWORD" />", zatim pritisnite TAB, a zatim svoju naredbu ili pretraživanje.</translation>
@@ -6879,6 +6906,7 @@
 <translation id="7625568159987162309">Pregledajte dopuštenja i podatke pohranjene na web-lokacijama</translation>
 <translation id="7625823789272218216">Nova kartica s lijeve strane</translation>
 <translation id="7628201176665550262">Učestalost osvježavanja</translation>
+<translation id="7628392600831846024">Stil simbola</translation>
 <translation id="7629827748548208700">Kartica: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">Uređajem upravlja <ph name="MANAGER" /> i zahtijeva da se svaki put prijavite.</translation>
 <translation id="7631014249255418691">Uspješno su stvorene sigurnosne kopije Linux aplikacija i datoteka</translation>
@@ -8004,6 +8032,7 @@
 <translation id="8688672835843460752">Dostupno</translation>
 <translation id="8690129572193755009">Web-lokacije mogu tražiti dopuštenje za upravljanje protokolima</translation>
 <translation id="8692107307702113268">Broj znakova zaporke ne smije biti veći od 1000</translation>
+<translation id="8694596275649352090">Zaključaj tijekom mirovanja ili kad je poklopac zatvoren</translation>
 <translation id="8695139659682234808">Dodavanje roditeljskog nadzora nakon postavljanja</translation>
 <translation id="8695825812785969222">Open &amp;Location... (Otvori Lokaciju...)</translation>
 <translation id="8698269656364382265">Da biste se vratili na prethodni zaslon, prijeđite prstom slijeva nadesno.</translation>
@@ -8052,6 +8081,7 @@
 <translation id="8732844209475700754">Više postavki koje se odnose na privatnost, sigurnost i prikupljanje podataka</translation>
 <translation id="8734073480934656039">Omogućivanjem ove postavke aplikacije kioska mogu se automatski pokrenuti prilikom pokretanja zaslona.</translation>
 <translation id="8734674662128056360">Blokiranje kolačića treće strane</translation>
+<translation id="8734755021067981851">Nije priključen nijedan USB uređaj.</translation>
 <translation id="873545264931343897">Kada dodatak <ph name="PLUGIN_NAME" /> završi s ažuriranjem, ponovo učitajte stranicu da biste ga aktivirali</translation>
 <translation id="8736288397686080465">Web-lokacija se ažurirala u pozadini.</translation>
 <translation id="8737709691285775803">Shill</translation>
@@ -8178,6 +8208,7 @@
 <translation id="8850251000316748990">Pogledajte više...</translation>
 <translation id="885246833287407341">Argumenti za funkciju API-ja</translation>
 <translation id="8853586775156634952">Ova će se kartica spremiti samo na vaš uređaj</translation>
+<translation id="8854745870658584490">Prečac odabira</translation>
 <translation id="8855977033756560989">Uz ovaj Chromebook Enterprise uređaj dobiva se Nadogradnja za Chrome za poduzeća. Da biste iskoristili mogućnosti koje se nude tvrtkama, registrirajte ovaj uređaj pomoću Google Admin računa.</translation>
 <translation id="8856028055086294840">Vrati aplikacije i stranice</translation>
 <translation id="885701979325669005">Prostor za pohranu</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index 3d6e32a..26dce2f3 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">Default</translation>
 <translation id="1252987234827889034">Terjadi error profil</translation>
 <translation id="1254593899333212300">Koneksi internet langsung</translation>
+<translation id="1257336506558170607">Ekspor sertifikat yang dipilih</translation>
 <translation id="1258491128795710625">Yang Baru</translation>
 <translation id="1259152067760398571">Pemeriksaan keamanan berjalan kemarin</translation>
 <translation id="1260451001046713751">Selalu izinkan pop-up dan pengalihan dari <ph name="HOST" /></translation>
@@ -326,6 +327,7 @@
 <translation id="1307165550267142340">PIN telah dibuat</translation>
 <translation id="1307431692088049276">Jangan tanya saya lagi</translation>
 <translation id="1307559529304613120">Ups! Sistem gagal menyimpan token akses API jangka panjang untuk perangkat ini.</translation>
+<translation id="1312811472299082263">Buat dari Playbook Ansible atau file cadangan Crostini</translation>
 <translation id="1313405956111467313">Konfigurasi proxy otomatis</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Anda akan logout dari semua situs, termasuk tab apa pun yang aktif</translation>
@@ -1109,6 +1111,7 @@
 <translation id="2028449514182362831">Fitur yang memerlukan sensor gerakan tidak akan berfungsi</translation>
 <translation id="202918510990975568">Masukkan sandi Anda untuk mengonfigurasi keamanan dan login</translation>
 <translation id="2030455719695904263">Trackpad</translation>
+<translation id="2031385797619033640">Klik untuk mengizinkan <ph name="EXTENSIONS_REQUESTING_ACCESS" /> membaca dan mengubah <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Sandi disimpan di Akun Google Anda</translation>
 <translation id="2031914984822377766">Tambahkan <ph name="LINK_BEGIN" />bahasa situs<ph name="LINK_END" /> pilihan Anda. Bahasa di bagian teratas daftar akan digunakan untuk terjemahan.</translation>
 <translation id="2033758234986231162">Tidak dapat mempertahankan koneksi dengan ponsel Anda. Pastikan ponsel di dekat Anda, tidak terkunci, serta Bluetooth dan Wi-Fi aktif.</translation>
@@ -1468,6 +1471,7 @@
 <translation id="2328561734797404498">Mulai ulang perangkat Anda untuk menggunakan <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Jika Anda menggunakan mode Samaran, situs hanya dapat menggunakan cookie untuk melihat aktivitas penjelajahan Anda di situsnya. Cookie akan dihapus pada akhir sesi Samaran.</translation>
 <translation id="2329597144923131178">Login untuk mendapatkan bookmark, histori, sandi, dan setelan Anda lainnya di semua perangkat.</translation>
+<translation id="2332115969598251205">Tidak dapat memuat perangkat yang disimpan ke <ph name="PRIMARY_EMAIL" />. Periksa koneksi internet Anda, lalu coba lagi.</translation>
 <translation id="2332131598580221120">Lihat di toko</translation>
 <translation id="2332192922827071008">Buka Preferensi</translation>
 <translation id="2332515770639153015">Safe Browsing yang Disempurnakan aktif</translation>
@@ -1911,6 +1915,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Periksa Grammar Dengan Ejaaan</translation>
 <translation id="2753677631968972007">Kontrol izin situs secara manual.</translation>
+<translation id="2754226775788136540">Mencari perangkat Sambungan Cepat yang disimpan ke <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Mulai dari produktivitas hingga hiburan, temukan berbagai aplikasi yang Anda butuhkan di Google Play Store. Anda dapat menginstal aplikasi kapan saja.</translation>
 <translation id="2755349111255270002">Reset <ph name="DEVICE_TYPE" /> ini</translation>
 <translation id="2755367719610958252">Kelola fitur aksesibilitas</translation>
@@ -2126,6 +2131,7 @@
 <translation id="2942279350258725020">Android Message</translation>
 <translation id="2942560570858569904">Menunggu...</translation>
 <translation id="2942581856830209953">Sesuaikan halaman ini</translation>
+<translation id="2943268899142471972">Pilih Playbook Ansible atau file cadangan Crostini</translation>
 <translation id="2944060181911631861">Kirim data penggunaan dan diagnostik. Bantuan sempurnakan pengalaman Android Anda dengan otomatis mengirim data diagnostik, perangkat, dan penggunaan aplikasi ke Google. Data ini akan membantu sistem dan stabilitas aplikasi serta peningkatan lainnya. Beberapa data gabungan juga akan membantu aplikasi dan partner Google, seperti developer Android. Jika setelan Aktivitas Web &amp; Aplikasi tambahan diaktifkan, data ini mungkin akan disimpan ke Akun Google Anda. <ph name="BEGIN_LINK1" />Pelajari Lebih Lanjut<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Buka file</translation>
 <translation id="2946119680249604491">Tambahkan koneksi</translation>
@@ -2966,6 +2972,7 @@
 <translation id="3784472333786002075">Cookie adalah file yang dibuat oleh situs. Terdapat dua jenis cookie: Cookie pihak pertama dibuat oleh situs yang Anda kunjungi. Situs tersebut ditampilkan di kolom URL. Cookie pihak ketiga dibuat oleh situs lain. Situs ini memiliki beberapa konten, seperti iklan atau gambar, yang dilihat di situs yang Anda kunjungi.</translation>
 <translation id="3785308913036335955">Tampilkan Pintasan Aplikasi</translation>
 <translation id="3785727820640310185">Sandi yang tersimpan untuk situs ini</translation>
+<translation id="3787434344076711519">Menunggu terjemahan</translation>
 <translation id="3788301286821743879">Aplikasi kios tidak dapat diluncurkan.</translation>
 <translation id="3788331399335602504">file berikut</translation>
 <translation id="3788401245189148511">Aplikasi/ekstensi dapat:</translation>
@@ -3249,6 +3256,7 @@
 <translation id="4036778507053569103">Kebijakan yang didownload dari server tidak valid.</translation>
 <translation id="4037084878352560732">Kuda</translation>
 <translation id="403725336528835653">Coba dulu</translation>
+<translation id="4040041015953651705">Bahasa sumber</translation>
 <translation id="4040105702484676956">Hapus data situs dan izin untuk <ph name="SITE_NAME" /> dan aplikasi terinstalnya?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Keluar dari Halaman}other{Keluar dari Halaman}}</translation>
 <translation id="4043267180218562935">Ukuran kursor</translation>
@@ -4055,6 +4063,7 @@
 <translation id="4838170306476614339">Lihat foto, media, dan notifikasi ponsel</translation>
 <translation id="4838836835474292213">Akses baca papan klip diizinkan</translation>
 <translation id="4838907349371614303">Sandi diperbarui</translation>
+<translation id="4838958829619609362"><ph name="LANGUAGE" /> tidak tersedia</translation>
 <translation id="4839303808932127586">Sim&amp;pan video sebagai...</translation>
 <translation id="4840096453115567876">Tetap keluar dari mode Samaran?</translation>
 <translation id="4841741146571978176">Mesin virtual yang diperlukan tidak ada. Coba siapkan <ph name="VM_TYPE" /> untuk melanjutkan</translation>
@@ -4826,6 +4835,7 @@
 <translation id="558918721941304263">Memuat aplikasi...</translation>
 <translation id="5590418976913374224">Putar suara saat perangkat dinyalakan</translation>
 <translation id="5592595402373377407">Data yang tersedia belum cukup.</translation>
+<translation id="5594899180331219722">Pilih file</translation>
 <translation id="5595307023264033512">Total penyimpanan yang digunakan oleh situs: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Edit alamat</translation>
 <translation id="5596627076506792578">Opsi lainnya</translation>
@@ -5058,6 +5068,7 @@
 <translation id="5834581999798853053">Sekitar <ph name="TIME" /> menit lagi</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - Perekaman kamera atau mikrofon</translation>
 <translation id="583673505367439042">Situs dapat meminta untuk mengedit file dan folder di perangkat Anda</translation>
+<translation id="5836999627049108525">Bahasa Sumber</translation>
 <translation id="583756221537636748">Casing</translation>
 <translation id="5840658767386246331">Telusuri dengan Google</translation>
 <translation id="5840680448799937675">File akan selalu dibagikan secara offline</translation>
@@ -5568,6 +5579,7 @@
 <translation id="6318944945640833942">Tidak dapat mendeteksi printer. Harap masukkan alamat printer lagi.</translation>
 <translation id="6322370287306604163">Buka kunci lebih cepat dengan sidik jari</translation>
 <translation id="6322559670748154781">File ini tidak biasa didownload dan telah diblokir oleh Perlindungan Lanjutan</translation>
+<translation id="6324083483652497048">Klik untuk mengizinkan ekstensi ini membaca dan mengubah <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Edit pintasan</translation>
 <translation id="6325191661371220117">Nonaktifkan luncurkan otomatis</translation>
 <translation id="6326175484149238433">Hapus dari Chrome</translation>
@@ -6598,6 +6610,7 @@
 <translation id="7343372807593926528">Jelaskan masalahnya sebelum mengirim masukan.</translation>
 <translation id="7344585835349671209">Kelola sertifikat HTTPS/SSL di perangkat</translation>
 <translation id="7345706641791090287">Konfirmasi sandi Anda</translation>
+<translation id="7345919885156673810"><ph name="LANGUAGE" /> Tidak Tersedia</translation>
 <translation id="7346909386216857016">Oke, mengerti</translation>
 <translation id="7347452120014970266">Ini akan menghapus semua data dan cookie yang disimpan oleh <ph name="ORIGIN_NAME" /> dan aplikasi yang terinstal di dalamnya</translation>
 <translation id="7347751611463936647">Untuk menggunakan ekstensi ini, ketik "<ph name="EXTENSION_KEYWORD" />", lalu TAB, kemudian perintah atau penelusuran Anda.</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb
index f538fbf1..08c93f1ec 100644
--- a/chrome/app/resources/generated_resources_is.xtb
+++ b/chrome/app/resources/generated_resources_is.xtb
@@ -327,6 +327,7 @@
 <translation id="1307165550267142340">PIN-númerið þitt var búið til</translation>
 <translation id="1307431692088049276">Ekki spyrja aftur</translation>
 <translation id="1307559529304613120">Úbbs! Kerfinu tókst ekki að vista langtímaaðgangslykil forritaskila fyrir þetta tæki.</translation>
+<translation id="1312811472299082263">Búa til úr Ansible-handbók eða afriti Crostini-skráar</translation>
 <translation id="1313405956111467313">Sjálfvirk proxy-stilling</translation>
 <translation id="131364520783682672">Hástafalás</translation>
 <translation id="1313660246522271310">Þú verður skráð(ur) út af öllum vefsvæðum, þar á meðal opnum flipum</translation>
@@ -1110,6 +1111,7 @@
 <translation id="2028449514182362831">Eiginleikar sem þurfa hreyfiskynjara virka ekki</translation>
 <translation id="202918510990975568">Færðu inn aðgangsorðið til að stilla öryggi og innskráningu</translation>
 <translation id="2030455719695904263">Snertiflötur</translation>
+<translation id="2031385797619033640">Smelltu til að leyfa <ph name="EXTENSIONS_REQUESTING_ACCESS" /> að lesa og breyta <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Aðgangsorðið þitt er vistað á Google reikningnum þínum</translation>
 <translation id="2031914984822377766">Bættu við <ph name="LINK_BEGIN" />kjörtungumálum þínum fyrir vefsvæði<ph name="LINK_END" />. Efsta tungumál listans verður notað við þýðingar.</translation>
 <translation id="2033758234986231162">Ekki er hægt að halda tengingu við símann þinn. Gakktu úr skugga um að síminn sé nálægt þér, ólæstur og með kveikt á Bluetooth og Wi-Fi.</translation>
@@ -1469,6 +1471,7 @@
 <translation id="2328561734797404498">Endurræstu tækið til að nota <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Þegar þú notar huliðsstillingu geta vefsvæði aðeins notað fótspor til að sjá vafranotkun þína á sínu eigin vefsvæði. Fótsporum er eytt við lok hverrar huliðslotu.</translation>
 <translation id="2329597144923131178">Skráðu þig inn til að fá bókamerkin þín, ferilinn, aðgangsorð og aðrar stillingar í öll tækin þín.</translation>
+<translation id="2332115969598251205">Ekki tókst að hlaða tækjum sem eru vistuð á <ph name="PRIMARY_EMAIL" />. Athugaðu nettenginguna og reyndu aftur.</translation>
 <translation id="2332131598580221120">Skoða í verslun</translation>
 <translation id="2332192922827071008">Opna kjörstillingar</translation>
 <translation id="2332515770639153015">Kveikt er á enn öruggari vefskoðun</translation>
@@ -1912,6 +1915,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Athuga málfræði og stafsetningu</translation>
 <translation id="2753677631968972007">Stjórna vefsvæðaheimildum handvirkt.</translation>
+<translation id="2754226775788136540">Leitar að hraðpörunartækjum sem eru vistuð á <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Öll forrit sem þú þarft á að halda til að auka afköst og til afþreyingar er að finna í Google Play Store. Þú getur sett upp forrit hvenær sem er.</translation>
 <translation id="2755349111255270002">Endurstilla þetta <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Stjórna aðgengiseiginleikum</translation>
@@ -2127,6 +2131,7 @@
 <translation id="2942279350258725020">Skilaboð í Android</translation>
 <translation id="2942560570858569904">Bíður...</translation>
 <translation id="2942581856830209953">Sérsníða þessa síðu</translation>
+<translation id="2943268899142471972">Veldu Ansible-handbók eða afrit Crostini-skráar</translation>
 <translation id="2944060181911631861">Senda notkunar- og greiningargögn. Hjálpaðu okkur að bæta Android fyrir þig með því að senda sjálfkrafa greiningargögn, tækisgögn og upplýsingar um forritanotkun til Google. Þetta mun stuðla að því að bæta stöðugleika kerfa og forrita auk annarra endurbóta. Sum uppsöfnuð gögn munu einnig gagnast forritum og samstarfsaðilum Google, til dæmis þróunaraðilum Android. Ef kveikt er á ítarlegri vef- og forritavirkni geta þessi gögn verið vistuð á Google reikningnum þínum. <ph name="BEGIN_LINK1" />Frekari upplýsingar<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Opna skrár</translation>
 <translation id="2946119680249604491">Bæta tengingu við</translation>
@@ -2967,6 +2972,7 @@
 <translation id="3784472333786002075">Fótspor eru skrár sem vefsvæði búa til. Það eru tvær tegundir af fótsporum: Fótspor frá fyrsta aðila eru búin til af vefsvæðinu sem þú heimsækir. Vefsvæðið kemur fram á veffangastikunni. Fótspor frá þriðja aðila eru búin til af öðrum vefsvæðum. Þessi vefsvæði eiga eitthvað af efninu, eins og auglýsingar eða myndir, sem þú sérð á vefsvæðinu sem þú heimsækir.</translation>
 <translation id="3785308913036335955">Sýna flýtileiðir í forrit</translation>
 <translation id="3785727820640310185">Vistuð aðgangsorð fyrir þetta vefsvæði</translation>
+<translation id="3787434344076711519">Bíður eftir þýðingu</translation>
 <translation id="3788301286821743879">Ekki var hægt að ræsa sjálfsalaforritið.</translation>
 <translation id="3788331399335602504">þessar skrár</translation>
 <translation id="3788401245189148511">Þetta kann að:</translation>
@@ -3250,6 +3256,7 @@
 <translation id="4036778507053569103">Reglan sem sótt var frá þjóninum er ógild.</translation>
 <translation id="4037084878352560732">Hestur</translation>
 <translation id="403725336528835653">Prófaðu þetta fyrst</translation>
+<translation id="4040041015953651705">Tungumál sem á að þýða úr</translation>
 <translation id="4040105702484676956">Hreinsa vefsvæðisgögn og heimildir fyrir <ph name="SITE_NAME" /> og uppsett forrit?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Loka síðu}one{Loka síðum}other{Loka síðum}}</translation>
 <translation id="4043267180218562935">Stærð bendils</translation>
@@ -4056,6 +4063,7 @@
 <translation id="4838170306476614339">Skoðaðu myndir, margmiðlunarefni og tilkynningar símans</translation>
 <translation id="4838836835474292213">Lestraraðgangur að klippiborðinu leyfður</translation>
 <translation id="4838907349371614303">Aðgangsorð uppfært</translation>
+<translation id="4838958829619609362">Val er ekki stillt á <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">&amp;Vista myndskeið sem...</translation>
 <translation id="4840096453115567876">Viltu samt loka huliðsstillingu?</translation>
 <translation id="4841741146571978176">Áskilin sýndarvél er ekki til staðar. Reyndu að setja upp <ph name="VM_TYPE" /> til að halda áfram</translation>
@@ -4827,6 +4835,7 @@
 <translation id="558918721941304263">Hleður forrit...</translation>
 <translation id="5590418976913374224">Spila hljóð þegar kveikt er á tæki</translation>
 <translation id="5592595402373377407">Ekki næg gögn komin enn.</translation>
+<translation id="5594899180331219722">Velja skrá</translation>
 <translation id="5595307023264033512">Heildargeymslurými sem vefsvæði nota: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Breyta heimilisfangi</translation>
 <translation id="5596627076506792578">Fleiri valkostir</translation>
@@ -5059,6 +5068,7 @@
 <translation id="5834581999798853053">Um <ph name="TIME" /> mínútur eftir</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – upptaka á myndavél eða hljóðnema</translation>
 <translation id="583673505367439042">Vefsvæði geta beðið um leyfi til að breyta skrám og möppum í tækinu þínu</translation>
+<translation id="5836999627049108525">Tungumál sem á að þýða úr</translation>
 <translation id="583756221537636748">Hulstur</translation>
 <translation id="5840658767386246331">Leita með Google</translation>
 <translation id="5840680448799937675">Skrám verður alltaf deilt án nettengingar</translation>
@@ -5569,6 +5579,7 @@
 <translation id="6318944945640833942">Ekki tókst að greina prentara. Sláðu veffang prentara inn aftur.</translation>
 <translation id="6322370287306604163">Þú ert fljótari að taka úr lás með fingrafari</translation>
 <translation id="6322559670748154781">Þessi skrá er ekki sótt oft og ítarleg vernd setti hana á bannlista</translation>
+<translation id="6324083483652497048">Smelltu til að leyfa viðbótunum að lesa og breyta <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Breyta flýtileið</translation>
 <translation id="6325191661371220117">Slökkva á sjálfvirkri ræsingu</translation>
 <translation id="6326175484149238433">Fjarlægja úr Chrome</translation>
@@ -6601,6 +6612,7 @@
 <translation id="7343372807593926528">Lýstu vandamálinu áður en þú sendir ábendingu.</translation>
 <translation id="7344585835349671209">Stjórna HTTPS-/SSL-vottorðum í tækinu þínu</translation>
 <translation id="7345706641791090287">Staðfestu aðgangsorðið þitt</translation>
+<translation id="7345919885156673810">Val er ekki stillt á <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Ég skil</translation>
 <translation id="7347452120014970266">Þetta hreinsar öll gögn og fótspor sem <ph name="ORIGIN_NAME" /> og uppsett forrit þess hafa vistað</translation>
 <translation id="7347751611463936647">Til að nota þessa viðbót skaltu slá inn „<ph name="EXTENSION_KEYWORD" />“, ýta á Tab-lykilinn og slá síðan inn skipun eða leitarorð.</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index a2c55dcb4..812bc2b 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -275,6 +275,7 @@
 <translation id="125220115284141797">Predefiniti</translation>
 <translation id="1252987234827889034">Errore con il profilo</translation>
 <translation id="1254593899333212300">Connessione diretta a Internet</translation>
+<translation id="1257336506558170607">Esporta certificato selezionato</translation>
 <translation id="1258491128795710625">Novità</translation>
 <translation id="1259152067760398571">Il controllo di sicurezza è stato eseguito ieri</translation>
 <translation id="1260451001046713751">Consenti sempre popup e reindirizzamenti da <ph name="HOST" /></translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index d257443..3a7b189 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -279,6 +279,7 @@
 <translation id="125220115284141797">ברירת מחדל</translation>
 <translation id="1252987234827889034">אירעה שגיאה בפרופיל</translation>
 <translation id="1254593899333212300">חיבור אינטרנט ישיר</translation>
+<translation id="1257336506558170607">ייצוא האישור שנבחר</translation>
 <translation id="1258491128795710625">מה חדש</translation>
 <translation id="1259152067760398571">בדיקת הבטיחות פעלה אתמול</translation>
 <translation id="1260451001046713751">התרה תמיד של חלונות קופצים והפניות אוטומטיות מ-<ph name="HOST" /></translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb
index 4183cd3..3864133 100644
--- a/chrome/app/resources/generated_resources_kn.xtb
+++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -3278,6 +3278,7 @@
 <translation id="4062561150282203854">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಆ್ಯಪ್‌ಗಳು, ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಹಾಗೂ ಇತ್ಯಾದಿಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಿ</translation>
 <translation id="4065876735068446555">ನೀವು ಬಳಸುತ್ತಿರುವ ನೆಟ್‌ವರ್ಕ್ (<ph name="NETWORK_ID" />) ನ ಲಾಗಿನ್ ಪುಟಕ್ಕೆ ಭೇಟಿ ನೀಡಬೇಕಾದ ಅಗತ್ಯವಿದೆ.</translation>
 <translation id="4066207411788646768">ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ಲಭ್ಯವಿರುವ ಪ್ರಿಂಟರ್‌ಗಳನ್ನು ನೋಡಲು, ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಿ</translation>
+<translation id="4066945815577305767">ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ದೃಢೀಕರಣ ಅವಧಿ ಮೀರಿದೆ</translation>
 <translation id="4068776064906523561">ಉಳಿಸಿದ ಬೆರಳಚ್ಚುಗಳು</translation>
 <translation id="407173827865827707">ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ</translation>
 <translation id="4072701974556190758">ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ <ph name="ACCOUNT" /> ಉಳಿಸಲಾಗುತ್ತದೆ. ನೀವು ಅದನ್ನು ನೆನಪಿಟ್ಟುಕೊಳ್ಳಬೇಕಾಗಿಲ್ಲ.</translation>
@@ -5586,6 +5587,7 @@
 <translation id="6335920438823100346">Linux ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು, ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಬ್ಯಾಕಪ್ ಮಾಡುವುದು ಮತ್ತು ಈ Chromebook ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ರಿಸೆಟ್ ಮಾಡುವುದನ್ನು <ph name="MANAGER" /> ಬಯಸುತ್ತದೆ.</translation>
 <translation id="6336038146639916978">ADB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು <ph name="MANAGER" /> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ. ಇದು ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಅನ್ನು 24 ಗಂಟೆಗಳಲ್ಲಿ ಮರುಹೊಂದಿಸುತ್ತದೆ. ನೀವು ಇರಿಸಿಕೊಳ್ಳಲು ಬಯಸುವ ಯಾವುದೇ ಫೈಲ್‌ಗಳನ್ನು ಬ್ಯಾಕಪ್ ಮಾಡಿ.</translation>
 <translation id="6338402296920404442"><ph name="FILENAME" /> ಅನ್ನು ಅಳಿಸಲು ಪರಿಗಣಿಸಿ, ಆದ್ದರಿಂದ ಈ ಸಾಧನವನ್ನು ಬಳಸುವ ಇತರರು ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ನೋಡಲಾಗುವುದಿಲ್ಲ.</translation>
+<translation id="6338968693068997776">USB ಸಾಧನವನ್ನು ಸೇರಿಸಿ</translation>
 <translation id="6338981933082930623">ಎಲ್ಲಾ ಸೈಟ್‌ಗಳು ನಿಮಗೆ ಯಾವುದಾದರೂ ಜಾಹೀರಾತುಗಳನ್ನು ತೋರಿಸಬಹುದು</translation>
 <translation id="6339668969738228384"><ph name="USER_EMAIL_ADDRESS" /> ಗೆ ಹೊಸ ಪ್ರೊಫೈಲ್ ಅನ್ನು ರಚಿಸಿ</translation>
 <translation id="6340071272923955280">ಇಂಟರ್ನೆಟ್ ಮುದ್ರಿಸುವಿಕೆಯ ಪ್ರೊಟೊಕಾಲ್ (IPPS)</translation>
@@ -6185,6 +6187,7 @@
 <translation id="6903907808598579934">ಸಿಂಕ್‌ ಆನ್‌ ಮಾಡಿ</translation>
 <translation id="6904344821472985372">ಫೈಲ್ ಪ್ರವೇಶವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ</translation>
 <translation id="6904655473976120856">ನಿರ್ಗಮಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಬಟನ್‌ ಅನ್ನು ಒತ್ತಿ</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಸುರಕ್ಷಿತವಾಗಿರಿಸಲು, 1 ನಿಮಿಷದ ನಿಷ್ಕ್ರಿಯತೆಯ ನಂತರ Google Password Manager ಲಾಕ್ ಆಗುತ್ತದೆ}one{ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಸುರಕ್ಷಿತವಾಗಿರಿಸಲು, {NUM_MINS} ನಿಮಿಷಗಳ ನಿಷ್ಕ್ರಿಯತೆಯ ನಂತರ Google Password Manager ಲಾಕ್ ಆಗುತ್ತದೆ}other{ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಸುರಕ್ಷಿತವಾಗಿರಿಸಲು, {NUM_MINS} ನಿಮಿಷಗಳ ನಿಷ್ಕ್ರಿಯತೆಯ ನಂತರ Google Password Manager ಲಾಕ್ ಆಗುತ್ತದೆ}}</translation>
 <translation id="6909422577741440844">ಈ ಸಾಧನದಿಂದ ಸ್ವೀಕರಿಸಬೇಕೇ?</translation>
 <translation id="6910211073230771657">ಅಳಿಸಲಾಗಿದೆ</translation>
 <translation id="691106080621596509"><ph name="SITE_GROUP_NAME" /> ಹಾಗೂ ಇದಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಯಾವುದೇ ಸೈಟ್‌ಗಳು ಮತ್ತು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ ಮೂಲಕ ಸಂಗ್ರಹಿಸಲಾದ ಎಲ್ಲಾ ಡೇಟಾ ಮತ್ತು ಕುಕೀಗಳನ್ನು ಇದು ತೆರವುಗೊಳಿಸುತ್ತದೆ</translation>
@@ -8023,6 +8026,7 @@
 <translation id="8688672835843460752">ಲಭ್ಯವಿದೆ</translation>
 <translation id="8690129572193755009">ಪ್ರೊಟೊಕಾಲ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಸೈಟ್‌ಗಳು ಕೇಳಬಹುದು</translation>
 <translation id="8692107307702113268">ಪಾಸ್‌ವರ್ಡ್ 1000 ಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಅಕ್ಷರಗಳನ್ನು ಹೊಂದಿದೆ</translation>
+<translation id="8694596275649352090">ಮಲಗುವಾಗ ಅಥವಾ ಮುಚ್ಚಳವು ಮುಚ್ಚಿರುವಾಗ ಲಾಕ್ ಮಾಡಿ</translation>
 <translation id="8695139659682234808">ಸೆಟಪ್‌ನ ನಂತರ ಪೋಷಕ ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ</translation>
 <translation id="8695825812785969222">&amp;ಸ್ಥಾನವನ್ನು ತೆರೆಯಿರಿ...</translation>
 <translation id="8698269656364382265">ಹಿಂದಿನ ಸ್ಕ್ರೀನ್‌ಗೆ ಮರಳಲು, ಎಡ ಬದಿಯಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ.</translation>
@@ -8071,6 +8075,7 @@
 <translation id="8732844209475700754">ಗೌಪ್ಯತೆ, ಸುರಕ್ಷತೆ ಮತ್ತು ಡೇಟಾ ಸಂಗ್ರಹಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಇನ್ನಷ್ಟು ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
 <translation id="8734073480934656039">ಈ ಸೆಟ್ಟಿಂಗ್‍‍ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವುದರಿಂದ ಆರಂಭಿಸುವಿಕೆಯಲ್ಲಿ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕಿಯೋಸ್ಕ್ ಅಪ್ಲಿಕೇಶನ್‍ ಅನ್ನು ಲಾಂಚ್ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ.</translation>
 <translation id="8734674662128056360">ಮೂರನೇ-ವ್ಯಕ್ತಿ ಕುಕೀ ನಿರ್ಬಂಧಿಸುವಿಕೆ</translation>
+<translation id="8734755021067981851">ಯಾವುದೇ USB ಸಾಧನಗಳನ್ನು ಸೇರಿಸಲಾಗಿಲ್ಲ.</translation>
 <translation id="873545264931343897"><ph name="PLUGIN_NAME" /> ಅಪ್‌‌ಡೇಟ್‌ ಮುಕ್ತಾಯಗೊಳಿಸುವಾಗ, ಅದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ಪುಟವನ್ನು ಮರುಲೋಡ್ ಮಾಡಿ</translation>
 <translation id="8736288397686080465">ಈ ಸೈಟ್ ಅನ್ನು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲಾಗಿದೆ.</translation>
 <translation id="8737709691285775803">ಶಿಲ್</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index 31b2317..ed42891 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">기본</translation>
 <translation id="1252987234827889034">프로필 오류가 발생했습니다.</translation>
 <translation id="1254593899333212300">인터넷에 바로 연결</translation>
+<translation id="1257336506558170607">선택한 인증서 내보내기</translation>
 <translation id="1258491128795710625">새로운 기능</translation>
 <translation id="1259152067760398571">안전 확인이 어제 실행됨</translation>
 <translation id="1260451001046713751"><ph name="HOST" />에서 팝업 및 리디렉션을 항상 허용</translation>
@@ -326,6 +327,7 @@
 <translation id="1307165550267142340">PIN이 생성되었습니다.</translation>
 <translation id="1307431692088049276">다시 묻지 않음</translation>
 <translation id="1307559529304613120">시스템이 이 기기에 대한 장기 API 액세스 토큰을 저장하지 못했습니다.</translation>
+<translation id="1312811472299082263">Ansible Playbook 또는 Crostini 백업 파일에서 만들기</translation>
 <translation id="1313405956111467313">자동 프록시 설정</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">열려 있는 탭을 포함한 모든 사이트에서 로그아웃됩니다.</translation>
@@ -1109,6 +1111,7 @@
 <translation id="2028449514182362831">움직임 감지 센서가 필요한 기능이 작동하지 않음</translation>
 <translation id="202918510990975568">비밀번호를 입력하여 보안을 구성하고 로그인하세요.</translation>
 <translation id="2030455719695904263">트랙패드</translation>
+<translation id="2031385797619033640">클릭하여 <ph name="EXTENSIONS_REQUESTING_ACCESS" /> 확장 프로그램이 <ph name="ORIGIN" /> 사이트를 읽고 변경하도록 허용합니다.</translation>
 <translation id="2031639749079821948">비밀번호가 Google 계정에 저장되었습니다.</translation>
 <translation id="2031914984822377766">선호하는 <ph name="LINK_BEGIN" />웹사이트 언어<ph name="LINK_END" />를 추가하세요. 번역 시 목록의 가장 위에 있는 언어가 사용됩니다.</translation>
 <translation id="2033758234986231162">휴대전화와 연결을 유지할 수 없습니다. 휴대전화가 근처에 있고, 잠금 해제되어 있으며, 블루투스와 Wi-Fi가 켜져 있는지 확인하세요.</translation>
@@ -1469,6 +1472,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" /> 앱을 사용하려면 기기를 다시 시작해 주세요.</translation>
 <translation id="2328636661627946415">시크릿 모드에서 사이트는 사용자의 사이트 내 탐색 활동을 보기 위해서만 쿠키를 사용할 수 있습니다. 시크릿 세션이 종료되면 쿠키가 삭제됩니다.</translation>
 <translation id="2329597144923131178">로그인하면 모든 기기에서 북마크, 방문 기록, 비밀번호, 기타 설정을 사용할 수 있습니다.</translation>
+<translation id="2332115969598251205"><ph name="PRIMARY_EMAIL" />에 저장된 기기를 로드할 수 없습니다. 인터넷 연결을 확인하고 다시 시도해 보세요.</translation>
 <translation id="2332131598580221120">스토어에서 보기</translation>
 <translation id="2332192922827071008">환경설정 열기</translation>
 <translation id="2332515770639153015">향상된 세이프 브라우징 사용 설정됨</translation>
@@ -1912,6 +1916,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">영문 철자 및 문법 검사</translation>
 <translation id="2753677631968972007">사이트 권한을 수동으로 관리합니다.</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" />에 저장된 빠른 페어링 기기를 찾는 중</translation>
 <translation id="2754825024506485820">Google Play 스토어에서 생산성, 엔터테인먼트 등 나에게 필요한 다양한 앱을 찾아보세요. 언제든지 앱을 설치할 수 있습니다.</translation>
 <translation id="2755349111255270002"><ph name="DEVICE_TYPE" /> 초기화</translation>
 <translation id="2755367719610958252">접근성 기능 관리</translation>
@@ -2127,6 +2132,7 @@
 <translation id="2942279350258725020">Android 메시지</translation>
 <translation id="2942560570858569904">대기 중...</translation>
 <translation id="2942581856830209953">페이지 맞춤설정</translation>
+<translation id="2943268899142471972">Ansible Playbook 또는 Crostini 백업 파일 선택</translation>
 <translation id="2944060181911631861">사용 및 진단 데이터를 보냅니다. 진단, 기기, 앱 사용 데이터를 Google에 자동으로 보내 Android 사용 환경 개선에 참여합니다. 이 데이터는 시스템 및 앱 안정성 등을 개선하는 데 활용됩니다. 일부 수집 데이터는 Google 앱과 파트너(Android 개발자 등)에게도 도움을 줍니다. 추가 웹 및 앱 활동이 사용 설정되어 있다면 이 데이터가 Google 계정에 저장될 수 있습니다. <ph name="BEGIN_LINK1" />자세히 알아보기<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">파일로 이동</translation>
 <translation id="2946119680249604491">연결 추가</translation>
@@ -2967,6 +2973,7 @@
 <translation id="3784472333786002075">쿠키는 웹사이트에서 생성된 파일로, 다음과 같은 2가지 유형이 있습니다. 제1사 쿠키는 사용자가 방문하는 사이트에 의해 생성됩니다. 이때 사이트가 주소 표시줄에 나타납니다. 제3사 쿠키는 다른 사이트, 즉 광고나 이미지 등 사용자가 방문하는 웹사이트에 표시되는 일부 콘텐츠를 소유한 사이트에 의해 생성됩니다.</translation>
 <translation id="3785308913036335955">앱 단축키 표시</translation>
 <translation id="3785727820640310185">이 사이트의 저장된 비밀번호</translation>
+<translation id="3787434344076711519">번역 대기 중</translation>
 <translation id="3788301286821743879">키오스크 애플리케이션을 시작할 수 없습니다.</translation>
 <translation id="3788331399335602504">파일</translation>
 <translation id="3788401245189148511">이전에 가능했던 대상:</translation>
@@ -3250,6 +3257,7 @@
 <translation id="4036778507053569103">서버에서 다운로드한 정책이 올바르지 않습니다.</translation>
 <translation id="4037084878352560732">말</translation>
 <translation id="403725336528835653">먼저 사용해 보기</translation>
+<translation id="4040041015953651705">출발 언어</translation>
 <translation id="4040105702484676956"><ph name="SITE_NAME" /> 및 설치된 앱의 사이트 데이터와 권한을 삭제하시겠습니까?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{페이지 나가기}other{페이지 나가기}}</translation>
 <translation id="4043267180218562935">커서 크기</translation>
@@ -4054,6 +4062,7 @@
 <translation id="4838170306476614339">휴대전화의 사진, 미디어, 알림을 봅니다.</translation>
 <translation id="4838836835474292213">클립보드 읽기 액세스 허용됨</translation>
 <translation id="4838907349371614303">비밀번호가 업데이트됨</translation>
+<translation id="4838958829619609362">선택 항목이 <ph name="LANGUAGE" />로 제공되지 않음</translation>
 <translation id="4839303808932127586">동영상을 다른 이름으로 저장...(&amp;V)</translation>
 <translation id="4840096453115567876">시크릿 모드를 종료하시겠습니까?</translation>
 <translation id="4841741146571978176">필수 가상 머신이 존재하지 않습니다. 계속하려면 <ph name="VM_TYPE" /> VM을 설정해 보세요.</translation>
@@ -4825,6 +4834,7 @@
 <translation id="558918721941304263">앱 로드 중...</translation>
 <translation id="5590418976913374224">기기 시작 시 소리 재생</translation>
 <translation id="5592595402373377407">아직 데이터가 충분하지 않습니다.</translation>
+<translation id="5594899180331219722">파일 선택</translation>
 <translation id="5595307023264033512">사이트에서 사용 중인 총 저장용량: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">주소 수정</translation>
 <translation id="5596627076506792578">옵션 더보기</translation>
@@ -5057,6 +5067,7 @@
 <translation id="5834581999798853053">약 <ph name="TIME" />분 남음</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - 카메라 또는 마이크 녹음</translation>
 <translation id="583673505367439042">사이트에서 기기의 파일 및 폴더 수정을 요청할 수 있음</translation>
+<translation id="5836999627049108525">출발 언어</translation>
 <translation id="583756221537636748">케이스</translation>
 <translation id="5840658767386246331">Google로 검색</translation>
 <translation id="5840680448799937675">항상 오프라인으로 파일 공유</translation>
@@ -5567,6 +5578,7 @@
 <translation id="6318944945640833942">프린터를 찾을 수 없습니다. 프린터 주소를 다시 입력해 주세요.</translation>
 <translation id="6322370287306604163">지문으로 신속하게 잠금 해제</translation>
 <translation id="6322559670748154781">일반적으로 다운로드하지 않는 파일이며, 고급 보호 기능으로 차단되었습니다</translation>
+<translation id="6324083483652497048">클릭하여 다음 확장 프로그램이 <ph name="ORIGIN" /> 사이트를 읽고 변경하도록 허용합니다.</translation>
 <translation id="6324916366299863871">바로가기 수정</translation>
 <translation id="6325191661371220117">자동 실행 사용 안함</translation>
 <translation id="6326175484149238433">Chrome에서 삭제</translation>
@@ -6597,6 +6609,7 @@
 <translation id="7343372807593926528">의견을 보내기 전에 문제를 설명해 주세요.</translation>
 <translation id="7344585835349671209">기기에서 HTTPS/SSL 인증서 관리</translation>
 <translation id="7345706641791090287">비밀번호 확인</translation>
+<translation id="7345919885156673810">선택 항목이 <ph name="LANGUAGE" />로 제공되지 않음</translation>
 <translation id="7346909386216857016">확인</translation>
 <translation id="7347452120014970266"><ph name="ORIGIN_NAME" /> 및 설치된 앱에서 저장한 모든 데이터와 쿠키가 삭제됩니다.</translation>
 <translation id="7347751611463936647">이 확장 프로그램을 사용하려면 '<ph name="EXTENSION_KEYWORD" />'(을)를 입력하고 TAB을 누른 다음 명령어 또는 검색어를 입력하세요.</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb
index 969878d..7544c0b 100644
--- a/chrome/app/resources/generated_resources_ky.xtb
+++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -327,6 +327,7 @@
 <translation id="1307165550267142340">PIN кодуңуз түзүлдү</translation>
 <translation id="1307431692088049276">Экинчи суралбасын</translation>
 <translation id="1307559529304613120">Ой! Тутум бул түзмөктүн узак мөөнөттүү API энбелгисин сактап калган жок.</translation>
+<translation id="1312811472299082263">Камдык көчүрмөсү сакталган Ansible Playbook же Crostini файлынан түзүү</translation>
 <translation id="1313405956111467313">Автоматтык прокси конфигурациясы</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Бардык сайттардан, анын ичинде ачылып турган өтмөктөрдөн чыгасыз</translation>
@@ -1110,6 +1111,7 @@
 <translation id="2028449514182362831">Кыймыл сенсорун колдонгон функциялар иштебейт</translation>
 <translation id="202918510990975568">Коопсуздукту жана кирүү параметрлерин жөндөө үчүн сырсөзүңүздү киргизиңиз</translation>
 <translation id="2030455719695904263">Трекпад</translation>
+<translation id="2031385797619033640"><ph name="EXTENSIONS_REQUESTING_ACCESS" /> кеңейтүүсүнө <ph name="ORIGIN" /> булагын окуп жана өзгөртүүгө уруксат берүү үчүн чыкылдатыңыз:</translation>
 <translation id="2031639749079821948">Сырсөзүңүз Google аккаунтуңузда сакталды</translation>
 <translation id="2031914984822377766">Вебсайт үчүн артыкчылыктуу <ph name="LINK_BEGIN" />тилдериңизди<ph name="LINK_END" /> кошуңуз. Тексттер тизменин башында турган тилге которулат.</translation>
 <translation id="2033758234986231162">Телефонуңузга туташпай калды. Телефонуңуз жакын жерде турганын жана анын кулпусу ачык болуп, Bluetooth менен Wi-Fi күйгүзүлгөнүн текшериңиз.</translation>
@@ -1469,6 +1471,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" /> колдонмосун ачуудан мурда үчүн түзмөгүңүздү өчүрүп күйгүзүңүз.</translation>
 <translation id="2328636661627946415">Жашыруун режимде болгонуңузда сайттар cookie файлдары аркылуу гана сайтында көрүлгөн барактарды көрө алышат. Жашыруун сеанстын аягында cookie файлдары өчүрүлөт.</translation>
 <translation id="2329597144923131178">Бардык түзмөктөрүңүздөн кыстармаларды, таржымалды, сырсөздөрдү жана башка жөндөөлөрүңүздү алуу үчүн аккаунтка кириңиз.</translation>
+<translation id="2332115969598251205">Төмөнкүгө сакталган түзмөктөр жүктөлбөй жатат: <ph name="PRIMARY_EMAIL" />. Интернет байланышыңызды текшерип, кайталап көрүңүз.</translation>
 <translation id="2332131598580221120">Дүкөндөн карап көрүү</translation>
 <translation id="2332192922827071008">Жеке параметрлерди ачуу</translation>
 <translation id="2332515770639153015">Өркүндөтүлгөн коопсуз серептөө күйүк</translation>
@@ -1912,6 +1915,7 @@
 <translation id="2749836841884031656">SIM-карта</translation>
 <translation id="2749881179542288782">Орфография менен грамматиканы айкалыштырып текшерүү</translation>
 <translation id="2753677631968972007">Сайттын уруксаттарын кол менен текшерүү.</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" /> аккаунтуна сакталган Fast Pair түзмөктөрү изделүүдө</translation>
 <translation id="2754825024506485820">Google Play Store'дон керектүү колдонмолорду (иштин майнаптуулугун арттыруучу, көңүл ачуучу, ж.б.) табыңыз. Колдонмолорду каалаган убакта орното аласыз.</translation>
 <translation id="2755349111255270002"><ph name="DEVICE_TYPE" /> түзмөгүн баштапкы абалга келтириңиз</translation>
 <translation id="2755367719610958252">Атайын мүмкүнчүлүктөрдү башкаруу</translation>
@@ -2127,6 +2131,7 @@
 <translation id="2942279350258725020">Android жазышуулары</translation>
 <translation id="2942560570858569904">Күтүп жатат…</translation>
 <translation id="2942581856830209953">Бул баракты ыңгайлаштыруу</translation>
+<translation id="2943268899142471972">Камдык көчүрмөсү сакталган Ansible Playbook же Crostini файлын тандоо</translation>
 <translation id="2944060181911631861">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Google'га мүчүлүштүктөрдү аныктоо жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө жөнөтүп, Android'де иштөө тажрыйбаңызды жакшыртууга жардам бериңиз. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым нерселердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK1" />Кеңири маалымат<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Файлдарга өтүү</translation>
 <translation id="2946119680249604491">Туташуу кошуу</translation>
@@ -2967,6 +2972,7 @@
 <translation id="3784472333786002075">Cookie файлдары вебсайттарда түзүлөт. Алардын эки түрү болот: Жеке cookie файлдарын сиз баш баккан сайт өзү түзөт. Сайт дарек тилкесинде көрүнүп турат. Ал эми үчүнчү тараптардын cookie файлдарын сиз баш баккан сайтка жарнамалар же сүрөттөр сыяктуу материалдарын жайгаштырган башка сайттар түзүшөт.</translation>
 <translation id="3785308913036335955">Колдонмолор кыска жолун көрсөтүү</translation>
 <translation id="3785727820640310185">Бул сайт үчүн сакталган сырсөздөр</translation>
+<translation id="3787434344076711519">Которуу күтүлүүдө</translation>
 <translation id="3788301286821743879">Киоск колдонмосу ишке киргизилген жок.</translation>
 <translation id="3788331399335602504">бул файлдар</translation>
 <translation id="3788401245189148511">Мындай болмок:</translation>
@@ -3250,6 +3256,7 @@
 <translation id="4036778507053569103">Серверден жүктөлүп алынган саясат жараксыз.</translation>
 <translation id="4037084878352560732">Жылкы</translation>
 <translation id="403725336528835653">Байкап көрүү</translation>
+<translation id="4040041015953651705">Төмөнкү тилден которуу</translation>
 <translation id="4040105702484676956"><ph name="SITE_NAME" /> сайтындагы жана анын орнотулган колдонмосундагы маалыматтар жана уруксаттар тазалансынбы?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Барактан чыгуу}other{Барактардан чыгуу}}</translation>
 <translation id="4043267180218562935">Курсордун өлчөмү</translation>
@@ -4056,6 +4063,7 @@
 <translation id="4838170306476614339">Телефонуңуздагы сүрөттөрдү, медиа файлдарды жана билдирмелерди көрүү</translation>
 <translation id="4838836835474292213">Алмашуу буферин окууга уруксат берилди</translation>
 <translation id="4838907349371614303">Сырсөз жаңыртылды</translation>
+<translation id="4838958829619609362">Тандалган нерсе төмөнкү тилде эмес: <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Видеону төмөнкүдөй сак&amp;тоо…</translation>
 <translation id="4840096453115567876">Жашыруун режимден баары бир чыгасызбы?</translation>
 <translation id="4841741146571978176">Талап кылынган виртуалдык машина жок. Улантуу үчүн төмөнкүнү жөндөп көрүңүз: <ph name="VM_TYPE" /></translation>
@@ -4827,6 +4835,7 @@
 <translation id="558918721941304263">Колдонмолор жүктөлүүдө…</translation>
 <translation id="5590418976913374224">Түзмөк күйгүзүлгөндө сигналды ойнотуу</translation>
 <translation id="5592595402373377407">Жеткиликтүү дайындар жок.</translation>
+<translation id="5594899180331219722">Файл тандоо</translation>
 <translation id="5595307023264033512">Сайттар ээлеген жалпы орун: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Даректи өзгөртүү</translation>
 <translation id="5596627076506792578">Дагы параметрлер</translation>
@@ -5059,6 +5068,7 @@
 <translation id="5834581999798853053">Болжол менен <ph name="TIME" /> мүнөт калды</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – Видео же аудио жаздырылууда</translation>
 <translation id="583673505367439042">Сайттар сиздин уруксатыңыз менен түзмөгүңүздөгү файлдарды жана папкаларды түзөтө алат</translation>
+<translation id="5836999627049108525">Төмөнкү тилден которуу</translation>
 <translation id="583756221537636748">Кутуча</translation>
 <translation id="5840658767386246331">Google менен издөө</translation>
 <translation id="5840680448799937675">Файлдар ар дайым оффлайн режиминде бөлүшүлөт</translation>
@@ -5569,6 +5579,7 @@
 <translation id="6318944945640833942">Принтер аныкталган жок. Принтердин дарегин кайра киргизиңиз.</translation>
 <translation id="6322370287306604163">Манжаңыздын изи менен кулпусун тезирээк ачыңыз</translation>
 <translation id="6322559670748154781">Бул файл көп жүктөлүп алынбайт жана Өркүндөтүлгөн коргоо тарабынан бөгөттөлгөн</translation>
+<translation id="6324083483652497048">Бул кеңейтүүлөргө <ph name="ORIGIN" /> булагын окуп жана өзгөртүүгө уруксат берүү үчүн чыкылдатыңыз:</translation>
 <translation id="6324916366299863871">Кыска жолду түзөтүү</translation>
 <translation id="6325191661371220117">Авто-ишке киргизүүнү өчүрүп коюу</translation>
 <translation id="6326175484149238433">Chrome'дон алып салуу</translation>
@@ -6599,6 +6610,7 @@
 <translation id="7343372807593926528">Пикир жөнөтүүдөн мурун, көйгөйдү сүрөттөп берсеңиз.</translation>
 <translation id="7344585835349671209">Түзмөгүңүздөгү HTTPS/SSL тастыктамаларын башкаруу</translation>
 <translation id="7345706641791090287">Сырсөзүңүздү ырастаңыз</translation>
+<translation id="7345919885156673810">Тандалган нерсе төмөнкү тилде ЭМЕС: <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Жарайт, түшүндүм</translation>
 <translation id="7347452120014970266">Ушуну менен <ph name="ORIGIN_NAME" /> сакталган бардык маалымат жана cookie-файлдары, ошондой эле ал орноткон колдонмолор тазаланат</translation>
 <translation id="7347751611463936647">Бул кеңейтүүнү колдонуу үчүн алгач "<ph name="EXTENSION_KEYWORD" />", андан кийин TAB, андан соң буйрук же издөөңүздү териңиз.</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb
index a814b8bb..304a811 100644
--- a/chrome/app/resources/generated_resources_lo.xtb
+++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">ຄ່າເລີ່ມຕົ້ນ</translation>
 <translation id="1252987234827889034">ເກີດຄວາມຜິດພາດກັບໂປຣໄຟລ໌</translation>
 <translation id="1254593899333212300">ການເຊື່ອມຕໍ່ອິນເຕີເນັດໂດຍກົງ</translation>
+<translation id="1257336506558170607">ສົ່ງອອກໃບຮັບຮອງທີ່ເລືອກ</translation>
 <translation id="1258491128795710625">ມີຫຍັງໃໝ່</translation>
 <translation id="1259152067760398571">ດຳເນີນການກວດສອບຄວາມປອດໄພມື້ວານນີ້</translation>
 <translation id="1260451001046713751">ອະນຸຍາດປັອບອັບ ແລະ ການປ່ຽນເສັ້ນທາງຈາກ <ph name="HOST" /> ທຸກເທື່ອ</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index 005fc51..9be7694 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -280,6 +280,7 @@
 <translation id="125220115284141797">Numatytoji</translation>
 <translation id="1252987234827889034">Įvyko profilio klaida</translation>
 <translation id="1254593899333212300">Tiesioginis interneto ryšys</translation>
+<translation id="1257336506558170607">Eksportuoti pasirinktą sertifikatą</translation>
 <translation id="1258491128795710625">Kas naujo</translation>
 <translation id="1259152067760398571">Saugos patikra atlikta vakar</translation>
 <translation id="1260451001046713751">Visada leisti rodyti iššokančiuosius langus ir peradresavimus iš <ph name="HOST" /></translation>
@@ -329,6 +330,7 @@
 <translation id="1307165550267142340">PIN kodas sukurtas</translation>
 <translation id="1307431692088049276">Daugiau neklausti</translation>
 <translation id="1307559529304613120">Oi, sistemai nepavyko išsaugoti šio įrenginio ilgalaikio API prieigos kodo.</translation>
+<translation id="1312811472299082263">Kūrimas iš „Ansible Playbook“ ar „Crostini“ atsarginės kopijos failo</translation>
 <translation id="1313405956111467313">Automatinė tarpinio serverio konfigūracija</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Būsite atjungti nuo visų svetainių, įskaitant atidarytus skirtukus</translation>
@@ -1112,6 +1114,7 @@
 <translation id="2028449514182362831">Funkcijos, kurioms reikalingi judesio jutikliai, neveiks</translation>
 <translation id="202918510990975568">Įveskite slaptažodį ir konfigūruokite saugos bei prisijungimo nustatymus</translation>
 <translation id="2030455719695904263">Jutiklinė dalis</translation>
+<translation id="2031385797619033640">Spustelėkite, kad leistumėte „<ph name="EXTENSIONS_REQUESTING_ACCESS" />“ skaityti ir keisti <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Slaptažodis išsaugotas „Google“ paskyroje</translation>
 <translation id="2031914984822377766">Pridėkite pageidaujamas <ph name="LINK_BEGIN" />svetainės kalbas<ph name="LINK_END" />. Bus verčiama į sąrašo viršuje nurodytą kalbą.</translation>
 <translation id="2033758234986231162">Nepavyko išlaikyti ryšio su telefonu. Įsitikinkite, kad telefonas yra netoliese, atrakintas ir įjungtas „Bluetooth“ bei „Wi-Fi“.</translation>
@@ -1471,6 +1474,7 @@
 <translation id="2328561734797404498">Paleiskite įrenginį iš naujo, kad galėtumėte naudoti programą „<ph name="APP_NAME" />“.</translation>
 <translation id="2328636661627946415">Kai naršote inkognito režimu, svetainės gali naudoti slapukus, kad peržiūrėtų jūsų naršymo veiklą tik savo svetainėje. Pasibaigus inkognito režimo seansui slapukai ištrinami.</translation>
 <translation id="2329597144923131178">Pris. ir pas. žymių, ist., slapt. bei kitų nust. duom. visuose įreng.</translation>
+<translation id="2332115969598251205">Nepavyko įkelti įrenginių, išsaugotų paskyroje <ph name="PRIMARY_EMAIL" />. Patikrinkite interneto ryšį ir bandykite dar kartą.</translation>
 <translation id="2332131598580221120">Žiūrėti parduotuvėje</translation>
 <translation id="2332192922827071008">Atidarykite nuostatas</translation>
 <translation id="2332515770639153015">Sustiprintas saugus naršymas įjungtas</translation>
@@ -1914,6 +1918,7 @@
 <translation id="2749836841884031656">SIM kortelė</translation>
 <translation id="2749881179542288782">Tikrinti gramatiką ir rašybą</translation>
 <translation id="2753677631968972007">Neautomatiškai valdyti svetainių leidimus.</translation>
+<translation id="2754226775788136540">Ieškoma sparčiojo susiejimo įrenginių, išsaugotų paskyroje <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Raskite reikalingas programas „Google Play“ parduotuvėje – nuo produktyvumo iki pramogų Programas galite įdiegti bet kuriuo metu.</translation>
 <translation id="2755349111255270002">Nustatykite iš naujo šį „<ph name="DEVICE_TYPE" />“ įrenginį</translation>
 <translation id="2755367719610958252">Tvarkyti pritaikymo neįgaliesiems funkcijas</translation>
@@ -2129,6 +2134,7 @@
 <translation id="2942279350258725020">Android Messages</translation>
 <translation id="2942560570858569904">Laukiama...</translation>
 <translation id="2942581856830209953">Tinkinti šį puslapį</translation>
+<translation id="2943268899142471972">„Ansible Playbook“ arba „Crostini“ atsarginės kopijos failo pasirinkimas</translation>
 <translation id="2944060181911631861">Siųskite naudojimo ir diagnostikos duomenis. Padėkite tobulinti „Android“ funkcijas automatiškai siųsdami „Google“ diagnostikos, įrenginio ir programų naudojimo duomenis. Tai padės pagerinti sistemos bei programos stabilumą ir teikti kitus patobulinimus. Kai kurie sukaupti duomenys taip pat bus naudingi „Google“ programoms ir partneriams, pvz., „Android“ kūrėjams. Jei papildomas „Žiniatinklio ir programų veiklos“ nustatymas įjungtas, šie duomenys gali būti išsaugoti „Google“ paskyroje. <ph name="BEGIN_LINK1" />Sužinokite daugiau<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Eiti į failus</translation>
 <translation id="2946119680249604491">Pridėti ryšį</translation>
@@ -2969,6 +2975,7 @@
 <translation id="3784472333786002075">Slapukai yra svetainių sukurti failai. Yra dviejų tipų slapukai: pirmųjų šalių slapukus kuria svetainė, kurioje lankotės. Svetainė rodoma adreso juostoje. Trečiųjų šalių slapukus kuria kitos svetainės. Šioms svetainėms priklauso tam tikras svetainės, kurioje lankotės, rodomas turinys, pvz., skelbimai ar vaizdai.</translation>
 <translation id="3785308913036335955">Rodyti spartųjį programų klavišą</translation>
 <translation id="3785727820640310185">Išsaugoti šios svetainės slaptažodžiai</translation>
+<translation id="3787434344076711519">Laukiama, kol bus išversta</translation>
 <translation id="3788301286821743879">Deja, nepavyko paleisti viešojo terminalo programos.</translation>
 <translation id="3788331399335602504">šie failai</translation>
 <translation id="3788401245189148511">Prašoma leidimo:</translation>
@@ -3252,6 +3259,7 @@
 <translation id="4036778507053569103">Iš serverio atsisiųsta politika yra netinkama.</translation>
 <translation id="4037084878352560732">Arklys</translation>
 <translation id="403725336528835653">Pirmiausia išbandyti</translation>
+<translation id="4040041015953651705">Kalba, iš kurios verčiama</translation>
 <translation id="4040105702484676956">Išvalyti svetainės <ph name="SITE_NAME" /> ir įdiegtos programos duomenis bei leidimus?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Išeiti iš puslapio}one{Išeiti iš puslapių}few{Išeiti iš puslapių}many{Išeiti iš puslapių}other{Išeiti iš puslapių}}</translation>
 <translation id="4043267180218562935">Žymeklio dydis</translation>
@@ -4058,6 +4066,7 @@
 <translation id="4838170306476614339">Peržiūrėkite telefono nuotraukas, mediją ir pranešimus</translation>
 <translation id="4838836835474292213">Iškarpinės skaitymo prieiga leidžiama</translation>
 <translation id="4838907349371614303">Slaptažodis atnaujintas</translation>
+<translation id="4838958829619609362">Pasirinkto teksto kalba nėra <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Iš&amp;saugoti vaizdo įrašą kaip...</translation>
 <translation id="4840096453115567876">Vis tiek išjungti inkognito režimą?</translation>
 <translation id="4841741146571978176">Būtino virtualaus įrenginio nėra. Pabandykite nustatyti „<ph name="VM_TYPE" />“, kad galėtumėte tęsti</translation>
@@ -4829,6 +4838,7 @@
 <translation id="558918721941304263">Įkeliamos programos...</translation>
 <translation id="5590418976913374224">Leisti garsą paleidžiant įrenginį</translation>
 <translation id="5592595402373377407">Kol kas nepakanka duomenų.</translation>
+<translation id="5594899180331219722">Pasirinkti failą</translation>
 <translation id="5595307023264033512">Iš viso svetainių naudojamos vietos saugykloje: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Adreso redagavimas</translation>
 <translation id="5596627076506792578">Daugiau parinkčių</translation>
@@ -5062,6 +5072,7 @@
 <translation id="5834581999798853053">Liko apie <ph name="TIME" /> min.</translation>
 <translation id="5835486486592033703">„<ph name="WINDOW_TITLE" />“ – fotoaparato ar mikrofono įrašymas</translation>
 <translation id="583673505367439042">Svetainėse gali būti prašoma redaguoti failus ir aplankus jūsų įrenginyje</translation>
+<translation id="5836999627049108525">Kalba, iš kurios verčiama</translation>
 <translation id="583756221537636748">Dėklas</translation>
 <translation id="5840658767386246331">„Google“ paieška</translation>
 <translation id="5840680448799937675">Failai visada bus bendrinami neprisijungus</translation>
@@ -5572,6 +5583,7 @@
 <translation id="6318944945640833942">Nepavyko aptikti spausdintuvo. Dar kartą įveskite spausdintuvo adresą.</translation>
 <translation id="6322370287306604163">Atrakinkite greičiau kontroliniu kodu</translation>
 <translation id="6322559670748154781">Šis failas atsisiunčiamas retai ir buvo užblokuotas naudojant Papildomos apsaugos nustatymą</translation>
+<translation id="6324083483652497048">Spustelėkite, kad leistumėte šiems plėtiniams skaityti ir keisti <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Redaguoti spartųjį klavišą</translation>
 <translation id="6325191661371220117">Neleisti automatinio paleidimo</translation>
 <translation id="6326175484149238433">Pašalinti iš „Chrome“</translation>
@@ -6608,6 +6620,7 @@
 <translation id="7343372807593926528">Prieš išsiųsdami atsiliepimą, kuo išsamiau apibūdinkite problemą.</translation>
 <translation id="7344585835349671209">Tvarkykite HTTPS / SSL sertifikatus įrenginyje</translation>
 <translation id="7345706641791090287">Patvirtinkite slaptažodį</translation>
+<translation id="7345919885156673810">Pasirinkto teksto kalba nėra <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Gerai, supratau</translation>
 <translation id="7347452120014970266">Bus išvalyti visi <ph name="ORIGIN_NAME" /> ir įdiegtų programų saugomi duomenys ir slapukai</translation>
 <translation id="7347751611463936647">Jei norite naudoti šį plėtinį, įveskite „<ph name="EXTENSION_KEYWORD" />“, tada paspauskite TABULIAVIMO klavišą ir įveskite komandą ar paieškos terminą.</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index bffd140..347659c0 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -3267,6 +3267,7 @@
 <translation id="4062561150282203854">നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> ആപ്പുകൾ, ക്രമീകരണം എന്നിവയും മറ്റും സമന്വയിപ്പിക്കുക</translation>
 <translation id="4065876735068446555">നിങ്ങൾ ഉപയോഗിക്കുന്ന നെറ്റ്‌വർക്ക് (<ph name="NETWORK_ID" />) അതിന്റെ ലോഗിൻ പേജ് സന്ദർശിക്കാൻ നിങ്ങളോട് ആവശ്യപ്പെടാം.</translation>
 <translation id="4066207411788646768">നിങ്ങളുടെ നെറ്റ്‌വർക്കിൽ ലഭ്യമായ പ്രിന്ററുകൾ കാണാൻ നിങ്ങളുടെ കണക്ഷൻ പരിശോധിക്കുക</translation>
+<translation id="4066945815577305767">പാസ്‌വേഡ് ടൈംഔട്ടായി</translation>
 <translation id="4068776064906523561">സംരക്ഷിച്ച വിരലടയാളങ്ങൾ</translation>
 <translation id="407173827865827707">ക്ലിക്കിൽ</translation>
 <translation id="4072701974556190758">നിങ്ങളുടെ <ph name="ACCOUNT" /> എന്ന Google അക്കൗണ്ടിൽ പാസ്‌വേഡ് സംരക്ഷിക്കും. നിങ്ങൾ ഇത് ഓർത്തിരിക്കേണ്ടതില്ല.</translation>
@@ -5575,6 +5576,7 @@
 <translation id="6335920438823100346">Linux ആരംഭിക്കാൻ, നിങ്ങളുടെ ഡാറ്റ ബാക്കപ്പ് ചെയ്‌ത് ഫാക്‌ടറി ക്രമീകരണത്തിലേക്ക് ഈ Chromebook റീസെറ്റ് ചെയ്യാൻ <ph name="MANAGER" /> ആവശ്യപ്പെടുന്നു.</translation>
 <translation id="6336038146639916978"><ph name="MANAGER" />, ADB ഡീബഗ് ചെയ്യൽ പ്രവർത്തനരഹിതമാക്കി. ഇത് നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> 24 മണിക്കൂറിനുള്ളിൽ റീസെറ്റ് ചെയ്യും. നിലനിർത്തണമെന്നുള്ള എല്ലാ ഫയലുകളും ബാക്കപ്പ് ചെയ്യുക.</translation>
 <translation id="6338402296920404442"><ph name="FILENAME" /> ഇല്ലാതാക്കുന്നത് പരിഗണനയിലുള്ളതിനാൽ, ഈ ഉപകരണം ഉപയോഗിക്കുന്ന മറ്റുള്ളവർക്ക് നിങ്ങളുടെ പാസ്‌വേഡുകൾ കാണാനാകില്ല.</translation>
+<translation id="6338968693068997776">USB ഉപകരണം ചേർക്കുക</translation>
 <translation id="6338981933082930623">എല്ലാ സൈറ്റുകൾക്കും നിങ്ങളെ ഏത് പരസ്യം വേണമെങ്കിലും കാണിക്കാം</translation>
 <translation id="6339668969738228384"><ph name="USER_EMAIL_ADDRESS" /> എന്നയാൾക്ക് വേണ്ടി പുതിയ പ്രൊഫൈൽ സൃഷ്‌ടിക്കുക</translation>
 <translation id="6340071272923955280">ഇന്റർനെറ്റ് പ്രിന്റിംഗ് പ്രോട്ടോക്കോൾ (IPPS)</translation>
@@ -6172,6 +6174,7 @@
 <translation id="6903907808598579934">സമന്വയിപ്പിക്കൽ ഓണാക്കുക</translation>
 <translation id="6904344821472985372">ഫയൽ ആക്‌സസ് റദ്ദാക്കുക</translation>
 <translation id="6904655473976120856">പുറത്തുകടക്കുന്നതിന് ആപ്പ് ബട്ടൺ അമർത്തുക</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{നിങ്ങളുടെ പാസ്‌വേഡുകൾ സുരക്ഷിതമായി സൂക്ഷിക്കാൻ, ഒരു മിനിറ്റ് നിഷ്ക്രിയമായിരുന്നാൽ Google Password Manager ലോക്ക് ആകുന്നു}other{നിങ്ങളുടെ പാസ്‌വേഡുകൾ സുരക്ഷിതമായി സൂക്ഷിക്കാൻ, {NUM_MINS} മിനിറ്റ് നിഷ്ക്രിയമായിരുന്നാൽ Google Password Manager ലോക്ക് ആകുന്നു}}</translation>
 <translation id="6909422577741440844">ഈ ഉപകരണത്തിൽ നിന്ന് സ്വീകരിക്കണോ?</translation>
 <translation id="6910211073230771657">ഇല്ലാതാക്കി</translation>
 <translation id="691106080621596509">ഇത് <ph name="SITE_GROUP_NAME" /> എന്നതും അതിന് കീഴിലുള്ള എല്ലാ സൈറ്റുകളും അതിന്റെ ഇൻസ്‌റ്റാൾ ചെയ്തിരിക്കുന്ന ആപ്പും സംഭരിച്ചിരിക്കുന്ന എല്ലാ ഡാറ്റയും കുക്കികളും മായ്ക്കും</translation>
@@ -8012,6 +8015,7 @@
 <translation id="8688672835843460752">ലഭ്യമാണ്</translation>
 <translation id="8690129572193755009">പ്രോട്ടോകോളുകൾ കൈകാര്യം ചെയ്യാൻ സൈറ്റുകൾക്ക് അനുവാദം ചോദിക്കാം</translation>
 <translation id="8692107307702113268">പാസ്‌വേഡിൽ 1000-ലേറെ പ്രതീകങ്ങൾ അടങ്ങിയിരിക്കുന്നു</translation>
+<translation id="8694596275649352090">ഉറങ്ങുമ്പോഴോ ലിഡ് അടഞ്ഞിരിക്കുമ്പോഴോ ലോക്ക് ചെയ്യുക</translation>
 <translation id="8695139659682234808">സജ്ജീകരിച്ചതിനുശേഷം രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ ചേർക്കുക</translation>
 <translation id="8695825812785969222">&amp;സ്ഥാനം തുറക്കുക...</translation>
 <translation id="8698269656364382265">മുമ്പത്തെ സ്ക്രീനിലേക്ക് മടങ്ങാൻ ഇടതുവശത്ത് നിന്ന് സ്വൈപ്പ് ചെയ്യുക.</translation>
@@ -8060,6 +8064,7 @@
 <translation id="8732844209475700754">സ്വകാര്യത, സുരക്ഷ, ഡാറ്റാ ശേഖരണം എന്നിവയുമായി ബന്ധപ്പെട്ട കൂടുതൽ ക്രമീകരണം</translation>
 <translation id="8734073480934656039">ഈ ക്രമീകരണം പ്രവർത്തനക്ഷമമാക്കുന്നത് സ്റ്റാർട്ടപ്പിൽ കിയോ‌ക് ആപ്പുകൾ സ്വയമേവ ലോഞ്ച് ചെയ്യുന്നതിന് അനുവദിക്കുന്നു.</translation>
 <translation id="8734674662128056360">മൂന്നാം കക്ഷി കുക്കി ബ്ലോക്ക് ചെയ്യൽ</translation>
+<translation id="8734755021067981851">USB ഉപകരണങ്ങളൊന്നും അറ്റാച്ച് ചെയ്തിട്ടില്ല.</translation>
 <translation id="873545264931343897"><ph name="PLUGIN_NAME" /> അപ്‌ഡേറ്റ് ചെയ്‌തുകഴിയുമ്പോൾ, അത് സജീവമാക്കുന്നതിന് പേജ് റീലോഡ് ചെയ്യുക</translation>
 <translation id="8736288397686080465">ഈ സൈറ്റ് പശ്‌ചാത്തലത്തിൽ അപ്‌ഡേറ്റ് ചെയ്‌തു.</translation>
 <translation id="8737709691285775803">ഷിൽ</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 07427cd2..11aaeed 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">Lalai</translation>
 <translation id="1252987234827889034">Ralat profil berlaku</translation>
 <translation id="1254593899333212300">Sambungan Internet Langsung</translation>
+<translation id="1257336506558170607">Eksport sijil terpilih</translation>
 <translation id="1258491128795710625">Perkara Baharu</translation>
 <translation id="1259152067760398571">Semakan keselamatan dijalankan semalam</translation>
 <translation id="1260451001046713751">Sentiasa benarkan tetingkap timbul daripada <ph name="HOST" /></translation>
@@ -326,6 +327,7 @@
 <translation id="1307165550267142340">PIN anda telah dibuat</translation>
 <translation id="1307431692088049276">Jangan tanya saya lagi</translation>
 <translation id="1307559529304613120">Op!  Sistem gagal menyimpan token akses API jangka panjang untuk peranti ini.</translation>
+<translation id="1312811472299082263">Buat daripada Panduan Ansible atau fail sandaran Crostini</translation>
 <translation id="1313405956111467313">Konfigurasi proksi automatik</translation>
 <translation id="131364520783682672">Kunci Huruf Besar</translation>
 <translation id="1313660246522271310">Anda akan dilog keluar daripada semua tapak, termasuk dalam tab yang terbuka</translation>
@@ -1109,6 +1111,7 @@
 <translation id="2028449514182362831">Ciri yang memerlukan penderia gerakan tidak akan berfungsi</translation>
 <translation id="202918510990975568">Masukkan kata laluan anda untuk mengkonfigurasikan keselamatan dan log masuk</translation>
 <translation id="2030455719695904263">Pad jejak</translation>
+<translation id="2031385797619033640">Klik untuk membenarkan <ph name="EXTENSIONS_REQUESTING_ACCESS" /> untuk membaca dan menukar <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Kata laluan anda disimpan dalam Akaun Google anda</translation>
 <translation id="2031914984822377766">Tambah <ph name="LINK_BEGIN" />bahasa laman web<ph name="LINK_END" /> pilihan anda. Bahasa teratas daripada senarai akan digunakan untuk terjemahan.</translation>
 <translation id="2033758234986231162">Tidak dapat mengekalkan sambungan dengan telefon anda. Pastikan telefon ada pada anda, dibuka kunci dan Bluetooth serta Wi-Fi dihidupkan.</translation>
@@ -1468,6 +1471,7 @@
 <translation id="2328561734797404498">Sila mulakan semula peranti anda untuk menggunakan <ph name="APP_NAME" />.</translation>
 <translation id="2328636661627946415">Apabila anda berada dalam Mod inkognito, laman boleh menggunakan kuki untuk melihat aktiviti penyemakan imbas anda di laman mereka sendiri sahaja. Kuki dipadamkan pada penghujung Sesi inkognito.</translation>
 <translation id="2329597144923131178">Log masuk untuk mendapatkan penanda halaman, sejarah, kata laluan dan tetapan lain pada semua peranti anda.</translation>
+<translation id="2332115969598251205">Tidak dapat memuatkan peranti yang disimpan pada <ph name="PRIMARY_EMAIL" />. Periksa sambungan Internet anda dan cuba lagi.</translation>
 <translation id="2332131598580221120">Lihat di gedung</translation>
 <translation id="2332192922827071008">Buka Pilihan</translation>
 <translation id="2332515770639153015">Penyemakan Imbas Selamat Dipertingkat dihidupkan</translation>
@@ -1911,6 +1915,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Periksa Tatabahasa Dengan Ejaan</translation>
 <translation id="2753677631968972007">Kawal kebenaran tapak secara manual.</translation>
+<translation id="2754226775788136540">Mencari peranti Ganding Pantas yang disimpan pada <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Cari apl yang anda perlukan, daripada produktiviti kepada hiburan di Google Play Store. Anda boleh memasang apl pada bila-bila masa.</translation>
 <translation id="2755349111255270002">Tetapkan semula <ph name="DEVICE_TYPE" /> ini</translation>
 <translation id="2755367719610958252">Urus ciri kebolehaksesan</translation>
@@ -2126,6 +2131,7 @@
 <translation id="2942279350258725020">Android Messages</translation>
 <translation id="2942560570858569904">Menunggu...</translation>
 <translation id="2942581856830209953">Peribadikan halaman ini</translation>
+<translation id="2943268899142471972">Pilih Panduan Ansible atau fail sandaran Crostini</translation>
 <translation id="2944060181911631861">Hantar data penggunaan dan diagnostik. Bantu kami meningkatkan pengalaman Android anda dengan menghantar data diagnostik dan penggunaan peranti serta apl kepada Google secara automatik. Data ini akan membantu peningkatan kestabilan sistem dan apl serta pelbagai lagi. Sesetengah data agregat juga akan membantu apl dan rakan kongsi Google, seperti pembangun Android. Jika tetapan Aktiviti Web &amp; Apl tambahan anda dihidupkan, data ini mungkin disimpan pada Google Account anda. <ph name="BEGIN_LINK1" />Ketahui Lebih Lanjut<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Pergi ke fail</translation>
 <translation id="2946119680249604491">Tambah sambungan</translation>
@@ -2966,6 +2972,7 @@
 <translation id="3784472333786002075">Kuki ialah fail yang dibuat oleh laman web. Terdapat dua jenis kuki: Kuki pihak pertama dibuat oleh tapak yang anda lawati. Tapak ini ditunjukkan pada bar alamat. Kuki pihak ketiga dibuat oleh tapak lain. Tapak ini memiliki sebahagian daripada kandungan seperti iklan atau imej yang anda lihat pada laman web yang anda lawati.</translation>
 <translation id="3785308913036335955">Paparkan Pintasan Apl</translation>
 <translation id="3785727820640310185">Kata laluan disimpan untuk tapak ini</translation>
+<translation id="3787434344076711519">Menunggu terjemahan</translation>
 <translation id="3788301286821743879">Aplikasi kios tidak dapat dilancarkan.</translation>
 <translation id="3788331399335602504">fail ini</translation>
 <translation id="3788401245189148511">Item boleh:</translation>
@@ -3249,6 +3256,7 @@
 <translation id="4036778507053569103">Dasar yang dimuat turun daripada pelayan tidak sah.</translation>
 <translation id="4037084878352560732">Kuda</translation>
 <translation id="403725336528835653">Cuba dahulu</translation>
+<translation id="4040041015953651705">Bahasa sumber</translation>
 <translation id="4040105702484676956">Kosongkan data dan kebenaran laman untuk <ph name="SITE_NAME" /> dan aplnya yang dipasang?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Keluar daripada Halaman}other{Keluar daripada Halaman}}</translation>
 <translation id="4043267180218562935">Saiz kursor</translation>
@@ -4055,6 +4063,7 @@
 <translation id="4838170306476614339">Lihat foto, media dan pemberitahuan telefon anda.</translation>
 <translation id="4838836835474292213">Akses baca papan keratan dibenarkan</translation>
 <translation id="4838907349371614303">Kata laluan dikemas kini</translation>
+<translation id="4838958829619609362">Pilihan tiada dalam <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Si&amp;mpan video sebagai...</translation>
 <translation id="4840096453115567876">Keluar daripada mod Inkognito juga?</translation>
 <translation id="4841741146571978176">Mesin maya yang diperlukan tidak wujud. Sila cuba sediakan <ph name="VM_TYPE" /> untuk meneruskan</translation>
@@ -4826,6 +4835,7 @@
 <translation id="558918721941304263">Memuatkan apl...</translation>
 <translation id="5590418976913374224">Mainkan bunyi pada permulaan peranti</translation>
 <translation id="5592595402373377407">Data yang mencukupi belum tersedia lagi.</translation>
+<translation id="5594899180331219722">Pilih fail</translation>
 <translation id="5595307023264033512">Jumlah storan yang digunakan oleh laman: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Edit alamat</translation>
 <translation id="5596627076506792578">Lagi pilihan</translation>
@@ -5058,6 +5068,7 @@
 <translation id="5834581999798853053">Tinggal kira-kira <ph name="TIME" /> minit</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - Kamera atau mikrofon sedang merakam</translation>
 <translation id="583673505367439042">Laman boleh meminta untuk mengedit fail dan folder pada peranti anda</translation>
+<translation id="5836999627049108525">Bahasa Sumber</translation>
 <translation id="583756221537636748">Sarung</translation>
 <translation id="5840658767386246331">Cari dengan Google</translation>
 <translation id="5840680448799937675">Fail akan sentiasa dikongsi di luar talian</translation>
@@ -5568,6 +5579,7 @@
 <translation id="6318944945640833942">Tidak dapat mengesan pencetak. Sila masukkan alamat pencetak sekali lagi.</translation>
 <translation id="6322370287306604163">Buka kunci dengan lebih cepat menggunakan cap jari</translation>
 <translation id="6322559670748154781">Fail ini tidak biasa dimuat turun dan telah disekat oleh Perlindungan Lanjutan</translation>
+<translation id="6324083483652497048">Klik untuk membenarkan sambungan ini untuk membaca dan menukar <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Edit pintasan</translation>
 <translation id="6325191661371220117">Lumpuhkan autolancar</translation>
 <translation id="6326175484149238433">Alih keluar dari Chrome</translation>
@@ -6598,6 +6610,7 @@
 <translation id="7343372807593926528">Sila terangkan masalah tersebut sebelum menghantar maklum balas.</translation>
 <translation id="7344585835349671209">Urus sijil HTTPS/SSL pada peranti anda</translation>
 <translation id="7345706641791090287">Sahkan kata laluan anda</translation>
+<translation id="7345919885156673810">Pilihan Tiada dalam <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Ok, faham</translation>
 <translation id="7347452120014970266">Tindakan ini akan mengosongkan semua data dan kuki yang disimpan oleh <ph name="ORIGIN_NAME" /> dan apl yang dipasang</translation>
 <translation id="7347751611463936647">Untuk menggunakan sambungan ini, taip "<ph name="EXTENSION_KEYWORD" />", kemudian TAB, kemudian perintah atau carian anda.</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb
index ea3f751e..ef0f4c31 100644
--- a/chrome/app/resources/generated_resources_my.xtb
+++ b/chrome/app/resources/generated_resources_my.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">မူရင်း</translation>
 <translation id="1252987234827889034">ပရိုဖိုင်ချွတ်ယွင်းချက် ဖြစ်ပေါ်ခဲ့သည်</translation>
 <translation id="1254593899333212300">တိုက်ရိုက် အင်တာနက် ချိတ်ဆက်မှု</translation>
+<translation id="1257336506558170607">ရွေးထားသည့်အသိအမှတ်ပြုလက်မှတ်ကို ထုတ်ယူရန်</translation>
 <translation id="1258491128795710625">အသစ်ပါဝင်မှုများ</translation>
 <translation id="1259152067760398571">မနေ့က လုံခြုံရေး စစ်ဆေးခဲ့သည်</translation>
 <translation id="1260451001046713751"><ph name="HOST" /> ရှိ ပေါ့ပ်အပ်များနှင့် တစ်ဆင့်ပြန်ညွှန်ပြခြင်းများကို အမြဲခွင့်ပြုရန်</translation>
@@ -326,6 +327,7 @@
 <translation id="1307165550267142340">သင့်ပင်နံပါတ် ပြုလုပ်ပြီးပြီ</translation>
 <translation id="1307431692088049276">ထပ်မမေးပါနှင့်</translation>
 <translation id="1307559529304613120">အူးပ်စ်!  စနစ်သည် ဒီကိရိယာ အတွက် ရေရှည် API အသုံးပြုမှု တိုကင်ကို မသိုလှောင်နိုင်ခဲ့ပါ။</translation>
+<translation id="1312811472299082263">Ansible Playbook (သို့) Crostini အရန်ဖိုင်မှ ပြုလုပ်ရန်</translation>
 <translation id="1313405956111467313">အလိုအလျောက် ပရောက်စီ စီစဉ်ဖွဲ့စည်းမှု</translation>
 <translation id="131364520783682672">စာလုံးကြီးရန် သော့ခလုတ်</translation>
 <translation id="1313660246522271310">ဖွင့်ထားသော တဘ်များအပါအဝင် ဝဘ်ဆိုက်အားလုံးမှ သင် ထွက်သွားပါမည်</translation>
@@ -1107,6 +1109,7 @@
 <translation id="2028449514182362831">လှုပ်ရှားမှုအာရုံခံစနစ် လိုအပ်သည့် ဝန်ဆောင်မှုများ အလုပ်လုပ်မည်မဟုတ်ပါ</translation>
 <translation id="202918510990975568">လုံခြုံရေးနှင့် လက်မှတ်ထိုးဝင်ခြင်းကို စီစဉ်သတ်မှတ်ရန် သင့်စကားဝှက်ကို ထည့်ပါ</translation>
 <translation id="2030455719695904263">တာ့ချ်ပက်</translation>
+<translation id="2031385797619033640"><ph name="EXTENSIONS_REQUESTING_ACCESS" /> အား <ph name="ORIGIN" /> ကို ဖတ်ရှုပြင်ဆင်ခွင့်ပြုရန် နှိပ်ပါ-</translation>
 <translation id="2031639749079821948">စကားဝှက်ကို သင့် Google Account တွင် သိမ်းထားသည်</translation>
 <translation id="2031914984822377766">ဦးစားပေး <ph name="LINK_BEGIN" />ဝဘ်ဆိုက် ဘာသာစကားများ<ph name="LINK_END" /> ထည့်ပါ။ ဘာသာပြန်ဆိုချက်များအတွက် စာရင်းထဲမှ ထိပ်ဆုံးဘာသာစကားကို သုံးမည်။</translation>
 <translation id="2033758234986231162">သင့်ဖုန်းနှင့် ချိတ်ဆက်ထား၍မရပါ။ သင့်ဖုန်းသည် အနီးတွင်ရှိပြီး လော့ခ်ဖွင့်ထားကာ ဘလူးတုသ်နှင့် Wi-Fi ဖွင့်ထားကြောင်း သေချာပါစေ။</translation>
@@ -1466,6 +1469,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" /> အသုံးပြုရန် သင့်စက်ကို ပြန်စတင်ပါ။</translation>
 <translation id="2328636661627946415">‘ရုပ်ဖျက်မုဒ်’ ဖွင့်ထားပါက ဝဘ်ဆိုက်များသည် ၎င်းတို့၏ဝဘ်ဆိုက်များတွင် သင်၏ကြည့်ရှုခြင်းများကို ကြည့်ရန် ကွတ်ကီးများကိုသာ သုံးနိုင်သည်။ ကွတ်ကီးများကို ‘ရုပ်ဖျက်စက်ရှင်’ ပြီးသည်နှင့် ဖျက်ပါသည်။</translation>
 <translation id="2329597144923131178">သင့်စာညှပ်များ၊ မှတ်တမ်း၊ စကားဝှက်များနှင့် အခြား ဆက်တင်များအား သင်၏ ကိရိယာများ အားလုံးတွင် ရရှိရန် လက်မှတ်ထိုး ဝင်ပါ</translation>
+<translation id="2332115969598251205"><ph name="PRIMARY_EMAIL" /> တွင် သိမ်းထားသောစက်များကို ဖွင့်၍မရပါ။ သင်၏ အင်တာနက်ချိတ်ဆက်မှုကို စစ်ဆေးပြီး ထပ်စမ်းကြည့်ပါ။</translation>
 <translation id="2332131598580221120">စတိုးမှာ ကြည့်ရန်</translation>
 <translation id="2332192922827071008">စနစ်သတ်မှတ်ချက်များ ဖွင့်ရန်</translation>
 <translation id="2332515770639153015">‘အရည်အသွေးမြှင့် ဘေးကင်းလုံခြုံသည့် အသုံးပြုမှု’ ဖွင့်ထားသည်</translation>
@@ -1909,6 +1913,7 @@
 <translation id="2749836841884031656">ဆင်းမ်</translation>
 <translation id="2749881179542288782">သဒ္ဒါကို စာလုံးပေါင်းနှင့်အတူ စစ်ကြည့်ရန်</translation>
 <translation id="2753677631968972007">ဝဘ်ဆိုက်ခွင့်ပြုချက်များကို ကိုယ်တိုင် ထိန်းချုပ်မည်။</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" /> တွင် သိမ်းထားသော ‘အမြန်တွဲချိတ်ခြင်း’ စက်များကို ရှာနေသည်</translation>
 <translation id="2754825024506485820">အလုပ်ပြီးမြောက်မှုမှ ဖျော်ဖြေရေးအထိ လိုအပ်သောအက်ပ်များကို Google Play Store တွင် ရှာနိုင်သည်။ အက်ပ်များကို အချိန်မရွေး ထည့်သွင်းနိုင်သည်။</translation>
 <translation id="2755349111255270002">ဤ <ph name="DEVICE_TYPE" /> ကို ပြင်ဆင်သတ်မှတ်ပါ</translation>
 <translation id="2755367719610958252">သုံးစွဲနိုင်ခြင်းဆိုင်ရာ ဝန်ဆောင်မှုများကို စီမံပါ</translation>
@@ -2124,6 +2129,7 @@
 <translation id="2942279350258725020">Android messages</translation>
 <translation id="2942560570858569904">စောင့်နေသည်...</translation>
 <translation id="2942581856830209953">ဤစာမျက်နှာကို စိတ်ကြိုက်လုပ်ရန်</translation>
+<translation id="2943268899142471972">Ansible Playbook (သို့) Crostini အရန်ဖိုင် ရွေးပါ</translation>
 <translation id="2944060181911631861">အသုံးပြုမှုနှင့် အမှားရှာဖွေမှုဒေတာ ပို့ပါ။ အမှားရှာဖွေမှု၊ စက်ပစ္စည်းနှင့်အက်ပ် အသုံးပြုမှုဒေတာများကို Google သို့ အလိုအလျောက်ပို့၍ Android အသုံးပြုမှု ပိုမိုကောင်းမွန်လာစေရန် ကူညီပါ။ ၎င်းက စနစ်နှင့် အက်ပ်တည်ငြိမ်မှု၊ အခြား တိုးတက်ပြင်ဆင်မှုများအတွက် ပံ့ပိုးပေးပါမည်။ စုစည်းထားသော ဒေတာအချို့က Google အက်ပ်နှင့် Android ဆော့ဖ်ဝဲအင်ဂျင်နီယာများကဲ့သို့ ပါတနာများကို ကူညီပေးပါမည်။ သင်၏ထပ်တိုး 'ဝဘ်နှင့် အက်ပ်လုပ်ဆောင်ချက်' ကို ဖွင့်ထားသည့်အခါ ဤဒေတာကို သင့် Google အကောင့်သို့ သိမ်းသွားပါမည်။ <ph name="BEGIN_LINK1" />ပိုမိုလေ့လာရန်<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">ဖိုင်များသို့သွားရန်</translation>
 <translation id="2946119680249604491">ချိတ်ဆက်မှုကို ထည့်ရန်</translation>
@@ -2964,6 +2970,7 @@
 <translation id="3784472333786002075">ကွတ်ကီးများဟူသည်မှာ ဝဘ်ဆိုက်များက ပြုလုပ်ထားသော ဖိုင်များဖြစ်သည်။ ကွက်ကီးနှစ်မျိုး ရှိပါသည်− ပင်မကွတ်ကီးများကို သင်ဝင်ကြည့်သော ဝဘ်ဆိုက်က ပြုလုပ်ခြင်းဖြစ်သည်။ ဝဘ်ဆိုက်ကို လိပ်စာဘားတွင် ပြထားသည်။ ပြင်ပကွတ်ကီးများကို အခြားဝဘ်ဆိုက်များက ပြုလုပ်ခြင်းဖြစ်သည်။ ဤဝဘ်ဆိုက်များတွင် သင်ဝင်ကြည့်သည့်ဝဘ်ဆိုက်ပေါ်တွင် တွေ့ရသည့်ကြော်ငြာ သို့မဟုတ် ပုံများကဲ့သို့ အကြောင်းအရာအချို့ ပါဝင်သည်။</translation>
 <translation id="3785308913036335955">အက်ပ်များ ဖြတ်လမ်းကို ပြပေးရန်</translation>
 <translation id="3785727820640310185">ဤဝဘ်ဆိုက်အတွက် သိမ်းဆည်းထားသည့် စကားဝှက်များ</translation>
+<translation id="3787434344076711519">ဘာသာပြန်ရန် စောင့်နေသည်</translation>
 <translation id="3788301286821743879">Koisk အပလီကေးရှင်း စတင်၍ မရပါ။</translation>
 <translation id="3788331399335602504">ဤဖိုင်များ</translation>
 <translation id="3788401245189148511">ဖြစ်နိုင်ခဲ့သည်မှာ:</translation>
@@ -3246,6 +3253,7 @@
 <translation id="4036778507053569103">ဆာဗာမှနေ၍ ဒေါင်းလုဒ်လုပ်ထားသည့် မူဝါဒသည် မမှန်ကန်ပါ။</translation>
 <translation id="4037084878352560732">မြင်း</translation>
 <translation id="403725336528835653">ဦးစွာ စမ်းကြည့်ရန်</translation>
+<translation id="4040041015953651705">ဖော်ပြပါဘာသာစကားမှ ဘာသာပြန်ဆိုရန်</translation>
 <translation id="4040105702484676956"><ph name="SITE_NAME" /> နှင့် ၎င်းထည့်သွင်းထားသော အက်ပ်အတွက် ဝဘ်ဆိုက်ဒေတာနှင့် ခွင့်ပြုချက်များ ဖယ်ရှားမလား။</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{စာမျက်နှာကို ပိတ်ရန်}other{စာမျက်နှာများကို ပိတ်ရန်}}</translation>
 <translation id="4043267180218562935">ကာဆာအရွယ်အစား</translation>
@@ -4052,6 +4060,7 @@
 <translation id="4838170306476614339">သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များကို ကြည့်နိုင်သည်</translation>
 <translation id="4838836835474292213">ကလစ်ဘုတ် ကြည့်ရှုခွင့် ပေးထားသည်</translation>
 <translation id="4838907349371614303">စကားဝှက် အပ်ဒိတ်လုပ်ပြီးပြီ</translation>
+<translation id="4838958829619609362">ရွေးချယ်ထားသည်မှာ <ph name="LANGUAGE" />  မဟုတ်ပါ</translation>
 <translation id="4839303808932127586">ဗီဒီယိုအား သိမ်းမည်...</translation>
 <translation id="4840096453115567876">မည်သို့ပင်ဖြစ်စေ ရုပ်ဖျက်မုဒ်မှ ထွက်လိုပါသလား။</translation>
 <translation id="4841741146571978176">သတ်မှတ်ထားသော ပကတိအသွင်စက် မရှိပါ။ ရှေ့ဆက်ရန် <ph name="VM_TYPE" /> ကို စနစ်ထည့်သွင်းကြည့်ပါ</translation>
@@ -4823,6 +4832,7 @@
 <translation id="558918721941304263">အက်ပ်များကို တင်နေသည်...</translation>
 <translation id="5590418976913374224">စက်စတင်ချိန်တွင် အသံဖွင့်ရန်</translation>
 <translation id="5592595402373377407">လုံလောက်သည့် ဒေတာမရနိုင်သေးပါ။</translation>
+<translation id="5594899180331219722">ဖိုင်ရွေးရန်</translation>
 <translation id="5595307023264033512">ဝဘ်ဆိုက်များက အသုံးပြုထားသည့် စုစုပေါင်းသိုလှောင်ခန်း- <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">လိပ်စာ တည်းဖြတ်ရန်</translation>
 <translation id="5596627076506792578">ပိုမို ရွေးချယ်စရာများ</translation>
@@ -5056,6 +5066,7 @@
 <translation id="5834581999798853053"><ph name="TIME" /> မိနစ်ခန့် ကျန်</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - ကင်မရာ သို့မဟုတ် မိုက်ခရိုဖုန်း ဖမ်းယူရိုက်ကူးခြင်း</translation>
 <translation id="583673505367439042">သင့်စက်ပေါ်ရှိ ဖိုင်နှင့် ဖိုင်တွဲများ တည်းဖြတ်လိုပါက ဝဘ်ဆိုက်များက ခွင့်တောင်းနိုင်သည်</translation>
+<translation id="5836999627049108525">ဖော်ပြပါဘာသာစကားမှ ဘာသာပြန်ဆိုရန်</translation>
 <translation id="583756221537636748">ဘူး</translation>
 <translation id="5840658767386246331">Google ဖြင့် ရှာရန်</translation>
 <translation id="5840680448799937675">ဖိုင်များကို အမြဲတမ်း အော့ဖ်လိုင်း မျှဝေပါမည်</translation>
@@ -5565,6 +5576,7 @@
 <translation id="6318944945640833942">ပရင်တာကို မတွေ့ပါ။ ပရင်တာ၏ လိပ်စာကို ထပ်မံ၍ ထည့်သွင်းပါ။</translation>
 <translation id="6322370287306604163">လက်ဗွေဖြင့် ပိုမိုမြန်ဆန်စွာ ဖွင့်ပါ</translation>
 <translation id="6322559670748154781">ဤဖိုင်ကို အများအားဖြင့် ဒေါင်းလုဒ်လုပ်လေ့ မရှိပါ။ အဆင့်မြင့်ကာကွယ်ရေးက ပိတ်ထားပါသည်</translation>
+<translation id="6324083483652497048">ဤနောက်ဆက်တွဲများအား <ph name="ORIGIN" /> ကို ဖတ်ရှုပြင်ဆင်ခွင့်ပြုရန် နှိပ်ပါ-</translation>
 <translation id="6324916366299863871">ဖြတ်လမ်းလင့်ခ်ကို တည်းဖြတ်ခြင်း</translation>
 <translation id="6325191661371220117">အလိုအလျောက်-စတင်ခြင်း မပြုရန်</translation>
 <translation id="6326175484149238433">Chrome ထဲမှ ဖယ်ရှားပစ်ရန်</translation>
@@ -6593,6 +6605,7 @@
 <translation id="7343372807593926528">အကြံပြုချက်မပို့မီ ပြဿနာကို ဖော်ပြပါ။</translation>
 <translation id="7344585835349671209">စက်ပေါ်တွင် HTTPS/SSL အသိအမှတ်ပြုလက်မှတ်များကို စီမံနိုင်သည်</translation>
 <translation id="7345706641791090287">သင့် စကားဝှက် အတည်ပြုပါ</translation>
+<translation id="7345919885156673810">ရွေးချယ်ထားသည်မှာ <ph name="LANGUAGE" />  မဟုတ်ပါ</translation>
 <translation id="7346909386216857016">OK</translation>
 <translation id="7347452120014970266">ဤလုပ်ဆောင်ချက်က <ph name="ORIGIN_NAME" /> နှင့် ၎င်းထည့်သွင်းထားသော အက်ပ်များ သိမ်းထားသည့် ဒေတာနှင့် ကွတ်ကီးအားလုံးကို ရှင်းထုတ်ပါမည်</translation>
 <translation id="7347751611463936647">ဒီတိုးချဲ့မှုကို အသုံးပြုရန်၊ "<ph name="EXTENSION_KEYWORD" />" ကို၊ ၎င်းနောက်မှာ TAB၊ အဲဒီနောက်မှာ သင်၏ ညွှန်ကြားချက် သို့မဟုတ် ရှာဖွေမှုကို တိုက်ရိုက် ထည့်သွင်းပါ။</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index 1fa50d02..f93b6893 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -3266,6 +3266,7 @@
 <translation id="4062561150282203854">आफ्नो <ph name="DEVICE_TYPE" /> मा भएका एप, सेटिङ र अन्य कुराहरू सिंक गर्नुहोस्</translation>
 <translation id="4065876735068446555">तपाईँले प्रयोग गरिरहनु भएको सञ्जाल (<ph name="NETWORK_ID" />) लाई तपाईँले यसको लगइन पृष्ठ भ्रमण गर्न आवश्यकता हुन सक्छ।</translation>
 <translation id="4066207411788646768">आफ्नो नेटवर्कमा उपलब्ध प्रिन्टरहरू हेर्न आफ्नो इन्टरनेटको जाँच गर्नुहोस्</translation>
+<translation id="4066945815577305767">पासवर्डहरूको म्याद सकियो</translation>
 <translation id="4068776064906523561">सुरक्षित गरिएका फिंगरप्रिन्टहरू</translation>
 <translation id="407173827865827707">क्लिक गर्दा</translation>
 <translation id="4072701974556190758">यो पासवर्ड तपाईंको Google खाता <ph name="ACCOUNT" /> मा सेभ गरिने छ। तपाईंले यो पासवर्ड याद गरिराख्नु पर्दैन।</translation>
@@ -5571,6 +5572,7 @@
 <translation id="6335920438823100346">Linux सुरु गर्न <ph name="MANAGER" /> का अनुसार तपाईंले आफ्नो डेटा ब्याकअप गरी यो Chromebook रिसेट गरेर फ्याक्ट्री सेटिङमा लैजानु पर्ने हुन्छ।</translation>
 <translation id="6336038146639916978"><ph name="MANAGER" /> ले ADB डिबग प्रक्रिया अफ गर्नुभएको छ। परिणामस्वरूप, अबको २४ घन्टामा तपाईंको <ph name="DEVICE_TYPE" /> रिसेट हुने छ। आफूले सुरक्षित राख्न चाहेका सबै फाइलहरू ब्याकअप गर्नुहोस्।</translation>
 <translation id="6338402296920404442">यो डिभाइस प्रयोग गर्ने अरू मान्छेले तपाईंका पासवर्ड देख्न नसकून भन्नाका लागि <ph name="FILENAME" /> मेटाउनुहोस्।</translation>
+<translation id="6338968693068997776">USB डिभाइस एट्याच गर्नुहोस्</translation>
 <translation id="6338981933082930623">सबै साइटहरू तपाईंलाई जुनसुकै विज्ञापन देखाउन सक्छन्</translation>
 <translation id="6339668969738228384"><ph name="USER_EMAIL_ADDRESS" /> को नयाँ प्रोफाइल सिर्जना गर्नुहोस्</translation>
 <translation id="6340071272923955280">इन्टरनेट प्रिन्टिङ प्रोटोकोल (IPPS)</translation>
@@ -6168,6 +6170,7 @@
 <translation id="6903907808598579934">सिंकलाई अन गर्नुहोस्</translation>
 <translation id="6904344821472985372">फाइल पहुँच रद्द गर्नुहोस्</translation>
 <translation id="6904655473976120856">बाहिर निस्कनका लागि एप बटन थिच्नुहोस्</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Google पासवर्ड म्यानेजरले तपाईंका पासवर्डहरू सुरक्षित राख्ने प्रयोजनका लागि कुनै साइट १ मिनेटसम्म निष्क्रिय भएपछि सो साइट लक गर्छ}other{Google पासवर्ड म्यानेजरले तपाईंका पासवर्डहरू सुरक्षित राख्ने प्रयोजनका लागि कुनै साइट {NUM_MINS} मिनेटसम्म निष्क्रिय भएपछि सो साइट लक गर्छ}}</translation>
 <translation id="6909422577741440844">यो यन्त्रबाट प्राप्त गर्ने हो?</translation>
 <translation id="6910211073230771657">मेटाइएको</translation>
 <translation id="691106080621596509">यस कार्यले <ph name="SITE_GROUP_NAME" />, यसअन्तर्गतका सबै साइट र यिनमा इन्स्टल गरिएको एपले भण्डारण गरेका सबै डेटा र कुकीहरू हटाउने छ</translation>
@@ -8008,6 +8011,7 @@
 <translation id="8688672835843460752">उपलब्ध</translation>
 <translation id="8690129572193755009">साइटहरूले प्रोटोकोल व्यवस्थापन गर्ने अनुमति माग्न सक्छन्</translation>
 <translation id="8692107307702113268">पासवर्ड १००० वर्णभन्दा लामो छ</translation>
+<translation id="8694596275649352090">स्लिप मोडमा हुँदा वा लिड बन्द गरेपछि लक गरियोस्</translation>
 <translation id="8695139659682234808">सेटअप पूरा गरिसकेपछि अभिभावकीय नियन्त्रणहरू थप्नुहोस्</translation>
 <translation id="8695825812785969222">स्थान &amp;खोल्नुहोस्...</translation>
 <translation id="8698269656364382265">अघिल्लो स्क्रिनमा फर्कन बायाँ छेउबाट स्वाइप गर्नुहोस्।</translation>
@@ -8056,6 +8060,7 @@
 <translation id="8732844209475700754">गोपनीयता, सुरक्षा र डेटा सङ्कलनसँग सम्बन्धित थप सेटिङहरू</translation>
 <translation id="8734073480934656039">यस सेटिङ सक्षम गर्नाले किओस्क अनुप्रयोगहजरू सुरुवातमा स्वचालित रूपमा सुरु गर्न अनुमति दिन्छ।</translation>
 <translation id="8734674662128056360">तेस्रो पक्षीय कुकीलाई रोक लगाउने कार्य</translation>
+<translation id="8734755021067981851">कुनै पनि USB डिभाइस एट्याच गरिएको छैन।</translation>
 <translation id="873545264931343897"><ph name="PLUGIN_NAME" /> अद्यावधिक भइसकेपछि, त्यसलाई सक्रिय गर्न पृष्ठलाई पुन: लोड गर्नुहोस्</translation>
 <translation id="8736288397686080465">यो साइट पृष्ठभूमिमा अद्यावधिक गरिएको छ।</translation>
 <translation id="8737709691285775803">Shill</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index 3e976d7..cc7c7e34 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -275,6 +275,7 @@
 <translation id="125220115284141797">Standaard</translation>
 <translation id="1252987234827889034">Er is een profielfout opgetreden</translation>
 <translation id="1254593899333212300">Rechtstreekse internetverbinding</translation>
+<translation id="1257336506558170607">Geselecteerd certificaat exporteren</translation>
 <translation id="1258491128795710625">Wat is er nieuw</translation>
 <translation id="1259152067760398571">Veiligheidscheck is gisteren uitgevoerd</translation>
 <translation id="1260451001046713751">Pop-ups en omleidingen van <ph name="HOST" /> altijd toestaan</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb
index 3c7b0366..d22ee2e 100644
--- a/chrome/app/resources/generated_resources_or.xtb
+++ b/chrome/app/resources/generated_resources_or.xtb
@@ -276,6 +276,7 @@
 <translation id="125220115284141797">ଡିଫଲ୍ଟ</translation>
 <translation id="1252987234827889034">ପ୍ରୋଫାଇଲ୍‌ ତ୍ରୁଟି ହେଲା</translation>
 <translation id="1254593899333212300">ସିଧାସଳଖ ଇଣ୍ଟର୍ନେ‍ଟ୍ ସଂଯୋଗ</translation>
+<translation id="1257336506558170607">ଚୟନିତ ସାର୍ଟିଫିକେଟ ଏକ୍ସପୋର୍ଟ କରନ୍ତୁ</translation>
 <translation id="1258491128795710625">ନୂଆ କଣ ଅଛି</translation>
 <translation id="1259152067760398571">ସୁରକ୍ଷା ଯାଞ୍ଚ ଗତକାଲି ଚାଲିଥିଲା</translation>
 <translation id="1260451001046713751"><ph name="HOST" /> ଠାରୁ ସର୍ବଦା ପପ୍-ଅପ୍ ଏବଂ ରିଡାଇରେକ୍ଟର ଅନୁମତି ଦିଅନ୍ତୁ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index b724f60..f5eb06b 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Coś poszło nie tak. Linux mógł nie zostać w pełni uaktualniony. Aby dowiedzieć się więcej, przejrzyj dzienniki. Zostały one zapisane tutaj: Pliki &gt; Moje pliki &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Wyczyścić też dane z tych aplikacji?</translation>
 <translation id="1043824690776631483">Aby wejść na tę stronę, musisz mieć pozwolenie. Strona może zawierać nieodpowiednie treści.</translation>
+<translation id="104419033123549300">Styl mapy klawiszy</translation>
 <translation id="104710386808485638">Uruchomić Linuksa ponownie?</translation>
 <translation id="1047431265488717055">Kopiuj te&amp;kst linku</translation>
 <translation id="1048286738600630630">Wyświetlanie</translation>
@@ -277,6 +278,7 @@
 <translation id="125220115284141797">Domyślne</translation>
 <translation id="1252987234827889034">Wystąpił błąd profilu</translation>
 <translation id="1254593899333212300">Bezpośrednie połączenie internetowe</translation>
+<translation id="1257336506558170607">Eksportuj wybrany certyfikat</translation>
 <translation id="1258491128795710625">Nowe funkcje</translation>
 <translation id="1259152067760398571">Kontrola zabezpieczeń została wykonana wczoraj</translation>
 <translation id="1260451001046713751">Zawsze zezwalaj na wyskakujące okienka i przekierowania z <ph name="HOST" /></translation>
@@ -326,6 +328,7 @@
 <translation id="1307165550267142340">Kod PIN został utworzony</translation>
 <translation id="1307431692088049276">Nie pytaj ponownie</translation>
 <translation id="1307559529304613120">Ups. System nie może zapisać długoterminowego tokena dostępu API dla tego urządzenia.</translation>
+<translation id="1312811472299082263">Utwórz na podstawie pliku kopii zapasowej poradnika Ansible lub Crostini</translation>
 <translation id="1313405956111467313">Automatyczna konfiguracja serwera proxy</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Wylogujemy Cię ze wszystkich stron – także na otwartych kartach</translation>
@@ -772,6 +775,7 @@
 <translation id="1721312023322545264">Aby wejść na tę stronę, musisz uzyskać pozwolenie od użytkownika <ph name="NAME" /></translation>
 <translation id="1722460139690167654">Twoim <ph name="BEGIN_LINK" />urządzeniem <ph name="DEVICE_TYPE" /> zarządza<ph name="END_LINK" /> domena <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Nowe okno</translation>
+<translation id="1724801751621173132">Tryb wprowadzania</translation>
 <translation id="1725562816265788801">Przewijanie kart</translation>
 <translation id="1729533290416704613">Kontroluje także to, jaka strona wyświetla się po wyszukiwaniu w omniboksie.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Aby usunąć aplikacje, otwórz Ustawienia &gt; Sklep Google Play &gt; Zarządzaj ustawieniami Androida &gt; Aplikacje lub Menedżer aplikacji. Następnie kliknij aplikację, którą chcesz odinstalować (jeśli to konieczne, przesuń palcem w prawo lub w lewo, by ją znaleźć), a potem kliknij Odinstaluj lub Wyłącz.<ph name="END_PARAGRAPH1" /></translation>
@@ -1095,6 +1099,7 @@
 <translation id="2028449514182362831">Nie będą działać funkcje, które potrzebują czujników ruchu</translation>
 <translation id="202918510990975568">Wpisz hasło, by skonfigurować zabezpieczenia i logowanie</translation>
 <translation id="2030455719695904263">Trackpad</translation>
+<translation id="2031385797619033640">Kliknij, aby zezwolić rozszerzeniu <ph name="EXTENSIONS_REQUESTING_ACCESS" /> na odczytywanie i modyfikowanie strony <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Twoje hasło zostało zapisane na koncie Google</translation>
 <translation id="2031914984822377766">Dodaj preferowane <ph name="LINK_BEGIN" />języki stron<ph name="LINK_END" />. Język znajdujący się na samej górze listy będzie wykorzystywany do tłumaczeń.</translation>
 <translation id="2033758234986231162">Nie można utrzymać połączenia z telefonem. Sprawdź, czy telefon jest wystarczająco blisko, jest odblokowany i ma włączone Bluetooth oraz Wi-Fi.</translation>
@@ -1440,6 +1445,7 @@
 <translation id="2328561734797404498">Aby użyć <ph name="APP_NAME" />, uruchom ponownie urządzenie.</translation>
 <translation id="2328636661627946415">Kiedy jesteś w trybie incognito, witryny mogą używać plików cookie tylko do sprawdzania Twojej aktywności związanej z przeglądaniem w danej witrynie. Po zakończeniu sesji incognito pliki cookie są usuwane.</translation>
 <translation id="2329597144923131178">Zaloguj się, by korzystać z zakładek, historii, haseł i innych ustawień na wszystkich swoich urządzeniach.</translation>
+<translation id="2332115969598251205">Nie udało się wczytać urządzeń zapisanych na koncie <ph name="PRIMARY_EMAIL" />. Sprawdź połączenie z internetem i spróbuj ponownie.</translation>
 <translation id="2332131598580221120">Wyświetl w sklepie</translation>
 <translation id="2332192922827071008">Otwórz Ustawienia</translation>
 <translation id="2332515770639153015">Włączono Ulepszone Bezpieczne przeglądanie</translation>
@@ -1883,6 +1889,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Sprawdzaj gramatykę razem z pisownią</translation>
 <translation id="2753677631968972007">Ręcznie określ uprawnienia do witryn.</translation>
+<translation id="2754226775788136540">Szukam urządzeń obsługujących Szybkie parowanie zapisanych na koncie <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Znajdź w Sklepie Google Play aplikacje, których potrzebujesz – od zwiększających produktywność po rozrywkowe. Możesz je zainstalować w dowolnym momencie.</translation>
 <translation id="2755349111255270002">Zresetuj to urządzenie <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Zarządzaj ułatwieniami dostępu</translation>
@@ -1934,6 +1941,7 @@
 <translation id="2796740370559399562">Nadal zezwalaj na pliki cookie</translation>
 <translation id="2798347533012571708">Zachowaj aktualizacje</translation>
 <translation id="2799223571221894425">Uruchom ponownie</translation>
+<translation id="2800309299477632167">Niestandardowa mapa klawiszy</translation>
 <translation id="2800760947029405028">Prześlij obraz</translation>
 <translation id="2801954693771979815">Rozmiar elementów na ekranie</translation>
 <translation id="2802557211515765772">Nie ma zarządzanych drukarek.</translation>
@@ -1995,6 +2003,7 @@
 <translation id="2849767214114481738">Kod PIN został dodany</translation>
 <translation id="2849936225196189499">Krytyczne</translation>
 <translation id="2850541429955027218">Dodaj motyw</translation>
+<translation id="2850672011315104382">Styl znaków przestankowych</translation>
 <translation id="2851634818064021665">Musisz mieć pozwolenie, by wejść na tę stronę</translation>
 <translation id="2851728849045278002">Coś poszło nie tak. Kliknij, by uzyskać więcej informacji.</translation>
 <translation id="2852385257476173980">Gdy zaczniesz przeglądać strony, tu pojawi się lista witryn</translation>
@@ -2098,6 +2107,7 @@
 <translation id="2942279350258725020">Wiadomości na Androida</translation>
 <translation id="2942560570858569904">Czekam…</translation>
 <translation id="2942581856830209953">Dostosuj tę stronę</translation>
+<translation id="2943268899142471972">Wybierz plik kopii zapasowej poradnika Ansible lub Crostini</translation>
 <translation id="2944060181911631861">Wysyłaj dane diagnostyczne oraz informacje o użytkowaniu. Pomóż ulepszyć działanie Androida, wysyłając automatycznie do Google dane diagnostyczne oraz informacje o używaniu urządzenia i aplikacji. Dzięki temu będziemy mogli poprawić stabilność systemu i aplikacji oraz wprowadzić inne ulepszenia. Niektóre dane zbiorcze pomogą nam też udoskonalić aplikacje Google lub zostaną wykorzystane przez naszych partnerów, na przykład deweloperów aplikacji na Androida. Jeśli włączysz ustawienie Dodatkowa aktywność w internecie i aplikacjach, te dane mogą być zapisywane na Twoim koncie Google. <ph name="BEGIN_LINK1" />Więcej informacji<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Przejdź do plików</translation>
 <translation id="2946119680249604491">Dodaj połączenie</translation>
@@ -2490,6 +2500,7 @@
 <translation id="3359256513598016054">Ograniczenia zasad certyfikatu</translation>
 <translation id="3360297538363969800">Drukowanie nie udało się. Sprawdź swoją drukarkę i spróbuj ponownie.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> udostępnia Ci <ph name="ATTACHMENTS" />.}few{<ph name="DEVICE_NAME" /> udostępnia Ci <ph name="ATTACHMENTS" />.}many{<ph name="DEVICE_NAME" /> udostępnia Ci <ph name="ATTACHMENTS" />.}other{<ph name="DEVICE_NAME" /> udostępnia Ci <ph name="ATTACHMENTS" />.}}</translation>
+<translation id="3361954577771524115">Z aplikacji</translation>
 <translation id="3363202073972776113">Tym nowym profilem będzie zarządzać Twoja organizacja. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Od administratora: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Użyj klawisza Ctrl lub Alt</translation>
@@ -2938,6 +2949,7 @@
 <translation id="3784472333786002075">Pliki cookie są tworzone przez strony internetowe. Dzielą się na dwa typy: własne pliki cookie są zapisywane przez odwiedzaną stronę. Jej adres znajdziesz w pasku adresu. Pliki cookie innych firm są tworzone przez inne strony. Na tych stronach znajdują się niektóre treści, np. reklamy i obrazy, które wyświetlają się na odwiedzanej stronie.</translation>
 <translation id="3785308913036335955">Pokaż skrót do aplikacji</translation>
 <translation id="3785727820640310185">Zapisano hasła do tej strony</translation>
+<translation id="3787434344076711519">Czekam na tłumaczenie</translation>
 <translation id="3788301286821743879">Nie udało się uruchomić aplikacji kiosku.</translation>
 <translation id="3788331399335602504">te pliki</translation>
 <translation id="3788401245189148511">Będzie mógł:</translation>
@@ -3013,6 +3025,7 @@
 <translation id="3848547754896969219">Otwórz w oknie &amp;incognito</translation>
 <translation id="385051799172605136">Wstecz</translation>
 <translation id="3851428669031642514">Wczytaj niezabezpieczone skrypty</translation>
+<translation id="3852215160863921508">Pomoc przy wprowadzaniu danych</translation>
 <translation id="3854599674806204102">Wybierz jedną z opcji</translation>
 <translation id="3854967233147778866">Proponuj tłumaczenie stron w innych językach</translation>
 <translation id="3854976556788175030">Zasobnik wyjściowy jest pełny</translation>
@@ -3221,6 +3234,7 @@
 <translation id="4036778507053569103">Zasady pobrane z serwera są nieprawidłowe.</translation>
 <translation id="4037084878352560732">Koń</translation>
 <translation id="403725336528835653">Najpierw wypróbuj</translation>
+<translation id="4040041015953651705">Język źródłowy tłumaczenia</translation>
 <translation id="4040105702484676956">Czy chcesz wyczyścić dane i uprawnienia witryny <ph name="SITE_NAME" /> i zainstalowanych z niej aplikacji?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Zamknij stronę}few{Zamknij strony}many{Zamknij strony}other{Zamknij strony}}</translation>
 <translation id="4043267180218562935">Rozmiar kursora</translation>
@@ -3768,6 +3782,7 @@
 <translation id="4579453506923101210">Zapomnij połączony telefon</translation>
 <translation id="4579581181964204535">Nie udało się przesłać <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Aby wyświetlić powiadomienia przeglądarki, otwórz <ph name="LINK_BEGIN" />Ustawienia przeglądarki Chrome<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Zaloguj się ponownie w Menedżerze haseł Google</translation>
 <translation id="4580596421317071374">Hasła przechowuje <ph name="GOOGLE_PASSWORD_MANAGER" /> na tym urządzeniu.</translation>
 <translation id="4580626299762849806">Nie udało się zaimportować haseł. Sprawdź, czy plik <ph name="FILENAME" /> jest poprawnie sformatowany.</translation>
 <translation id="4581774856936278355">Błąd podczas przywracania Linuksa</translation>
@@ -4026,6 +4041,7 @@
 <translation id="4838170306476614339">Wyświetlaj zdjęcia, pliki multimedialne i powiadomienia z telefonu</translation>
 <translation id="4838836835474292213">Przyznano uprawnienia do odczytu zawartości schowka</translation>
 <translation id="4838907349371614303">Hasło zostało zaktualizowane</translation>
+<translation id="4838958829619609362">Wybrany element jest niedostępny w tym języku (<ph name="LANGUAGE" />)</translation>
 <translation id="4839303808932127586">Za&amp;pisz film wideo jako...</translation>
 <translation id="4840096453115567876">Zamknąć tryb incognito mimo to?</translation>
 <translation id="4841741146571978176">Wymagana maszyna wirtualna nie istnieje. Aby przejść dalej, spróbuj skonfigurować maszynę wirtualną typu <ph name="VM_TYPE" /></translation>
@@ -4448,6 +4464,7 @@
 <translation id="5268373933383932086">Twoja strona, Twoje zasady</translation>
 <translation id="5269977353971873915">Niepowodzenie drukowania</translation>
 <translation id="5273806377963980154">Edytuj adres URL witryny</translation>
+<translation id="5275084684151588738">Słowniki użytkownika</translation>
 <translation id="5275338516105640560">Przycisk zapisanej grupy kart</translation>
 <translation id="5275352920323889391">Pies</translation>
 <translation id="527605719918376753">Wycisz kartę</translation>
@@ -4662,6 +4679,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{Kod PIN musi mieć co najmniej 1 znak}few{Kod PIN musi mieć co najmniej # znaki}many{Kod PIN musi mieć co najmniej # znaków}other{Kod PIN musi mieć co najmniej # znaku}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> wymaga połączenia się z Wi-Fi i pobrania aktualizacji. Możesz też rozpocząć pobieranie za pomocą połączenia z pomiarem użycia danych (mogą zostać naliczone opłaty).</translation>
 <translation id="5481273127572794904">Nie zezwolono na automatyczne pobieranie wielu plików</translation>
+<translation id="5481755802440890178">Obecnie nie można przetłumaczyć tego fragmentu</translation>
 <translation id="5481941284378890518">Dodaj drukarki znalezione w pobliżu</translation>
 <translation id="5483785310822538350">Anuluj dostęp do plików i urządzeń</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> wymaga utworzenia kopii zapasowej danych i zwrotu tego urządzenia (<ph name="DEVICE_TYPE" />) dzisiaj. <ph name="LINK_BEGIN" />Zobacz szczegóły<ph name="LINK_END" />}few{<ph name="MANAGER" /> wymaga utworzenia kopii zapasowej danych i zwrotu tego urządzenia (<ph name="DEVICE_TYPE" />) w ciągu {NUM_DAYS} dni. <ph name="LINK_BEGIN" />Zobacz szczegóły<ph name="LINK_END" />}many{<ph name="MANAGER" /> wymaga utworzenia kopii zapasowej danych i zwrotu tego urządzenia (<ph name="DEVICE_TYPE" />) w ciągu {NUM_DAYS} dni. <ph name="LINK_BEGIN" />Zobacz szczegóły<ph name="LINK_END" />}other{<ph name="MANAGER" /> wymaga utworzenia kopii zapasowej danych i zwrotu tego urządzenia (<ph name="DEVICE_TYPE" />) w ciągu {NUM_DAYS} dnia. <ph name="LINK_BEGIN" />Zobacz szczegóły<ph name="LINK_END" />}}</translation>
@@ -4796,6 +4814,7 @@
 <translation id="558918721941304263">Wczytuję aplikacje…</translation>
 <translation id="5590418976913374224">Odtwarzaj dźwięk podczas uruchamiania urządzenia</translation>
 <translation id="5592595402373377407">Brak wystarczającej ilości danych.</translation>
+<translation id="5594899180331219722">Wybierz plik</translation>
 <translation id="5595307023264033512">Całkowita pamięć używana przez strony: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Edytuj adres</translation>
 <translation id="5596627076506792578">Więcej opcji</translation>
@@ -4893,6 +4912,7 @@
 <translation id="5696143504434933566">Zgłoś nadużycie dotyczące rozszerzenia „<ph name="EXTENSION_NAME" />”</translation>
 <translation id="5696679855467848181">Bieżący plik PPD: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Selektor emotikonów</translation>
+<translation id="5698462638680260399">Aby używać haseł, musisz się zalogować</translation>
 <translation id="570043786759263127">Aplikacje i usługi Google Play</translation>
 <translation id="5700836101007545240">Dodawanie połączenia zostało wyłączone przez administratora</translation>
 <translation id="5701080607174488915">Podczas pobierania zasad z serwera wystąpił błąd.</translation>
@@ -4910,6 +4930,7 @@
 <translation id="5712153969432126546">Czasami witryny publikują pliki PDF takie jak dokumenty, umowy i formularze</translation>
 <translation id="571222594670061844">Witryny mogą wyświetlać prośby o zalogowanie się pochodzące od usług tożsamości</translation>
 <translation id="5713158217420111469">Połączono z siecią <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Styl wprowadzania spacji</translation>
 <translation id="5715711091495208045">Broker wtyczek: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Domyślne wyszukiwarki</translation>
 <translation id="5719854774000914513">Witryny mogą prosić o zgodę na połączenie z urządzeniami HID</translation>
@@ -5028,6 +5049,7 @@
 <translation id="5834581999798853053">Zostało około <ph name="TIME" /> min</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – nagrywanie kamerą lub mikrofonem</translation>
 <translation id="583673505367439042">Strony mogą prosić o zgodę na edytowanie plików i folderów na urządzeniu</translation>
+<translation id="5836999627049108525">Język źródłowy tłumaczenia</translation>
 <translation id="583756221537636748">Etui</translation>
 <translation id="5840658767386246331">Wyszukaj w Google</translation>
 <translation id="5840680448799937675">Pliki będą zawsze udostępniane offline</translation>
@@ -5538,6 +5560,7 @@
 <translation id="6318944945640833942">Nie udało się wykryć drukarki. Wpisz jej adres ponownie.</translation>
 <translation id="6322370287306604163">Szybsze odblokowywanie odciskiem palca</translation>
 <translation id="6322559670748154781">Ten plik jest rzadko pobierany, dlatego zablokowała go Ochrona zaawansowana</translation>
+<translation id="6324083483652497048">Kliknij, aby zezwolić tym rozszerzeniom na odczytywanie i modyfikowanie strony <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Edytuj skrót</translation>
 <translation id="6325191661371220117">Wyłącz automatyczne uruchamianie</translation>
 <translation id="6326175484149238433">Usuń z Chrome</translation>
@@ -6332,6 +6355,7 @@
 <translation id="7069811530847688087"><ph name="WEBSITE" /> może wymagać nowszego lub innego rodzaju klucza bezpieczeństwa</translation>
 <translation id="7070484045139057854">Może odczytywać i modyfikować dane witryn</translation>
 <translation id="7072010813301522126">Nazwa skrótu</translation>
+<translation id="7074066049407662839">Aby zapisywać hasła, musisz się zalogować</translation>
 <translation id="7075513071073410194">PKCS #1, MD5 z szyfrowaniem RSA</translation>
 <translation id="7075625805486468288">Zarządzanie certyfikatami i ustawieniami HTTPS/SSL</translation>
 <translation id="7076875098323397992">Nie można rozpocząć uaktualnienia</translation>
@@ -6570,6 +6594,7 @@
 <translation id="7343372807593926528">Zanim wyślesz opinię, opisz problem.</translation>
 <translation id="7344585835349671209">Zarządzaj certyfikatami HTTPS/SSL na urządzeniu</translation>
 <translation id="7345706641791090287">Potwierdź hasło</translation>
+<translation id="7345919885156673810">Wybrany element jest niedostępny w tym języku (<ph name="LANGUAGE" />)</translation>
 <translation id="7346909386216857016">Rozumiem</translation>
 <translation id="7347452120014970266">Spowoduje to usunięcie wszystkich danych i plików cookie zapisanych przez stronę <ph name="ORIGIN_NAME" /> oraz jej zainstalowane aplikacje</translation>
 <translation id="7347751611463936647">Aby skorzystać z tego rozszerzenia, wpisz „<ph name="EXTENSION_KEYWORD" />”, naciśnij klawisz TAB i wpisz odpowiednie polecenie lub wyszukiwany tekst.</translation>
@@ -6862,6 +6887,7 @@
 <translation id="7625568159987162309">Pokaż uprawnienia i zapisane dane wszystkich witryn</translation>
 <translation id="7625823789272218216">Nowa karta po lewej</translation>
 <translation id="7628201176665550262">Częstotliwość odświeżania</translation>
+<translation id="7628392600831846024">Styl symboli</translation>
 <translation id="7629827748548208700">Karta: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">Administrator tego urządzenia (<ph name="MANAGER" />) wymaga logowania się za każdym razem.</translation>
 <translation id="7631014249255418691">Pomyślnie utworzono kopię zapasową aplikacji i plików Linuksa</translation>
@@ -8162,6 +8188,7 @@
 <translation id="8850251000316748990">Zobacz więcej…</translation>
 <translation id="885246833287407341">Argumenty funkcji interfejsu API</translation>
 <translation id="8853586775156634952">Ta karta zostanie zapisana tylko na tym urządzeniu</translation>
+<translation id="8854745870658584490">Skrót wyboru</translation>
 <translation id="8855977033756560989">To urządzenie Chromebook Enterprise ma licencję na Chrome Enterprise. Aby korzystać z funkcji dla firm, zarejestruj to urządzenie na koncie administratora Google.</translation>
 <translation id="8856028055086294840">Przywróć aplikacje i strony</translation>
 <translation id="885701979325669005">Pamięć</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb
index efe1168f..aece76c 100644
--- a/chrome/app/resources/generated_resources_pt-PT.xtb
+++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Algo correu mal. O Linux pode ter sido atualizado apenas parcialmente. Consulte os registos para obter mais informações. Os registos foram guardados em Files &gt; Os meus ficheiros &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Também pretende limpar os dados destas apps?</translation>
 <translation id="1043824690776631483">Necessita de autorização para visitar este site. Pode ter conteúdo impróprio.</translation>
+<translation id="104419033123549300">Estilo do esquema do teclado</translation>
 <translation id="104710386808485638">Pretende reiniciar o Linux?</translation>
 <translation id="1047431265488717055">Copiar te&amp;xto do link</translation>
 <translation id="1048286738600630630">Ecrãs</translation>
@@ -772,6 +773,7 @@
 <translation id="1721312023322545264">Precisa da autorização de <ph name="NAME" /> para visitar este site</translation>
 <translation id="1722460139690167654">O <ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" /> é gerido<ph name="END_LINK" /> por <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Nova janela</translation>
+<translation id="1724801751621173132">Método de introdução</translation>
 <translation id="1725562816265788801">Deslocamento do separador</translation>
 <translation id="1729533290416704613">Também controla a página apresentada quando pesquisa a partir da Caixa geral.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para remover aplicações, aceda a Definições &gt; Google Play Store &gt; Gerir as preferências do Android &gt; Apps ou Gestor de aplicações. Toque na aplicação que pretende desinstalar (pode ter de deslizar rapidamente para a direita ou para a esquerda para encontrar a aplicação). Em seguida, toque em Desinstalar ou em Desativar.<ph name="END_PARAGRAPH1" /></translation>
@@ -1952,6 +1954,7 @@
 <translation id="2796740370559399562">Continuar a permitir cookies</translation>
 <translation id="2798347533012571708">Manter atualizações</translation>
 <translation id="2799223571221894425">Reiniciar</translation>
+<translation id="2800309299477632167">Mapa de teclas personalizado</translation>
 <translation id="2800760947029405028">Carregar uma imagem</translation>
 <translation id="2801954693771979815">Tamanho do ecrã</translation>
 <translation id="2802557211515765772">Não existem impressoras geridas.</translation>
@@ -2013,6 +2016,7 @@
 <translation id="2849767214114481738">O seu PIN foi adicionado</translation>
 <translation id="2849936225196189499">Crítica</translation>
 <translation id="2850541429955027218">Adicionar tema</translation>
+<translation id="2850672011315104382">Estilo da pontuação</translation>
 <translation id="2851634818064021665">Necessita de autorização para aceder a este site</translation>
 <translation id="2851728849045278002">Ocorreu um erro. Clique para obter mais detalhes.</translation>
 <translation id="2852385257476173980">Uma lista de sites que visita pode aparecer aqui enquanto navega na Web</translation>
@@ -2510,6 +2514,7 @@
 <translation id="3359256513598016054">Restrições de políticas de certificados</translation>
 <translation id="3360297538363969800">Falha ao imprimir. Verifique a impressora e tente novamente.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> está a partilhar <ph name="ATTACHMENTS" /> consigo.}other{<ph name="DEVICE_NAME" /> está a partilhar <ph name="ATTACHMENTS" /> consigo.}}</translation>
+<translation id="3361954577771524115">A partir da app</translation>
 <translation id="3363202073972776113">Este novo perfil vai ser gerido pela sua organização. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Do seu administrador: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Utilize Ctrl ou Alt.</translation>
@@ -3034,6 +3039,7 @@
 <translation id="3848547754896969219">Abra numa &amp;janela de navegação anónima</translation>
 <translation id="385051799172605136">Anterior</translation>
 <translation id="3851428669031642514">Carregar scripts não seguros</translation>
+<translation id="3852215160863921508">Assistência de introdução</translation>
 <translation id="3854599674806204102">Escolha uma opção</translation>
 <translation id="3854967233147778866">Proponha a tradução de Websites noutros idiomas</translation>
 <translation id="3854976556788175030">O tabuleiro de saída está cheio</translation>
@@ -3790,6 +3796,7 @@
 <translation id="4579453506923101210">Esquecer telemóvel associado</translation>
 <translation id="4579581181964204535">Não é possível transmitir <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Para as notificações do navegador, aceda às <ph name="LINK_BEGIN" />Definições do navegador Chrome<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Volte a iniciar sessão no Gestor de Palavras-passe da Google</translation>
 <translation id="4580596421317071374">As palavras-passe são guardadas no <ph name="GOOGLE_PASSWORD_MANAGER" /> neste dispositivo.</translation>
 <translation id="4580626299762849806">Não é possível importar palavras-passe. Verifique o ficheiro <ph name="FILENAME" /> e confirme que tem o formato correto.</translation>
 <translation id="4581774856936278355">Erro ao restaurar o Linux</translation>
@@ -4471,6 +4478,7 @@
 <translation id="5268373933383932086">A sua página, à sua maneira</translation>
 <translation id="5269977353971873915">Falha de Impressão</translation>
 <translation id="5273806377963980154">Editar o URL do site</translation>
+<translation id="5275084684151588738">Dicionários do utilizador</translation>
 <translation id="5275338516105640560">Botão do grupo de separadores guardado</translation>
 <translation id="5275352920323889391">Cão</translation>
 <translation id="527605719918376753">Desativar som do separador</translation>
@@ -4686,6 +4694,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{O PIN tem de ter, pelo menos, um caráter.}other{O PIN tem de ter, pelo menos, # carateres.}}</translation>
 <translation id="5474859849784484111">O domínio <ph name="MANAGER" /> requer que estabeleça ligação a uma rede Wi-Fi agora e transfira uma atualização. Em alternativa, transfira a partir de uma ligação com acesso limitado (podem aplicar-se custos).</translation>
 <translation id="5481273127572794904">Sem autorização para transferir vários ficheiros automaticamente</translation>
+<translation id="5481755802440890178">Não foi possível traduzir a seleção neste momento</translation>
 <translation id="5481941284378890518">Adicionar impressoras próximas</translation>
 <translation id="5483785310822538350">Revogar o acesso a ficheiros e a dispositivos</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> requer que faça uma cópia de segurança dos seus dados e devolva este <ph name="DEVICE_TYPE" /> hoje. <ph name="LINK_BEGIN" />Veja os detalhes<ph name="LINK_END" />}other{<ph name="MANAGER" /> requer que faça uma cópia de segurança dos seus dados e devolva este <ph name="DEVICE_TYPE" /> dentro de {NUM_DAYS} dias. <ph name="LINK_BEGIN" />Veja os detalhes<ph name="LINK_END" />}}</translation>
@@ -4919,6 +4928,7 @@
 <translation id="5696143504434933566">Denunciar abuso de "<ph name="EXTENSION_NAME" />"</translation>
 <translation id="5696679855467848181">Ficheiro PPD atualmente em utilização: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Selecionador de emojis</translation>
+<translation id="5698462638680260399">Inicie sessão para usar palavras-passe</translation>
 <translation id="570043786759263127">Apps e serviços do Google Play</translation>
 <translation id="5700836101007545240">A opção Adicionar ligação foi desativada pelo gestor</translation>
 <translation id="5701080607174488915">Erro ao obter a política do servidor.</translation>
@@ -4936,6 +4946,7 @@
 <translation id="5712153969432126546">Por vezes, os sites publicam PDFs, como documentos, contratos e formulários</translation>
 <translation id="571222594670061844">Os sites podem mostrar pedidos de início de sessão de serviços de identidade</translation>
 <translation id="5713158217420111469">Ligado a <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Estilo de introdução de espaço</translation>
 <translation id="5715711091495208045">Mediador de plug-ins: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Motores de pesquisa predefinidos</translation>
 <translation id="5719854774000914513">Os sites podem solicitar a ligação a dispositivos HID</translation>
@@ -6358,6 +6369,7 @@
 <translation id="7069811530847688087">O Website <ph name="WEBSITE" /> pode exigir um tipo de chave de segurança mais recente ou diferente.</translation>
 <translation id="7070484045139057854">Permite ler e alterar os dados do site</translation>
 <translation id="7072010813301522126">Nome do atalho</translation>
+<translation id="7074066049407662839">Inicie sessão para guardar palavras-passe</translation>
 <translation id="7075513071073410194">PKCS #1 MD5 Com encriptação RSA</translation>
 <translation id="7075625805486468288">Gerir certificados e definições HTTPS/SSL</translation>
 <translation id="7076875098323397992">Não é possível iniciar a atualização</translation>
@@ -6889,6 +6901,7 @@
 <translation id="7625568159987162309">Ver autorizações e dados armazenados em sites</translation>
 <translation id="7625823789272218216">Novo separador à esquerda</translation>
 <translation id="7628201176665550262">Taxa de atualização</translation>
+<translation id="7628392600831846024">Estilo dos símbolos</translation>
 <translation id="7629827748548208700">Separador: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">Este dispositivo é gerido por <ph name="MANAGER" /> e requer que inicie sessão sempre.</translation>
 <translation id="7631014249255418691">Cópia de segurança das aplicações e dos ficheiros do Linux efetuada com êxito</translation>
@@ -8187,6 +8200,7 @@
 <translation id="8850251000316748990">Veja mais…</translation>
 <translation id="885246833287407341">Argumentos de função da API</translation>
 <translation id="8853586775156634952">Este cartão será guardado apenas neste dispositivo.</translation>
+<translation id="8854745870658584490">Atalho de seleção</translation>
 <translation id="8855977033756560989">Este dispositivo Chromebook Enterprise é fornecido juntamente com a Chrome Enterprise Upgrade. Para tirar partido das capacidades empresariais, inscreva este dispositivo com uma conta de administrador Google.</translation>
 <translation id="8856028055086294840">Restaurar apps e páginas</translation>
 <translation id="885701979325669005">Armazenamento</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index 16550e7..0d41cd1e 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -3263,6 +3263,7 @@
 <translation id="4062561150282203854">Sincronizează aplicațiile, setările și altele de pe dispozitivul <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Rețeaua pe care o folosești (<ph name="NETWORK_ID" />) poate solicita accesarea paginii de conectare.</translation>
 <translation id="4066207411788646768">Verifică-ți conexiunea pentru a vedea imprimantele disponibile din rețea</translation>
+<translation id="4066945815577305767">Parolele au expirat</translation>
 <translation id="4068776064906523561">Amprentele salvate</translation>
 <translation id="407173827865827707">Când se dă clic</translation>
 <translation id="4072701974556190758">Parola va fi salvată în Contul tău Google, <ph name="ACCOUNT" />. Nu este nevoie să o reții.</translation>
@@ -5565,6 +5566,7 @@
 <translation id="6335920438823100346">Pentru a inițializa Linux, <ph name="MANAGER" /> îți solicită să faci backup datelor și să revii la setările din fabrică ale Chromebookului.</translation>
 <translation id="6336038146639916978"><ph name="MANAGER" /> a dezactivat remedierea erorilor prin ADB. Astfel, <ph name="DEVICE_TYPE" /> se va reseta în termen de 24 de ore. Fă backup pentru fișierele pe care vrei să le păstrezi.</translation>
 <translation id="6338402296920404442">Șterge <ph name="FILENAME" />, pentru ca persoanele care folosesc acest dispozitiv să nu îți poată vedea parolele.</translation>
+<translation id="6338968693068997776">Adaugă un dispozitiv USB</translation>
 <translation id="6338981933082930623">Toate site-urile pot afișa orice anunțuri</translation>
 <translation id="6339668969738228384">Creează un profil nou pentru <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Internet Printing Protocol (IPPS)</translation>
@@ -6164,6 +6166,7 @@
 <translation id="6903907808598579934">Activează sincronizarea</translation>
 <translation id="6904344821472985372">Revocați accesul la fișiere</translation>
 <translation id="6904655473976120856">Apasă pe butonul Aplicație pentru ieșire</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Pentru a-ți proteja parolele, Managerul de parole Google se blochează după un minut de inactivitate}few{Pentru a-ți proteja parolele, Managerul de parole Google se blochează după {NUM_MINS} minute de inactivitate}other{Pentru a-ți proteja parolele, Managerul de parole Google se blochează după {NUM_MINS} de minute de inactivitate}}</translation>
 <translation id="6909422577741440844">Primești fișiere de la acest dispozitiv?</translation>
 <translation id="6910211073230771657">Șters</translation>
 <translation id="691106080621596509">Astfel, se vor șterge toate datele și cookie-urile stocate de <ph name="SITE_GROUP_NAME" /> și de site-urile subordonate, precum și de aplicația instalată asociată</translation>
@@ -8003,6 +8006,7 @@
 <translation id="8688672835843460752">Disponibilă</translation>
 <translation id="8690129572193755009">Site-urile pot solicita permisiunea de a gestiona protocoale</translation>
 <translation id="8692107307702113268">Parola are peste 1.000 de caractere</translation>
+<translation id="8694596275649352090">Blochează în modul de inactivitate sau când capacul este închis</translation>
 <translation id="8695139659682234808">Adaugă opțiuni de control parental după configurare</translation>
 <translation id="8695825812785969222">Deschide &amp;locația...</translation>
 <translation id="8698269656364382265">Pentru a reveni la ecranul anterior, glisează din stânga.</translation>
@@ -8051,6 +8055,7 @@
 <translation id="8732844209475700754">Mai multe setări privind confidențialitatea, securitatea și colectarea datelor</translation>
 <translation id="8734073480934656039">Dacă activați această setare, aplicațiile de tip chioșc se pot lansa automat la pornire.</translation>
 <translation id="8734674662128056360">Blocarea cookie-urilor terță-parte</translation>
+<translation id="8734755021067981851">Nu există dispozitive USB atașate.</translation>
 <translation id="873545264931343897">După ce actualizarea pluginului <ph name="PLUGIN_NAME" /> se finalizează, reîncarcă pagina pentru a-l activa</translation>
 <translation id="8736288397686080465">Acest site a fost actualizat în fundal.</translation>
 <translation id="8737709691285775803">Shill</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index 0d04f037..f3f9844 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -278,6 +278,7 @@
 <translation id="125220115284141797">По умолчанию</translation>
 <translation id="1252987234827889034">Ошибка в профиле</translation>
 <translation id="1254593899333212300">Прямое подключение к Интернету</translation>
+<translation id="1257336506558170607">Экспортировать выбранный сертификат</translation>
 <translation id="1258491128795710625">Что нового</translation>
 <translation id="1259152067760398571">Проверка безопасности выполнена вчера.</translation>
 <translation id="1260451001046713751">Всегда показывать всплывающие окна с сайта <ph name="HOST" /> и разрешить перенаправление с него</translation>
@@ -327,6 +328,7 @@
 <translation id="1307165550267142340">PIN-код создан.</translation>
 <translation id="1307431692088049276">Больше не спрашивать</translation>
 <translation id="1307559529304613120">Системе не удалось сохранить токен доступа для API на этом устройстве.</translation>
+<translation id="1312811472299082263">Добавьте сценарий Ansible или файл резервной копии Crostini</translation>
 <translation id="1313405956111467313">Автоматическая настройка прокси-сервера</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Вы автоматически выйдете из аккаунтов на всех сайтах, в том числе на открытых вкладках.</translation>
@@ -1099,6 +1101,7 @@
 <translation id="2028449514182362831">Функции, которые используют датчики движения, не будут работать</translation>
 <translation id="202918510990975568">Чтобы настроить параметры безопасности и входа, введите пароль.</translation>
 <translation id="2030455719695904263">Сенсорная панель</translation>
+<translation id="2031385797619033640">Нажмите, чтобы разрешить расширению "<ph name="EXTENSIONS_REQUESTING_ACCESS" />" читать и изменять <ph name="ORIGIN" /></translation>
 <translation id="2031639749079821948">Пароль сохранен в вашем аккаунте Google.</translation>
 <translation id="2031914984822377766">Добавьте <ph name="LINK_BEGIN" />языки для сайтов<ph name="LINK_END" />. Для перевода будет использоваться первый язык в списке.</translation>
 <translation id="2033758234986231162">Подключение к телефону прервано. Убедитесь, что он находится рядом, разблокирован и на нем включены функции Bluetooth и Wi-Fi.</translation>
@@ -1455,6 +1458,7 @@
 <translation id="2328561734797404498">Чтобы использовать <ph name="APP_NAME" />, перезапустите устройство.</translation>
 <translation id="2328636661627946415">В режиме инкогнито сайты могут использовать файлы cookie, только чтобы собирать данные о действиях на своих страницах. При выходе из режима инкогнито файлы cookie удаляются автоматически.</translation>
 <translation id="2329597144923131178">Войдите, чтобы синхронизировать закладки, пароли, историю и т. д. на всех устройствах.</translation>
+<translation id="2332115969598251205">Не удалось загрузить данные об устройствах, сохраненных в аккаунте <ph name="PRIMARY_EMAIL" />. Проверьте подключение к интернету и повторите попытку.</translation>
 <translation id="2332131598580221120">Открыть в Интернет-магазине</translation>
 <translation id="2332192922827071008">Открыть настройки</translation>
 <translation id="2332515770639153015">Включен улучшенный Безопасный просмотр</translation>
@@ -1898,6 +1902,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Проверять грамматику и правописание</translation>
 <translation id="2753677631968972007">Управление доступом к сайтам вручную</translation>
+<translation id="2754226775788136540">Выполняется поиск устройств с Быстрым подключением, сохраненных в аккаунте <ph name="PRIMARY_EMAIL" />.</translation>
 <translation id="2754825024506485820">В Google Play вы найдете любые интересующие вас приложения. Их можно установить в любое время.</translation>
 <translation id="2755349111255270002">Сбросьте настройки устройства <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Настроить специальные возможности</translation>
@@ -2113,6 +2118,7 @@
 <translation id="2942279350258725020">Android Сообщения</translation>
 <translation id="2942560570858569904">Ожидание...</translation>
 <translation id="2942581856830209953">Персонализировать эту страницу</translation>
+<translation id="2943268899142471972">Выберите сценарий Ansible или файл резервной копии Crostini</translation>
 <translation id="2944060181911631861">Отправка данных о работе устройства. Помогите сделать Android ещё лучше – разрешите автоматически отправлять в Google диагностическую информацию, данные об использовании приложений и самого устройства. Эти данные нужны нам, чтобы в будущем повысить стабильность приложений и внести другие улучшения. Некоторые данные в обобщенном виде пригодятся партнерам Google, например разработчикам Android. Если запись дополнительной истории приложений и веб-поиска включена, эта информация может сохраняться в вашем аккаунте. <ph name="BEGIN_LINK1" />Подробнее…<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Открыть файлы</translation>
 <translation id="2946119680249604491">Добавить подключение</translation>
@@ -2953,6 +2959,7 @@
 <translation id="3784472333786002075">Файлы cookie создаются сайтами. Существует два типа таких файлов. Собственные файлы cookie создает тот сайт, на который вы зашли. Он указан в адресной строке браузера. Сторонние файлы cookie создаются другими сайтами, которые размещают свой контент (например, объявления или изображения) на просматриваемых вами веб-страницах.</translation>
 <translation id="3785308913036335955">Показывать кнопку "Сервисы"</translation>
 <translation id="3785727820640310185">Сохраненные пароли для этого сайта</translation>
+<translation id="3787434344076711519">Ожидается выполнение перевода</translation>
 <translation id="3788301286821743879">Не удалось запустить киоск-приложение.</translation>
 <translation id="3788331399335602504">эти файлы</translation>
 <translation id="3788401245189148511">Разрешения:</translation>
@@ -3236,6 +3243,7 @@
 <translation id="4036778507053569103">Скачанная с сервера политика недействительна.</translation>
 <translation id="4037084878352560732">Лошадь</translation>
 <translation id="403725336528835653">Попробовать</translation>
+<translation id="4040041015953651705">Исходный язык</translation>
 <translation id="4040105702484676956">Удалить данные и разрешения для сайта <ph name="SITE_NAME" /> и связанного установленного приложения?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Закрыть страницу}one{Закрыть страницы}few{Закрыть страницы}many{Закрыть страницы}other{Закрыть страницы}}</translation>
 <translation id="4043267180218562935">Размер курсора</translation>
@@ -4041,6 +4049,7 @@
 <translation id="4838170306476614339">Просмотр фотографий, медиафайлов и уведомлений с телефона</translation>
 <translation id="4838836835474292213">Доступ к буферу обмена открыт</translation>
 <translation id="4838907349371614303">Пароль обновлен</translation>
+<translation id="4838958829619609362">Выбранный элемент недоступен на следующем языке: <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Со&amp;хранить видео как...</translation>
 <translation id="4840096453115567876">Вы действительно хотите выйти из режима инкогнито?</translation>
 <translation id="4841741146571978176">Нет обязательной виртуальной машины. Чтобы продолжить, установите ВМ "<ph name="VM_TYPE" />".</translation>
@@ -4812,6 +4821,7 @@
 <translation id="558918721941304263">Загрузка...</translation>
 <translation id="5590418976913374224">Воспроизводить звук при запуске устройства</translation>
 <translation id="5592595402373377407">Недостаточно данных.</translation>
+<translation id="5594899180331219722">Выбрать файл</translation>
 <translation id="5595307023264033512">Объем хранилища, занятый сайтами: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Изменить адрес</translation>
 <translation id="5596627076506792578">Ещё</translation>
@@ -5044,6 +5054,7 @@
 <translation id="5834581999798853053">Осталось <ph name="TIME" /> мин.</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" />: идет запись с камеры или микрофона</translation>
 <translation id="583673505367439042">Разрешить сайтам отправлять запрос на редактирование файлов или папок на устройстве</translation>
+<translation id="5836999627049108525">Исходный язык</translation>
 <translation id="583756221537636748">Чехол</translation>
 <translation id="5840658767386246331">Найти в Google</translation>
 <translation id="5840680448799937675">Всегда передавать файлы в офлайн-режиме</translation>
@@ -5554,6 +5565,7 @@
 <translation id="6318944945640833942">Принтер не найден. Укажите адрес ещё раз.</translation>
 <translation id="6322370287306604163">Снимайте блокировку с помощью отпечатка пальца ещё быстрее</translation>
 <translation id="6322559670748154781">Этот файл скачивают редко. Он заблокирован Дополнительной защитой.</translation>
+<translation id="6324083483652497048">Нажмите, чтобы разрешить этим расширениям читать и изменять <ph name="ORIGIN" /></translation>
 <translation id="6324916366299863871">Изменить ярлык</translation>
 <translation id="6325191661371220117">Отключить автозапуск</translation>
 <translation id="6326175484149238433">Удалить</translation>
@@ -6590,6 +6602,7 @@
 <translation id="7343372807593926528">Прежде чем отправить отзыв, опишите проблему.</translation>
 <translation id="7344585835349671209">Управление сертификатами HTTPS/SSL на устройстве</translation>
 <translation id="7345706641791090287">Подтвердите пароль</translation>
+<translation id="7345919885156673810">Выбранный элемент недоступен на следующем языке: <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">ОК</translation>
 <translation id="7347452120014970266">Будут удалены все данные и файлы cookie, которые сохранены сайтом <ph name="ORIGIN_NAME" /> и установленными с него приложениями.</translation>
 <translation id="7347751611463936647">Чтобы использовать это расширение, введите "<ph name="EXTENSION_KEYWORD" />", нажмите клавишу табуляции, а затем введите команду или поисковый запрос.</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb
index ef66b12..f1ccdc5ed 100644
--- a/chrome/app/resources/generated_resources_si.xtb
+++ b/chrome/app/resources/generated_resources_si.xtb
@@ -278,6 +278,7 @@
 <translation id="125220115284141797">පෙරනිමි</translation>
 <translation id="1252987234827889034">පැතිකඩ දෝෂයක් ඇති විය</translation>
 <translation id="1254593899333212300">සෘජු අන්තර්ජාල සබැඳුම</translation>
+<translation id="1257336506558170607">තෝරාගත් සහතිකය නිර්යාත කරන්න</translation>
 <translation id="1258491128795710625">අලුත් මොනවාද</translation>
 <translation id="1259152067760398571">ආරක්‍ෂක පරීක්‍ෂාව ඊයේ ධාවන විය</translation>
 <translation id="1260451001046713751">සැමවිටම <ph name="HOST" /> වෙතින් උත්පතන සහ හරවා යැවීමට ඉඩ දෙන්න</translation>
@@ -327,6 +328,7 @@
 <translation id="1307165550267142340">ඔබේ රහස් අංකය සාදන ලදි</translation>
 <translation id="1307431692088049276">නැවත මගෙන් නොඅසන්න</translation>
 <translation id="1307559529304613120">අපොයි!  මෙම උපාංගය සඳහා දිගුකාලීන API ප්‍රවේශ ටෝකනය ගබඩා කිරීමට පද්ධතිය අපොහොසත් විය.</translation>
+<translation id="1312811472299082263">Ansible අත්පොතකින් හෝ Crostini උපස්ථ ගොනුවකින් තනන්න</translation>
 <translation id="1313405956111467313">ස්වයංක්‍රීය ප්‍රොක්සි වින්‍යාසකරණය</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">ඔබ විවෘත පටිති ඇතුළුව සියලුම වෙබ් අඩවිවලින් වරනු ලැබේ</translation>
@@ -1098,6 +1100,7 @@
 <translation id="2028449514182362831">චලන සංවේදක අවශ්‍ය විශේෂාංග ක්‍රියා නොකරනු ඇත</translation>
 <translation id="202918510990975568">සුරක්‍ෂිතතාව වින්‍යාස කර පුරනය වීමට ඔබගේ මුරපදය ඇතුළු කරන්න</translation>
 <translation id="2030455719695904263">ට්‍රැක්පෑඩ්</translation>
+<translation id="2031385797619033640"><ph name="EXTENSIONS_REQUESTING_ACCESS" /> හට <ph name="ORIGIN" /> කියවීමට සහ වෙනස් කිරීමට ඉඩ දීමට ක්ලික් කරන්න:</translation>
 <translation id="2031639749079821948">ඔබේ මුරපදය ඔබේ Google ගිණුම තුළ සුරැකේ</translation>
 <translation id="2031914984822377766">ඔබ වඩා කැමති <ph name="LINK_BEGIN" />වෙබ් අඩවි භාෂා<ph name="LINK_END" /> එක් කරන්න ලැයිස්තුවේ ඉහළම භාෂාව පරිවර්තන සඳහා භාවිත කරනු ඇත.</translation>
 <translation id="2033758234986231162">ඔබගේ දුරකථනය සමඟ සම්බන්ධතාවක් පවත්වා ගත නොහැකිය. ඔබගේ දුරකථනය ළඟ තිබෙන බව, අගුලු හැර ඇති බව, බ්ලූටූත් සහ Wi-Fi ක්‍රියාත්මක කර ඇති බව සහතික කර ගන්න.</translation>
@@ -1457,6 +1460,7 @@
 <translation id="2328561734797404498"><ph name="APP_NAME" /> භාවිත කිරීමට ඔබේ උපාංගය යළි අරඹන්න.</translation>
 <translation id="2328636661627946415">ඔබ අප්‍රසිද්ධ ප්‍රකාරයේ සිටින විට, අඩවිවලට කුකි භාවිත කළ හැක්කේ ඔවුන්ගේම අඩවියේ ඔබගේ බ්‍රවුස් කිරීමේ ක්‍රියාකාරකම් බැලීමට පමණි. අප්‍රසිද්ධ සැසිය අවසානයේ කුකි මකනු ලැබේ.</translation>
 <translation id="2329597144923131178">ඔබගේ සියලුම උපාංග මත ඇති පොත් සලකුණු, ඉතිහාසය, මුරපද හා වෙනත් සැකසීම් ලබා ගැනීමට පුරනය වන්න.</translation>
+<translation id="2332115969598251205"><ph name="PRIMARY_EMAIL" /> වෙත සුරැකි උපාංග පූරණය කළ නොහැක. ඔබේ අන්තර්ජාල සබැඳුම පරීක්ෂා කර නැවත උත්සාහ කරන්න.</translation>
 <translation id="2332131598580221120">අලෙවිසැලෙහි බලන්න</translation>
 <translation id="2332192922827071008">මනාප විවෘත කරන්න</translation>
 <translation id="2332515770639153015">ඉහළ නැංවූ සුරක්ෂිත බ්‍රවුස් කිරීම ක්‍රියාත්මකයි</translation>
@@ -1900,6 +1904,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">අකුරු සමඟ ව්‍යාකරණ පරීක්ෂා කරන්න</translation>
 <translation id="2753677631968972007">වෙබ් අඩවි අවසර හස්තීයව පාලන කරන්න.</translation>
+<translation id="2754226775788136540"><ph name="PRIMARY_EMAIL" /> වෙත සුරකින ලද Fast Pair උපාංග සොයමින්</translation>
 <translation id="2754825024506485820">ඵලදායිතාව සිට විනෝදාස්වාදය දක්වා, ඔබට අවශ්‍ය යෙදුම්, Google Play Store හි සොයා ගන්න. ඔබට ඕනෑම වේලාවක යෙදුම් ස්ථාපනය කළ හැකිය.</translation>
 <translation id="2755349111255270002">මෙම <ph name="DEVICE_TYPE" /> යළි සකසන්න</translation>
 <translation id="2755367719610958252">ප්‍රවේශ්‍යතා විශේෂාංග කළමනාකරණය කරන්න</translation>
@@ -2115,6 +2120,7 @@
 <translation id="2942279350258725020">Android පණිවුඩ</translation>
 <translation id="2942560570858569904">රැඳෙමින්...</translation>
 <translation id="2942581856830209953">මෙම පිටුව අභිරුචිකරණය කරන්න</translation>
+<translation id="2943268899142471972">Ansible අත්පොතක් හෝ Crostini උපස්ථ ගොනුවක් තෝරන්න</translation>
 <translation id="2944060181911631861">භාවිත සහ දෝෂ නිර්ණ දත්ත යවන්න. ස්වයංක්‍රියව රෝග විනිශ්චය, උපාංග සහ යෙදුම් භාවිත දත්ත Google වෙත යැවීමෙන් ඔබගේ Android අත්දැකීම වැඩි දියුණු කර ගැනීමට උපකාරී වන්න. මෙය පද්ධති සහ යෙදුම් ස්ථායිතාවට සහ අනෙකුත් වැඩිදියුණු කිරීම්වලට උදවු කරයි. සමහර එකතු කළ දත්ත Google යෙදුම්වලට සහ Android සංවර්ධකයින් වැනි හවුල්කරුවන්ට ද උදවු කරති. ඔබේ අමතර වෙබ් සහ යෙදුම් ක්‍රියාකාරකම් සැකසීම සක්‍රීය නම්, මෙම දත්ත ඔබේ Google ගිණුුමට සුරකිනු ලැබේ. <ph name="BEGIN_LINK1" />තවත් දැන ගන්න<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">ගොනු වෙත යන්න</translation>
 <translation id="2946119680249604491">සබඳතාව එක් කරන්න</translation>
@@ -2955,6 +2961,7 @@
 <translation id="3784472333786002075">කුකී යනු වෙබ් අඩවිවලින් නිර්මාණ කෙරෙන ගොනු වේ. කුකී වර්ග දෙකක් තිබේ: පළවෙනි පාර්ශ්ව කුකී ඔබ පැමිණෙන වෙබ් අඩවියෙන් නිර්මාණ කෙරේ. වෙබ් අඩවිය ලිපින තීරුවේ පෙන්වනු ලැබේ. තෙවන පාර්ශ්ව කුකී වෙනත් වෙබ් අඩවිවලින් නිර්මාණ කෙරේ. මෙම වෙබ් අඩවිවලට ඔබ පැමිණෙන වෙබ් අඩවිය මත ඔබ දකින රූප හෝ දැන්වීම් වැනි සමහර අන්තර්ගත හිමි වේ.</translation>
 <translation id="3785308913036335955">යෙදුම් කෙටිමං පෙන්වන්න</translation>
 <translation id="3785727820640310185">මෙම අඩවිය සඳහා සුරැකි මුරපද</translation>
+<translation id="3787434344076711519">පරිවර්තනය සඳහා රැඳී සිටිමින්</translation>
 <translation id="3788301286821743879">ඩාර්න්, කියෝස්ක් යෙදුම දියත් කිරීමට නොහැකි විය.</translation>
 <translation id="3788331399335602504">මෙම ගොනු</translation>
 <translation id="3788401245189148511">එයට හේතුව:</translation>
@@ -3239,6 +3246,7 @@
 <translation id="4036778507053569103">සේවාදායකයෙන් බාගත් ප්‍රතිපත්තිය අවලංගුයි.</translation>
 <translation id="4037084878352560732">අශ්වයා</translation>
 <translation id="403725336528835653">පළමුව එය උත්සාහ කරන්න</translation>
+<translation id="4040041015953651705">පරිවර්තනය කිරීමට භාෂාව</translation>
 <translation id="4040105702484676956"><ph name="SITE_NAME" /> සඳහා අඩවි දත්ත සහ අවසර සහ එහි ස්ථාපිත යෙදුම් හිස් කරන්නද?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{පිටවීමේ පිටුව}one{පිටවීමේ පිටු}other{පිටවීමේ පිටු}}</translation>
 <translation id="4043267180218562935">කර්සරයේ තරම</translation>
@@ -4044,6 +4052,7 @@
 <translation id="4838170306476614339">ඔබගේ දුරකථනයේ ඡායාරූප, මාධ්‍ය සහ ඔබගේ දැනුම්දීම් බලන්න</translation>
 <translation id="4838836835474292213">පසුරු පුවරුව කියවීමේ ප්‍රවේශයට ඉඩ දෙයි</translation>
 <translation id="4838907349371614303">මුරපදය යාවත්කාලීන කරන ලදි</translation>
+<translation id="4838958829619609362">තේරීම <ph name="LANGUAGE" /> තුළ නොමැත</translation>
 <translation id="4839303808932127586">ලෙස වීඩියෝව සුරකින්න(&amp;v)...</translation>
 <translation id="4840096453115567876">කෙසේ වුවත් අප්‍රසිද්ධ ප්‍රකාරයෙන් ඉවත් වන්නද?</translation>
 <translation id="4841741146571978176">අවශ්‍ය අතථ්‍ය යන්ත්‍රයක් නොපවතී. ඉදිරියට යාමට කරුණාකර <ph name="VM_TYPE" /> පිහිටුවීමට උත්සාහ කරන්න</translation>
@@ -4815,6 +4824,7 @@
 <translation id="558918721941304263">යෙදුම් පූරණය වේ...</translation>
 <translation id="5590418976913374224">උපාංගය ආරම්භයේ දී ශබ්දය වාදනය කරන්න</translation>
 <translation id="5592595402373377407">තවම ප්‍රමාණවත් දත්ත නොමැත.</translation>
+<translation id="5594899180331219722">ගොනුව තෝරන්න</translation>
 <translation id="5595307023264033512">අඩවිවලින් මුළු ගබඩා භාවිතය: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">ලිපිනය සංස්කරණය</translation>
 <translation id="5596627076506792578">තවත් විකල්ප</translation>
@@ -5048,6 +5058,7 @@
 <translation id="5834581999798853053">මිනිත්තු <ph name="TIME" /> පමණ ඉතිරිව ඇත</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - කැමරා හෝ මයික්‍රෆෝන පටිගත කිරීම</translation>
 <translation id="583673505367439042">අඩවි ඔබගේ උපාංගයෙහි ගොනු සහ ෆෝල්ඩර සංස්කරණය කිරීමට ඉල්ලිය හැකිය</translation>
+<translation id="5836999627049108525">පරිවර්තනය කිරීමට භාෂාව</translation>
 <translation id="583756221537636748">ආවරණය</translation>
 <translation id="5840658767386246331">Google සමග සොයන්න</translation>
 <translation id="5840680448799937675">ගොනු සැම විටම නොබැඳිව බෙදා ගනු ඇත</translation>
@@ -5558,6 +5569,7 @@
 <translation id="6318944945640833942">මුද්‍රකයක් අනාවරණ කළ නොහැකි වි. මුද්‍රක ලිපිනය නැවත ඇතුළත් කරන්න.</translation>
 <translation id="6322370287306604163">ඇඟිලි සලකුණ සමග වඩා වේගයෙන් අගුලු හරින්න</translation>
 <translation id="6322559670748154781">මෙම ගොනුව සුලබව බානොගන්නා අතර ඉහළ ආරක්ෂාව මඟින් අවහිර කර ඇත</translation>
+<translation id="6324083483652497048">මෙම දිගුවලට <ph name="ORIGIN" /> කියවීමට සහ වෙනස් කිරීමට ඉඩ දීමට ක්ලික් කරන්න:</translation>
 <translation id="6324916366299863871">කෙටිමඟ සංස්කරණය</translation>
 <translation id="6325191661371220117">ස්වයං-දියත් කිරීම අබල කරන්න</translation>
 <translation id="6326175484149238433">Chrome වෙතින් ඉවත් කරන්න</translation>
@@ -6588,6 +6600,7 @@
 <translation id="7343372807593926528">ප්‍රතිපෝෂණ යැවීමට පෙර කරුණාකර ගැටලුව විස්තර කරන්න.</translation>
 <translation id="7344585835349671209">ඔබේ උපාංගයෙහි HTTPS/SSL සහතික කළමනාකරණය කරන්න</translation>
 <translation id="7345706641791090287">ඔබගේ මුරපදය තහවුරු කරන්න</translation>
+<translation id="7345919885156673810">තේරීම <ph name="LANGUAGE" /> තුළ නොමැත</translation>
 <translation id="7346909386216857016">හරි, තේරුම් ගත්තා!</translation>
 <translation id="7347452120014970266">මෙය <ph name="ORIGIN_NAME" /> සහ එහි ස්ථාපිත යෙදුම් විසින් ගබඩා කරනු ලැබූ සියලුම දත්ත සහ කුකී ඉවත් කරයි</translation>
 <translation id="7347751611463936647">මෙම දිගුව භාවිතයට, "<ph name="EXTENSION_KEYWORD" />" යොදා, ඊලඟට TAB, ඉන්පසු ඔබේ විධායන හෝ සෙවුම ලියන්න.</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index 9d72c27..8190dc1 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -277,6 +277,7 @@
 <translation id="125220115284141797">Predvolené</translation>
 <translation id="1252987234827889034">Vyskytla sa chyba profilu</translation>
 <translation id="1254593899333212300">Priame pripojenie k Internetu</translation>
+<translation id="1257336506558170607">Exportovať vybraný certifikát</translation>
 <translation id="1258491128795710625">Novinky</translation>
 <translation id="1259152067760398571">Kontrola bezpečnosti prebehla včera</translation>
 <translation id="1260451001046713751">Vždy povoliť zobrazovanie kontextových okien z webu <ph name="HOST" /></translation>
@@ -326,6 +327,7 @@
 <translation id="1307165550267142340">PIN bol vytvorený</translation>
 <translation id="1307431692088049276">Nabudúce sa nepýtať</translation>
 <translation id="1307559529304613120">Ojoj! Systému sa nepodarilo uložiť dlhodobý prístupový token rozhrania API pre toto zariadenie.</translation>
+<translation id="1312811472299082263">Vytvorenie z príručky Ansible alebo záložného súboru Crostini</translation>
 <translation id="1313405956111467313">Automatická konfigurácia servera proxy</translation>
 <translation id="131364520783682672">Caps Lock</translation>
 <translation id="1313660246522271310">Systém vás odhlási zo všetkých webov (aj v otvorených kartách).</translation>
@@ -1099,6 +1101,7 @@
 <translation id="2028449514182362831">Funkcie vyžadujúce senzory pohybu nebudú fungovať</translation>
 <translation id="202918510990975568">Ak chcete konfigurovať zabezpečenie a prihlásenie, zadajte heslo</translation>
 <translation id="2030455719695904263">Trackpad</translation>
+<translation id="2031385797619033640">Kliknutím umožníte rozšíreniu <ph name="EXTENSIONS_REQUESTING_ACCESS" /> čítať a meniť web <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">Heslo máte uložené v účte Google</translation>
 <translation id="2031914984822377766">Pridajte preferované <ph name="LINK_BEGIN" />jazyky webu<ph name="LINK_END" />. Pri prekladoch sa použije prvý jazyk zoznamu.</translation>
 <translation id="2033758234986231162">Pripojenie s vaším telefónom sa nedá udržať. Uistite sa, že telefón máte nablízku, odomknutý a so zapnutým rozhraním Bluetooth a pripojením Wi‑Fi.</translation>
@@ -1455,6 +1458,7 @@
 <translation id="2328561734797404498">Ak chcete používať <ph name="APP_NAME" />, reštartujte svoje zariadenie.</translation>
 <translation id="2328636661627946415">Keď máte aktivovaný režim inkognito, weby uvidia pomocou súborov cookie vašu aktivitu prehliadania iba na vlastných stránkach. Po ukončení relácie inkognito sa súbory cookie odstránia.</translation>
 <translation id="2329597144923131178">Prihláste sa a používajte svoje záložky, históriu, heslá a ďalšie nastavenia vo všetkých svojich zariadeniach.</translation>
+<translation id="2332115969598251205">Zariadenia uložené v účte <ph name="PRIMARY_EMAIL" /> sa nedajú načítať. Skontrolujte internetové pripojenie a skúste to znova.</translation>
 <translation id="2332131598580221120">Zobraziť v obchode</translation>
 <translation id="2332192922827071008">Otvoriť predvoľby</translation>
 <translation id="2332515770639153015">Zlepšené bezpečné prehliadanie je zapnuté</translation>
@@ -1898,6 +1902,7 @@
 <translation id="2749836841884031656">SIM</translation>
 <translation id="2749881179542288782">Skontrolovať gramatiku s pravopisom</translation>
 <translation id="2753677631968972007">Ručne ovládať povolenia webu</translation>
+<translation id="2754226775788136540">Hľadajú sa zariadenia s rýchlym párovaním uložené do účtu <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="2754825024506485820">Vyhľadajte v Obchode Google Play aplikácie, ktoré potrebujete, napríklad kancelárske alebo také, ktoré vás zabavia. Aplikácie môžete inštalovať kedykoľvek.</translation>
 <translation id="2755349111255270002">Resetovanie tohto zariadenia <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">Spravovať funkcie dostupnosti</translation>
@@ -2113,6 +2118,7 @@
 <translation id="2942279350258725020">Správy pre Android</translation>
 <translation id="2942560570858569904">Čaká sa...</translation>
 <translation id="2942581856830209953">Prispôsobiť túto stránku</translation>
+<translation id="2943268899142471972">Výber príručky Ansible alebo záložného súboru Crostini</translation>
 <translation id="2944060181911631861">Odosielať údaje o využití a diagnostiky. Pomôžte zlepšiť prostredie Androidu automatickým odosielaním diagnostík a údajov o používaní zariadenia a aplikácií do Googlu. Pomôžu zvýšiť stabilitu systému a aplikácií a poskytovať ďalšie vylepšenia. Niektoré súhrnné údaje tiež pomôžu aplikáciám Google a partnerom, ako napríklad vývojárom Androidu. Ak aktivujete dodatočnú aktivitu na internete a v aplikáciách, tieto údaje sa môžu uložiť vo vašom účte Google. <ph name="BEGIN_LINK1" />Ďalšie informácie<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">Prejsť na súbory</translation>
 <translation id="2946119680249604491">Pridať pripojenie</translation>
@@ -2953,6 +2959,7 @@
 <translation id="3784472333786002075">Súbory cookie sú vytvárané webmi. Existujú dva typy súborov cookie: súbory cookie hostiteľskej domény sú vytvorené webom, ktorý navštívite. Tento web je uvedený v paneli s adresou. Súbory cookie tretích strán sú vytvárané ďalšími webmi. Tieto weby sú vlastníkmi niektorého obsahu (napríklad reklám alebo obrázkov), ktorý sa vám pri ich návšteve zobrazuje.</translation>
 <translation id="3785308913036335955">Zobrazovať odkaz aplikácií</translation>
 <translation id="3785727820640310185">Uložené heslá pre tento web</translation>
+<translation id="3787434344076711519">Čaká sa na preklad</translation>
 <translation id="3788301286821743879">Verejnú aplikáciu sa nepodarilo spustiť.</translation>
 <translation id="3788331399335602504">tieto súbory</translation>
 <translation id="3788401245189148511">Mohli by:</translation>
@@ -3236,6 +3243,7 @@
 <translation id="4036778507053569103">Pravidlo stiahnuté zo servera je neplatné.</translation>
 <translation id="4037084878352560732">Kôň</translation>
 <translation id="403725336528835653">Najprv vyskúšať</translation>
+<translation id="4040041015953651705">Jazyk, z ktorého chcete prekladať</translation>
 <translation id="4040105702484676956">Chcete vymazať dáta a povolenia webu <ph name="SITE_NAME" /> a jeho nainštalovanú aplikáciu?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{Opustiť stránku}few{Opustiť stránky}many{Opustiť stránky}other{Opustiť stránky}}</translation>
 <translation id="4043267180218562935">Veľkosť kurzora</translation>
@@ -4041,6 +4049,7 @@
 <translation id="4838170306476614339">Zobrazujte si fotky, médiá a upozornenia svojho telefónu</translation>
 <translation id="4838836835474292213">Je povolený prístup k čítaniu schránky</translation>
 <translation id="4838907349371614303">Heslo bolo aktualizované</translation>
+<translation id="4838958829619609362">Výber nie je v jazyku <ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">Uložiť &amp;video ako...</translation>
 <translation id="4840096453115567876">Naozaj chcete ukončiť režim inkognito?</translation>
 <translation id="4841741146571978176">Povinný virtuálny počítač neexistuje. Pokračujte nastavením virtuálneho počítača <ph name="VM_TYPE" />.</translation>
@@ -4812,6 +4821,7 @@
 <translation id="558918721941304263">Načítavajú sa aplikácie...</translation>
 <translation id="5590418976913374224">Prehrávať zvuk pri spustení zariadenia</translation>
 <translation id="5592595402373377407">Zatiaľ nie je k dispozícii dostatok údajov.</translation>
+<translation id="5594899180331219722">Vybrať súbor</translation>
 <translation id="5595307023264033512">Celkový priestor využitý webmi: <ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">Upraviť adresu</translation>
 <translation id="5596627076506792578">Ďalšie možnosti</translation>
@@ -5044,6 +5054,7 @@
 <translation id="5834581999798853053">Zostáva približne <ph name="TIME" /> min.</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> – Kamera alebo mikrofón zaznamenáva obsah</translation>
 <translation id="583673505367439042">Weby môžu žiadať o úpravu súborov a priečinkov v zariadení</translation>
+<translation id="5836999627049108525">Jazyk, z ktorého chcete prekladať</translation>
 <translation id="583756221537636748">Puzdro</translation>
 <translation id="5840658767386246331">Hľadať pomocou Googlu</translation>
 <translation id="5840680448799937675">Súbory sa vždy budú zdieľať offline</translation>
@@ -5554,6 +5565,7 @@
 <translation id="6318944945640833942">Nepodarilo sa rozpoznať tlačiareň. Znova zadajte adresu tlačiarne.</translation>
 <translation id="6322370287306604163">Odomykajte rýchlejšie odtlačkom prsta</translation>
 <translation id="6322559670748154781">Tento súbor si používatelia bežne nesťahujú a rozšírená ochrana ho zablokovala</translation>
+<translation id="6324083483652497048">Kliknutím povolíte týmto rozšíreniam čítať a meniť web <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">Upraviť skratku</translation>
 <translation id="6325191661371220117">Zakázať automatické spúšťanie</translation>
 <translation id="6326175484149238433">Odstrániť z Chromu</translation>
@@ -6588,6 +6600,7 @@
 <translation id="7343372807593926528">Opíšte problém a až potom odošlite spätnú väzbu.</translation>
 <translation id="7344585835349671209">Spravujte certifikáty HTTPS a SSL v zariadení</translation>
 <translation id="7345706641791090287">Potvrdenie hesla</translation>
+<translation id="7345919885156673810">Výber nie je v jazyku <ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">Dobre</translation>
 <translation id="7347452120014970266">Týmto vymažete všetky dáta a súbory cookie uložené webom <ph name="ORIGIN_NAME" /> a jeho nainštalovanými aplikáciami</translation>
 <translation id="7347751611463936647">Ak chcete použiť toto rozšírenie, zadajte text „<ph name="EXTENSION_KEYWORD" />“, stlačte kláves Tab a začnite písať svoj príkaz alebo vyhľadávaný výraz.</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index 8c775e39..c235207 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Prišlo je do napake. Linux je morda samo delno nadgrajen. Če želite več informacij, preglejte dnevnike. Dnevniki so shranjeni v aplikaciji Datoteke &gt; Moje datoteke &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Želite izbrisati tudi podatke iz teh aplikacij?</translation>
 <translation id="1043824690776631483">Za obisk tega spletnega mesta potrebujete dovoljenje. Morda vsebuje neprimerno vsebino.</translation>
+<translation id="104419033123549300">Slog razporeditve tipk</translation>
 <translation id="104710386808485638">Želite znova zagnati Linux?</translation>
 <translation id="1047431265488717055">&amp;Kopiraj besedilo povezave</translation>
 <translation id="1048286738600630630">Zasloni</translation>
@@ -786,6 +787,7 @@
 <translation id="1721312023322545264"><ph name="NAME" /> vam mora odobriti obisk tega spletnega mesta</translation>
 <translation id="1722460139690167654">Napravo <ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" /> upravlja<ph name="END_LINK" /> domena <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Novo okno</translation>
+<translation id="1724801751621173132">Način vnosa</translation>
 <translation id="1725562816265788801">Drsenje z zavihki</translation>
 <translation id="1729533290416704613">Določa tudi, katera stran je prikazana, ko iščete v naslovni vrstici.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Če želite odstraniti aplikacije, pojdite v »Nastavitve« &gt; »Trgovina Google Play« &gt; »Upravljanje nastavitev Androida« &gt; »Aplikacije« ali odprite upravitelja aplikacij. Nato se dotaknite aplikacije, ki jo želite odstraniti (morda boste morali s prstom povleči v desno ali levo, da jo boste našli). Nato se dotaknite »Odstrani« ali »Onemogoči«.<ph name="END_PARAGRAPH1" /></translation>
@@ -1970,6 +1972,7 @@
 <translation id="2796740370559399562">Še naprej dovoli piškotke</translation>
 <translation id="2798347533012571708">Ohrani posodobitve</translation>
 <translation id="2799223571221894425">Vnovičen zagon</translation>
+<translation id="2800309299477632167">Razporeditev tipk po meri</translation>
 <translation id="2800760947029405028">Naloži sliko</translation>
 <translation id="2801954693771979815">Velikost zaslona</translation>
 <translation id="2802557211515765772">Na voljo ni upravljanih tiskalnikov.</translation>
@@ -2031,6 +2034,7 @@
 <translation id="2849767214114481738">Koda PIN je dodana</translation>
 <translation id="2849936225196189499">Kritično</translation>
 <translation id="2850541429955027218">Dodaj temo</translation>
+<translation id="2850672011315104382">Slog postavljanja ločil</translation>
 <translation id="2851634818064021665">Za obisk tega spletnega mesta potrebujete dovoljenje</translation>
 <translation id="2851728849045278002">Prišlo je do napake. Kliknite za več podrobnosti.</translation>
 <translation id="2852385257476173980">Tukaj bo morda prikazan seznam obiskanih spletnih mest, ko brskate po spletu.</translation>
@@ -2527,6 +2531,7 @@
 <translation id="3359256513598016054">Omejitve pravilnika potrdila</translation>
 <translation id="3360297538363969800">Tiskanje ni uspelo. Preverite tiskalnik in poskusite znova.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{Naprava <ph name="DEVICE_NAME" /> z vami deli priloge (<ph name="ATTACHMENTS" />).}one{Naprava <ph name="DEVICE_NAME" /> z vami deli priloge (<ph name="ATTACHMENTS" />).}two{Naprava <ph name="DEVICE_NAME" /> z vami deli priloge (<ph name="ATTACHMENTS" />).}few{Naprava <ph name="DEVICE_NAME" /> z vami deli priloge (<ph name="ATTACHMENTS" />).}other{Naprava <ph name="DEVICE_NAME" /> z vami deli priloge (<ph name="ATTACHMENTS" />).}}</translation>
+<translation id="3361954577771524115">Iz aplikacije</translation>
 <translation id="3363202073972776113">Ta novi profil bo upravljala vaša organizacija. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Od skrbnika: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Uporabite Ctrl ali Alt</translation>
@@ -3051,6 +3056,7 @@
 <translation id="3848547754896969219">Odpiranje v &amp;anonimnem oknu</translation>
 <translation id="385051799172605136">Nazaj</translation>
 <translation id="3851428669031642514">Naloži skripte, ki niso varni</translation>
+<translation id="3852215160863921508">Pomoč pri vnosu</translation>
 <translation id="3854599674806204102">Izberite možnost</translation>
 <translation id="3854967233147778866">Ponudi prevajanje spletnih mest v drugih jezikih</translation>
 <translation id="3854976556788175030">Izhodni pladenj je poln</translation>
@@ -3287,6 +3293,7 @@
 <translation id="4062561150282203854">Sinhroniziranje vseh aplikacij, nastavitev in drugega v napravi <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Omrežje, ki ga uporabljate (<ph name="NETWORK_ID" />), morda zahteva, da obiščete stran za prijavo.</translation>
 <translation id="4066207411788646768">Preverite povezavo, če si želite ogledati razpoložljive tiskalnike v omrežju</translation>
+<translation id="4066945815577305767">Časovna omejitev za gesla je potekla</translation>
 <translation id="4068776064906523561">Shranjeni prstni odtisi</translation>
 <translation id="407173827865827707">Ob kliku</translation>
 <translation id="4072701974556190758">Geslo bo shranjeno v računu Google, <ph name="ACCOUNT" />. Ne bo si vam ga treba zapomniti.</translation>
@@ -3808,6 +3815,7 @@
 <translation id="4579453506923101210">Pozaba povezanega telefona</translation>
 <translation id="4579581181964204535">Ni mogoče predvajati <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Za obvestila brskalnika obiščite <ph name="LINK_BEGIN" />nastavitve brskalnika Chrome<ph name="LINK_END" />.</translation>
+<translation id="4580587929153007251">Znova se prijavite v Googlovega upravitelja gesel.</translation>
 <translation id="4580596421317071374">Gesla se shranjujejo v storitvi <ph name="GOOGLE_PASSWORD_MANAGER" /> v tej napravi.</translation>
 <translation id="4580626299762849806">Gesel ni mogoče uvoziti. Preverite, ali je <ph name="FILENAME" /> pravilno oblikovana.</translation>
 <translation id="4581774856936278355">Napaka pri obnavljanju Linuxa</translation>
@@ -4489,6 +4497,7 @@
 <translation id="5268373933383932086">Vaša stran, vaš slog</translation>
 <translation id="5269977353971873915">Tiskanje ni uspelo</translation>
 <translation id="5273806377963980154">Urejanje URL-ja spletnega mesta</translation>
+<translation id="5275084684151588738">Uporabniški slovarji</translation>
 <translation id="5275338516105640560">Gumb za shranjeno skupino zavihkov</translation>
 <translation id="5275352920323889391">Pes</translation>
 <translation id="527605719918376753">Izklop zvoka zavihka</translation>
@@ -4704,6 +4713,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{Koda PIN mora vsebovati najmanj en znak}one{Koda PIN mora vsebovati najmanj # znak}two{Koda PIN mora vsebovati najmanj # znaka}few{Koda PIN mora vsebovati najmanj # znake}other{Koda PIN mora vsebovati najmanj # znakov}}</translation>
 <translation id="5474859849784484111">Domena <ph name="MANAGER" /> zahteva, da se povežete z omrežjem Wi-Fi in prenesete posodobitev. Prenesete jo lahko tudi prek povezave z omejenim prenosom podatkov (prenos podatkov se morda zaračuna).</translation>
 <translation id="5481273127572794904">Ni dovoljeno samodejno prenesti več datotek</translation>
+<translation id="5481755802440890178">Izbranega besedila trenutno ni bilo mogoče prevesti.</translation>
 <translation id="5481941284378890518">Dodajanje tiskalnikov v bližini</translation>
 <translation id="5483785310822538350">Umakni dostop do datotek in naprav</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> še danes. <ph name="LINK_BEGIN" />Ogled podrobnosti<ph name="LINK_END" />}one{<ph name="MANAGER" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> v {NUM_DAYS} dnevu. <ph name="LINK_BEGIN" />Ogled podrobnosti<ph name="LINK_END" />}two{<ph name="MANAGER" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> v {NUM_DAYS} dnevih. <ph name="LINK_BEGIN" />Ogled podrobnosti<ph name="LINK_END" />}few{<ph name="MANAGER" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> v {NUM_DAYS} dneh. <ph name="LINK_BEGIN" />Ogled podrobnosti<ph name="LINK_END" />}other{<ph name="MANAGER" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> v {NUM_DAYS} dneh. <ph name="LINK_BEGIN" />Ogled podrobnosti<ph name="LINK_END" />}}</translation>
@@ -4938,6 +4948,7 @@
 <translation id="5696143504434933566">Prijava zlorabe v razširitvi »<ph name="EXTENSION_NAME" />«</translation>
 <translation id="5696679855467848181">Trenutna datoteka PPD v uporabi: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Izbirnik emodžijev</translation>
+<translation id="5698462638680260399">Prijavite se, če želite uporabljati gesla</translation>
 <translation id="570043786759263127">Aplikacije in storitve iz Googla Play</translation>
 <translation id="5700836101007545240">Skrbnik je onemogočil funkcijo dodajanja povezave</translation>
 <translation id="5701080607174488915">Napaka pri prenosu pravilnika iz strežnika.</translation>
@@ -4955,6 +4966,7 @@
 <translation id="5712153969432126546">Spletna mesta občasno objavijo datoteke PDF, na primer dokumente, pogodbe in obrazce.</translation>
 <translation id="571222594670061844">Spletna mesta lahko prikazujejo pozive za prijavo storitev za identiteto</translation>
 <translation id="5713158217420111469">Vzpostavljena povezava z napravo <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Slog vnosa presledkov</translation>
 <translation id="5715711091495208045">Posrednik za vtičnik: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Privzeti iskalniki</translation>
 <translation id="5719854774000914513">Spletna mesta lahko zahtevajo vzpostavitev povezave z napravami HID.</translation>
@@ -5596,6 +5608,7 @@
 <translation id="6335920438823100346">Če želite zagnati Linux, <ph name="MANAGER" /> zahteva, da varnostno kopirate podatke in ta Chromebook ponastavite na tovarniške nastavitve.</translation>
 <translation id="6336038146639916978">Domena <ph name="MANAGER" /> je onemogočila most za odpravljanje težav s sistemom Android (ADB). S tem bo naprava <ph name="DEVICE_TYPE" /> v 24 urah ponastavljena. Varnostno kopirajte datoteke, ki jih želite obdržati.</translation>
 <translation id="6338402296920404442">Priporočamo, da izbrišete datoteko <ph name="FILENAME" />, da drugi uporabniki te naprave ne bodo mogli videti vaših gesel.</translation>
+<translation id="6338968693068997776">Dodajanje naprave USB</translation>
 <translation id="6338981933082930623">Vsa spletna mesta vam lahko prikazujejo kakršne koli oglase</translation>
 <translation id="6339668969738228384">Ustvarjanje novega profila za uporabnika <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Internet Printing Protocol (IPPS)</translation>
@@ -6199,6 +6212,7 @@
 <translation id="6903907808598579934">Vklopi sinhronizacijo</translation>
 <translation id="6904344821472985372">Preklic dostopa do datotek</translation>
 <translation id="6904655473976120856">Pritisnite gumb za aplikacije, če želite zapreti</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Zaradi zagotavljanja varnosti gesel se Googlov upravitelj gesel zaklene po eni minuti nedejavnosti.}one{Zaradi zagotavljanja varnosti gesel se Googlov upravitelj gesel zaklene po {NUM_MINS} minuti nedejavnosti.}two{Zaradi zagotavljanja varnosti gesel se Googlov upravitelj gesel zaklene po {NUM_MINS} minutah nedejavnosti.}few{Zaradi zagotavljanja varnosti gesel se Googlov upravitelj gesel zaklene po {NUM_MINS} minutah nedejavnosti.}other{Zaradi zagotavljanja varnosti gesel se Googlov upravitelj gesel zaklene po {NUM_MINS} minutah nedejavnosti.}}</translation>
 <translation id="6909422577741440844">Želite prejeti iz te naprave?</translation>
 <translation id="6910211073230771657">Izbrisano</translation>
 <translation id="691106080621596509">S tem bodo izbrisani vsi podatki in piškotki, ki so jih shranili skupina <ph name="SITE_GROUP_NAME" />, vsa spletna mesta v njej in nameščena aplikacija.</translation>
@@ -6383,6 +6397,7 @@
 <translation id="7069811530847688087">Spletno mesto <ph name="WEBSITE" /> morda zahteva novejši ali drugačni varnostni ključ</translation>
 <translation id="7070484045139057854">Lahko bere in spreminja podatke spletnega mesta</translation>
 <translation id="7072010813301522126">Ime bližnjice</translation>
+<translation id="7074066049407662839">Prijavite se, če želite shraniti gesla</translation>
 <translation id="7075513071073410194">PKCS #1 MD5 s šifriranjem RSA</translation>
 <translation id="7075625805486468288">Upravljanje potrdil HTTPS/SSL in nastavitev</translation>
 <translation id="7076875098323397992">Nadgradnje ni mogoče začeti</translation>
@@ -6914,6 +6929,7 @@
 <translation id="7625568159987162309">Ogled dovoljenj in podatkov, shranjenih na spletnih mestih</translation>
 <translation id="7625823789272218216">Novi zavihek na levi</translation>
 <translation id="7628201176665550262">Hitrost osveževanja</translation>
+<translation id="7628392600831846024">Slog simbola</translation>
 <translation id="7629827748548208700">Zavihek: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382">To napravo upravlja <ph name="MANAGER" />, ki zahteva, da se vsakič prijavite.</translation>
 <translation id="7631014249255418691">Aplikacije in datoteke za Linux so uspešno varnostno kopirane</translation>
@@ -8040,6 +8056,7 @@
 <translation id="8688672835843460752">Na voljo</translation>
 <translation id="8690129572193755009">Spletna mesta lahko zahtevajo obravnavo protokolov.</translation>
 <translation id="8692107307702113268">Geslo vsebuje več kot 1000 znakov.</translation>
+<translation id="8694596275649352090">Zakleni v načinu pripravljenosti ali ko je pokrov zaprt</translation>
 <translation id="8695139659682234808">Dodajanje starševskega nadzora po nastavitvi</translation>
 <translation id="8695825812785969222">Odpri &amp;mesto ...</translation>
 <translation id="8698269656364382265">Če se želite vrniti na prejšnji zaslon, s prstom povlecite od leve strani.</translation>
@@ -8088,6 +8105,7 @@
 <translation id="8732844209475700754">Več nastavitev, povezanih z zasebnostjo, varnostjo in zbiranjem podatkov</translation>
 <translation id="8734073480934656039">Če omogočite to nastavitev, se lahko aplikacije za kiosk ob zagonu samodejno zaženejo.</translation>
 <translation id="8734674662128056360">Blokiranje piškotkov drugih mest</translation>
+<translation id="8734755021067981851">Nobena naprava USB ni priključena.</translation>
 <translation id="873545264931343897">Po posodobitvi vtičnika <ph name="PLUGIN_NAME" /> znova naložite stran, če ga želite aktivirati</translation>
 <translation id="8736288397686080465">To spletno mesto je bilo posodobljeno v ozadju.</translation>
 <translation id="8737709691285775803">Shill</translation>
@@ -8215,6 +8233,7 @@
 <translation id="8850251000316748990">Več ...</translation>
 <translation id="885246833287407341">Argumenti funkcije API-ja</translation>
 <translation id="8853586775156634952">Ta kartica bo shranjena samo v to napravo</translation>
+<translation id="8854745870658584490">Bližnjica za izbor</translation>
 <translation id="8855977033756560989">Ta naprava Chromebook Enterprise je opremljena s svežnjem za nadgradnjo Chrome Enterprise. Če želite izkoristiti zmožnosti za podjetja, včlanite to napravo s skrbniškim računom Google.</translation>
 <translation id="8856028055086294840">Obnovitev aplikacij in strani</translation>
 <translation id="885701979325669005">Shramba</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb
index 5c3462d..cbcbf16 100644
--- a/chrome/app/resources/generated_resources_sr-Latn.xtb
+++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Došlo je do greške. Linux je možda samo delimično nadograđen. Pregledajte evidenciju za više informacija. Evidencija je sačuvana u odeljku Fajlovi &gt; Moji fajlovi &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Želite i da obrišete podatke iz ovih aplikacija?</translation>
 <translation id="1043824690776631483">Treba vam dozvola da biste posetili ovaj sajt. Može da obuhvata neprikladan sadržaj.</translation>
+<translation id="104419033123549300">Stil mape tastera</translation>
 <translation id="104710386808485638">Želite li da restartujete Linux?</translation>
 <translation id="1047431265488717055">Kopiraj tek&amp;st linka</translation>
 <translation id="1048286738600630630">Prikazi</translation>
@@ -771,6 +772,7 @@
 <translation id="1721312023322545264">Potrebna vam je dozvola korisnika <ph name="NAME" /> da biste posetili ovaj sajt</translation>
 <translation id="1722460139690167654"><ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" />-om upravlja<ph name="END_LINK" /> <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Novi prozor</translation>
+<translation id="1724801751621173132">Režim unosa</translation>
 <translation id="1725562816265788801">Pomeranje kartica</translation>
 <translation id="1729533290416704613">Kontroliše i stranicu koja se prikazuje kada pretražujete iz omniboksa.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Da biste uklonili aplikacije, idite u odeljak Podešavanja &gt; Google Play prodavnica &gt; Upravljajte Android podešavanjima &gt; Aplikacije ili Menadžer aplikacija. Dodirnite aplikaciju koju želite da deinstalirate (možda ćete morati da prevučete nadesno ili nalevo da biste pronašli aplikaciju). Onda dodirnite Deinstaliraj ili Onemogući.<ph name="END_PARAGRAPH1" /></translation>
@@ -1951,6 +1953,7 @@
 <translation id="2796740370559399562">Nastavi sa dozvoljavanjem kolačića</translation>
 <translation id="2798347533012571708">Zadrži ažuriranja</translation>
 <translation id="2799223571221894425">Ponovo pokreni</translation>
+<translation id="2800309299477632167">Prilagođena mapa tastera</translation>
 <translation id="2800760947029405028">Otpremi sliku</translation>
 <translation id="2801954693771979815">Veličina ekrana</translation>
 <translation id="2802557211515765772">Nema upravljanih štampača.</translation>
@@ -2012,6 +2015,7 @@
 <translation id="2849767214114481738">PIN je dodat</translation>
 <translation id="2849936225196189499">Od presudne važnosti</translation>
 <translation id="2850541429955027218">Dodaj temu</translation>
+<translation id="2850672011315104382">Stil interpunkcije</translation>
 <translation id="2851634818064021665">Treba vam dozvola da biste posetili ovaj sajt</translation>
 <translation id="2851728849045278002">Došlo je do greške. Kliknite za više detalja.</translation>
 <translation id="2852385257476173980">Lista sajtova koje posećujete se može prikazati ovde dok pregledate veb</translation>
@@ -2508,6 +2512,7 @@
 <translation id="3359256513598016054">Ograničenja smernica sertifikata</translation>
 <translation id="3360297538363969800">Štampanje nije uspelo. Proverite štampač i pokušajte ponovo.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> deli sa vama (<ph name="ATTACHMENTS" />).}one{<ph name="DEVICE_NAME" /> deli sa vama (<ph name="ATTACHMENTS" />).}few{<ph name="DEVICE_NAME" /> deli <ph name="ATTACHMENTS" /> sa vama.}other{<ph name="DEVICE_NAME" /> deli <ph name="ATTACHMENTS" /> sa vama.}}</translation>
+<translation id="3361954577771524115">Iz aplikacije</translation>
 <translation id="3363202073972776113">Ovim novim profilom će upravljati organizacija. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Od administratora: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Koristite Ctrl ili Alt</translation>
@@ -3032,6 +3037,7 @@
 <translation id="3848547754896969219">Otvori u &amp;prozoru bez arhiviranja</translation>
 <translation id="385051799172605136">Nazad</translation>
 <translation id="3851428669031642514">Učitavaj nebezbedne skripte</translation>
+<translation id="3852215160863921508">Pomoć pri unosu</translation>
 <translation id="3854599674806204102">Izaberite opciju</translation>
 <translation id="3854967233147778866">Ponudi prevod veb-sajtova koji su na drugim jezicima</translation>
 <translation id="3854976556788175030">Posuda za odštampani materijal je puna</translation>
@@ -3268,6 +3274,7 @@
 <translation id="4062561150282203854">Sinhronizujte<ph name="DEVICE_TYPE" /> aplikacije, podešavanja i drugo</translation>
 <translation id="4065876735068446555">Mreža koju koristite (<ph name="NETWORK_ID" />) će možda zahtevati da posetite stranicu za prijavljivanje.</translation>
 <translation id="4066207411788646768">Proverite vezu da biste videli dostupne štampače na mreži</translation>
+<translation id="4066945815577305767">Vreme za lozinke je isteklo</translation>
 <translation id="4068776064906523561">Sačuvani otisci prstiju</translation>
 <translation id="407173827865827707">Pri kliku</translation>
 <translation id="4072701974556190758">Lozinka će biti sačuvana na vašem Google nalogu, <ph name="ACCOUNT" />. Nećete morati da je pamtite.</translation>
@@ -3788,6 +3795,7 @@
 <translation id="4579453506923101210">Zaboravite povezani telefon</translation>
 <translation id="4579581181964204535">Nije uspelo prebacivanje za <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Ako želite obaveštenja pregledača, idite u <ph name="LINK_BEGIN" />Podešavanja Chrome pregledača<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Ponovo se prijavite u Google menadžer lozinki</translation>
 <translation id="4580596421317071374">Lozinke se čuvaju na ovom uređaju u:<ph name="GOOGLE_PASSWORD_MANAGER" />.</translation>
 <translation id="4580626299762849806">Uvoz lozinki nije uspeo. Proverite fajl <ph name="FILENAME" /> i uverite se da je pravilno formatiran.</translation>
 <translation id="4581774856936278355">Greška pri vraćanju Linux-a</translation>
@@ -4469,6 +4477,7 @@
 <translation id="5268373933383932086">Vaša stranica, vaš način</translation>
 <translation id="5269977353971873915">Štampanje nije uspelo</translation>
 <translation id="5273806377963980154">Izmenite URL sajta</translation>
+<translation id="5275084684151588738">Korisnički rečnici</translation>
 <translation id="5275338516105640560">Dugme sačuvane grupe kartica</translation>
 <translation id="5275352920323889391">Pas</translation>
 <translation id="527605719918376753">Isključi zvuk kartice</translation>
@@ -4683,6 +4692,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN mora da sadrži bar jedan znak}one{PIN mora da sadrži bar # znak}few{PIN mora da sadrži bar # znaka}other{PIN mora da sadrži bar # znakova}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> zahteva da se odmah povežete na WiFi i da preuzmete ažuriranje. Ili preuzmite pomoću veze sa ograničenjem (možda se naplaćuju troškovi).</translation>
 <translation id="5481273127572794904">Nije im dozvoljeno da automatski preuzimaju više fajlova</translation>
+<translation id="5481755802440890178">Izbor trenutno ne može da se prevede</translation>
 <translation id="5481941284378890518">Dodaj obližnje štampače</translation>
 <translation id="5483785310822538350">Opozovi pristup datotekama i uređaju</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> zahteva da napravite rezervnu kopiju podataka i da vratite ovaj <ph name="DEVICE_TYPE" /> danas. <ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}one{<ph name="MANAGER" /> zahteva da napravite rezervnu kopiju podataka i da vratite ovaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}few{<ph name="MANAGER" /> zahteva da napravite rezervnu kopiju podataka i da vratite ovaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}other{<ph name="MANAGER" /> zahteva da napravite rezervnu kopiju podataka i da vratite ovaj <ph name="DEVICE_TYPE" /> u roku od {NUM_DAYS} dana.<ph name="LINK_BEGIN" />Pogledajte detalje<ph name="LINK_END" />}}</translation>
@@ -4916,6 +4926,7 @@
 <translation id="5696143504434933566">Prijavi zloupotrebu od „<ph name="EXTENSION_NAME" />“</translation>
 <translation id="5696679855467848181">Trenutna PPD datoteka u upotrebi: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Birač emodžija</translation>
+<translation id="5698462638680260399">Prijavite se da biste koristili lozinke</translation>
 <translation id="570043786759263127">Google Play aplikacije i usluge</translation>
 <translation id="5700836101007545240">Administrator je onemogućio dodavanje veze</translation>
 <translation id="5701080607174488915">Greška pri preuzimanju smernica sa servera.</translation>
@@ -4933,6 +4944,7 @@
 <translation id="5712153969432126546">Sajtovi ponekad objavljuju PDF-ove, poput dokumenata, ugovora i obrazaca</translation>
 <translation id="571222594670061844">Sajtovi mogu da prikazuju upite za prijavljivanje iz usluga za identitet</translation>
 <translation id="5713158217420111469">Uspostavljena je veza sa: <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Stil unosa za Space</translation>
 <translation id="5715711091495208045">Posrednik dodatne komponente: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Podrazumevani pretraživači</translation>
 <translation id="5719854774000914513">Sajtovi mogu da traže da se povezuju sa HID uređajima</translation>
@@ -5574,6 +5586,7 @@
 <translation id="6335920438823100346">Da biste pokrenuli Linux, <ph name="MANAGER" /> zahteva da napravite rezervnu kopiju podataka i resetujete ovaj Chromebook na fabrička podešavanja.</translation>
 <translation id="6336038146639916978"><ph name="MANAGER" /> je onemogućio ADB otklanjanje grešaka. To će resetovati <ph name="DEVICE_TYPE" /> za 24 sata. Napravite rezervne kopije svih fajlova koje želite da zadržite.</translation>
 <translation id="6338402296920404442">Razmislite o tome da izbrišete <ph name="FILENAME" /> da drugi koji koriste ovaj uređaj ne bi mogli da vide vaše lozinke.</translation>
+<translation id="6338968693068997776">Dodajte USB uređaj</translation>
 <translation id="6338981933082930623">Svi sajtovi mogu da prikazuju sve oglase</translation>
 <translation id="6339668969738228384">Otvori novi profil za <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Internet protokol za štampanje (IPPS)</translation>
@@ -6175,6 +6188,7 @@
 <translation id="6903907808598579934">Uključi sinhronizaciju</translation>
 <translation id="6904344821472985372">Opozovi pristup datotekama</translation>
 <translation id="6904655473976120856">Pritisnite dugme za aplikaciju da biste izašli</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Da bi zaštitio lozinke, Google menadžer lozinki se zaključava posle 1 minuta neaktivnosti}one{Da bi zaštitio lozinke, Google menadžer lozinki se zaključava posle {NUM_MINS} minuta neaktivnosti}few{Da bi zaštitio lozinke, Google menadžer lozinki se zaključava posle {NUM_MINS} minuta neaktivnosti}other{Da bi zaštitio lozinke, Google menadžer lozinki se zaključava posle {NUM_MINS} minuta neaktivnosti}}</translation>
 <translation id="6909422577741440844">Da li želite da primite sadržaj sa ovog uređaja?</translation>
 <translation id="6910211073230771657">Izbrisano</translation>
 <translation id="691106080621596509">Ovim brišete sve podatke i kolačiće koje čuvaju sajt <ph name="SITE_GROUP_NAME" />, svi njemu podređeni sajtovi i njegove instalirane aplikacije</translation>
@@ -6359,6 +6373,7 @@
 <translation id="7069811530847688087"><ph name="WEBSITE" /> možda zahteva noviju ili drugačiju vrstu bezbednosnog ključa</translation>
 <translation id="7070484045139057854">Ovo može da čita i menja podatke sajtova</translation>
 <translation id="7072010813301522126">Naziv prečice</translation>
+<translation id="7074066049407662839">Prijavite se da biste sačuvali lozinke</translation>
 <translation id="7075513071073410194">PKCS #1 MD5 sa RSA šifrovanjem</translation>
 <translation id="7075625805486468288">Upravljanje HTTPS/SSL sertifikatima i podešavanjima</translation>
 <translation id="7076875098323397992">Pokretanje nadogradnje nije uspelo</translation>
@@ -6890,6 +6905,7 @@
 <translation id="7625568159987162309">Pregledajte dozvole i podatke koji se čuvaju na svim sajtovima</translation>
 <translation id="7625823789272218216">Nova kartica na levoj strani</translation>
 <translation id="7628201176665550262">Učestalost osvežavanja</translation>
+<translation id="7628392600831846024">Stil simbola</translation>
 <translation id="7629827748548208700">Kartica: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382"><ph name="MANAGER" /> upravlja ovim uređajem i zahteva da se prijavite svaki put.</translation>
 <translation id="7631014249255418691">Napravljena je rezervna kopija Linux aplikacija i datoteka</translation>
@@ -8015,6 +8031,7 @@
 <translation id="8688672835843460752">Dostupno</translation>
 <translation id="8690129572193755009">Sajtovi mogu da traže da upravljaju protokolima</translation>
 <translation id="8692107307702113268">Lozinka premašuje 1000 znakova</translation>
+<translation id="8694596275649352090">Zaključaj tokom spavanja ili kada je poklopac zatvoren</translation>
 <translation id="8695139659682234808">Dodajte roditeljski nadzor posle podešavanja</translation>
 <translation id="8695825812785969222">Open &amp;Location... (Otvori lokaciju)</translation>
 <translation id="8698269656364382265">Da biste se vratili na prethodni ekran, prevucite počev od leve strane.</translation>
@@ -8063,6 +8080,7 @@
 <translation id="8732844209475700754">Još podešavanja u vezi sa privatnošću, bezbednošću i prikupljanjem podataka</translation>
 <translation id="8734073480934656039">Omogućavanjem ovog podešavanja dozvoljavate kiosk aplikacijama da se automatski pokreću pri pokretanju računara.</translation>
 <translation id="8734674662128056360">Blokiranje kolačića trećih strana</translation>
+<translation id="8734755021067981851">Nije priključen nijedan USB uređaj.</translation>
 <translation id="873545264931343897">Kada se završi ažuriranje dodatne komponente <ph name="PLUGIN_NAME" />, ponovo učitajte stranicu da biste je aktivirali</translation>
 <translation id="8736288397686080465">Ovaj sajt je ažuriran u pozadini.</translation>
 <translation id="8737709691285775803">Shill</translation>
@@ -8189,6 +8207,7 @@
 <translation id="8850251000316748990">Prikaži više...</translation>
 <translation id="885246833287407341">Promenljive za API funkciju</translation>
 <translation id="8853586775156634952">Ova kartica će se sačuvati samo na ovom uređaju</translation>
+<translation id="8854745870658584490">Prečica izbora</translation>
 <translation id="8855977033756560989">Uz ovaj Chromebook Enterprise uređaj dobija se nadogradnja na Chrome za preduzeća. Da biste iskoristili pogodnosti verzije za preduzeća, registrujte ovaj uređaj pomoću naloga Google administratora.</translation>
 <translation id="8856028055086294840">Vraćanje aplikacija i stranica</translation>
 <translation id="885701979325669005">Memorijski prostor</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index 5e2c477f..e69c0da 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -46,6 +46,7 @@
 <translation id="1043505821207197890">Дошло је до грешке. Linux је можда само делимично надограђен. Прегледајте евиденцију за више информација. Евиденција је сачувана у одељку Фајлови &gt; Моји фајлови &gt; <ph name="LOG_FILE" /></translation>
 <translation id="1043818413152647937">Желите и да обришете податке из ових апликација?</translation>
 <translation id="1043824690776631483">Треба вам дозвола да бисте посетили овај сајт. Може да обухвата неприкладан садржај.</translation>
+<translation id="104419033123549300">Стил мапе тастера</translation>
 <translation id="104710386808485638">Желите ли да рестартујете Linux?</translation>
 <translation id="1047431265488717055">Копирај тек&amp;ст линка</translation>
 <translation id="1048286738600630630">Прикази</translation>
@@ -771,6 +772,7 @@
 <translation id="1721312023322545264">Потребна вам је дозвола корисника <ph name="NAME" /> да бисте посетили овај сајт</translation>
 <translation id="1722460139690167654"><ph name="BEGIN_LINK" /><ph name="DEVICE_TYPE" />-ом управља<ph name="END_LINK" /> <ph name="ENROLLMENT_DOMAIN" /></translation>
 <translation id="1723824996674794290">&amp;Нови прозор</translation>
+<translation id="1724801751621173132">Режим уноса</translation>
 <translation id="1725562816265788801">Померање картица</translation>
 <translation id="1729533290416704613">Контролише и страницу која се приказује када претражујете из омнибокса.</translation>
 <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Да бисте уклонили апликације, идите у одељак Подешавања &gt; Google Play продавница &gt; Управљајте Android подешавањима &gt; Апликације или Менаџер апликација. Додирните апликацију коју желите да деинсталирате (можда ћете морати да превучете надесно или налево да бисте пронашли апликацију). Онда додирните Деинсталирај или Онемогући.<ph name="END_PARAGRAPH1" /></translation>
@@ -1951,6 +1953,7 @@
 <translation id="2796740370559399562">Настави са дозвољавањем колачића</translation>
 <translation id="2798347533012571708">Задржи ажурирања</translation>
 <translation id="2799223571221894425">Поново покрени</translation>
+<translation id="2800309299477632167">Прилагођена мапа тастера</translation>
 <translation id="2800760947029405028">Отпреми слику</translation>
 <translation id="2801954693771979815">Величина екрана</translation>
 <translation id="2802557211515765772">Нема управљаних штампача.</translation>
@@ -2012,6 +2015,7 @@
 <translation id="2849767214114481738">PIN је додат</translation>
 <translation id="2849936225196189499">Од пресудне важности</translation>
 <translation id="2850541429955027218">Додај тему</translation>
+<translation id="2850672011315104382">Стил интерпункције</translation>
 <translation id="2851634818064021665">Треба вам дозвола да бисте посетили овај сајт</translation>
 <translation id="2851728849045278002">Дошло је до грешке. Кликните за више детаља.</translation>
 <translation id="2852385257476173980">Листа сајтова које посећујете се може приказати овде док прегледате веб</translation>
@@ -2508,6 +2512,7 @@
 <translation id="3359256513598016054">Ограничења смерница сертификата</translation>
 <translation id="3360297538363969800">Штампање није успело. Проверите штампач и покушајте поново.</translation>
 <translation id="3361421571228286637">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> дели са вама (<ph name="ATTACHMENTS" />).}one{<ph name="DEVICE_NAME" /> дели са вама (<ph name="ATTACHMENTS" />).}few{<ph name="DEVICE_NAME" /> дели <ph name="ATTACHMENTS" /> са вама.}other{<ph name="DEVICE_NAME" /> дели <ph name="ATTACHMENTS" /> са вама.}}</translation>
+<translation id="3361954577771524115">Из апликације</translation>
 <translation id="3363202073972776113">Овим новим профилом ће управљати организација. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation>
 <translation id="3364986687961713424">Од администратора: <ph name="ADMIN_MESSAGE" /></translation>
 <translation id="3365598184818502391">Користите Ctrl или Alt</translation>
@@ -3032,6 +3037,7 @@
 <translation id="3848547754896969219">Отвори у &amp;прозору без архивирања</translation>
 <translation id="385051799172605136">Назад</translation>
 <translation id="3851428669031642514">Учитавај небезбедне скрипте</translation>
+<translation id="3852215160863921508">Помоћ при уносу</translation>
 <translation id="3854599674806204102">Изаберите опцију</translation>
 <translation id="3854967233147778866">Понуди превод веб-сајтова који су на другим језицима</translation>
 <translation id="3854976556788175030">Посуда за одштампани материјал је пуна</translation>
@@ -3268,6 +3274,7 @@
 <translation id="4062561150282203854">Синхронизујте<ph name="DEVICE_TYPE" /> апликације, подешавања и друго</translation>
 <translation id="4065876735068446555">Мрежа коју користите (<ph name="NETWORK_ID" />) ће можда захтевати да посетите страницу за пријављивање.</translation>
 <translation id="4066207411788646768">Проверите везу да бисте видели доступне штампаче на мрежи</translation>
+<translation id="4066945815577305767">Време за лозинке је истекло</translation>
 <translation id="4068776064906523561">Сачувани отисци прстију</translation>
 <translation id="407173827865827707">При клику</translation>
 <translation id="4072701974556190758">Лозинка ће бити сачувана на вашем Google налогу, <ph name="ACCOUNT" />. Нећете морати да је памтите.</translation>
@@ -3788,6 +3795,7 @@
 <translation id="4579453506923101210">Заборавите повезани телефон</translation>
 <translation id="4579581181964204535">Није успело пребацивање за <ph name="HOST_NAME" />.</translation>
 <translation id="4579876313423027742">Ако желите обавештења прегледача, идите у <ph name="LINK_BEGIN" />Подешавања Chrome прегледача<ph name="LINK_END" /></translation>
+<translation id="4580587929153007251">Поново се пријавите у Google менаџер лозинки</translation>
 <translation id="4580596421317071374">Лозинке се чувају на овом уређају у:<ph name="GOOGLE_PASSWORD_MANAGER" />.</translation>
 <translation id="4580626299762849806">Увоз лозинки није успео. Проверите фајл <ph name="FILENAME" /> и уверите се да је правилно форматиран.</translation>
 <translation id="4581774856936278355">Грешка при враћању Linux-а</translation>
@@ -4469,6 +4477,7 @@
 <translation id="5268373933383932086">Ваша страница, ваш начин</translation>
 <translation id="5269977353971873915">Штампање није успело</translation>
 <translation id="5273806377963980154">Измените URL сајта</translation>
+<translation id="5275084684151588738">Кориснички речници</translation>
 <translation id="5275338516105640560">Дугме сачуване групе картица</translation>
 <translation id="5275352920323889391">Пас</translation>
 <translation id="527605719918376753">Искључи звук картице</translation>
@@ -4683,6 +4692,7 @@
 <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN мора да садржи бар један знак}one{PIN мора да садржи бар # знак}few{PIN мора да садржи бар # знака}other{PIN мора да садржи бар # знакова}}</translation>
 <translation id="5474859849784484111"><ph name="MANAGER" /> захтева да се одмах повежете на WiFi и да преузмете ажурирање. Или преузмите помоћу везе са ограничењем (можда се наплаћују трошкови).</translation>
 <translation id="5481273127572794904">Није им дозвољено да аутоматски преузимају више фајлова</translation>
+<translation id="5481755802440890178">Избор тренутно не може да се преведе</translation>
 <translation id="5481941284378890518">Додај оближње штампаче</translation>
 <translation id="5483785310822538350">Опозови приступ датотекама и уређају</translation>
 <translation id="5484772771923374861">{NUM_DAYS,plural, =1{<ph name="MANAGER" /> захтева да направите резервну копију података и да вратите овај <ph name="DEVICE_TYPE" /> данас. <ph name="LINK_BEGIN" />Погледајте детаље<ph name="LINK_END" />}one{<ph name="MANAGER" /> захтева да направите резервну копију података и да вратите овај <ph name="DEVICE_TYPE" /> у року од {NUM_DAYS} данa.<ph name="LINK_BEGIN" />Погледајте детаље<ph name="LINK_END" />}few{<ph name="MANAGER" /> захтева да направите резервну копију података и да вратите овај <ph name="DEVICE_TYPE" /> у року од {NUM_DAYS} данa.<ph name="LINK_BEGIN" />Погледајте детаље<ph name="LINK_END" />}other{<ph name="MANAGER" /> захтева да направите резервну копију података и да вратите овај <ph name="DEVICE_TYPE" /> у року од {NUM_DAYS} данa.<ph name="LINK_BEGIN" />Погледајте детаље<ph name="LINK_END" />}}</translation>
@@ -4916,6 +4926,7 @@
 <translation id="5696143504434933566">Пријави злоупотребу од „<ph name="EXTENSION_NAME" />“</translation>
 <translation id="5696679855467848181">Тренутна PPD датотека у употреби: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">Бирач емоџија</translation>
+<translation id="5698462638680260399">Пријавите се да бисте користили лозинке</translation>
 <translation id="570043786759263127">Google Play апликације и услуге</translation>
 <translation id="5700836101007545240">Администратор је онемогућио додавање везе</translation>
 <translation id="5701080607174488915">Грешка при преузимању смерница са сервера.</translation>
@@ -4933,6 +4944,7 @@
 <translation id="5712153969432126546">Сајтови понекад објављују PDF-ове, попут докумената, уговора и образаца</translation>
 <translation id="571222594670061844">Сајтови могу да приказују упите за пријављивање из услуга за идентитет</translation>
 <translation id="5713158217420111469">Успостављена је веза са: <ph name="DEVICE" /></translation>
+<translation id="5713960379473463904">Стил уноса за Space</translation>
 <translation id="5715711091495208045">Посредник додатне компоненте: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">Подразумевани претраживачи</translation>
 <translation id="5719854774000914513">Сајтови могу да траже да се повезују са HID уређајима</translation>
@@ -5574,6 +5586,7 @@
 <translation id="6335920438823100346">Да бисте покренули Linux, <ph name="MANAGER" /> захтева да направите резервну копију података и ресетујете овај Chromebook на фабричка подешавања.</translation>
 <translation id="6336038146639916978"><ph name="MANAGER" /> је онемогућио ADB отклањање грешака. То ће ресетовати <ph name="DEVICE_TYPE" /> за 24 сата. Направите резервне копије свих фајлова које желите да задржите.</translation>
 <translation id="6338402296920404442">Размислите о томе да избришете <ph name="FILENAME" /> да други који користе овај уређај не би могли да виде ваше лозинке.</translation>
+<translation id="6338968693068997776">Додајте USB уређај</translation>
 <translation id="6338981933082930623">Сви сајтови могу да приказују све огласе</translation>
 <translation id="6339668969738228384">Отвори нови профил за <ph name="USER_EMAIL_ADDRESS" /></translation>
 <translation id="6340071272923955280">Интернет протокол за штампање (IPPS)</translation>
@@ -6175,6 +6188,7 @@
 <translation id="6903907808598579934">Укључи синхронизацију</translation>
 <translation id="6904344821472985372">Опозови приступ датотекама</translation>
 <translation id="6904655473976120856">Притисните дугме за апликацију да бисте изашли</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{Да би заштитио лозинке, Google менаџер лозинки се закључава после 1 минута неактивности}one{Да би заштитио лозинке, Google менаџер лозинки се закључава после {NUM_MINS} минута неактивности}few{Да би заштитио лозинке, Google менаџер лозинки се закључава после {NUM_MINS} минута неактивности}other{Да би заштитио лозинке, Google менаџер лозинки се закључава после {NUM_MINS} минута неактивности}}</translation>
 <translation id="6909422577741440844">Да ли желите да примите садржај са овог уређаја?</translation>
 <translation id="6910211073230771657">Избрисано</translation>
 <translation id="691106080621596509">Овим бришете све податке и колачиће које чувају сајт <ph name="SITE_GROUP_NAME" />, сви њему подређени сајтови и његове инсталиране апликације</translation>
@@ -6359,6 +6373,7 @@
 <translation id="7069811530847688087"><ph name="WEBSITE" /> можда захтева новију или другачију врсту безбедносног кључа</translation>
 <translation id="7070484045139057854">Ово може да чита и мења податке сајтова</translation>
 <translation id="7072010813301522126">Назив пречице</translation>
+<translation id="7074066049407662839">Пријавите се да бисте сачували лозинке</translation>
 <translation id="7075513071073410194">PKCS #1 MD5 са RSA шифровањем</translation>
 <translation id="7075625805486468288">Управљање HTTPS/SSL сертификатима и подешавањима</translation>
 <translation id="7076875098323397992">Покретање надоградње није успело</translation>
@@ -6890,6 +6905,7 @@
 <translation id="7625568159987162309">Прегледајте дозволе и податке који се чувају на свим сајтовима</translation>
 <translation id="7625823789272218216">Нова картица на левој страни</translation>
 <translation id="7628201176665550262">Учесталост освежавања</translation>
+<translation id="7628392600831846024">Стил симбола</translation>
 <translation id="7629827748548208700">Картица: <ph name="TAB_NAME" /></translation>
 <translation id="7630426712700473382"><ph name="MANAGER" /> управља овим уређајем и захтева да се пријавите сваки пут.</translation>
 <translation id="7631014249255418691">Направљена је резервна копија Linux апликација и датотека</translation>
@@ -8015,6 +8031,7 @@
 <translation id="8688672835843460752">Доступно</translation>
 <translation id="8690129572193755009">Сајтови могу да траже да управљају протоколима</translation>
 <translation id="8692107307702113268">Лозинка премашује 1000 знакова</translation>
+<translation id="8694596275649352090">Закључај током спавања или када је поклопац затворен</translation>
 <translation id="8695139659682234808">Додајте родитељски надзор после подешавања</translation>
 <translation id="8695825812785969222">Open &amp;Location... (Отвори локацију)</translation>
 <translation id="8698269656364382265">Да бисте се вратили на претходни екран, превуците почев од леве стране.</translation>
@@ -8063,6 +8080,7 @@
 <translation id="8732844209475700754">Још подешавања у вези са приватношћу, безбедношћу и прикупљањем података</translation>
 <translation id="8734073480934656039">Омогућавањем овог подешавања дозвољавате киоск апликацијама да се аутоматски покрећу при покретању рачунара.</translation>
 <translation id="8734674662128056360">Блокирање колачића трећих страна</translation>
+<translation id="8734755021067981851">Није прикључен ниједан USB уређај.</translation>
 <translation id="873545264931343897">Када се заврши ажурирање додатне компоненте <ph name="PLUGIN_NAME" />, поново учитајте страницу да бисте је активирали</translation>
 <translation id="8736288397686080465">Овај сајт је ажуриран у позадини.</translation>
 <translation id="8737709691285775803">Shill</translation>
@@ -8189,6 +8207,7 @@
 <translation id="8850251000316748990">Прикажи више...</translation>
 <translation id="885246833287407341">Променљиве за API функцију</translation>
 <translation id="8853586775156634952">Ова картица ће се сачувати само на овом уређају</translation>
+<translation id="8854745870658584490">Пречица избора</translation>
 <translation id="8855977033756560989">Уз овај Chromebook Enterprise уређај добија се надоградња на Chrome за предузећа. Да бисте искористили погодности верзије за предузећа, региструјте овај уређај помоћу налога Google администратора.</translation>
 <translation id="8856028055086294840">Враћање апликација и страница</translation>
 <translation id="885701979325669005">Меморијски простор</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb
index a91ebb2..98b65946 100644
--- a/chrome/app/resources/generated_resources_ur.xtb
+++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -3271,6 +3271,7 @@
 <translation id="4062561150282203854">اپنی <ph name="DEVICE_TYPE" /> ایپس، ترتیبات اور مزید کو مطابقت پذیر بنائیں</translation>
 <translation id="4065876735068446555">آپ کا زیر استعمال نیٹ ورک (<ph name="NETWORK_ID" />) آپ سے اپنا لاگ ان صفحہ ملاحظہ کرنے کا تقاضہ کر سکتا ہے۔</translation>
 <translation id="4066207411788646768">اپنے نیٹ ورک میں دستیاب پرنٹرز دیکھنے کے لیے براہ کرم اپنا کنکشن چیک کریں</translation>
+<translation id="4066945815577305767">پاس ورڈز کا وقت ختم ہو گیا</translation>
 <translation id="4068776064906523561">محفوظ کردہ فنگر پرنٹس</translation>
 <translation id="407173827865827707">کلک کرنے پر</translation>
 <translation id="4072701974556190758">‏پاس ورڈ آپ کے Google اکاؤنٹ میں محفوظ کیا جائے گا، <ph name="ACCOUNT" />۔ آپ کو اسے یاد رکھنے کی ضرورت نہیں ہے۔</translation>
@@ -5576,6 +5577,7 @@
 <translation id="6335920438823100346">‏Linux شروع کرنے کے لیے <ph name="MANAGER" /> کا تقاضہ ہے کہ آپ اپنے ڈیٹا کا بیک اپ لیں اور اس Chromebook کو فیکٹری کی ترتیبات پر ری سیٹ کریں۔</translation>
 <translation id="6336038146639916978">‏<ph name="MANAGER" /> نے ADB ڈیبگنگ کو غیر فعال کر دیا ہے۔ یہ آپ کے <ph name="DEVICE_TYPE" /> کو 24 گھنٹوں میں ری سیٹ کر دے گا۔ کوئی بھی فائل کا بیک اپ لیں جسے آپ رکھنا چاہتے ہیں۔</translation>
 <translation id="6338402296920404442"><ph name="FILENAME" /> کو حذف کرنے پر غور کریں، تاکہ دوسرے لوگ جو اس آلہ کو استعمال کرتے ہیں وہ آپ کے پاس ورڈز نہ دیکھ سکیں۔</translation>
+<translation id="6338968693068997776">‏USB آلہ شامل کریں</translation>
 <translation id="6338981933082930623">سبھی سائٹس آپ کو کوئی اشتہار دکھا سکتی ہیں</translation>
 <translation id="6339668969738228384"><ph name="USER_EMAIL_ADDRESS" /> کیلئے ایک نیا پروفائل بنائیں</translation>
 <translation id="6340071272923955280">‏انٹرنیٹ پرنٹنگ پروٹوکول (IPPS)</translation>
@@ -6173,6 +6175,7 @@
 <translation id="6903907808598579934">مطابقت پذیری آن کریں</translation>
 <translation id="6904344821472985372">فائل کی رسائی کالعدم کریں</translation>
 <translation id="6904655473976120856">باہر نکلنے کیلئے ایپ بٹن دبائیں</translation>
+<translation id="6906095067383230422">{NUM_MINS,plural, =1{‏آپ کے پاس ورڈز کو محفوظ رکھنے کے لیے Google پاس ورڈ مینیجر 1 منٹ کی غیر فعالیت کے بعد مقفل ہو جاتا ہے}other{‏آپ کے پاس ورڈز کو محفوظ رکھنے کے لیے Google پاس ورڈ مینیجر {NUM_MINS} منٹ کی غیر فعالیت کے بعد مقفل ہو جاتا ہے}}</translation>
 <translation id="6909422577741440844">اس آلہ سے موصول کریں؟</translation>
 <translation id="6910211073230771657">حذف کردہ</translation>
 <translation id="691106080621596509">اس سے <ph name="SITE_GROUP_NAME" /> کا اسٹور کردہ تمام ڈیٹا اور کوکیز اور اس کے ماتحت سبھی سائٹس اور اس کی انسٹال کردہ ایپ صاف ہو جائے گی</translation>
@@ -8012,6 +8015,7 @@
 <translation id="8688672835843460752">دستیاب</translation>
 <translation id="8690129572193755009">سائٹس پروٹوکولز ہینڈل کرنے کے لئے پوچھ سکتی ہیں</translation>
 <translation id="8692107307702113268">پاس ورڈ میں 1000 سے زیادہ حروف ہیں</translation>
+<translation id="8694596275649352090">سوتے وقت یا لِڈ بند ہونے پر مقفل کریں</translation>
 <translation id="8695139659682234808">سیٹ اپ کے بعد پیرنٹل کنٹرولز شامل کریں</translation>
 <translation id="8695825812785969222">&amp;مقام کھولیں…</translation>
 <translation id="8698269656364382265">سابقہ اسکرین پر واپس جانے کے لیے، بائیں طرف سے سوائپ کریں۔</translation>
@@ -8060,6 +8064,7 @@
 <translation id="8732844209475700754">راز داری، سیکیورٹی اور ڈیٹا کے مجموعے سے متعلق مزید ترتیبات</translation>
 <translation id="8734073480934656039">اس ترتیب کو فعال کرنا اسٹارٹ اپ پر کیوسک ایپلیکیشنز کو خود بخود شروع ہونے کی اجازت دیتا ہے۔</translation>
 <translation id="8734674662128056360">فریق ثالث کوکی مسدود کرنے کا عمل فعال ہے</translation>
+<translation id="8734755021067981851">‏کوئی بھی USB آلہ منسلک نہیں ہے۔</translation>
 <translation id="873545264931343897"><ph name="PLUGIN_NAME" /> کو اپ ڈیٹ کرنا مکمل ہو جانے پر، اسے فعال کرنے کیلئے صفحہ دوبار لوڈ کریں</translation>
 <translation id="8736288397686080465">اس سائٹ کو بیک گراؤنڈ میں اپ ڈیٹ کر دیا گیا ہے۔</translation>
 <translation id="8737709691285775803">Shill</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index 8ec467da..711ce7e4 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -275,6 +275,7 @@
 <translation id="125220115284141797">默认</translation>
 <translation id="1252987234827889034">发生个人资料错误</translation>
 <translation id="1254593899333212300">直接连接到互联网</translation>
+<translation id="1257336506558170607">导出所选证书</translation>
 <translation id="1258491128795710625">新变化</translation>
 <translation id="1259152067760398571">昨天运行过安全检查</translation>
 <translation id="1260451001046713751">始终允许 <ph name="HOST" /> 显示弹出式窗口和进行重定向</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb
index c00a349..eff2ccd 100644
--- a/chrome/app/resources/generated_resources_zh-HK.xtb
+++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -278,6 +278,7 @@
 <translation id="125220115284141797">預設</translation>
 <translation id="1252987234827889034">設定檔發生錯誤</translation>
 <translation id="1254593899333212300">直接連線到互聯網</translation>
+<translation id="1257336506558170607">匯出選取的憑證</translation>
 <translation id="1258491128795710625">新功能</translation>
 <translation id="1259152067760398571">昨天已執行安全檢查</translation>
 <translation id="1260451001046713751">一律顯示 <ph name="HOST" /> 的彈出式視窗及重新導向</translation>
@@ -327,6 +328,7 @@
 <translation id="1307165550267142340">已建立 PIN</translation>
 <translation id="1307431692088049276">不要再問我</translation>
 <translation id="1307559529304613120">糟糕!系統無法為這部裝置儲存長期 API 存取憑證。</translation>
+<translation id="1312811472299082263">使用 Ansible Playbook 或 Crostini 備份檔案建立</translation>
 <translation id="1313405956111467313">自動 Proxy 設定</translation>
 <translation id="131364520783682672">Caps Lock 鍵</translation>
 <translation id="1313660246522271310">您將會從所有網站 (包括已開啟的分頁) 登出</translation>
@@ -1111,6 +1113,7 @@
 <translation id="2028449514182362831">需要動作感應器的功能將無法運作</translation>
 <translation id="202918510990975568">請輸入您的密碼以進行安全性和登入設定</translation>
 <translation id="2030455719695904263">觸控板</translation>
+<translation id="2031385797619033640">按一下即可允許「<ph name="EXTENSIONS_REQUESTING_ACCESS" />」讀取及變更 <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">您的密碼已儲存在 Google 帳戶中</translation>
 <translation id="2031914984822377766">新增偏好的<ph name="LINK_BEGIN" />網站語言<ph name="LINK_END" />。系統會將文字翻譯成清單頂部的語言。</translation>
 <translation id="2033758234986231162">無法與您的手機維持連線狀態。請確認您的手機在附近且已解鎖,並已開啟藍牙和 Wi-Fi。</translation>
@@ -1470,6 +1473,7 @@
 <translation id="2328561734797404498">請重新啟動裝置,以便使用 <ph name="APP_NAME" />。</translation>
 <translation id="2328636661627946415">在無痕模式時,網站只能使用 Cookie 查看您在該網站的瀏覽活動。系統就會無痕工作階段結束時刪除 Cookie。</translation>
 <translation id="2329597144923131178">登入後,即可從您使用的任何裝置取得自己的書籤、歷史記錄、密碼和其他設定。</translation>
+<translation id="2332115969598251205">無法載入已儲存到 <ph name="PRIMARY_EMAIL" /> 的裝置,請檢查網際網路連線,然後再試一次。</translation>
 <translation id="2332131598580221120">前往商店檢視</translation>
 <translation id="2332192922827071008">開啟偏好設定</translation>
 <translation id="2332515770639153015">已啟用「強化安全瀏覽」功能</translation>
@@ -1913,6 +1917,7 @@
 <translation id="2749836841884031656">SIM 卡</translation>
 <translation id="2749881179542288782">檢查拼字及文法</translation>
 <translation id="2753677631968972007">手動控制網站權限。</translation>
+<translation id="2754226775788136540">正在尋找已儲存到 <ph name="PRIMARY_EMAIL" /> 的快速配對裝置</translation>
 <translation id="2754825024506485820">在 Google Play 商店上尋找您需要的應用程式,從提升工作效率到娛樂,種類一應俱全。您可隨時安裝應用程式。</translation>
 <translation id="2755349111255270002">重設此 <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">管理無障礙功能</translation>
@@ -2130,6 +2135,7 @@
 <translation id="2942279350258725020">Android 訊息</translation>
 <translation id="2942560570858569904">正在等待…</translation>
 <translation id="2942581856830209953">自訂呢個頁面</translation>
+<translation id="2943268899142471972">選取 Ansible Playbook 或 Crostini 備份檔案</translation>
 <translation id="2944060181911631861">傳送使用情況和診斷資料。自動將診斷、裝置及應用程式的使用情況資料傳送至 Google,協助改善您的 Android 使用體驗。這些資料將有助改善系統和應用程式的穩定性和其他效能。部分彙整資料也會用於協助 Google 應用程式與合作夥伴 (例如 Android 開發人員)。如果已開啟其他「網絡及應用程式活動記錄」設定,系統可能會將此資料儲存至您的 Google 帳戶。<ph name="BEGIN_LINK1" />瞭解詳情<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">前往檔案</translation>
 <translation id="2946119680249604491">新增連線</translation>
@@ -2971,6 +2977,7 @@
 <translation id="3784472333786002075">Cookie 是網站所建立的檔案,並可分為兩種:第一方 Cookie 由您瀏覽的網站建立,網址列上會顯示該網站的網址。第三方 Cookie 則由其他網站建立。這些網站擁有您所瀏覽網站的部分內容,例如廣告和圖片。</translation>
 <translation id="3785308913036335955">顯示應用程式捷徑</translation>
 <translation id="3785727820640310185">已儲存此網站的密碼</translation>
+<translation id="3787434344076711519">正在等待翻譯</translation>
 <translation id="3788301286821743879">無法啟動 Kiosk 應用程式。</translation>
 <translation id="3788331399335602504">這些檔案</translation>
 <translation id="3788401245189148511">要求存取下列權限:</translation>
@@ -3255,6 +3262,7 @@
 <translation id="4036778507053569103">從伺服器下載的政策無效。</translation>
 <translation id="4037084878352560732">馬</translation>
 <translation id="403725336528835653">先試用</translation>
+<translation id="4040041015953651705">原文語言</translation>
 <translation id="4040105702484676956">要清除 <ph name="SITE_NAME" /> 和網站已安裝應用程式的網站資料和權限嗎?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{離開網頁}other{離開網頁}}</translation>
 <translation id="4043267180218562935">游標大小</translation>
@@ -4062,6 +4070,7 @@
 <translation id="4838170306476614339">查看手機上的相片、媒體和通知</translation>
 <translation id="4838836835474292213">已允許讀取剪貼簿</translation>
 <translation id="4838907349371614303">已更新密碼</translation>
+<translation id="4838958829619609362">所選內容的語言不是<ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">另存影片(&amp;V)…</translation>
 <translation id="4840096453115567876">仍要離開無痕模式嗎?</translation>
 <translation id="4841741146571978176">必要的虛擬機器不存在。如要繼續,請嘗試設定 <ph name="VM_TYPE" /></translation>
@@ -4835,6 +4844,7 @@
 <translation id="558918721941304263">正在載入應用程式…</translation>
 <translation id="5590418976913374224">在裝置啟動時播放音效</translation>
 <translation id="5592595402373377407">目前還沒有足夠的數據。</translation>
+<translation id="5594899180331219722">選取檔案</translation>
 <translation id="5595307023264033512">網站使用的總儲存空間:<ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">編輯地址</translation>
 <translation id="5596627076506792578">更多選項</translation>
@@ -5067,6 +5077,7 @@
 <translation id="5834581999798853053">還有大約 <ph name="TIME" /> 分鐘</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - 相機或麥克風錄製中</translation>
 <translation id="583673505367439042">網站可要求編輯裝置中的檔案和資料夾</translation>
+<translation id="5836999627049108525">原文語言</translation>
 <translation id="583756221537636748">充電盒</translation>
 <translation id="5840658767386246331">使用 Google 搜尋</translation>
 <translation id="5840680448799937675">一律在離線時分享檔案</translation>
@@ -5577,6 +5588,7 @@
 <translation id="6318944945640833942">偵測不到打印機,請再次輸入打印機位址。</translation>
 <translation id="6322370287306604163">指紋加快解鎖速度</translation>
 <translation id="6322559670748154781">此檔案不常下載,因此已被進階保護功能封鎖</translation>
+<translation id="6324083483652497048">按一下即可允許這些擴充功能讀取及變更 <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">編輯捷徑</translation>
 <translation id="6325191661371220117">停用自動啟動功能</translation>
 <translation id="6326175484149238433">從 Chrome 中移除</translation>
@@ -6608,6 +6620,7 @@
 <translation id="7343372807593926528">請在傳送意見前說明問題。</translation>
 <translation id="7344585835349671209">管理裝置上的 HTTPS/SSL 憑證</translation>
 <translation id="7345706641791090287">確認密碼</translation>
+<translation id="7345919885156673810">所選內容的語言不是<ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">好,我知道了</translation>
 <translation id="7347452120014970266">此操作會清除 <ph name="ORIGIN_NAME" /> 儲存的所有資料和 Cookie,以及該網站所安裝的應用程式</translation>
 <translation id="7347751611463936647">如要使用這個擴充功能,請輸入「<ph name="EXTENSION_KEYWORD" />」,然後按 TAB 鍵,再輸入您的指令或搜尋項目。</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb
index 4c9a2aac5..d64c04f 100644
--- a/chrome/app/resources/generated_resources_zh-TW.xtb
+++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -275,6 +275,7 @@
 <translation id="125220115284141797">預設值</translation>
 <translation id="1252987234827889034">設定檔發生錯誤</translation>
 <translation id="1254593899333212300">直接連線到網際網路</translation>
+<translation id="1257336506558170607">匯出選取的憑證</translation>
 <translation id="1258491128795710625">新功能</translation>
 <translation id="1259152067760398571">昨天已執行安全檢查</translation>
 <translation id="1260451001046713751">一律允許 <ph name="HOST" /> 的彈出式視窗和重新導向</translation>
@@ -324,6 +325,7 @@
 <translation id="1307165550267142340">已建立 PIN 碼</translation>
 <translation id="1307431692088049276">不要再詢問我</translation>
 <translation id="1307559529304613120">糟糕!系統無法為這個裝置儲存長期 API 存取符記。</translation>
+<translation id="1312811472299082263">使用 Ansible Playbook 或 Crostini 備份檔案建立</translation>
 <translation id="1313405956111467313">自動 Proxy 設定</translation>
 <translation id="131364520783682672">Caps Lock 鍵</translation>
 <translation id="1313660246522271310">系統會將你登出所有網站,包含已開啟的分頁</translation>
@@ -1097,6 +1099,7 @@
 <translation id="2028449514182362831">需要動作感應器的功能將無法運作</translation>
 <translation id="202918510990975568">請輸入你的密碼以進行安全性與登入設定</translation>
 <translation id="2030455719695904263">觸控板</translation>
+<translation id="2031385797619033640">按一下即可允許「<ph name="EXTENSIONS_REQUESTING_ACCESS" />」讀取及變更 <ph name="ORIGIN" />:</translation>
 <translation id="2031639749079821948">你已將密碼儲存在 Google 帳戶中</translation>
 <translation id="2031914984822377766">新增偏好的<ph name="LINK_BEGIN" />網站語言<ph name="LINK_END" />。系統會將文字翻譯成清單頂端的語言。</translation>
 <translation id="2033758234986231162">無法與你的手機維持連線狀態。請確認你的手機在附近且處於解鎖狀態,並已開啟藍牙和 Wi-Fi。</translation>
@@ -1453,6 +1456,7 @@
 <translation id="2328561734797404498">請重新啟動裝置以使用「<ph name="APP_NAME" />」。</translation>
 <translation id="2328636661627946415">使用無痕模式時,網站只能使用 Cookie 查看你在該網站上的瀏覽活動。無痕模式工作階段結束時,系統就會刪除 Cookie。</translation>
 <translation id="2329597144923131178">登入後,即可從您使用的任何裝置取得自己的書籤、歷史記錄、密碼和其他設定。</translation>
+<translation id="2332115969598251205">無法載入已儲存到 <ph name="PRIMARY_EMAIL" /> 的裝置,請檢查網際網路連線,然後再試一次。</translation>
 <translation id="2332131598580221120">前往商店查看</translation>
 <translation id="2332192922827071008">開啟偏好設定</translation>
 <translation id="2332515770639153015">已啟用安全瀏覽強化防護功能</translation>
@@ -1896,6 +1900,7 @@
 <translation id="2749836841884031656">SIM 卡</translation>
 <translation id="2749881179542288782">檢查拼字及文法</translation>
 <translation id="2753677631968972007">手動控管網站權限。</translation>
+<translation id="2754226775788136540">正在尋找已儲存到 <ph name="PRIMARY_EMAIL" /> 的快速配對裝置</translation>
 <translation id="2754825024506485820">Google Play 商店提供各種應用程式,從提升工作效率到生活娛樂都能滿足所需,而且隨時都能安裝。</translation>
 <translation id="2755349111255270002">重設這部 <ph name="DEVICE_TYPE" /></translation>
 <translation id="2755367719610958252">管理無障礙功能</translation>
@@ -2111,6 +2116,7 @@
 <translation id="2942279350258725020">Android 訊息</translation>
 <translation id="2942560570858569904">等待中…</translation>
 <translation id="2942581856830209953">自訂這個頁面</translation>
+<translation id="2943268899142471972">選取 Ansible Playbook 或 Crostini 備份檔案</translation>
 <translation id="2944060181911631861">傳送使用狀況與診斷資料。讓系統自動將診斷資料以及裝置和應用程式的使用狀況資料傳送給 Google,協助改善你的 Android 使用體驗。這些資料將有助於系統和應用程式提高穩定性及做出其他改善。部分匯總資料還能夠為 Google 應用程式和合作夥伴 (例如 Android 開發人員) 提供幫助。如果你的「其他網路和應用程式活動」設定為開啟,系統可能會將這些資料儲存到你的 Google 帳戶。<ph name="BEGIN_LINK1" />瞭解詳情<ph name="END_LINK1" /></translation>
 <translation id="2946054015403765210">前往檔案</translation>
 <translation id="2946119680249604491">新增連線</translation>
@@ -2951,6 +2957,7 @@
 <translation id="3784472333786002075">Cookie 是網站所建立的檔案,可分為兩種類型:第一方 Cookie 由你造訪過的網站所建立,也就是網址列所顯示的網站。第三方 Cookie 由其他網站所建立。這類網站通常是在你造訪的網站上提供部分內容 (例如廣告或圖片) 的其他網站。</translation>
 <translation id="3785308913036335955">顯示應用程式捷徑</translation>
 <translation id="3785727820640310185">已儲存這個網站的密碼</translation>
+<translation id="3787434344076711519">正在等待翻譯</translation>
 <translation id="3788301286821743879">無法啟動資訊站應用程式。</translation>
 <translation id="3788331399335602504">這些檔案</translation>
 <translation id="3788401245189148511">要求下列權限:</translation>
@@ -3233,6 +3240,7 @@
 <translation id="4036778507053569103">從伺服器下載的政策無效。</translation>
 <translation id="4037084878352560732">馬</translation>
 <translation id="403725336528835653">先試用看看</translation>
+<translation id="4040041015953651705">原文語言</translation>
 <translation id="4040105702484676956">要對 <ph name="SITE_NAME" /> 和其安裝的應用程式清除相關網站資料和權限嗎?</translation>
 <translation id="4042863763121826131">{NUM_PAGES,plural, =1{離開網頁}other{離開網頁}}</translation>
 <translation id="4043267180218562935">游標大小</translation>
@@ -4038,6 +4046,7 @@
 <translation id="4838170306476614339">查看手機上的相片、媒體和通知</translation>
 <translation id="4838836835474292213">已允許讀取剪貼簿</translation>
 <translation id="4838907349371614303">已更新密碼</translation>
+<translation id="4838958829619609362">所選內容的語言不是<ph name="LANGUAGE" /></translation>
 <translation id="4839303808932127586">將影片另存為(&amp;V)...</translation>
 <translation id="4840096453115567876">確定要結束無痕模式嗎?</translation>
 <translation id="4841741146571978176">必要的虛擬機器不存在。如要繼續,請嘗試設定「<ph name="VM_TYPE" />」</translation>
@@ -4809,6 +4818,7 @@
 <translation id="558918721941304263">正在載入應用程式...</translation>
 <translation id="5590418976913374224">裝置開啟時播放音效</translation>
 <translation id="5592595402373377407">目前還沒有足夠的資料。</translation>
+<translation id="5594899180331219722">選取檔案</translation>
 <translation id="5595307023264033512">網站使用的總儲存空間:<ph name="TOTAL_USAGE" /></translation>
 <translation id="5595485650161345191">編輯地址</translation>
 <translation id="5596627076506792578">更多選項</translation>
@@ -5039,6 +5049,7 @@
 <translation id="5834581999798853053">剩下 <ph name="TIME" /> 分鐘</translation>
 <translation id="5835486486592033703"><ph name="WINDOW_TITLE" /> - 攝影機或麥克風錄影/錄音中</translation>
 <translation id="583673505367439042">網站可以要求編輯裝置上的檔案和資料夾</translation>
+<translation id="5836999627049108525">原文語言</translation>
 <translation id="583756221537636748">充電盒</translation>
 <translation id="5840658767386246331">透過 Google 搜尋</translation>
 <translation id="5840680448799937675">一律在離線時分享檔案</translation>
@@ -5548,6 +5559,7 @@
 <translation id="6318944945640833942">偵測不到印表機,請再次輸入印表機位址。</translation>
 <translation id="6322370287306604163">使用指紋快速解鎖</translation>
 <translation id="6322559670748154781">這個檔案不是常見的下載項目,因此遭到進階保護功能封鎖</translation>
+<translation id="6324083483652497048">按一下即可允許這些擴充功能讀取及變更 <ph name="ORIGIN" />:</translation>
 <translation id="6324916366299863871">編輯捷徑</translation>
 <translation id="6325191661371220117">停用自動啟動功能</translation>
 <translation id="6326175484149238433">從 Chrome 中移除</translation>
@@ -6578,6 +6590,7 @@
 <translation id="7343372807593926528">請先說明問題再傳送意見回饋。</translation>
 <translation id="7344585835349671209">管理裝置上的 HTTPS/SSL 憑證</translation>
 <translation id="7345706641791090287">確認您的密碼</translation>
+<translation id="7345919885156673810">所選內容的語言不是<ph name="LANGUAGE" /></translation>
 <translation id="7346909386216857016">好,我知道了</translation>
 <translation id="7347452120014970266">這會清除 <ph name="ORIGIN_NAME" /> 儲存的所有資料和 Cookie,以及該網站所安裝的應用程式資料和 Cookie</translation>
 <translation id="7347751611463936647">如要使用這個擴充功能,請輸入「<ph name="EXTENSION_KEYWORD" />」,然後按 TAB 鍵,接著再輸入你的指令或搜尋項目。</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index f667419..0174d77 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -89,9 +89,12 @@
   <message name="IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_COMPLETE" desc="Success message when Live Caption files have completed downloading.">
     Speech files downloaded
   </message>
-  <message name="IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR" desc="Error message when Live Caption files can’t be downloaded.">
+  <message name="IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR" desc="Generic error message when Live Caption files can’t be downloaded.">
     Can't download speech files. Try again later.
   </message>
+  <message name="IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED" desc="Error message shown when a OS reboot is required to install the Live Caption files.">
+    Restart needed to install speech files.
+  </message>
   <message name="IDS_SETTINGS_ENABLE_CARET_BROWSING_TITLE" desc="Name of the setting to enable Caret Browsing, which allows you to move around any web page using a text caret.">
     Navigate pages with a text cursor
   </message>
@@ -3319,6 +3322,10 @@
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_LABEL" desc="Label for button to clear displayed site data">
     Clear displayed data
+  </message>  <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL" translateable="false" desc="Placeholder string for first party sets member count shown on site details and site entry">
+    {MEMBERS, plural,
+        =1 {Allowed for 1 <ph name="FPS_OWNER">$1<ex>google.com</ex></ph> site}
+        other {Allowed for {MEMBERS} <ph name="FPS_OWNER">{FPS_OWNER}<ex>google.com</ex></ph> sites}}
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON" translateable="false" desc="Placeholder string for first party sets show related sites button">
     Show related sites
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR.png.sha1
index f92ee07..bc92276 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR.png.sha1
@@ -1 +1 @@
-0d66a691ee919d120d9edc83caeb17079b8f4bab
\ No newline at end of file
+0d66a691ee919d120d9edc83caeb17079b8f4bab
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
new file mode 100644
index 0000000..85682e8
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED.png.sha1
@@ -0,0 +1 @@
+8897b4af3956e3dc3f19be91af8d757394fa0d7b
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index e6327fc..3e2e383 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4425,6 +4425,7 @@
       "//chrome/browser/ash/system_web_apps/types:types",
       "//chrome/browser/cart:mojo_bindings",
       "//chrome/browser/enterprise/connectors/analysis:features",
+      "//chrome/browser/enterprise/connectors/device_trust:prefs",
       "//chrome/browser/enterprise/signals:utils",
       "//chrome/browser/first_party_sets",
       "//chrome/browser/image_editor:image_editor_component_util",
@@ -4602,7 +4603,10 @@
         "upgrade_detector/upgrade_detector_impl.h",
       ]
 
-      deps += [ "//chrome/browser/enterprise/connectors/device_trust/key_management/browser" ]
+      deps += [
+        "//chrome/browser/enterprise/connectors/device_trust:features",
+        "//chrome/browser/enterprise/connectors/device_trust/key_management/browser",
+      ]
     }
     if (!is_chromeos_lacros) {
       sources += [
@@ -5460,6 +5464,8 @@
       "lacros/arc/arc_intent_helper_mojo_lacros.h",
       "lacros/automation_manager_lacros.cc",
       "lacros/automation_manager_lacros.h",
+      "lacros/browser_launcher.cc",
+      "lacros/browser_launcher.h",
       "lacros/browser_service_lacros.cc",
       "lacros/browser_service_lacros.h",
       "lacros/cert/cert_db_initializer.h",
@@ -6407,8 +6413,6 @@
       "download/download_status_updater_linux.cc",
       "first_run/upgrade_util_linux.cc",
       "first_run/upgrade_util_linux.h",
-      "themes/theme_service_aura_linux.cc",
-      "themes/theme_service_aura_linux.h",
     ]
     deps += [ "//chrome/app/theme:chrome_unscaled_resources_grit" ]
 
@@ -6709,6 +6713,8 @@
       "chrome_browser_main_extra_parts_linux.cc",
       "chrome_browser_main_extra_parts_linux.h",
       "obsolete_system/obsolete_system_linux.cc",
+      "themes/theme_service_aura_linux.cc",
+      "themes/theme_service_aura_linux.h",
     ]
   }
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 5a5c8049..c8dd188d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4639,6 +4639,10 @@
      flag_descriptions::kBackGestureRefactorAndroidName,
      flag_descriptions::kBackGestureRefactorAndroidDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kBackGestureRefactorAndroid)},
+    {"infobar-scroll-optimization",
+     flag_descriptions::kInfobarScrollOptimizationName,
+     flag_descriptions::kInfobarScrollOptimizationDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kInfobarScrollOptimization)},
 #endif  // BUILDFLAG(IS_ANDROID)
     {"disallow-doc-written-script-loads",
      flag_descriptions::kDisallowDocWrittenScriptsUiName,
@@ -8136,12 +8140,6 @@
      flag_descriptions::kUpdateHistoryEntryPointsInIncognitoDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kUpdateHistoryEntryPointsInIncognito)},
 
-    {"throttle-foreground-timers",
-     flag_descriptions::kThrottleForegroundTimersName,
-     flag_descriptions::kThrottleForegroundTimersDescription,
-     kOsDesktop | kOsAndroid,
-     FEATURE_VALUE_TYPE(blink::features::kThrottleForegroundTimers)},
-
     {"align-wakeups", flag_descriptions::kAlignWakeUpsName,
      flag_descriptions::kAlignWakeUpsDescription, kOsAll,
      FEATURE_VALUE_TYPE(base::kAlignWakeUps)},
@@ -8969,14 +8967,6 @@
      FEATURE_VALUE_TYPE(
          features::kBrokerFileOperationsOnDiskCacheInNetworkService)},
 
-    {"autofill-remove-card-expiry-from-downstream-suggestion",
-     flag_descriptions::kAutofillRemoveCardExpiryFromDownstreamSuggestionName,
-     flag_descriptions::
-         kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription,
-     kOsAll,
-     FEATURE_VALUE_TYPE(autofill::features::
-                            kAutofillRemoveCardExpiryFromDownstreamSuggestion)},
-
 #if !BUILDFLAG(IS_CHROMEOS)
     {"dm-token-deletion", flag_descriptions::kDmTokenDeletionName,
      flag_descriptions::kDmTokenDeletionDescription, kOsAll,
diff --git a/chrome/browser/apps/app_service/metrics/DEPS b/chrome/browser/apps/app_service/metrics/DEPS
index df77277..658ec2b 100644
--- a/chrome/browser/apps/app_service/metrics/DEPS
+++ b/chrome/browser/apps/app_service/metrics/DEPS
@@ -6,4 +6,7 @@
     "+ash/test/ash_test_base.h",
     "+ash/test/ash_test_helper.h",
   ],
+  "website_metrics\.cc": [
+    "+ash/shell.h",
+  ],
 }
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.cc b/chrome/browser/apps/app_service/metrics/website_metrics.cc
index ae862836e..141fbb4 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.cc
@@ -6,6 +6,7 @@
 
 #include <random>
 
+#include "ash/shell.h"
 #include "base/containers/contains.h"
 #include "base/json/values_util.h"
 #include "base/rand_util.h"
@@ -26,6 +27,7 @@
 #include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
 #include "ui/aura/window.h"
 #include "ui/wm/core/window_util.h"
+#include "ui/wm/public/activation_client.h"
 
 namespace {
 
@@ -65,18 +67,6 @@
   return nullptr;
 }
 
-wm::ActivationClient* GetActivationClientWithTabStripModel(
-    TabStripModel* tab_strip_model) {
-  auto* window = GetWindowWithTabStripModel(tab_strip_model);
-  if (!window) {
-    return nullptr;
-  }
-
-  auto* root_window = window->GetRootWindow();
-  DCHECK(root_window);
-  return wm::GetActivationClient(root_window);
-}
-
 }  // namespace
 
 namespace apps {
@@ -178,6 +168,8 @@
 
   auto* window = GetWindowWithBrowser(browser);
   if (window) {
+    observed_windows_.AddObservation(window);
+    MaybeObserveWindowActivationClient();
     window_to_web_contents_[window] = nullptr;
   }
 }
@@ -235,6 +227,14 @@
   dict.clear();
 }
 
+void WebsiteMetrics::OnWindowDestroying(aura::Window* window) {
+  if (base::Contains(window_to_web_contents_, window)) {
+    window_to_web_contents_.erase(window);
+  }
+  observed_windows_.RemoveObservation(window);
+  MaybeRemoveObserveWindowActivationClient();
+}
+
 void WebsiteMetrics::HistoryServiceBeingDeleted(
     history::HistoryService* history_service) {
   DCHECK(history_observation_.IsObservingSource(history_service));
@@ -266,6 +266,28 @@
   url_infos.swap(url_infos_);
 }
 
+void WebsiteMetrics::MaybeObserveWindowActivationClient() {
+  if (activation_client_observation_.IsObserving() ||
+      !ash::Shell::HasInstance()) {
+    return;
+  }
+
+  aura::Window* root_window = ash::Shell::Get()->GetPrimaryRootWindow();
+  if (root_window) {
+    auto* activation_client = wm::GetActivationClient(root_window);
+    if (activation_client) {
+      activation_client_observation_.Observe(activation_client);
+    }
+  }
+}
+
+void WebsiteMetrics::MaybeRemoveObserveWindowActivationClient() {
+  if (window_to_web_contents_.empty() &&
+      activation_client_observation_.IsObserving()) {
+    activation_client_observation_.Reset();
+  }
+}
+
 void WebsiteMetrics::OnTabStripModelChangeInsert(
     TabStripModel* tab_strip_model,
     const TabStripModelChange::Insert& insert,
@@ -273,17 +295,6 @@
   if (insert.contents.size() == 0) {
     return;
   }
-  // First tab attached.
-  if (tab_strip_model->count() == static_cast<int>(insert.contents.size())) {
-    // Observe the activation client of the root window of the browser's aura
-    // window if this is the first browser matching it (there is no other
-    // tracked browser matching it).
-    auto* activation_client =
-        GetActivationClientWithTabStripModel(tab_strip_model);
-    if (!activation_client_observations_.IsObservingSource(activation_client)) {
-      activation_client_observations_.AddObservation(activation_client);
-    }
-  }
 
   for (const auto& inserted_tab : insert.contents) {
     content::WebContents* contents = inserted_tab.contents;
@@ -307,20 +318,13 @@
 
   // Last tab detached.
   if (tab_strip_model->count() == 0) {
-    // Unobserve the activation client of the root window of the browser's aura
-    // window if the last browser using it was just removed.
-    auto* activation_client =
-        GetActivationClientWithTabStripModel(tab_strip_model);
-    if (activation_client_observations_.IsObservingSource(activation_client)) {
-      activation_client_observations_.RemoveObservation(activation_client);
-    }
-
     // The browser window will be closed, so remove the window and the web
     // contents.
     auto it = window_to_web_contents_.find(window);
     if (it != window_to_web_contents_.end()) {
       OnTabClosed(it->second);
       window_to_web_contents_.erase(it);
+      MaybeRemoveObserveWindowActivationClient();
     }
   }
 }
@@ -338,13 +342,16 @@
 
     // Clear `old_contents` from `window_to_web_contents_`.
     auto it = window_to_web_contents_.find(window);
-    if (it != window_to_web_contents_.end())
+    if (it != window_to_web_contents_.end()) {
       it->second = nullptr;
+    }
   }
 
   if (new_contents) {
-    SetTabActivated(new_contents);
     window_to_web_contents_[window] = new_contents;
+    if (wm::IsActiveWindow(window)) {
+      SetTabActivated(new_contents);
+    }
   }
 }
 
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.h b/chrome/browser/apps/app_service/metrics/website_metrics.h
index 6804bc8f..683d814 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.h
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.h
@@ -22,6 +22,8 @@
 #include "content/public/browser/page.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
 #include "ui/wm/public/activation_change_observer.h"
 #include "ui/wm/public/activation_client.h"
 #include "url/gurl.h"
@@ -54,6 +56,7 @@
 // TabStripModel to record the website usage time metrics.
 class WebsiteMetrics : public BrowserListObserver,
                        public TabStripModelObserver,
+                       public aura::WindowObserver,
                        public wm::ActivationChangeObserver,
                        public history::HistoryServiceObserver {
  public:
@@ -78,6 +81,9 @@
                          aura::Window* gained_active,
                          aura::Window* lost_active) override;
 
+  // aura::WindowObserver:
+  void OnWindowDestroying(aura::Window* window) override;
+
   // history::HistoryServiceObserver:
   void OnURLsDeleted(history::HistoryService* history_service,
                      const history::DeletionInfo& deletion_info) override;
@@ -146,6 +152,14 @@
     base::Value ConvertToValue() const;
   };
 
+  // Observes the root window's activation client for the OnWindowActivated
+  // callback.
+  void MaybeObserveWindowActivationClient();
+
+  // Removes observing the root window's activation client when the last browser
+  // window is closed.
+  void MaybeRemoveObserveWindowActivationClient();
+
   void OnTabStripModelChangeInsert(TabStripModel* tab_strip_model,
                                    const TabStripModelChange::Insert& insert,
                                    const TabStripSelectionChange& selection);
@@ -234,10 +248,11 @@
 
   bool should_record_ukm_from_pref_ = true;
 
-  // A set of observed activation clients for all browser's windows.
-  base::ScopedMultiSourceObservation<wm::ActivationClient,
-                                     wm::ActivationChangeObserver>
-      activation_client_observations_{this};
+  base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
+      observed_windows_{this};
+
+  base::ScopedObservation<wm::ActivationClient, wm::ActivationChangeObserver>
+      activation_client_observation_{this};
 
   base::ScopedObservation<history::HistoryService,
                           history::HistoryServiceObserver>
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
index c1c1be9..314ea268 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
@@ -703,11 +703,6 @@
   i = browser2->tab_strip_model()->GetIndexOfWebContents(tab_app4);
   browser2->tab_strip_model()->CloseWebContentsAt(
       i, TabCloseTypes::CLOSE_USER_GESTURE);
-  // Simulate the window's activated status is switched from `window2` to
-  // `window1`.
-  website_metrics()->OnWindowActivated(
-      wm::ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT,
-      window1, window2);
   EXPECT_EQ(1u, window_to_web_contents().size());
   EXPECT_EQ(1u, webcontents_to_observer_map().size());
   EXPECT_TRUE(base::Contains(webcontents_to_observer_map(),
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index e3ff76f..5fd9a468 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -1627,16 +1627,9 @@
   }
 }
 
-// This method calls App Service directly with a list of intent filters received
-// from ARC, rather than going through AppServiceProxy's
-// SetSupportedlinksPreference method. This is because recent changes to app
-// intent filters (such as after an install or update) may not have propagated
-// to AppServiceProxy's AppRegistryCache yet.
-// TODO(crbug.com/1265315): Use AppServiceProxy to set the preference once app
-// changes are synchronous within Ash.
 void ArcApps::OnArcSupportedLinksChanged(
-    const std::vector<arc::mojom::SupportedLinksPtr>& added,
-    const std::vector<arc::mojom::SupportedLinksPtr>& removed,
+    const std::vector<arc::mojom::SupportedLinksPackagePtr>& added,
+    const std::vector<arc::mojom::SupportedLinksPackagePtr>& removed,
     arc::mojom::SupportedLinkChangeSource source) {
   mojo::Remote<apps::mojom::AppService>& app_service = proxy()->AppService();
   if (!app_service.is_bound()) {
@@ -1651,7 +1644,7 @@
   for (const auto& supported_link : added) {
     std::string app_id =
         prefs->GetAppIdByPackageName(supported_link->package_name);
-    if (app_id.empty() || !supported_link->filters.has_value()) {
+    if (app_id.empty()) {
       continue;
     }
 
@@ -1670,16 +1663,7 @@
       continue;
     }
 
-    apps::IntentFilters app_service_filters;
-    for (const auto& arc_filter : supported_link->filters.value()) {
-      auto converted = apps_util::CreateIntentFilterForArc(arc_filter);
-      if (apps_util::IsSupportedLinkForApp(app_id, converted)) {
-        app_service_filters.push_back(std::move(converted));
-      }
-    }
-
-    proxy()->SetSupportedLinksPreference(app_id,
-                                         std::move(app_service_filters));
+    proxy()->SetSupportedLinksPreference(app_id);
   }
 
   for (const auto& supported_link : removed) {
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.h b/chrome/browser/apps/app_service/publishers/arc_apps.h
index 9838a58..5e5d302 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.h
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.h
@@ -209,8 +209,8 @@
   void OnIntentFiltersUpdated(
       const absl::optional<std::string>& package_name) override;
   void OnArcSupportedLinksChanged(
-      const std::vector<arc::mojom::SupportedLinksPtr>& added,
-      const std::vector<arc::mojom::SupportedLinksPtr>& removed,
+      const std::vector<arc::mojom::SupportedLinksPackagePtr>& added,
+      const std::vector<arc::mojom::SupportedLinksPackagePtr>& removed,
       arc::mojom::SupportedLinkChangeSource source) override;
 
   // ash::ArcNotificationsHostInitializer::Observer overrides.
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
index ad4abfce..d2b7f35e 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
@@ -213,6 +213,16 @@
         ->PreferredAppsList();
   }
 
+  std::vector<arc::mojom::SupportedLinksPackagePtr> CreateSupportedLinks(
+      const std::string& package_name) {
+    std::vector<arc::mojom::SupportedLinksPackagePtr> result;
+    auto link = arc::mojom::SupportedLinksPackage::New();
+    link->package_name = package_name;
+    result.push_back(std::move(link));
+
+    return result;
+  }
+
  private:
   content::BrowserTaskEnvironment task_environment_;
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -240,11 +250,8 @@
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
-  std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(absl::in_place, package_name,
-                           CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links), {},
+      CreateSupportedLinks(package_name), {},
       arc::mojom::SupportedLinkChangeSource::kArcSystem);
 
   FlushMojoCalls();
@@ -293,11 +300,8 @@
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
-  std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(absl::in_place, package_name,
-                           CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links), {},
+      CreateSupportedLinks(package_name), {},
       arc::mojom::SupportedLinkChangeSource::kArcSystem);
 
   FlushMojoCalls();
@@ -323,11 +327,8 @@
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
-  std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(absl::in_place, package_name,
-                           CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links), {},
+      CreateSupportedLinks(package_name), {},
       arc::mojom::SupportedLinkChangeSource::kArcSystem);
   FlushMojoCalls();
 
@@ -339,12 +340,8 @@
       package_name,
       CreateFilterList(package_name, {kTestAuthority, kTestAuthority2}));
   VerifyIntentFilters(app_id, {kTestAuthority, kTestAuthority2});
-  std::vector<arc::mojom::SupportedLinksPtr> added_links2;
-  added_links2.emplace_back(
-      absl::in_place, package_name,
-      CreateFilterList(package_name, {kTestAuthority, kTestAuthority2}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links2), {},
+      CreateSupportedLinks(package_name), {},
       arc::mojom::SupportedLinkChangeSource::kArcSystem);
   FlushMojoCalls();
 
@@ -370,11 +367,8 @@
   // installed.
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       package_name, CreateFilterList(package_name, {kTestAuthority}));
-  std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(absl::in_place, package_name,
-                           CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links), {},
+      CreateSupportedLinks(package_name), {},
       arc::mojom::SupportedLinkChangeSource::kUserPreference);
 
   FlushMojoCalls();
@@ -402,12 +396,8 @@
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       arc::kPlayStorePackage,
       CreateFilterList(arc::kPlayStorePackage, {kTestAuthority}));
-  std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(
-      absl::in_place, arc::kPlayStorePackage,
-      CreateFilterList(arc::kPlayStorePackage, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
-      std::move(added_links), {},
+      CreateSupportedLinks(arc::kPlayStorePackage), {},
       arc::mojom::SupportedLinkChangeSource::kArcSystem);
 
   FlushMojoCalls();
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.cc b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
index 41c6a99..c2e8388 100644
--- a/chrome/browser/apps/app_service/publishers/borealis_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
@@ -24,7 +24,6 @@
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/permission_utils.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -352,6 +351,27 @@
       .Uninstall(app_id, base::DoNothing());
 }
 
+void BorealisApps::GetMenuModel(const std::string& app_id,
+                                MenuType menu_type,
+                                int64_t display_id,
+                                base::OnceCallback<void(MenuItems)> callback) {
+  MenuItems menu_items;
+
+  if (borealis::BorealisService::GetForProfile(profile_)
+          ->Features()
+          .IsEnabled()) {
+    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
+  }
+
+  if (ShouldAddCloseItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+  }
+
+  // TODO(b/162562622): Menu models for borealis apps.
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void BorealisApps::Connect(
     mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
     apps::mojom::ConnectOptionsPtr opts) {
@@ -399,22 +419,8 @@
                                 apps::mojom::MenuType menu_type,
                                 int64_t display_id,
                                 GetMenuModelCallback callback) {
-  MenuItems menu_items;
-
-  if (borealis::BorealisService::GetForProfile(profile_)
-          ->Features()
-          .IsEnabled()) {
-    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
-  }
-
-  if (ShouldAddCloseItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                         profile_)) {
-    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
-  }
-
-  // TODO(b/162562622): Menu models for borealis apps.
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 void BorealisApps::OnRegistryUpdated(
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.h b/chrome/browser/apps/app_service/publishers/borealis_apps.h
index 726fec3..04f37e5 100644
--- a/chrome/browser/apps/app_service/publishers/borealis_apps.h
+++ b/chrome/browser/apps/app_service/publishers/borealis_apps.h
@@ -18,6 +18,7 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/permission.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
@@ -91,6 +92,10 @@
                  UninstallSource uninstall_source,
                  bool clear_site_data,
                  bool report_abuse) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::PublisherBase overrides.
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
index b99f656..22586ec 100644
--- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/services/app_service/public/cpp/app_types.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -163,6 +162,25 @@
   std::move(callback).Run(LaunchResult());
 }
 
+void BuiltInChromeOsApps::GetMenuModel(
+    const std::string& app_id,
+    MenuType menu_type,
+    int64_t display_id,
+    base::OnceCallback<void(MenuItems)> callback) {
+  MenuItems menu_items;
+
+  if (ShouldAddOpenItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
+                   menu_items);
+  }
+
+  if (ShouldAddCloseItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+  }
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void BuiltInChromeOsApps::Connect(
     mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
     apps::mojom::ConnectOptionsPtr opts) {
@@ -202,20 +220,8 @@
                                        apps::mojom::MenuType menu_type,
                                        int64_t display_id,
                                        GetMenuModelCallback callback) {
-  apps::MenuItems menu_items;
-
-  if (ShouldAddOpenItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                        profile_)) {
-    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
-                   menu_items);
-  }
-
-  if (ShouldAddCloseItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                         profile_)) {
-    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
-  }
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h
index f1c6e8f9..0440a9b 100644
--- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h
+++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/apps/app_service/launch_result_type.h"
 #include "chrome/browser/apps/app_service/publishers/app_publisher.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -58,6 +59,10 @@
               WindowInfoPtr window_info) override;
   void LaunchAppWithParams(AppLaunchParams&& params,
                            LaunchCallback callback) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::mojom::Publisher overrides.
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.cc b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
index 41888eb..35ad639 100644
--- a/chrome/browser/apps/app_service/publishers/crostini_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
@@ -33,7 +33,6 @@
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 #include "storage/browser/file_system/file_system_context.h"
@@ -53,11 +52,11 @@
 const char kTextWildcardMimeType[] = "text/*";
 
 bool ShouldShowDisplayDensityMenuItem(const std::string& app_id,
-                                      apps::mojom::MenuType menu_type,
+                                      apps::MenuType menu_type,
                                       int64_t display_id) {
   // The default terminal app is crosh in a Chrome window and it doesn't run in
   // the Crostini container so it doesn't support display density the same way.
-  if (menu_type != apps::mojom::MenuType::kShelf) {
+  if (menu_type != apps::MenuType::kShelf) {
     return false;
   }
 
@@ -233,6 +232,51 @@
       ->QueueUninstallApplication(app_id);
 }
 
+void CrostiniApps::GetMenuModel(const std::string& app_id,
+                                MenuType menu_type,
+                                int64_t display_id,
+                                base::OnceCallback<void(MenuItems)> callback) {
+  MenuItems menu_items;
+
+  if (menu_type == MenuType::kShelf) {
+    AddCommandItem(ash::APP_CONTEXT_MENU_NEW_WINDOW, IDS_APP_LIST_NEW_WINDOW,
+                   menu_items);
+  }
+
+  if (crostini::IsUninstallable(profile_, app_id)) {
+    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
+  }
+
+  if (ShouldAddOpenItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
+                   menu_items);
+  }
+
+  if (ShouldAddCloseItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+  }
+
+  // Offer users the ability to toggle per-application UI scaling.
+  // Some apps have high-density display support and do not require scaling
+  // to match the system display density, but others are density-unaware and
+  // look better when scaled to match the display density.
+  if (ShouldShowDisplayDensityMenuItem(app_id, menu_type, display_id)) {
+    absl::optional<guest_os::GuestOsRegistryService::Registration>
+        registration = registry_->GetRegistration(app_id);
+    if (registration) {
+      if (registration->IsScaled()) {
+        AddCommandItem(ash::CROSTINI_USE_HIGH_DENSITY,
+                       IDS_CROSTINI_USE_HIGH_DENSITY, menu_items);
+      } else {
+        AddCommandItem(ash::CROSTINI_USE_LOW_DENSITY,
+                       IDS_CROSTINI_USE_LOW_DENSITY, menu_items);
+      }
+    }
+  }
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void CrostiniApps::Connect(
     mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
     apps::mojom::ConnectOptionsPtr opts) {
@@ -302,47 +346,8 @@
                                 apps::mojom::MenuType menu_type,
                                 int64_t display_id,
                                 GetMenuModelCallback callback) {
-  MenuItems menu_items;
-
-  if (menu_type == apps::mojom::MenuType::kShelf) {
-    AddCommandItem(ash::APP_CONTEXT_MENU_NEW_WINDOW, IDS_APP_LIST_NEW_WINDOW,
-                   menu_items);
-  }
-
-  if (crostini::IsUninstallable(profile_, app_id)) {
-    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
-  }
-
-  if (ShouldAddOpenItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                        profile_)) {
-    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
-                   menu_items);
-  }
-
-  if (ShouldAddCloseItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                         profile_)) {
-    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
-  }
-
-  // Offer users the ability to toggle per-application UI scaling.
-  // Some apps have high-density display support and do not require scaling
-  // to match the system display density, but others are density-unaware and
-  // look better when scaled to match the display density.
-  if (ShouldShowDisplayDensityMenuItem(app_id, menu_type, display_id)) {
-    absl::optional<guest_os::GuestOsRegistryService::Registration>
-        registration = registry_->GetRegistration(app_id);
-    if (registration) {
-      if (registration->IsScaled()) {
-        AddCommandItem(ash::CROSTINI_USE_HIGH_DENSITY,
-                       IDS_CROSTINI_USE_HIGH_DENSITY, menu_items);
-      } else {
-        AddCommandItem(ash::CROSTINI_USE_LOW_DENSITY,
-                       IDS_CROSTINI_USE_LOW_DENSITY, menu_items);
-      }
-    }
-  }
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 void CrostiniApps::OnRegistryUpdated(
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.h b/chrome/browser/apps/app_service/publishers/crostini_apps.h
index 4bbea72f..819d94b 100644
--- a/chrome/browser/apps/app_service/publishers/crostini_apps.h
+++ b/chrome/browser/apps/app_service/publishers/crostini_apps.h
@@ -19,6 +19,7 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -79,6 +80,10 @@
                  UninstallSource uninstall_source,
                  bool clear_site_data,
                  bool report_abuse) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::mojom::Publisher overrides.
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 8b3c38a2..f7c5dd77 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -72,7 +72,6 @@
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "content/public/browser/clear_site_data_utils.h"
 #include "extensions/browser/app_window/app_window.h"
@@ -246,6 +245,61 @@
   }
 }
 
+void ExtensionAppsChromeOs::GetMenuModel(
+    const std::string& app_id,
+    MenuType menu_type,
+    int64_t display_id,
+    base::OnceCallback<void(MenuItems)> callback) {
+  MenuItems menu_items;
+  const auto* extension = MaybeGetExtension(app_id);
+  if (!extension) {
+    std::move(callback).Run(std::move(menu_items));
+    return;
+  }
+
+  if (app_id == app_constants::kChromeAppId) {
+    std::move(callback).Run(CreateBrowserMenuItems(profile()));
+    return;
+  }
+
+  bool is_platform_app = extension->is_platform_app();
+  if (!is_platform_app) {
+    CreateOpenNewSubmenu(
+        extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile()),
+                                  extension) ==
+                extensions::LaunchType::LAUNCH_TYPE_WINDOW
+            ? IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW
+            : IDS_APP_LIST_CONTEXT_MENU_NEW_TAB,
+        menu_items);
+  }
+
+  if (!is_platform_app && menu_type == MenuType::kAppList &&
+      extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile()) &&
+      extensions::OptionsPageInfo::HasOptionsPage(extension)) {
+    AddCommandItem(ash::OPTIONS, IDS_NEW_TAB_APP_OPTIONS, menu_items);
+  }
+
+  if (menu_type == MenuType::kShelf &&
+      instance_registry_->ContainsAppId(app_id)) {
+    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+  }
+
+  const extensions::ManagementPolicy* policy =
+      extensions::ExtensionSystem::Get(profile())->management_policy();
+  DCHECK(policy);
+  if (policy->UserMayModifySettings(extension, nullptr) &&
+      !policy->MustRemainInstalled(extension, nullptr)) {
+    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
+  }
+
+  if (extension->ShouldDisplayInAppLauncher()) {
+    AddCommandItem(ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO,
+                   menu_items);
+  }
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void ExtensionAppsChromeOs::LaunchAppWithIntent(
     const std::string& app_id,
     int32_t event_flags,
@@ -363,55 +417,8 @@
                                          apps::mojom::MenuType menu_type,
                                          int64_t display_id,
                                          GetMenuModelCallback callback) {
-  MenuItems menu_items;
-  const auto* extension = MaybeGetExtension(app_id);
-  if (!extension) {
-    std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
-    return;
-  }
-
-  if (app_id == app_constants::kChromeAppId) {
-    std::move(callback).Run(
-        ConvertMenuItemsToMojomMenuItems(CreateBrowserMenuItems(profile())));
-    return;
-  }
-
-  bool is_platform_app = extension->is_platform_app();
-  if (!is_platform_app) {
-    CreateOpenNewSubmenu(
-        extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile()),
-                                  extension) ==
-                extensions::LaunchType::LAUNCH_TYPE_WINDOW
-            ? IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW
-            : IDS_APP_LIST_CONTEXT_MENU_NEW_TAB,
-        menu_items);
-  }
-
-  if (!is_platform_app && menu_type == apps::mojom::MenuType::kAppList &&
-      extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile()) &&
-      extensions::OptionsPageInfo::HasOptionsPage(extension)) {
-    AddCommandItem(ash::OPTIONS, IDS_NEW_TAB_APP_OPTIONS, menu_items);
-  }
-
-  if (menu_type == apps::mojom::MenuType::kShelf &&
-      instance_registry_->ContainsAppId(app_id)) {
-    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
-  }
-
-  const extensions::ManagementPolicy* policy =
-      extensions::ExtensionSystem::Get(profile())->management_policy();
-  DCHECK(policy);
-  if (policy->UserMayModifySettings(extension, nullptr) &&
-      !policy->MustRemainInstalled(extension, nullptr)) {
-    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
-  }
-
-  if (extension->ShouldDisplayInAppLauncher()) {
-    AddCommandItem(ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO,
-                   menu_items);
-  }
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 void ExtensionAppsChromeOs::OnAppWindowAdded(
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h
index c416f01..0e617610 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.h
@@ -27,6 +27,7 @@
 #include "components/services/app_service/public/cpp/instance.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
 #include "components/services/app_service/public/cpp/intent.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -83,6 +84,10 @@
                            LaunchSource launch_source,
                            WindowInfoPtr window_info,
                            base::OnceCallback<void(bool)> callback) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::mojom::Publisher overrides.
   void LaunchAppWithIntent(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
index 2433ae1f..7c79511 100644
--- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
 #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
@@ -26,7 +27,7 @@
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
-#include "components/services/app_service/public/cpp/menu.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/services/app_service/public/cpp/permission_utils.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -158,6 +159,25 @@
   return app;
 }
 
+// Create a file intent filter with extension type conditions for App Service.
+apps::IntentFilters CreateIntentFilterForPluginVm(
+    const guest_os::GuestOsRegistryService::Registration& registration) {
+  const std::set<std::string>& extension_types_set = registration.Extensions();
+  if (extension_types_set.empty()) {
+    return {};
+  }
+  std::vector<std::string> extension_types(extension_types_set.begin(),
+                                           extension_types_set.end());
+  apps::IntentFilters intent_filters;
+  intent_filters.push_back(apps_util::CreateFileFilter(
+      {apps_util::kIntentActionView}, /*mime_types=*/{}, extension_types,
+      // TODO(crbug/1349974): Remove activity_name when default file handling
+      // preferences for Files App are migrated.
+      /*activity_name=*/apps_util::kGuestOsActivityName));
+
+  return intent_filters;
+}
+
 }  // namespace
 
 namespace apps {
@@ -172,12 +192,6 @@
     return;
   }
 
-  registry_ = guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_);
-  if (!registry_) {
-    return;
-  }
-  registry_->AddObserver(this);
-
   // Register for Plugin VM changes to policy and installed state, so that we
   // can update the availability and status of the Plugin VM app. Unretained is
   // safe as these are cleaned up upon destruction.
@@ -226,9 +240,11 @@
 }
 
 void PluginVmApps::Initialize() {
+  registry_ = guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_);
   if (!registry_) {
     return;
   }
+  registry_->AddObserver(this);
 
   PublisherBase::Initialize(proxy()->AppService(),
                             apps::mojom::AppType::kPluginVm);
@@ -302,6 +318,30 @@
       ->UninstallPluginVm();
 }
 
+void PluginVmApps::GetMenuModel(const std::string& app_id,
+                                MenuType menu_type,
+                                int64_t display_id,
+                                base::OnceCallback<void(MenuItems)> callback) {
+  MenuItems menu_items;
+
+  if (ShouldAddOpenItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
+                   menu_items);
+  }
+
+  if (ShouldAddCloseItem(app_id, menu_type, profile_)) {
+    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+  }
+
+  if (app_id == plugin_vm::kPluginVmShelfAppId &&
+      plugin_vm::IsPluginVmRunning(profile_)) {
+    AddCommandItem(ash::SHUTDOWN_GUEST_OS, IDS_PLUGIN_VM_SHUT_DOWN_MENU_ITEM,
+                   menu_items);
+  }
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void PluginVmApps::Launch(const std::string& app_id,
                           int32_t event_flags,
                           apps::mojom::LaunchSource launch_source,
@@ -335,26 +375,8 @@
                                 apps::mojom::MenuType menu_type,
                                 int64_t display_id,
                                 GetMenuModelCallback callback) {
-  apps::MenuItems menu_items;
-
-  if (ShouldAddOpenItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                        profile_)) {
-    AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
-                   menu_items);
-  }
-
-  if (ShouldAddCloseItem(app_id, ConvertMojomMenuTypeToMenuType(menu_type),
-                         profile_)) {
-    AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
-  }
-
-  if (app_id == plugin_vm::kPluginVmShelfAppId &&
-      plugin_vm::IsPluginVmRunning(profile_)) {
-    AddCommandItem(ash::SHUTDOWN_GUEST_OS, IDS_PLUGIN_VM_SHUT_DOWN_MENU_ITEM,
-                   menu_items);
-  }
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 void PluginVmApps::OnRegistryUpdated(
@@ -418,6 +440,8 @@
   app->show_in_shelf = false;
   app->show_in_management = false;
   app->allow_uninstall = false;
+  app->handles_intents = true;
+  app->intent_filters = CreateIntentFilterForPluginVm(registration);
 
   // TODO(crbug.com/1253250): Add other fields for the App struct.
   return app;
@@ -446,6 +470,9 @@
   app->show_in_shelf = apps::mojom::OptionalBool::kFalse;
   app->show_in_management = apps::mojom::OptionalBool::kFalse;
   app->allow_uninstall = apps::mojom::OptionalBool::kFalse;
+  app->handles_intents = apps::mojom::OptionalBool::kTrue;
+  app->intent_filters = ConvertIntentFiltersToMojomIntentFilters(
+      CreateIntentFilterForPluginVm(registration));
 
   return app;
 }
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h
index 139c03d..ee05301f 100644
--- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h
+++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h
@@ -17,6 +17,7 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/permission.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
@@ -74,6 +75,10 @@
                  UninstallSource uninstall_source,
                  bool clear_site_data,
                  bool report_abuse) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::PublisherBase overrides.
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps_unittest.cc b/chrome/browser/apps/app_service/publishers/plugin_vm_apps_unittest.cc
new file mode 100644
index 0000000..08113545
--- /dev/null
+++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps_unittest.cc
@@ -0,0 +1,120 @@
+// 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/publishers/plugin_vm_apps.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
+#include "chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/services/app_service/public/cpp/app_registry_cache.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace apps {
+
+class PluginVmAppsTest : public testing::Test {
+ public:
+  PluginVmAppsTest()
+      : task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD) {}
+
+  plugin_vm::PluginVmTestHelper* test_helper() { return test_helper_.get(); }
+
+  AppServiceProxy* app_service_proxy() { return app_service_proxy_; }
+
+  TestingProfile* profile() { return profile_.get(); }
+
+  void SetUp() override {
+    ash::CiceroneClient::InitializeFake();
+    profile_ = std::make_unique<TestingProfile>();
+    app_service_proxy_ = AppServiceProxyFactory::GetForProfile(profile_.get());
+    web_app::test::AwaitStartWebAppProviderAndSubsystems(profile_.get());
+    test_helper_ =
+        std::make_unique<plugin_vm::PluginVmTestHelper>(profile_.get());
+    test_helper_->AllowPluginVm();
+  }
+
+  void TearDown() override {
+    test_helper_.reset();
+    profile_.reset();
+    ash::CiceroneClient::Shutdown();
+  }
+
+  // Set up the test Crostini app for our desired mime types.
+  std::string AddPluginVmAppWithExtensionTypes(
+      std::string app_id,
+      std::string app_name,
+      std::vector<std::string> extension_types) {
+    vm_tools::apps::App app;
+    for (std::string extension_type : extension_types) {
+      app.add_extensions(extension_type);
+    }
+    app.set_desktop_file_id(app_id);
+    vm_tools::apps::App::LocaleString::Entry* entry =
+        app.mutable_name()->add_values();
+    entry->set_locale(std::string());
+    entry->set_value(app_name);
+    test_helper()->AddApp(app);
+    return plugin_vm::PluginVmTestHelper::GenerateAppId(app.desktop_file_id());
+  }
+
+  // Get the registered intent filters for the app in App Service.
+  std::vector<std::unique_ptr<IntentFilter>> GetIntentFiltersForApp(
+      std::string app_id) {
+    std::vector<std::unique_ptr<IntentFilter>> intent_filters;
+    app_service_proxy()->AppRegistryCache().ForOneApp(
+        app_id, [&intent_filters](const AppUpdate& update) {
+          intent_filters = update.IntentFilters();
+        });
+    return intent_filters;
+  }
+
+ private:
+  AppServiceProxy* app_service_proxy_ = nullptr;
+  content::BrowserTaskEnvironment task_environment_;
+  std::unique_ptr<TestingProfile> profile_;
+  std::unique_ptr<plugin_vm::PluginVmTestHelper> test_helper_;
+};
+
+TEST_F(PluginVmAppsTest, AppServiceHasPluginVmIntentFilters) {
+  std::vector<std::string> extension_types = {"csv", "txt"};
+
+  std::string app_id =
+      AddPluginVmAppWithExtensionTypes("app_id", "app_name", extension_types);
+  std::vector<std::unique_ptr<IntentFilter>> intent_filters =
+      GetIntentFiltersForApp(app_id);
+
+  EXPECT_EQ(intent_filters.size(), 1U);
+  EXPECT_EQ(intent_filters[0]->conditions.size(), 2U);
+
+  // Check that the filter has the correct action type.
+  {
+    const Condition* condition = intent_filters[0]->conditions[0].get();
+    ASSERT_EQ(condition->condition_type, ConditionType::kAction);
+    EXPECT_EQ(condition->condition_values.size(), 1U);
+    ASSERT_EQ(condition->condition_values[0]->match_type,
+              PatternMatchType::kLiteral);
+    ASSERT_EQ(condition->condition_values[0]->value,
+              apps_util::kIntentActionView);
+  }
+
+  // Check that the filter has all our extension types.
+  {
+    const Condition* condition = intent_filters[0]->conditions[1].get();
+    ASSERT_EQ(condition->condition_type, ConditionType::kFile);
+    EXPECT_EQ(condition->condition_values.size(), 2U);
+    ASSERT_EQ(condition->condition_values[0]->value, extension_types[0]);
+    ASSERT_EQ(condition->condition_values[1]->value, extension_types[1]);
+  }
+}
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.cc b/chrome/browser/apps/app_service/publishers/remote_apps.cc
index fbea8e6..7f7784f 100644
--- a/chrome/browser/apps/app_service/publishers/remote_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/remote_apps.cc
@@ -144,6 +144,13 @@
   std::move(callback).Run(LaunchResult());
 }
 
+void RemoteApps::GetMenuModel(const std::string& app_id,
+                              MenuType menu_type,
+                              int64_t display_id,
+                              base::OnceCallback<void(MenuItems)> callback) {
+  std::move(callback).Run(delegate_->GetMenuModel(app_id));
+}
+
 void RemoteApps::Connect(
     mojo::PendingRemote<mojom::Subscriber> subscriber_remote,
     mojom::ConnectOptionsPtr opts) {
@@ -170,7 +177,8 @@
                               mojom::MenuType menu_type,
                               int64_t display_id,
                               GetMenuModelCallback callback) {
-  std::move(callback).Run(delegate_->GetMenuModel(app_id));
+  std::move(callback).Run(
+      ConvertMenuItemsToMojomMenuItems(delegate_->GetMenuModel(app_id)));
 }
 
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.h b/chrome/browser/apps/app_service/publishers/remote_apps.h
index 443701c..60aaea9 100644
--- a/chrome/browser/apps/app_service/publishers/remote_apps.h
+++ b/chrome/browser/apps/app_service/publishers/remote_apps.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/ash/remote_apps/remote_apps_model.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -59,7 +60,7 @@
 
     virtual void LaunchApp(const std::string& id) = 0;
 
-    virtual apps::mojom::MenuItemsPtr GetMenuModel(const std::string& id) = 0;
+    virtual MenuItems GetMenuModel(const std::string& id) = 0;
   };
 
   RemoteApps(AppServiceProxy* proxy, Delegate* delegate);
@@ -95,6 +96,10 @@
               WindowInfoPtr window_info) override;
   void LaunchAppWithParams(AppLaunchParams&& params,
                            LaunchCallback callback) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::PublisherBase:
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index 1b608593..f5b9d33 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -22,7 +22,6 @@
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/app_constants/constants.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/views/widget/widget.h"
 
@@ -176,6 +175,14 @@
   std::move(callback).Run(LaunchResult());
 }
 
+void StandaloneBrowserApps::GetMenuModel(
+    const std::string& app_id,
+    MenuType menu_type,
+    int64_t display_id,
+    base::OnceCallback<void(MenuItems)> callback) {
+  std::move(callback).Run(CreateBrowserMenuItems(profile_));
+}
+
 void StandaloneBrowserApps::Connect(
     mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
     apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
index 36b8e99..52e342e 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
@@ -14,6 +14,7 @@
 #include "chrome/browser/ash/crosapi/browser_manager_observer.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom-forward.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -74,6 +75,10 @@
               WindowInfoPtr window_info) override;
   void LaunchAppWithParams(AppLaunchParams&& params,
                            LaunchCallback callback) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
 
   // apps::PublisherBase:
   void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
index 7d9f03d..1934ee4 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
@@ -27,7 +27,6 @@
 #include "components/app_restore/full_restore_utils.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/intent.h"
-#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 
 namespace apps {
@@ -253,6 +252,53 @@
                          report_abuse);
 }
 
+void StandaloneBrowserExtensionApps::GetMenuModel(
+    const std::string& app_id,
+    MenuType menu_type,
+    int64_t display_id,
+    base::OnceCallback<void(MenuItems)> callback) {
+  bool is_platform_app = true;
+  bool can_use_uninstall = false;
+  bool show_app_info = false;
+  WindowMode display_mode = WindowMode::kUnknown;
+  proxy()->AppRegistryCache().ForOneApp(
+      app_id, [&is_platform_app, &can_use_uninstall, &show_app_info,
+               &display_mode](const apps::AppUpdate& update) {
+        is_platform_app = update.IsPlatformApp().value_or(true);
+        can_use_uninstall = update.AllowUninstall().value_or(false);
+        show_app_info = update.ShowInManagement().value_or(false);
+        display_mode = update.WindowMode();
+      });
+
+  // This provides the context menu for hosted app in standalone browser.
+  // Note: The context menu for platform app in standalone browser is provided
+  // by StandaloneBrowserExtensionAppContextMenu.
+  DCHECK(!is_platform_app);
+
+  MenuItems menu_items;
+  CreateOpenNewSubmenu(display_mode == WindowMode::kWindow
+                           ? IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW
+                           : IDS_APP_LIST_CONTEXT_MENU_NEW_TAB,
+                       menu_items);
+
+  if (menu_type == MenuType::kShelf) {
+    if (proxy()->BrowserAppInstanceRegistry()->IsAppRunning(app_id)) {
+      AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, menu_items);
+    }
+  }
+
+  if (can_use_uninstall) {
+    AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, menu_items);
+  }
+
+  if (show_app_info) {
+    AddCommandItem(ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO,
+                   menu_items);
+  }
+
+  std::move(callback).Run(std::move(menu_items));
+}
+
 void StandaloneBrowserExtensionApps::SetWindowMode(const std::string& app_id,
                                                    WindowMode window_mode) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
@@ -382,48 +428,8 @@
     apps::mojom::MenuType menu_type,
     int64_t display_id,
     GetMenuModelCallback callback) {
-  bool is_platform_app = true;
-  bool can_use_uninstall = false;
-  bool show_app_info = false;
-  WindowMode display_mode = WindowMode::kUnknown;
-  proxy()->AppRegistryCache().ForOneApp(
-      app_id, [&is_platform_app, &can_use_uninstall, &show_app_info,
-               &display_mode](const apps::AppUpdate& update) {
-        is_platform_app = update.IsPlatformApp().value_or(true);
-        can_use_uninstall = update.AllowUninstall().value_or(false);
-        show_app_info = update.ShowInManagement().value_or(false);
-        display_mode = update.WindowMode();
-      });
-
-  // This provides the context menu for hosted app in standalone browser.
-  // Note: The context menu for platform app in standalone browser is provided
-  // by StandaloneBrowserExtensionAppContextMenu.
-  DCHECK(!is_platform_app);
-
-  apps::MenuItems menu_items;
-  apps::CreateOpenNewSubmenu(display_mode == WindowMode::kWindow
-                                 ? IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW
-                                 : IDS_APP_LIST_CONTEXT_MENU_NEW_TAB,
-                             menu_items);
-
-  if (menu_type == apps::mojom::MenuType::kShelf) {
-    if (proxy()->BrowserAppInstanceRegistry()->IsAppRunning(app_id)) {
-      apps::AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE,
-                           menu_items);
-    }
-  }
-
-  if (can_use_uninstall) {
-    apps::AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM,
-                         menu_items);
-  }
-
-  if (show_app_info) {
-    apps::AddCommandItem(ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO,
-                         menu_items);
-  }
-
-  std::move(callback).Run(ConvertMenuItemsToMojomMenuItems(menu_items));
+  GetMenuModel(app_id, ConvertMojomMenuTypeToMenuType(menu_type), display_id,
+               MenuItemsToMojomMenuItemsCallback(std::move(callback)));
 }
 
 void StandaloneBrowserExtensionApps::StopApp(const std::string& app_id) {
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
index 55b0512..6090a80c4 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
@@ -20,6 +20,7 @@
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
+#include "components/services/app_service/public/cpp/menu.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom-forward.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -104,6 +105,10 @@
                  UninstallSource uninstall_source,
                  bool clear_site_data,
                  bool report_abuse) override;
+  void GetMenuModel(const std::string& app_id,
+                    MenuType menu_type,
+                    int64_t display_id,
+                    base::OnceCallback<void(MenuItems)> callback);
   void SetWindowMode(const std::string& app_id,
                      WindowMode window_mode) override;
 
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 2ce9cd3a..adc73b29 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -320,8 +320,8 @@
 // Simulate real click with delay between mouse down and up.
 class LeftMouseClick {
  public:
-  explicit LeftMouseClick(content::WebContents* web_contents)
-      : web_contents_(web_contents),
+  explicit LeftMouseClick(content::RenderFrameHost* render_frame_host)
+      : render_frame_host_(render_frame_host),
         mouse_event_(blink::WebInputEvent::Type::kMouseDown,
                      blink::WebInputEvent::kNoModifiers,
                      blink::WebInputEvent::GetStaticTimeStampForTests()) {
@@ -339,14 +339,12 @@
     click_completed_ = false;
     mouse_event_.SetType(blink::WebInputEvent::Type::kMouseDown);
     mouse_event_.SetPositionInWidget(point.x(), point.y());
-    const gfx::Rect offset = web_contents_->GetContainerBounds();
+    const gfx::Rect offset =
+        render_frame_host_->GetRenderWidgetHost()->GetView()->GetViewBounds();
     mouse_event_.SetPositionInScreen(point.x() + offset.x(),
                                      point.y() + offset.y());
     mouse_event_.click_count = 1;
-    web_contents_->GetPrimaryMainFrame()
-        ->GetRenderViewHost()
-        ->GetWidget()
-        ->ForwardMouseEvent(mouse_event_);
+    render_frame_host_->GetRenderWidgetHost()->ForwardMouseEvent(mouse_event_);
 
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
@@ -366,17 +364,14 @@
  private:
   void SendMouseUp() {
     mouse_event_.SetType(blink::WebInputEvent::Type::kMouseUp);
-    web_contents_->GetPrimaryMainFrame()
-        ->GetRenderViewHost()
-        ->GetWidget()
-        ->ForwardMouseEvent(mouse_event_);
+    render_frame_host_->GetRenderWidgetHost()->ForwardMouseEvent(mouse_event_);
     click_completed_ = true;
     if (message_loop_runner_)
       message_loop_runner_->Quit();
   }
 
   // Unowned pointer.
-  raw_ptr<content::WebContents> web_contents_;
+  raw_ptr<content::RenderFrameHost> render_frame_host_;
 
   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
 
@@ -1357,18 +1352,18 @@
   content::WebContents* embedder_contents = GetFirstAppWindowWebContents();
   ASSERT_TRUE(embedder_contents);
 
-  std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
-      &guest_contents_list);
-  ASSERT_EQ(1u, guest_contents_list.size());
-  content::WebContents* guest_contents = guest_contents_list[0];
+  std::vector<content::RenderFrameHost*> guest_frames_list;
+  GetGuestViewManager()->GetGuestRenderFrameHostList(&guest_frames_list);
+  ASSERT_EQ(1u, guest_frames_list.size());
+  content::RenderFrameHost* guest_frame = guest_frames_list[0];
 
   const gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
-  const gfx::Rect guest_rect = guest_contents->GetContainerBounds();
+  const gfx::Rect guest_rect =
+      guest_frame->GetRenderWidgetHost()->GetView()->GetViewBounds();
   const gfx::Point click_point(guest_rect.x() - embedder_rect.x() + 10,
                                guest_rect.y() - embedder_rect.y() + 10);
 
-  LeftMouseClick mouse_click(guest_contents);
+  LeftMouseClick mouse_click(guest_frame);
   SelectControlWaiter select_control_waiter;
 
   for (int i = 0; i < 5; ++i) {
@@ -3894,23 +3889,24 @@
   // locked after the loadDataWithBaseURL navigation and is allowed to access
   // resources belonging to the base URL's origin.
   if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()) {
-    content::WebContents* guest =
-        GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
-    ASSERT_TRUE(guest);
-    content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
-    EXPECT_TRUE(main_frame->GetSiteInstance()->RequiresDedicatedProcess());
-    EXPECT_TRUE(main_frame->GetProcess()->IsProcessLockedToSiteForTesting());
+    content::RenderFrameHost* guest_main_frame =
+        GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated();
+    ASSERT_TRUE(guest_main_frame);
+    EXPECT_TRUE(
+        guest_main_frame->GetSiteInstance()->RequiresDedicatedProcess());
+    EXPECT_TRUE(
+        guest_main_frame->GetProcess()->IsProcessLockedToSiteForTesting());
 
     auto* security_policy = content::ChildProcessSecurityPolicy::GetInstance();
     url::Origin base_origin = url::Origin::Create(GURL("http://localhost"));
     EXPECT_TRUE(security_policy->CanAccessDataForOrigin(
-        main_frame->GetProcess()->GetID(), base_origin));
+        guest_main_frame->GetProcess()->GetID(), base_origin));
 
     // Ensure the process doesn't have access to some other origin. This
     // verifies that site isolation is enforced.
     url::Origin another_origin = url::Origin::Create(GURL("http://foo.com"));
     EXPECT_FALSE(security_policy->CanAccessDataForOrigin(
-        main_frame->GetProcess()->GetID(), another_origin));
+        guest_main_frame->GetProcess()->GetID(), another_origin));
   }
 }
 
@@ -4437,13 +4433,13 @@
 
   // Ensure that the <webview> process isn't considered an extension process,
   // even though the last committed URL is an extension URL.
-  content::WebContents* guest =
-      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
+  content::RenderFrameHost* guest =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
   GURL guest_url(guest->GetLastCommittedURL());
   EXPECT_TRUE(guest_url.SchemeIs(extensions::kExtensionScheme));
 
   auto* process_map = extensions::ProcessMap::Get(guest->GetBrowserContext());
-  auto* guest_process = guest->GetPrimaryMainFrame()->GetProcess();
+  auto* guest_process = guest->GetProcess();
   EXPECT_FALSE(process_map->Contains(guest_process->GetID()));
   EXPECT_TRUE(
       process_map->GetExtensionsInProcess(guest_process->GetID()).empty());
@@ -4464,16 +4460,16 @@
              "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);
 
   content::WebContents* embedder_contents = GetEmbedderWebContents();
-  content::WebContents* web_view_contents =
-      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
+  content::RenderFrameHost* web_view_frame =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
   ASSERT_TRUE(embedder_contents);
-  ASSERT_TRUE(web_view_contents);
+  ASSERT_TRUE(web_view_frame);
 
   GURL embedder_url(embedder_contents->GetLastCommittedURL());
   GURL webview_url(embedder_url.DeprecatedGetOriginAsURL().spec() +
                    "assets/foo.html");
 
-  EXPECT_EQ(webview_url, web_view_contents->GetLastCommittedURL());
+  EXPECT_EQ(webview_url, web_view_frame->GetLastCommittedURL());
 }
 
 // Tests that a WebView can navigate an iframe to a blob URL that it creates
@@ -4514,10 +4510,10 @@
              "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);
 
   content::WebContents* embedder_contents = GetEmbedderWebContents();
-  content::WebContents* web_view_contents =
-      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
+  content::RenderFrameHost* web_view_frame =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
   ASSERT_TRUE(embedder_contents);
-  ASSERT_TRUE(web_view_contents);
+  ASSERT_TRUE(web_view_frame);
 
   // Check that the webview stays at the first page that it loaded (foo.html),
   // and does not commit inaccessible.html.
@@ -4525,7 +4521,7 @@
   GURL foo_url(embedder_url.DeprecatedGetOriginAsURL().spec() +
                "assets/foo.html");
 
-  EXPECT_EQ(foo_url, web_view_contents->GetLastCommittedURL());
+  EXPECT_EQ(foo_url, web_view_frame->GetLastCommittedURL());
 }
 
 // Ensure that only app resources accessible to the webview can be loaded in a
@@ -5358,20 +5354,25 @@
 IN_PROC_BROWSER_TEST_P(WebViewTest, TouchpadPinchSyntheticWheelEvents) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   LoadAppWithGuest("web_view/touchpad_pinch");
-  content::WebContents* guest_contents = GetGuestWebContents();
 
-  content::WaitForHitTestData(guest_contents);
+  content::RenderFrameHost* render_frame_host =
+      GetGuestView()->GetGuestMainFrame();
+  content::WaitForHitTestData(render_frame_host);
+
+  content::RenderWidgetHost* render_widget_host =
+      render_frame_host->GetRenderWidgetHost();
+
   // Ensure the compositor thread is aware of the wheel listener.
-  content::MainThreadFrameObserver synchronize_threads(
-      guest_contents->GetRenderWidgetHostView()->GetRenderWidgetHost());
+  content::MainThreadFrameObserver synchronize_threads(render_widget_host);
   synchronize_threads.Wait();
 
   ExtensionTestMessageListener synthetic_wheel_listener("Seen wheel event");
 
-  const gfx::Rect contents_rect = guest_contents->GetContainerBounds();
-  const gfx::Point pinch_position(contents_rect.width() / 2,
-                                  contents_rect.height() / 2);
-  content::SimulateGesturePinchSequence(guest_contents, pinch_position, 1.23,
+  const gfx::Rect guest_rect = render_widget_host->GetView()->GetViewBounds();
+  const gfx::Point pinch_position(guest_rect.width() / 2,
+                                  guest_rect.height() / 2);
+  content::SimulateGesturePinchSequence(render_widget_host, pinch_position,
+                                        1.23,
                                         blink::WebGestureDevice::kTouchpad);
 
   ASSERT_TRUE(synthetic_wheel_listener.WaitUntilSatisfied());
@@ -5463,11 +5464,12 @@
 IN_PROC_BROWSER_TEST_P(PrivateNetworkAccessWebViewTest,
                        SpecialSchemeChromeGuest) {
   LoadAppWithGuest("web_view/simple");
-  content::WebContents* guest = GetGuestWebContents();
-  ASSERT_TRUE(guest);
+  content::RenderFrameHost* guest_frame_host = GetGuestRenderFrameHost();
+  ASSERT_TRUE(guest_frame_host);
 
-  EXPECT_FALSE(guest->GetLastCommittedURL().SchemeIs(content::kGuestScheme));
-  EXPECT_TRUE(guest->GetSiteInstance()->IsGuest());
+  EXPECT_FALSE(
+      guest_frame_host->GetLastCommittedURL().SchemeIs(content::kGuestScheme));
+  EXPECT_TRUE(guest_frame_host->GetSiteInstance()->IsGuest());
 
   // We'll try to fetch a local page with Access-Control-Allow-Origin: *, to
   // avoid having origin issues on top of privateness issues.
@@ -5481,7 +5483,7 @@
   // `network::mojom::IPAddressSpace::kUnknown`).
   // For now, unknown -> local is not blocked, so this fetch succeeds. See also
   // https://crbug.com/1178814.
-  EXPECT_EQ(true, content::EvalJs(guest,
+  EXPECT_EQ(true, content::EvalJs(guest_frame_host,
                                   content::JsReplace(
                                       "fetch($1).then(response => response.ok)",
                                       fetch_url)));
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 0a058a6..cca593f 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -1007,6 +1007,8 @@
     "file_manager/prefs_migration_uma.h",
     "file_manager/restore_io_task.cc",
     "file_manager/restore_io_task.h",
+    "file_manager/restore_to_destination_io_task.cc",
+    "file_manager/restore_to_destination_io_task.h",
     "file_manager/select_file_dialog_util.cc",
     "file_manager/select_file_dialog_util.h",
     "file_manager/snapshot_manager.cc",
@@ -1995,6 +1997,7 @@
     "//third_party/blink/public/common:headers",
     "//third_party/re2",
     "//third_party/securemessage/proto",
+    "//third_party/xdg_shared_mime_info",
     "//third_party/zlib",
     "//third_party/zlib/google:compression_utils",
     "//third_party/zlib/google:zip",
diff --git a/chrome/browser/ash/account_manager/account_apps_availability_unittest.cc b/chrome/browser/ash/account_manager/account_apps_availability_unittest.cc
index 5b2b15c..b1f8e73 100644
--- a/chrome/browser/ash/account_manager/account_apps_availability_unittest.cc
+++ b/chrome/browser/ash/account_manager/account_apps_availability_unittest.cc
@@ -122,9 +122,9 @@
   void LoginUserSession() {
     auto account_id = AccountId::FromUserEmailGaiaId(primary_account_.email,
                                                      primary_account_.gaia);
-    fake_user_manager_->AddUser(account_id);
-    fake_user_manager_->UserLoggedIn(
-        account_id, account_id.GetUserEmail() + "-hash", false, false);
+    auto* user = fake_user_manager_->AddUser(account_id);
+    fake_user_manager_->UserLoggedIn(account_id, user->username_hash(), false,
+                                     false);
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
diff --git a/chrome/browser/ash/app_restore/full_restore_service.cc b/chrome/browser/ash/app_restore/full_restore_service.cc
index bcc5b3f..6dcd55c1 100644
--- a/chrome/browser/ash/app_restore/full_restore_service.cc
+++ b/chrome/browser/ash/app_restore/full_restore_service.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ash/app_restore/full_restore_service.h"
 
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/constants/notifier_catalogs.h"
 #include "ash/public/cpp/notification_utils.h"
@@ -47,6 +48,7 @@
 namespace full_restore {
 
 namespace {
+
 // If the reboot occurred due to DeviceScheduledRebootPolicy, change the title
 // to notify the user that the device was rebooted by the administrator.
 int GetRestoreNotificationTitleId(Profile* profile) {
@@ -56,6 +58,13 @@
   }
   return IDS_RESTORE_NOTIFICATION_TITLE;
 }
+
+// Returns true if `profile` is the primary user profile.
+bool IsPrimaryUser(Profile* profile) {
+  return ProfileHelper::Get()->GetUserByProfile(profile) ==
+         user_manager::UserManager::Get()->GetPrimaryUser();
+}
+
 }  // namespace
 
 bool g_restore_for_testing = true;
@@ -134,8 +143,7 @@
 
   // Set profile path before init the restore process to create
   // FullRestoreSaveHandler to observe restore windows.
-  if (ProfileHelper::Get()->GetUserByProfile(profile_) ==
-      user_manager::UserManager::Get()->GetPrimaryUser()) {
+  if (IsPrimaryUser(profile_)) {
     ::full_restore::FullRestoreSaveHandler::GetInstance()
         ->SetPrimaryProfilePath(profile_->GetPath());
 
@@ -257,6 +265,11 @@
   }
 }
 
+void FullRestoreService::Restore() {
+  if (app_launch_handler_)
+    app_launch_handler_->SetShouldRestore();
+}
+
 void FullRestoreService::Close(bool by_user) {
   if (!skip_notification_histogram_) {
     RecordRestoreAction(
@@ -402,6 +415,15 @@
   if (!ShouldShowNotification())
     return;
 
+  // TODO(crbug.com/1353119): Update this logic once PM/UX have decided on how
+  // glanceables interact with full restore. For now, suppress the non-crash
+  // full restore notification for the primary user, because glanceables are
+  // only shown for the primary user.
+  if (features::AreGlanceablesEnabled() && id == kRestoreNotificationId &&
+      IsPrimaryUser(profile_)) {
+    return;
+  }
+
   // If the system is restored from crash, create the crash lock for the browser
   // session restore to help set the browser saving flag.
   ExitTypeService* exit_type_service =
@@ -471,11 +493,6 @@
   show_notification = true;
 }
 
-void FullRestoreService::Restore() {
-  if (app_launch_handler_)
-    app_launch_handler_->SetShouldRestore();
-}
-
 void FullRestoreService::RecordRestoreAction(const std::string& notification_id,
                                              RestoreAction restore_action) {
   base::UmaHistogramEnumeration(notification_id == kRestoreNotificationId
diff --git a/chrome/browser/ash/app_restore/full_restore_service.h b/chrome/browser/ash/app_restore/full_restore_service.h
index c841924..af8a7d3 100644
--- a/chrome/browser/ash/app_restore/full_restore_service.h
+++ b/chrome/browser/ash/app_restore/full_restore_service.h
@@ -87,6 +87,9 @@
 
   void MaybeCloseNotification(bool allow_save = true);
 
+  // Implement the restoration.
+  void Restore();
+
   // message_center::NotificationObserver:
   void Close(bool by_user) override;
   void Click(const absl::optional<int>& button_index,
@@ -122,9 +125,6 @@
   void MaybeShowRestoreNotification(const std::string& id,
                                     bool& show_notification);
 
-  // Implement the restoration.
-  void Restore();
-
   void RecordRestoreAction(const std::string& notification_id,
                            RestoreAction restore_action);
 
diff --git a/chrome/browser/ash/app_restore/full_restore_service_unittest.cc b/chrome/browser/ash/app_restore/full_restore_service_unittest.cc
index 9f74560..07aa8fb 100644
--- a/chrome/browser/ash/app_restore/full_restore_service_unittest.cc
+++ b/chrome/browser/ash/app_restore/full_restore_service_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ash/app_restore/full_restore_service.h"
 
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "base/command_line.h"
@@ -606,6 +607,23 @@
   FullRestoreService::MaybeCloseNotification(profile());
 }
 
+// If the OS restore setting is 'Ask every time' and glanceables are enabled,
+// the notification is not shown.
+TEST_F(FullRestoreServiceTestHavingFullRestoreFile,
+       AskEveryTimeWithGlanceables) {
+  base::test::ScopedFeatureList feature_list(features::kGlanceables);
+
+  profile()->GetPrefs()->SetInteger(
+      kRestoreAppsAndPagesPrefName,
+      static_cast<int>(RestoreOption::kAskEveryTime));
+  CreateFullRestoreServiceForTesting();
+
+  EXPECT_EQ(RestoreOption::kAskEveryTime, GetRestoreOption());
+
+  VerifyNotification(/*has_crash_notification=*/false,
+                     /*has_restore_notification=*/false);
+}
+
 // If the OS restore setting is 'Ask every time', after reboot, show the restore
 // notification, and verify the restore flag when click the Settings button.
 TEST_F(FullRestoreServiceTestHavingFullRestoreFile, AskEveryTimeAndSettings) {
diff --git a/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper.cc b/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper.cc
index a303ccc..e3952ea 100644
--- a/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper.cc
+++ b/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper.cc
@@ -462,6 +462,25 @@
     out_data->AddState(ax::mojom::State::kExpanded);
   }
 
+  if (node_ptr_->standard_actions) {
+    for (mojom::AccessibilityActionInAndroidPtr& android_action :
+         node_ptr_->standard_actions.value()) {
+      if (android_action->label.has_value()) {
+        const std::string& label = android_action->label.value();
+        const auto action_id =
+            static_cast<mojom::AccessibilityActionType>(android_action->id);
+        if (action_id == mojom::AccessibilityActionType::CLICK) {
+          out_data->AddStringAttribute(
+              ax::mojom::StringAttribute::kDoDefaultLabel, label);
+        }
+        if (action_id == mojom::AccessibilityActionType::LONG_CLICK) {
+          out_data->AddStringAttribute(
+              ax::mojom::StringAttribute::kLongClickLabel, label);
+        }
+      }
+    }
+  }
+
   // Custom actions.
   if (node_ptr_->custom_actions) {
     std::vector<int32_t> custom_action_ids;
diff --git a/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc b/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc
index b74ef0b9..cf8c43f 100644
--- a/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc
+++ b/chrome/browser/ash/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc
@@ -821,4 +821,24 @@
       &result_labels));
   EXPECT_EQ(std::vector<std::string>({"This is label"}), result_labels);
 }
+
+TEST_F(AccessibilityNodeInfoDataWrapperTest, ActionLabel) {
+  AXNodeInfoData root;
+  root.id = 1;
+  AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &root);
+
+  // Check if labels for click and long click are serialized as kDoDefaultLabel
+  // and kLongClickLabel.
+  AddStandardAction(&root, AXActionType::CLICK, "click label");
+  AddStandardAction(&root, AXActionType::LONG_CLICK, "long click label");
+
+  ui::AXNodeData data = CallSerialize(wrapper);
+  std::string val;
+  EXPECT_TRUE(data.GetStringAttribute(
+      ax::mojom::StringAttribute::kDoDefaultLabel, &val));
+  EXPECT_EQ("click label", val);
+  EXPECT_TRUE(data.GetStringAttribute(
+      ax::mojom::StringAttribute::kLongClickLabel, &val));
+  EXPECT_EQ("long click label", val);
+}
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.cc b/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.cc
index 966e6c1..5b27a92 100644
--- a/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.cc
+++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.cc
@@ -11,7 +11,7 @@
 void AddAction(
     std::vector<arc::mojom::AccessibilityActionInAndroidPtr>* actions,
     int id,
-    absl::optional<std::string> label = absl::nullopt) {
+    absl::optional<std::string> label) {
   actions->push_back(arc::mojom::AccessibilityActionInAndroid::New());
   arc::mojom::AccessibilityActionInAndroid* action = actions->back().get();
   action->id = id;
@@ -24,12 +24,14 @@
 namespace arc {
 
 void AddStandardAction(mojom::AccessibilityNodeInfoData* node,
-                       mojom::AccessibilityActionType action_type) {
+                       mojom::AccessibilityActionType action_type,
+                       absl::optional<std::string> label) {
   if (!node->standard_actions) {
     node->standard_actions =
         std::vector<mojom::AccessibilityActionInAndroidPtr>();
   }
-  AddAction(&node->standard_actions.value(), static_cast<int>(action_type));
+  AddAction(&node->standard_actions.value(), static_cast<int>(action_type),
+            label);
 }
 
 void AddCustomAction(mojom::AccessibilityNodeInfoData* node,
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.h b/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.h
index be055ed..381dd009 100644
--- a/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.h
+++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_test_util.h
@@ -26,7 +26,8 @@
 }
 
 void AddStandardAction(mojom::AccessibilityNodeInfoData* node,
-                       mojom::AccessibilityActionType action_type);
+                       mojom::AccessibilityActionType action_type,
+                       absl::optional<std::string> label = absl::nullopt);
 
 void AddCustomAction(mojom::AccessibilityNodeInfoData* node,
                      int id,
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_util.cc b/chrome/browser/ash/arc/fileapi/arc_documents_provider_util.cc
index 9aaa52f..f2bddbd 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_util.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_util.cc
@@ -26,15 +26,22 @@
   const char* extensions;
 };
 
-// The mapping from MIME types to file name extensions, taken from Android N.
+// The mapping from MIME types to file name extensions, taken from Android T.
 // See: frameworks/base/media/java/android/media/MediaFile.java
 constexpr MimeTypeToExtensions kAndroidMimeTypeMappings[] = {
-    {"application/mspowerpoint", "ppt"},
-    {"application/msword", "doc"},
+    {"application/vnd.ms-powerpoint", "ppt,pot,pps,ppa"},
+    {"application/msword", "doc,dot"},
+    {"application/"
+     "vnd.openxmlformats-officedocument.presentationml.presentation",
+     "pptx"},
+    {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+     "xlsx"},
+    {"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+     "docx"},
     {"application/ogg", "ogg,oga"},
     {"application/pdf", "pdf"},
     {"application/vnd.apple.mpegurl", "m3u8"},
-    {"application/vnd.ms-excel", "xls"},
+    {"application/vnd.ms-excel", "xls,xlt,xla"},
     {"application/vnd.ms-wpl", "wpl"},
     {"application/x-android-drm-fl", "fl"},
     {"application/x-mpegurl", "m3u"},
@@ -51,19 +58,23 @@
     {"audio/mpegurl", "m3u8"},
     {"audio/ogg", "ogg"},
     {"audio/sp-midi", "smf"},
+    {"audio/x-aiff", "aiff"},
     {"audio/x-matroska", "mka"},
     {"audio/x-mpegurl", "m3u,m3u8"},
     {"audio/x-ms-wma", "wma"},
     {"audio/x-scpls", "pls"},
     {"audio/x-wav", "wav"},
     {"image/gif", "gif"},
+    {"image/jp2", "jpg2"},
     {"image/jpeg", "jpg,jpeg"},
+    {"image/jpx", "jpx"},
     {"image/png", "png"},
     {"image/vnd.wap.wbmp", "wbmp"},
     {"image/webp", "webp"},
     {"image/x-adobe-dng", "dng"},
     {"image/x-canon-cr2", "cr2"},
     {"image/x-fuji-raf", "raf"},
+    {"image/x-heif", "heif"},
     {"image/x-ms-bmp", "bmp"},
     {"image/x-nikon-nef", "nef"},
     {"image/x-nikon-nrw", "nrw"},
diff --git a/chrome/browser/ash/authpolicy/OWNERS b/chrome/browser/ash/authpolicy/OWNERS
index bfe96c1..cf144fc 100644
--- a/chrome/browser/ash/authpolicy/OWNERS
+++ b/chrome/browser/ash/authpolicy/OWNERS
@@ -6,7 +6,7 @@
 fsandrade@chromium.org
 
 # Secondary owner(s)
-rsorokin@chromium.org
+rsorokin@google.com
 
 # Previous owners (for general questions, if current owners are not available)
 # Commented out so automatic tools don't prefer.
diff --git a/chrome/browser/ash/child_accounts/event_based_status_reporting_service_unittest.cc b/chrome/browser/ash/child_accounts/event_based_status_reporting_service_unittest.cc
index 1da312b2..e6087628 100644
--- a/chrome/browser/ash/child_accounts/event_based_status_reporting_service_unittest.cc
+++ b/chrome/browser/ash/child_accounts/event_based_status_reporting_service_unittest.cc
@@ -22,6 +22,7 @@
 #include "components/account_id/account_id.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/session_manager/core/session_manager.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "services/network/test/test_network_connection_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -106,9 +107,7 @@
 
     session_manager_.CreateSession(
         account_id(),
-        ProfileHelper::GetUserIdHashByUserIdForTesting(
-            account_id().GetUserEmail()),
-        true);
+        user_manager::FakeUserManager::GetFakeUsernameHash(account_id()), true);
     session_manager_.SetSessionState(
         session_manager::SessionState::LOGIN_PRIMARY);
 
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator_browsertest.cc b/chrome/browser/ash/crosapi/browser_data_migrator_browsertest.cc
index d74093e..725dc6f 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator_browsertest.cc
+++ b/chrome/browser/ash/crosapi/browser_data_migrator_browsertest.cc
@@ -24,6 +24,7 @@
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
 #include "components/policy/policy_constants.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_launcher.h"
 
@@ -33,9 +34,6 @@
 
 constexpr char kUserIdHash[] = "abcdefg";
 
-// As defined in /ash/components/login/auth/stub_authenticator.cc
-static const char kUserIdHashSuffix[] = "-hash";
-
 }  // namespace
 
 // Used to test whether migration gets triggered during the signin flow.
@@ -220,7 +218,7 @@
     const auto& user = login_manager_mixin_.users()[0];
 
     const std::string user_id_hash =
-        user.account_id.GetUserEmail() + kUserIdHashSuffix;
+        user_manager::FakeUserManager::GetFakeUsernameHash(user.account_id);
 
     // Setting this pref triggers a restart to resume move migration. Check
     // `BrowserDataMigratorImpl::MaybeForceResumeMoveMigration()`.
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index b924f4c..65b6deb 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -643,13 +643,12 @@
                                 : MojoOptionalBool::kFalse;
       }
 
-      const base::ListValue* usb_detachable_allow_list;
+      const base::Value::List* usb_detachable_allow_list;
       if (cros_settings->GetList(ash::kUsbDetachableAllowlist,
                                  &usb_detachable_allow_list)) {
         mojom::UsbDetachableAllowlistPtr allow_list =
             mojom::UsbDetachableAllowlist::New();
-        for (const auto& entry :
-             usb_detachable_allow_list->GetListDeprecated()) {
+        for (const auto& entry : *usb_detachable_allow_list) {
           mojom::UsbDeviceIdPtr usb_device_id = mojom::UsbDeviceId::New();
           absl::optional<int> vid =
               entry.FindIntKey(ash::kUsbDetachableAllowlistKeyVid);
diff --git a/chrome/browser/ash/crostini/crostini_shelf_utils_unittest.cc b/chrome/browser/ash/crostini/crostini_shelf_utils_unittest.cc
index b36991d..b0544ee 100644
--- a/chrome/browser/ash/crostini/crostini_shelf_utils_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_shelf_utils_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "chrome/browser/ash/crostini/crostini_test_helper.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
 #include "chrome/test/base/testing_profile.h"
@@ -46,9 +47,9 @@
  public:
   std::string GetShelfAppIdUsingProfile(const Profile* profile,
                                         WindowIds window_ids) const {
-    return GetCrostiniShelfAppId(
-        profile, base::OptionalOrNullptr(window_ids.app_id),
-        base::OptionalOrNullptr(window_ids.startup_id));
+    return GetCrostiniShelfAppId(profile,
+                                 base::OptionalToPtr(window_ids.app_id),
+                                 base::OptionalToPtr(window_ids.startup_id));
   }
 
   std::string GetShelfAppId(WindowIds window_ids) const {
diff --git a/chrome/browser/ash/drive/drive_integration_service.cc b/chrome/browser/ash/drive/drive_integration_service.cc
index f782abb..b496c7f16 100644
--- a/chrome/browser/ash/drive/drive_integration_service.cc
+++ b/chrome/browser/ash/drive/drive_integration_service.cc
@@ -40,7 +40,10 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/ash/components/drivefs/drivefs_bootstrap.h"
-#include "chromeos/ash/components/network/portal_detector/network_portal_detector.h"
+#include "chromeos/ash/components/network/network_handler.h"
+#include "chromeos/ash/components/network/network_state.h"
+#include "chromeos/ash/components/network/network_state_handler.h"
+#include "chromeos/ash/components/network/network_state_handler_observer.h"
 #include "components/drive/drive_api_util.h"
 #include "components/drive/drive_notification_manager.h"
 #include "components/drive/drive_pref_names.h"
@@ -348,10 +351,10 @@
 // Observes drive disable Preference's change.
 class DriveIntegrationService::PreferenceWatcher
     : public network::NetworkConnectionTracker::NetworkConnectionObserver,
-      public ash::NetworkPortalDetector::Observer {
+      public ash::NetworkStateHandlerObserver {
  public:
   explicit PreferenceWatcher(PrefService* pref_service)
-      : pref_service_(pref_service), integration_service_(nullptr) {
+      : pref_service_(pref_service) {
     DCHECK(pref_service);
     pref_change_registrar_.Init(pref_service);
     pref_change_registrar_.Add(
@@ -377,20 +380,18 @@
     if (integration_service_) {
       content::GetNetworkConnectionTracker()->RemoveNetworkConnectionObserver(
           this);
-      ash::network_portal_detector::GetInstance()->RemoveObserver(this);
+      if (ash::NetworkHandler::IsInitialized()) {
+        ash::NetworkHandler::Get()->network_state_handler()->RemoveObserver(
+            this);
+      }
     }
   }
 
-  void set_integration_service(DriveIntegrationService* integration_service) {
+  void SetIntegrationService(DriveIntegrationService* integration_service) {
     integration_service_ = integration_service;
     content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver(this);
 
-    // The NetworkPortalDetector instance may not be ready yet, so defer
-    // accessing it.
-    base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&DriveIntegrationService::PreferenceWatcher::
-                                      AddNetworkPortalDetectorObserver,
-                                  weak_ptr_factory_.GetWeakPtr()));
+    AddNetworkPortalDetectorObserver();
   }
 
   void UpdateSyncPauseState() {
@@ -404,10 +405,8 @@
   }
 
   bool is_offline() const {
-    return last_portal_status_ !=
-               ash::NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE &&
-           last_portal_status_ !=
-               ash::NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
+    return portal_state_ != ash::NetworkState::PortalState::kOnline &&
+           portal_state_ != ash::NetworkState::PortalState::kUnknown;
   }
 
  private:
@@ -437,34 +436,36 @@
   }
 
   void AddNetworkPortalDetectorObserver() {
-    if (ash::network_portal_detector::IsInitialized()) {
-      ash::network_portal_detector::GetInstance()->AddAndFireObserver(this);
-    } else {
-      // The NetworkPortalDetector instance still not ready. Postpone even more.
-      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE,
-          base::BindOnce(&DriveIntegrationService::PreferenceWatcher::
-                             AddNetworkPortalDetectorObserver,
-                         weak_ptr_factory_.GetWeakPtr()),
-          base::Seconds(5));
-    }
+    if (!ash::NetworkHandler::IsInitialized())
+      return;  // Test environment.
+    ash::NetworkStateHandler* handler =
+        ash::NetworkHandler::Get()->network_state_handler();
+    handler->AddObserver(this);
+    const ash::NetworkState* default_network = handler->DefaultNetwork();
+    ash::NetworkState::PortalState portal_state =
+        default_network ? default_network->GetPortalState()
+                        : ash::NetworkState::PortalState::kUnknown;
+    PortalStateChanged(default_network, portal_state);
   }
 
-  // ash::NetworkPortalDetector::Observer
-  void OnPortalDetectionCompleted(
-      const ash::NetworkState* network,
-      const ash::NetworkPortalDetector::CaptivePortalStatus status) override {
-    last_portal_status_ = status;
+  // ash::NetworkStateHandlerObserver
+  void PortalStateChanged(
+      const ash::NetworkState* default_network,
+      ash::NetworkState::PortalState portal_state) override {
+    portal_state_ = portal_state;
 
     if (integration_service_->remount_when_online_ &&
-        last_portal_status_ ==
-            ash::NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
+        portal_state == ash::NetworkState::PortalState::kOnline) {
       integration_service_->remount_when_online_ = false;
       integration_service_->mount_start_ = {};
       integration_service_->AddDriveMountPoint();
     }
   }
 
+  void OnShuttingDown() override {
+    ash::NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
+  }
+
   // network::NetworkConnectionTracker::NetworkConnectionObserver
   void OnConnectionChanged(network::mojom::ConnectionType type) override {
     if (!integration_service_->GetDriveFsInterface())
@@ -478,9 +479,9 @@
 
   PrefService* pref_service_;
   PrefChangeRegistrar pref_change_registrar_;
-  DriveIntegrationService* integration_service_;
-  ash::NetworkPortalDetector::CaptivePortalStatus last_portal_status_ =
-      ash::NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
+  DriveIntegrationService* integration_service_ = nullptr;
+  ash::NetworkState::PortalState portal_state_ =
+      ash::NetworkState::PortalState::kUnknown;
 
   base::WeakPtrFactory<PreferenceWatcher> weak_ptr_factory_{this};
 };
@@ -650,7 +651,7 @@
   if (util::IsDriveAvailableForProfile(profile)) {
     preference_watcher_ =
         std::make_unique<PreferenceWatcher>(profile->GetPrefs());
-    preference_watcher_->set_integration_service(this);
+    preference_watcher_->SetIntegrationService(this);
   }
 
   bool migrated_to_drivefs =
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 0159f1d..05c56e0 100644
--- a/chrome/browser/ash/file_manager/app_service_file_tasks.cc
+++ b/chrome/browser/ash/file_manager/app_service_file_tasks.cc
@@ -72,10 +72,11 @@
       return TASK_TYPE_FILE_HANDLER;
     case apps::AppType::kCrostini:
       return TASK_TYPE_CROSTINI_APP;
+    case apps::AppType::kPluginVm:
+      return TASK_TYPE_PLUGIN_VM_APP;
     case apps::AppType::kUnknown:
     case apps::AppType::kBuiltIn:
     case apps::AppType::kMacOs:
-    case apps::AppType::kPluginVm:
     case apps::AppType::kStandaloneBrowser:
     case apps::AppType::kRemote:
     case apps::AppType::kBorealis:
@@ -190,6 +191,7 @@
   if (ash::features::ShouldArcAndGuestOsFileTasksUseAppService()) {
     supported_app_types.push_back(apps::AppType::kArc);
     supported_app_types.push_back(apps::AppType::kCrostini);
+    supported_app_types.push_back(apps::AppType::kPluginVm);
   }
   for (auto& launch_entry : intent_launch_info) {
     auto app_type = proxy->AppRegistryCache().GetAppType(launch_entry.app_id);
@@ -227,7 +229,9 @@
         continue;
     }
 
-    if (app_type == apps::AppType::kCrostini && !files_shareable_to_vm) {
+    if ((app_type == apps::AppType::kCrostini ||
+         app_type == apps::AppType::kPluginVm) &&
+        !files_shareable_to_vm) {
       continue;
     }
 
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
index 8e1aef82..f93fb46 100644
--- a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
+++ b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
@@ -313,8 +313,8 @@
                                 apps::AppType::kChromeApp, true);
   }
 
-  apps::IntentFilterPtr CreateFileIntentFilter(std::string action,
-                                               std::string mime_type) {
+  apps::IntentFilterPtr CreateMimeTypeFileIntentFilter(std::string action,
+                                                       std::string mime_type) {
     auto intent_filter = std::make_unique<apps::IntentFilter>();
     intent_filter->AddSingleValueCondition(apps::ConditionType::kAction, action,
                                            apps::PatternMatchType::kLiteral);
@@ -324,6 +324,18 @@
     return intent_filter;
   }
 
+  apps::IntentFilterPtr CreateExtensionTypeFileIntentFilter(
+      std::string action,
+      std::string extension_type) {
+    auto intent_filter = std::make_unique<apps::IntentFilter>();
+    intent_filter->AddSingleValueCondition(apps::ConditionType::kAction, action,
+                                           apps::PatternMatchType::kLiteral);
+    intent_filter->AddSingleValueCondition(
+        apps::ConditionType::kFile, extension_type,
+        apps::PatternMatchType::kFileExtension);
+    return intent_filter;
+  }
+
   std::string AddArcAppWithIntentFilter(const std::string& package,
                                         const std::string& activity,
                                         apps::IntentFilterPtr intent_filter) {
@@ -335,12 +347,12 @@
     return app_id;
   }
 
-  void AddCrostiniAppWithIntentFilter(std::string app_id,
-                                      apps::IntentFilterPtr intent_filter) {
+  void AddGuestOsAppWithIntentFilter(std::string app_id,
+                                     apps::AppType app_type,
+                                     apps::IntentFilterPtr intent_filter) {
     std::vector<apps::IntentFilterPtr> filters;
     filters.push_back(std::move(intent_filter));
-    AddFakeAppWithIntentFilters(app_id, std::move(filters),
-                                apps::AppType::kCrostini, true);
+    AddFakeAppWithIntentFilters(app_id, std::move(filters), app_type, true);
   }
 
   base::test::ScopedFeatureList feature_list_;
@@ -389,7 +401,8 @@
   std::string text_activity = "TextViewerActivity";
   std::string text_app_id = AddArcAppWithIntentFilter(
       text_package_name, text_activity,
-      CreateFileIntentFilter(apps_util::kIntentActionView, text_mime_type));
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     text_mime_type));
 
   std::vector<FullTaskDescriptor> tasks =
       FindAppServiceTasks({{"foo.txt", text_mime_type}});
@@ -402,15 +415,30 @@
   std::string text_mime_type = "text/plain";
   std::string file_name = "foo.txt";
   std::string text_app_id = "Text app";
-  AddCrostiniAppWithIntentFilter(
-      text_app_id,
-      CreateFileIntentFilter(apps_util::kIntentActionView, text_mime_type));
+  AddGuestOsAppWithIntentFilter(
+      text_app_id, apps::AppType::kCrostini,
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     text_mime_type));
 
   std::vector<FullTaskDescriptor> tasks =
       FindAppServiceTasks({{file_name, text_mime_type}});
   ASSERT_EQ(0U, tasks.size());
 }
 
+// PluginVm apps should not be found when kArcAndGuestOsFileTasksUseAppService
+// is disabled.
+TEST_F(AppServiceFileTasksTestDisabled, FindAppServicePluginVmApp) {
+  std::string file_name = "foo.txt";
+  std::string app_id = "Text app";
+  AddGuestOsAppWithIntentFilter(
+      app_id, apps::AppType::kCrostini,
+      CreateExtensionTypeFileIntentFilter(apps_util::kIntentActionView, "txt"));
+
+  std::vector<FullTaskDescriptor> tasks =
+      FindAppServiceTasks({{file_name, kMimeTypeText}});
+  ASSERT_EQ(0U, tasks.size());
+}
+
 // An app which does not handle intents should not be found even if the filters
 // match.
 TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceFileTasksHandlesIntent) {
@@ -686,14 +714,16 @@
   std::string text_activity = "TextViewerActivity";
   std::string text_app_id = AddArcAppWithIntentFilter(
       text_package_name, text_activity,
-      CreateFileIntentFilter(apps_util::kIntentActionView, text_mime_type));
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     text_mime_type));
 
   // Create an app with an image file filter.
   std::string image_package_name = "com.example.imageViewer";
   std::string image_activity = "ImageViewerActivity";
   std::string image_app_id = AddArcAppWithIntentFilter(
       image_package_name, image_activity,
-      CreateFileIntentFilter(apps_util::kIntentActionView, image_mime_type));
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     image_mime_type));
 
   // Check if only the text ARC app appears as a result.
   std::vector<FullTaskDescriptor> tasks =
@@ -707,9 +737,10 @@
 TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceCrostiniApp) {
   std::string file_name = "foo.txt";
   std::string text_app_id = "Text app";
-  AddCrostiniAppWithIntentFilter(
-      text_app_id,
-      CreateFileIntentFilter(apps_util::kIntentActionView, kMimeTypeText));
+  AddGuestOsAppWithIntentFilter(
+      text_app_id, apps::AppType::kCrostini,
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     kMimeTypeText));
 
   // Check if the text Crostini app is returned.
   std::vector<FullTaskDescriptor> tasks =
@@ -720,12 +751,15 @@
   EXPECT_FALSE(tasks[0].is_file_extension_match);
 }
 
-TEST_F(AppServiceFileTasksTestEnabled, CrostiniCheckPathsCanBeShared) {
+// Checks that we can detect when the file paths can/ can't be shared for
+// Crostini and PluginVm.
+TEST_F(AppServiceFileTasksTestEnabled, CheckPathsCanBeShared) {
   std::string file_name = "foo.txt";
   std::string text_app_id = "Text app";
-  AddCrostiniAppWithIntentFilter(
-      text_app_id,
-      CreateFileIntentFilter(apps_util::kIntentActionView, kMimeTypeText));
+  AddGuestOsAppWithIntentFilter(
+      text_app_id, apps::AppType::kCrostini,
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     kMimeTypeText));
 
   // Possible to share path.
   std::vector<FullTaskDescriptor> tasks =
@@ -745,12 +779,14 @@
   std::string file_name = "foo.txt";
   std::string app_id_1 = "Text app 1";
   std::string app_id_2 = "Text app 2";
-  AddCrostiniAppWithIntentFilter(
-      app_id_1,
-      CreateFileIntentFilter(apps_util::kIntentActionView, kMimeTypeText));
-  AddCrostiniAppWithIntentFilter(
-      app_id_2,
-      CreateFileIntentFilter(apps_util::kIntentActionView, kMimeTypeText));
+  AddGuestOsAppWithIntentFilter(
+      app_id_1, apps::AppType::kCrostini,
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     kMimeTypeText));
+  AddGuestOsAppWithIntentFilter(
+      app_id_2, apps::AppType::kCrostini,
+      CreateMimeTypeFileIntentFilter(apps_util::kIntentActionView,
+                                     kMimeTypeText));
 
   // Check if both Crostini apps are returned.
   std::vector<FullTaskDescriptor> tasks =
@@ -778,7 +814,8 @@
   auto intent_filter =
       apps_util::CreateFileFilter({apps_util::kIntentActionView}, {mime_type},
                                   {extension}, "open-with", false);
-  AddCrostiniAppWithIntentFilter(app_id, std::move(intent_filter));
+  AddGuestOsAppWithIntentFilter(app_id, apps::AppType::kCrostini,
+                                std::move(intent_filter));
 
   std::vector<FullTaskDescriptor> tasks =
       FindAppServiceTasks({{file_name, "application/octet-stream"}});
@@ -786,5 +823,46 @@
   EXPECT_EQ(app_id, tasks[0].task_descriptor.app_id);
 }
 
+TEST_F(AppServiceFileTasksTestEnabled, FindAppServicePluginVmApp) {
+  std::string file_ext = "txt";
+  std::string file_name = "foo." + file_ext;
+  std::string text_app_id = "Text app";
+  AddGuestOsAppWithIntentFilter(text_app_id, apps::AppType::kPluginVm,
+                                CreateExtensionTypeFileIntentFilter(
+                                    apps_util::kIntentActionView, file_ext));
+
+  // Check if the text PluginVm app is returned.
+  std::vector<FullTaskDescriptor> tasks = FindAppServiceTasks({{file_name}});
+  ASSERT_EQ(1U, tasks.size());
+  EXPECT_EQ(text_app_id, tasks[0].task_descriptor.app_id);
+  EXPECT_FALSE(tasks[0].is_generic_file_handler);
+  EXPECT_TRUE(tasks[0].is_file_extension_match);
+}
+
+TEST_F(AppServiceFileTasksTestEnabled, FindMultipleAppServicePluginVmApps) {
+  std::string file_ext = "txt";
+  std::string file_name = "foo." + file_ext;
+  std::string app_id_1 = "Text app 1";
+  std::string app_id_2 = "Text app 2";
+  AddGuestOsAppWithIntentFilter(app_id_1, apps::AppType::kPluginVm,
+                                CreateExtensionTypeFileIntentFilter(
+                                    apps_util::kIntentActionView, file_ext));
+  AddGuestOsAppWithIntentFilter(app_id_2, apps::AppType::kPluginVm,
+                                CreateExtensionTypeFileIntentFilter(
+                                    apps_util::kIntentActionView, file_ext));
+
+  // Check if both PluginVm apps are returned.
+  std::vector<FullTaskDescriptor> tasks = FindAppServiceTasks({{file_name}});
+  ASSERT_EQ(2U, tasks.size());
+
+  EXPECT_EQ(app_id_1, tasks[0].task_descriptor.app_id);
+  EXPECT_FALSE(tasks[0].is_generic_file_handler);
+  EXPECT_TRUE(tasks[0].is_file_extension_match);
+
+  EXPECT_EQ(app_id_2, tasks[1].task_descriptor.app_id);
+  EXPECT_FALSE(tasks[1].is_generic_file_handler);
+  EXPECT_TRUE(tasks[1].is_file_extension_match);
+}
+
 }  // namespace file_tasks
 }  // namespace file_manager.
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task.cc b/chrome/browser/ash/file_manager/copy_or_move_io_task.cc
index db1f9f2..762bf988 100644
--- a/chrome/browser/ash/file_manager/copy_or_move_io_task.cc
+++ b/chrome/browser/ash/file_manager/copy_or_move_io_task.cc
@@ -85,8 +85,11 @@
     std::vector<storage::FileSystemURL> source_urls,
     storage::FileSystemURL destination_folder,
     Profile* profile,
-    scoped_refptr<storage::FileSystemContext> file_system_context)
-    : profile_(profile), file_system_context_(file_system_context) {
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    bool show_notification)
+    : IOTask(show_notification),
+      profile_(profile),
+      file_system_context_(file_system_context) {
   DCHECK(type == OperationType::kCopy || type == OperationType::kMove);
   progress_.state = State::kQueued;
   progress_.type = type;
@@ -107,12 +110,14 @@
     std::vector<base::FilePath> destination_file_names,
     storage::FileSystemURL destination_folder,
     Profile* profile,
-    scoped_refptr<storage::FileSystemContext> file_system_context)
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    bool show_notification)
     : CopyOrMoveIOTask(type,
                        source_urls,
                        std::move(destination_folder),
                        profile,
-                       file_system_context) {
+                       file_system_context,
+                       show_notification) {
   DCHECK_EQ(source_urls.size(), destination_file_names.size());
   destination_file_names_ = std::move(destination_file_names);
 }
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task.h b/chrome/browser/ash/file_manager/copy_or_move_io_task.h
index 52b5159..a04c98c8 100644
--- a/chrome/browser/ash/file_manager/copy_or_move_io_task.h
+++ b/chrome/browser/ash/file_manager/copy_or_move_io_task.h
@@ -35,7 +35,8 @@
       std::vector<storage::FileSystemURL> source_urls,
       storage::FileSystemURL destination_folder,
       Profile* profile,
-      scoped_refptr<storage::FileSystemContext> file_system_context);
+      scoped_refptr<storage::FileSystemContext> file_system_context,
+      bool show_notification = true);
   // Use this constructor if you require the destination entries to have
   // different file names to the source entries. The size of `source_urls` and
   // `destination_file_names` must be the same.
@@ -45,7 +46,8 @@
       std::vector<base::FilePath> destination_file_names,
       storage::FileSystemURL destination_folder,
       Profile* profile,
-      scoped_refptr<storage::FileSystemContext> file_system_context);
+      scoped_refptr<storage::FileSystemContext> file_system_context,
+      bool show_notification = true);
   ~CopyOrMoveIOTask() override;
 
   // Starts the copy or move.
diff --git a/chrome/browser/ash/file_manager/delete_io_task.cc b/chrome/browser/ash/file_manager/delete_io_task.cc
index af5d4b31..ba317c3 100644
--- a/chrome/browser/ash/file_manager/delete_io_task.cc
+++ b/chrome/browser/ash/file_manager/delete_io_task.cc
@@ -21,8 +21,9 @@
 
 DeleteIOTask::DeleteIOTask(
     std::vector<storage::FileSystemURL> file_urls,
-    scoped_refptr<storage::FileSystemContext> file_system_context)
-    : file_system_context_(file_system_context) {
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    bool show_notification)
+    : IOTask(show_notification), file_system_context_(file_system_context) {
   progress_.state = State::kQueued;
   progress_.type = OperationType::kDelete;
   progress_.bytes_transferred = 0;
diff --git a/chrome/browser/ash/file_manager/delete_io_task.h b/chrome/browser/ash/file_manager/delete_io_task.h
index 07bad4d..623810d 100644
--- a/chrome/browser/ash/file_manager/delete_io_task.h
+++ b/chrome/browser/ash/file_manager/delete_io_task.h
@@ -28,7 +28,8 @@
 class DeleteIOTask : public IOTask {
  public:
   DeleteIOTask(std::vector<storage::FileSystemURL> file_urls,
-               scoped_refptr<storage::FileSystemContext> file_system_context);
+               scoped_refptr<storage::FileSystemContext> file_system_context,
+               bool show_notification = true);
   ~DeleteIOTask() override;
 
   // Starts the delete.
diff --git a/chrome/browser/ash/file_manager/empty_trash_io_task.cc b/chrome/browser/ash/file_manager/empty_trash_io_task.cc
index e704b78..1255a0e6 100644
--- a/chrome/browser/ash/file_manager/empty_trash_io_task.cc
+++ b/chrome/browser/ash/file_manager/empty_trash_io_task.cc
@@ -31,8 +31,10 @@
     blink::StorageKey storage_key,
     Profile* profile,
     scoped_refptr<storage::FileSystemContext> file_system_context,
-    base::FilePath base_path)
-    : file_system_context_(file_system_context),
+    base::FilePath base_path,
+    bool show_notification)
+    : IOTask(show_notification),
+      file_system_context_(file_system_context),
       storage_key_(storage_key),
       profile_(profile),
       base_path_(base_path) {
diff --git a/chrome/browser/ash/file_manager/empty_trash_io_task.h b/chrome/browser/ash/file_manager/empty_trash_io_task.h
index 1d18178..883b308 100644
--- a/chrome/browser/ash/file_manager/empty_trash_io_task.h
+++ b/chrome/browser/ash/file_manager/empty_trash_io_task.h
@@ -37,7 +37,8 @@
       blink::StorageKey storage_key,
       Profile* profile,
       scoped_refptr<storage::FileSystemContext> file_system_context,
-      base::FilePath base_path);
+      base::FilePath base_path,
+      bool show_notification = true);
 
   ~EmptyTrashIOTask() override;
 
diff --git a/chrome/browser/ash/file_manager/extract_io_task.cc b/chrome/browser/ash/file_manager/extract_io_task.cc
index b73b09e8..a15a488e 100644
--- a/chrome/browser/ash/file_manager/extract_io_task.cc
+++ b/chrome/browser/ash/file_manager/extract_io_task.cc
@@ -35,8 +35,10 @@
     std::string password,
     storage::FileSystemURL parent_folder,
     Profile* profile,
-    scoped_refptr<storage::FileSystemContext> file_system_context)
-    : source_urls_(std::move(source_urls)),
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    bool show_notification)
+    : IOTask(show_notification),
+      source_urls_(std::move(source_urls)),
       password_(std::move(password)),
       parent_folder_(std::move(parent_folder)),
       profile_(profile),
diff --git a/chrome/browser/ash/file_manager/extract_io_task.h b/chrome/browser/ash/file_manager/extract_io_task.h
index fb3ddc4..d8607ed9 100644
--- a/chrome/browser/ash/file_manager/extract_io_task.h
+++ b/chrome/browser/ash/file_manager/extract_io_task.h
@@ -48,7 +48,8 @@
                 std::string password,
                 storage::FileSystemURL parent_folder,
                 Profile* profile,
-                scoped_refptr<storage::FileSystemContext> file_system_context);
+                scoped_refptr<storage::FileSystemContext> file_system_context,
+                bool show_notification = true);
   ~ExtractIOTask() override;
 
   void Execute(ProgressCallback progress_callback,
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 757b2cff..6692983 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -2200,6 +2200,12 @@
             .FilesSwa(),
         TestCase("trashTraversingFolderShowsDisallowedDialog")
             .EnableTrash()
+            .FilesSwa(),
+        TestCase("trashDontShowTrashRootOnSelectFileDialog")
+            .EnableTrash()
+            .FilesSwa(),
+        TestCase("trashDontShowTrashRootWhenOpeningAsAndroidFilePicker")
+            .EnableTrash()
             .FilesSwa()));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index 6e13d64..d41c5cb 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -2336,8 +2336,15 @@
     const std::string* type = value.FindString("type");
     if (type)
       arg_value.Set("type", *type);
+
+    const base::Value::List* volume_filter = value.FindList("volumeFilter");
+    if (volume_filter) {
+      base::Value::List cloned_volume_filter = volume_filter->Clone();
+      arg_value.Set("volumeFilter", std::move(cloned_volume_filter));
+    }
+
     std::string search;
-    if (launch_dir || type) {
+    if (launch_dir || type || volume_filter) {
       std::string json_args;
       base::JSONWriter::Write(arg_value, &json_args);
       search = base::StrCat(
diff --git a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
index 2c05b6b3..5f91daa 100644
--- a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
@@ -135,7 +135,8 @@
         if (test.mime_type != nullptr) {
           // Sniffing isn't used when GetMimeTypeFromFile() succeeds, so there
           // shouldn't be a hard-coded mime type configured.
-          EXPECT_TRUE(mime_type.empty());
+          EXPECT_TRUE(mime_type.empty())
+              << "Did not expect mime match " << mime_type << " for " << path;
           mime_type = test.mime_type;
         } else {
           EXPECT_FALSE(mime_type.empty()) << "No mime type for " << path;
@@ -187,21 +188,21 @@
       {"webp"},
 
       // Raw.
-      {"arw", false},
-      {"cr2", false},
-      {"dng", false},
-      {"nef", false},
-      {"nrw", false},
-      {"orf", false},
-      {"raf", false},
-      {"rw2", false},
+      {"arw"},
+      {"cr2"},
+      {"dng"},
+      {"nef"},
+      {"nrw"},
+      {"orf"},
+      {"raf"},
+      {"rw2"},
 
       // Video.
-      {"3gp", false},
-      {"avi", false},
+      {"3gp"},
+      {"avi"},
       {"m4v"},
-      {"mkv", false},
-      {"mov", false},
+      {"mkv"},
+      {"mov"},
       {"mp4"},
       {"mpeg"},
       {"mpeg4", false},
@@ -209,11 +210,11 @@
       {"mpg4", false},
       {"ogm"},
       {"ogv"},
-      {"ogx", false},
+      {"ogx"},
       {"webm"},
 
       // Audio.
-      {"amr", false},
+      {"amr"},
       {"flac"},
       {"m4a"},
       {"mp3"},
@@ -253,36 +254,28 @@
       {"png", kMediaAppId},
       {"webp", kMediaAppId},
       // Raw (handled by MediaApp).
-      {"arw", kMediaAppId, "image/tiff"},
-      {"cr2", kMediaAppId, "image/tiff"},
-      {"dng", kMediaAppId, "image/tiff"},
-      {"nef", kMediaAppId, "image/tiff"},
-      {"nrw", kMediaAppId, "image/tiff"},
-      {"orf", kMediaAppId, "image/tiff"},
-      {"raf", kMediaAppId, "image/tiff"},
-      {"rw2", kMediaAppId, "image/tiff"},
-      {"NRW", kMediaAppId, "image/tiff"},  // Uppercase extension.
-      {"arw", kMediaAppId, ""},  // Missing MIME type (unable to sniff).
+      {"arw", kMediaAppId},
+      {"cr2", kMediaAppId},
+      {"dng", kMediaAppId},
+      {"nef", kMediaAppId},
+      {"nrw", kMediaAppId},
+      {"orf", kMediaAppId},
+      {"raf", kMediaAppId},
+      {"rw2", kMediaAppId},
+      {"NRW", kMediaAppId},  // Uppercase extension.
   };
   TestExpectationsAgainstDefaultTasks(expectations);
 }
 
 IN_PROC_BROWSER_TEST_P(FileTasksBrowserTest, VideoHandlerChangeDetector) {
   std::vector<Expectation> expectations = {
-      {"3gp", kMediaAppId, "application/octet-stream"},
-      {"avi", kMediaAppId, "application/octet-stream"},
-      {"m4v", kMediaAppId},
-      {"mkv", kMediaAppId, "video/webm"},
-      {"mov", kMediaAppId, "application/octet-stream"},
-      {"mp4", kMediaAppId},
-      {"mpeg", kMediaAppId},
-      {"mpeg4", kMediaAppId, "video/mpeg"},
-      {"mpg", kMediaAppId},
-      {"mpg4", kMediaAppId, "video/mpeg"},
-      {"ogm", kMediaAppId},
-      {"ogv", kMediaAppId},
-      {"ogx", kMediaAppId, "video/ogg"},
-      {"webm", kMediaAppId},
+      {"3gp", kMediaAppId},  {"avi", kMediaAppId},
+      {"m4v", kMediaAppId},  {"mkv", kMediaAppId},
+      {"mov", kMediaAppId},  {"mp4", kMediaAppId},
+      {"mpeg", kMediaAppId}, {"mpeg4", kMediaAppId, "video/mpeg"},
+      {"mpg", kMediaAppId},  {"mpg4", kMediaAppId, "video/mpeg"},
+      {"ogm", kMediaAppId},  {"ogv", kMediaAppId},
+      {"ogx", kMediaAppId},  {"webm", kMediaAppId},
   };
   TestExpectationsAgainstDefaultTasks(expectations);
 }
@@ -320,11 +313,8 @@
   std::vector<Expectation> expectations = {
       {"doc", extension_misc::kQuickOfficeComponentExtensionId},
       {"docx", extension_misc::kQuickOfficeComponentExtensionId},
-      {"ppt", extension_misc::kQuickOfficeComponentExtensionId,
-       "application/vnd.ms-powerpoint"},
-      {"pptx", extension_misc::kQuickOfficeComponentExtensionId,
-       "application/"
-       "vnd.openxmlformats-officedocument.presentationml.presentation"},
+      {"ppt", extension_misc::kQuickOfficeComponentExtensionId},
+      {"pptx", extension_misc::kQuickOfficeComponentExtensionId},
       {"xls", extension_misc::kQuickOfficeComponentExtensionId},
       {"xlsx", extension_misc::kQuickOfficeComponentExtensionId},
   };
diff --git a/chrome/browser/ash/file_manager/filesystem_api_util.cc b/chrome/browser/ash/file_manager/filesystem_api_util.cc
index 2800fab..9ca1ff3d 100644
--- a/chrome/browser/ash/file_manager/filesystem_api_util.cc
+++ b/chrome/browser/ash/file_manager/filesystem_api_util.cc
@@ -12,8 +12,12 @@
 #include "base/callback.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/strings/string_util.h"
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/fileapi/arc_content_file_system_url_util.h"
+#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h"
+#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h"
+#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_util.h"
 #include "chrome/browser/ash/arc/fileapi/arc_file_system_operation_runner.h"
 #include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/drive/file_system_util.h"
@@ -31,6 +35,7 @@
 #include "google_apis/common/task_util.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 #include "storage/browser/file_system/file_system_context.h"
+#include "url/gurl.h"
 
 namespace file_manager {
 namespace util {
@@ -76,6 +81,53 @@
   }
 }
 
+void OnResolveToContentUrl(
+    base::OnceCallback<void(const absl::optional<std::string>&)> callback,
+    Profile* profile,
+    const base::FilePath& path,
+    const GURL& content_url) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(profile);
+
+  if (content_url.is_valid()) {
+    auto* runner =
+        arc::ArcFileSystemOperationRunner::GetForBrowserContext(profile);
+    if (!runner) {
+      std::move(callback).Run(absl::nullopt);
+      return;
+    }
+    runner->GetMimeType(
+        content_url,
+        base::BindOnce(&GetMimeTypeAfterGetMimeTypeForArcContentFileSystem,
+                       std::move(callback)));
+    return;
+  }
+
+  // If |content url| could not be parsed from documents provider special
+  // path (i.e. absolute path is obfuscated), then lookup by extension in the
+  // |kAndroidMimeTypeMappings| as a backup method.
+  if (path.empty()) {
+    LOG(ERROR) << "File path is empty";
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+  base::FilePath::StringType extension =
+      base::ToLowerASCII(path.FinalExtension());
+  if (extension.empty()) {
+    LOG(ERROR) << "File name is missing extension for path: " << path;
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+  extension = extension.substr(1);  // Strip the leading dot.
+  const std::string mime_type = arc::FindArcMimeTypeFromExtension(extension);
+  if (mime_type.empty()) {
+    LOG(ERROR) << "Could not find ARC mime type from extension: " << extension;
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+  std::move(callback).Run(mime_type);
+}
+
 // Helper function to converts a callback that takes boolean value to that takes
 // File::Error, by regarding FILE_OK as the only successful value.
 void BoolCallbackAsFileErrorCallback(base::OnceCallback<void(bool)> callback,
@@ -229,20 +281,59 @@
     return;
   }
 
-  if (arc::IsArcAllowedForProfile(profile) &&
-      base::FilePath(arc::kContentFileSystemMountPointPath).IsParent(path)) {
-    GURL arc_url = arc::PathToArcUrl(path);
-    auto* runner =
-        arc::ArcFileSystemOperationRunner::GetForBrowserContext(profile);
-    if (!runner) {
-      content::GetUIThreadTaskRunner({})->PostTask(
-          FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
-      return;
+  if (arc::IsArcAllowedForProfile(profile)) {
+    if (base::FilePath(arc::kContentFileSystemMountPointPath).IsParent(path)) {
+      const GURL arc_url = arc::PathToArcUrl(path);
+      if (!arc_url.is_valid()) {
+        LOG(ERROR) << "ARC URL is invalid for path: " << path;
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+        return;
+      }
+
+      auto* runner =
+          arc::ArcFileSystemOperationRunner::GetForBrowserContext(profile);
+      if (!runner) {
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+        return;
+      }
+      runner->GetMimeType(
+          arc_url,
+          base::BindOnce(&GetMimeTypeAfterGetMimeTypeForArcContentFileSystem,
+                         std::move(callback)));
+    } else if (base::FilePath(arc::kDocumentsProviderMountPointPath)
+                   .IsParent(path)) {
+      auto* root_map =
+          arc::ArcDocumentsProviderRootMap::GetForArcBrowserContext();
+      if (!root_map) {
+        LOG(ERROR) << "Could not find root map from ARC browser context";
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+        return;
+      }
+
+      std::string authority;
+      std::string root_document_id;
+      if (!arc::ParseDocumentsProviderPath(path, &authority,
+                                           &root_document_id)) {
+        LOG(ERROR) << "Failed to parse documents provider path: " << path;
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+        return;
+      }
+      auto* root = root_map->Lookup(authority, root_document_id);
+      if (!root) {
+        LOG(ERROR) << "No root found for authority: " << authority
+                   << " document_id: " << root_document_id;
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+        return;
+      }
+      root->ResolveToContentUrl(
+          path, base::BindOnce(&OnResolveToContentUrl, std::move(callback),
+                               profile, path));
     }
-    runner->GetMimeType(
-        arc_url,
-        base::BindOnce(&GetMimeTypeAfterGetMimeTypeForArcContentFileSystem,
-                       std::move(callback)));
     return;
   }
 
diff --git a/chrome/browser/ash/file_manager/io_task.cc b/chrome/browser/ash/file_manager/io_task.cc
index 732cadf..b6df4ac 100644
--- a/chrome/browser/ash/file_manager/io_task.cc
+++ b/chrome/browser/ash/file_manager/io_task.cc
@@ -36,7 +36,9 @@
 
 DummyIOTask::DummyIOTask(std::vector<storage::FileSystemURL> source_urls,
                          storage::FileSystemURL destination_folder,
-                         OperationType type) {
+                         OperationType type,
+                         bool show_notifications)
+    : IOTask(show_notifications) {
   progress_.state = State::kQueued;
   progress_.type = type;
   progress_.destination_folder = std::move(destination_folder);
diff --git a/chrome/browser/ash/file_manager/io_task.h b/chrome/browser/ash/file_manager/io_task.h
index 2d20eda..6463b45 100644
--- a/chrome/browser/ash/file_manager/io_task.h
+++ b/chrome/browser/ash/file_manager/io_task.h
@@ -45,7 +45,16 @@
   kEmptyTrash,
   kExtract,
   kMove,
+
+  // This restores to the location supplied in the .trashinfo folder, recreating
+  // the parent hierarchy as required. As .Trash folders reside on the same
+  // filesystem as trashed files, this implies an intra filesystem move.
   kRestore,
+
+  // This restores to a supplied destination only extracting the file name to
+  // properly name the destination file. The destination folder is expected to
+  // exist and items can be restored cross filesystem.
+  kRestoreToDestination,
   kTrash,
   kZip,
 };
@@ -110,12 +119,18 @@
 
   // The estimate time to finish the operation.
   double remaining_seconds = 0;
+
+  // Whether notifications should be shown on progress status.
+  bool show_notification = true;
 };
 
 // An IOTask represents an I/O operation over multiple files, and is responsible
 // for executing the operation and providing progress/completion reports.
 class IOTask {
  public:
+  IOTask() = delete;
+  IOTask(const IOTask& other) = delete;
+  IOTask& operator=(const IOTask& other) = delete;
   virtual ~IOTask() = default;
 
   using ProgressCallback = base::RepeatingCallback<void(const ProgressStatus&)>;
@@ -137,9 +152,9 @@
   const ProgressStatus& progress() { return progress_; }
 
  protected:
-  IOTask() = default;
-  IOTask(const IOTask& other) = delete;
-  IOTask& operator=(const IOTask& other) = delete;
+  explicit IOTask(bool show_notification) {
+    progress_.show_notification = show_notification;
+  }
 
   ProgressStatus progress_;
 
@@ -154,7 +169,8 @@
  public:
   DummyIOTask(std::vector<storage::FileSystemURL> source_urls,
               storage::FileSystemURL destination_folder,
-              OperationType type);
+              OperationType type,
+              bool show_notification = true);
   ~DummyIOTask() override;
 
   void Execute(ProgressCallback progress_callback,
diff --git a/chrome/browser/ash/file_manager/restore_io_task.cc b/chrome/browser/ash/file_manager/restore_io_task.cc
index a5b8808..a7d28ccb 100644
--- a/chrome/browser/ash/file_manager/restore_io_task.cc
+++ b/chrome/browser/ash/file_manager/restore_io_task.cc
@@ -38,8 +38,10 @@
     std::vector<storage::FileSystemURL> file_urls,
     Profile* profile,
     scoped_refptr<storage::FileSystemContext> file_system_context,
-    const base::FilePath base_path)
-    : file_system_context_(file_system_context),
+    const base::FilePath base_path,
+    bool show_notification)
+    : IOTask(show_notification),
+      file_system_context_(file_system_context),
       profile_(profile),
       base_path_(base_path) {
   progress_.state = State::kQueued;
diff --git a/chrome/browser/ash/file_manager/restore_io_task.h b/chrome/browser/ash/file_manager/restore_io_task.h
index 027dcc8..2e9dba7 100644
--- a/chrome/browser/ash/file_manager/restore_io_task.h
+++ b/chrome/browser/ash/file_manager/restore_io_task.h
@@ -33,10 +33,11 @@
   RestoreIOTask(std::vector<storage::FileSystemURL> file_urls,
                 Profile* profile,
                 scoped_refptr<storage::FileSystemContext> file_system_context,
-                const base::FilePath base_path);
+                const base::FilePath base_path,
+                bool show_notification = true);
   ~RestoreIOTask() override;
 
-  // Starts restore trask.
+  // Starts restore task.
   void Execute(ProgressCallback progress_callback,
                CompleteCallback complete_callback) override;
   void Cancel() override;
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc b/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc
new file mode 100644
index 0000000..722df0b3
--- /dev/null
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task.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 "chrome/browser/ash/file_manager/restore_to_destination_io_task.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "chrome/browser/ash/file_manager/path_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace file_manager::io_task {
+
+RestoreToDestinationIOTask::RestoreToDestinationIOTask(
+    std::vector<storage::FileSystemURL> file_urls,
+    storage::FileSystemURL destination_folder,
+    Profile* profile,
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    const base::FilePath base_path,
+    bool show_notification)
+    : IOTask(show_notification),
+      file_system_context_(file_system_context),
+      profile_(profile),
+      base_path_(base_path) {
+  progress_.state = State::kQueued;
+  progress_.type = OperationType::kRestoreToDestination;
+  progress_.destination_folder = std::move(destination_folder);
+  progress_.bytes_transferred = 0;
+  progress_.total_bytes = 0;
+
+  for (const auto& url : file_urls) {
+    progress_.sources.emplace_back(url, absl::nullopt);
+  }
+}
+
+RestoreToDestinationIOTask::~RestoreToDestinationIOTask() = default;
+
+void RestoreToDestinationIOTask::Execute(
+    IOTask::ProgressCallback progress_callback,
+    IOTask::CompleteCallback complete_callback) {
+  progress_callback_ = std::move(progress_callback);
+  complete_callback_ = std::move(complete_callback);
+
+  if (progress_.sources.size() == 0) {
+    Complete(State::kSuccess);
+    return;
+  }
+
+  progress_.state = State::kInProgress;
+  validator_ =
+      std::make_unique<trash::TrashInfoValidator>(profile_, base_path_);
+  validator_->SetDisconnectHandler(
+      base::BindOnce(&RestoreToDestinationIOTask::Complete,
+                     weak_ptr_factory_.GetWeakPtr(), State::kError));
+
+  ValidateTrashInfo(0);
+}
+
+// Calls the completion callback for the task. `progress_` should not be
+// accessed after calling this. If the `trash_service_` is disconnected, it will
+// end up here so avoid accessing `trash_service_` here.
+void RestoreToDestinationIOTask::Complete(State state) {
+  progress_.state = state;
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(complete_callback_), std::move(progress_)));
+}
+
+void RestoreToDestinationIOTask::ValidateTrashInfo(size_t idx) {
+  const base::FilePath& trash_info =
+      (base_path_.empty())
+          ? progress_.sources[idx].url.path()
+          : base_path_.Append(progress_.sources[idx].url.path());
+
+  auto on_parsed_callback =
+      base::BindOnce(&RestoreToDestinationIOTask::OnTrashInfoParsed,
+                     weak_ptr_factory_.GetWeakPtr(), idx);
+
+  validator_->ValidateAndParseTrashInfo(std::move(trash_info),
+                                        std::move(on_parsed_callback));
+}
+
+void RestoreToDestinationIOTask::OnTrashInfoParsed(
+    size_t idx,
+    base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data) {
+  if (parsed_data.is_error()) {
+    progress_.sources[idx].error = parsed_data.error();
+    Complete(State::kError);
+    return;
+  }
+
+  destination_file_names_.emplace_back(
+      parsed_data.value().absolute_restore_path.BaseName());
+  source_urls_.push_back(file_system_context_->CreateCrackedFileSystemURL(
+      progress_.sources[idx].url.storage_key(),
+      progress_.sources[idx].url.type(),
+      MakeRelativeFromBasePath(parsed_data.value().trashed_file_path)));
+
+  if (progress_.sources.size() == (idx + 1)) {
+    // Make sure to reset the TrashInfoValidator as it is not required anymore.
+    validator_.reset();
+
+    // The `RestoreToDestination` task is composed of the `CopyOrMoveIOTask`.
+    // All data is passed to the task, but a pointer is maintained to ensure the
+    // parent task is tied to the life of the child task.
+    move_io_task_ = std::make_unique<CopyOrMoveIOTask>(
+        OperationType::kMove, std::move(source_urls_),
+        std::move(destination_file_names_), progress_.destination_folder,
+        profile_, file_system_context_);
+    move_io_task_->Execute(std::move(progress_callback_),
+                           std::move(complete_callback_));
+    return;
+  }
+
+  ValidateTrashInfo(idx + 1);
+}
+
+base::FilePath RestoreToDestinationIOTask::MakeRelativeFromBasePath(
+    const base::FilePath& absolute_path) {
+  if (base_path_.empty() || !base_path_.IsParent(absolute_path)) {
+    return absolute_path;
+  }
+  std::string relative_path = absolute_path.value();
+  if (!file_manager::util::ReplacePrefix(
+          &relative_path, base_path_.AsEndingWithSeparator().value(), "")) {
+    LOG(ERROR) << "Failed to make absolute path relative";
+    return absolute_path;
+  }
+  return base::FilePath(relative_path);
+}
+
+void RestoreToDestinationIOTask::Cancel() {
+  progress_.state = State::kCancelled;
+  if (move_io_task_) {
+    // Delegate Cancel to the underlying `move_io_task_` if it has been started.
+    move_io_task_->Cancel();
+  }
+}
+
+}  // namespace file_manager::io_task
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task.h b/chrome/browser/ash/file_manager/restore_to_destination_io_task.h
new file mode 100644
index 0000000..e167561
--- /dev/null
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task.h
@@ -0,0 +1,105 @@
+// 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_FILE_MANAGER_RESTORE_TO_DESTINATION_IO_TASK_H_
+#define CHROME_BROWSER_ASH_FILE_MANAGER_RESTORE_TO_DESTINATION_IO_TASK_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/files/file_error_or.h"
+#include "base/files/file_path.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/file_manager/copy_or_move_io_task.h"
+#include "chrome/browser/ash/file_manager/io_task.h"
+#include "chrome/browser/ash/file_manager/trash_info_validator.h"
+#include "storage/browser/file_system/file_system_context.h"
+#include "storage/browser/file_system/file_system_url.h"
+
+class Profile;
+
+namespace file_manager::io_task {
+
+// This class represents a task restoring from trash. A restore task attempts to
+// restore files from a supported Trash folder to the supplied destination
+// folder. The validation of the supplied .trashinfo files occurs here but the
+// actual move operation is delegated to the `CopyOrMoveIOTask`.
+//
+// This follows the XDG specification
+// https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html
+class RestoreToDestinationIOTask : public IOTask {
+ public:
+  RestoreToDestinationIOTask(
+      std::vector<storage::FileSystemURL> file_urls,
+      storage::FileSystemURL destination_folder,
+      Profile* profile,
+      scoped_refptr<storage::FileSystemContext> file_system_context,
+      const base::FilePath base_path,
+      bool show_notification);
+  ~RestoreToDestinationIOTask() override;
+
+  // Starts restore to destination task.
+  void Execute(ProgressCallback progress_callback,
+               CompleteCallback complete_callback) override;
+
+  // Passes the Cancel on to the underlying `move_io_task_` in the event one has
+  // been kicked off.
+  void Cancel() override;
+
+ private:
+  // Finalises the RestoreToDestinationIOTask with the `state`.
+  // NOTE: This IOTask delegates the actual move operation to the underlying
+  // CopyOrMoveIOTask, so once all .trashinfo files are parsed the callbacks are
+  // passed to the next IOTask and this Complete method is no longer called.
+  void Complete(State state);
+
+  // Calls the underlying TrashInfoValidator to perform validation on the
+  // supplied .trashinfo file.
+  void ValidateTrashInfo(size_t idx);
+
+  // After parsing the .trashinfo, ensure the returned data is valid. Once all
+  // .trashinfo's are parsed, create and delegate the move operation to the
+  // `move_io_task`
+  void OnTrashInfoParsed(
+      size_t idx,
+      base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data);
+
+  base::FilePath MakeRelativeFromBasePath(const base::FilePath& absolute_path);
+
+  scoped_refptr<storage::FileSystemContext> file_system_context_;
+  raw_ptr<Profile> profile_;
+
+  // Represents the parent path that all the source URLs descend from. Used to
+  // work around the fact `FileSystemOperationRunner` requires relative paths
+  // only in testing.
+  base::FilePath base_path_;
+
+  // The file names are extracted from the supplied .trashinfo files and passed
+  // into the `move_io_task_` to ensure the restoration uses the restore file
+  // name instead of the on-disk file name.
+  std::vector<base::FilePath> destination_file_names_;
+
+  // Maintain a copy of the `source_urls_` to enable passing to the
+  // `move_io_task_` without trying to extract them back out of the
+  // `progress_.sources`.
+  std::vector<storage::FileSystemURL> source_urls_;
+
+  // The `CopyOrMoveIOTask` is the underlying move operation that is called once
+  // the .trashinfo files are successfully parsed.
+  std::unique_ptr<CopyOrMoveIOTask> move_io_task_ = nullptr;
+
+  // Validates and parses .trashinfo files.
+  std::unique_ptr<trash::TrashInfoValidator> validator_ = nullptr;
+
+  ProgressCallback progress_callback_;
+  CompleteCallback complete_callback_;
+
+  base::WeakPtrFactory<RestoreToDestinationIOTask> weak_ptr_factory_{this};
+};
+
+}  // namespace file_manager::io_task
+
+#endif  // CHROME_BROWSER_ASH_FILE_MANAGER_RESTORE_TO_DESTINATION_IO_TASK_H_
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc b/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc
new file mode 100644
index 0000000..0571bec
--- /dev/null
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc
@@ -0,0 +1,127 @@
+// 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/file_manager/restore_to_destination_io_task.h"
+
+#include "base/files/file_util.h"
+#include "base/rand_util.h"
+#include "base/run_loop.h"
+#include "base/strings/strcat.h"
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
+#include "base/time/time.h"
+#include "base/time/time_to_iso8601.h"
+#include "chrome/browser/ash/file_manager/trash_common_util.h"
+#include "chrome/browser/ash/file_manager/trash_unittest_base.h"
+#include "chromeos/ash/components/trash_service/public/cpp/trash_service.h"
+#include "chromeos/ash/components/trash_service/public/mojom/trash_service.mojom-forward.h"
+#include "chromeos/ash/components/trash_service/trash_service_impl.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "storage/common/file_system/file_system_types.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace file_manager::io_task {
+namespace {
+
+using ::base::test::RunClosure;
+using ::testing::_;
+using ::testing::Field;
+
+class RestoreToDestinationIOTaskTest : public TrashBaseTest {
+ public:
+  RestoreToDestinationIOTaskTest() = default;
+
+  RestoreToDestinationIOTaskTest(const RestoreToDestinationIOTaskTest&) =
+      delete;
+  RestoreToDestinationIOTaskTest& operator=(
+      const RestoreToDestinationIOTaskTest&) = delete;
+
+  void SetUp() override {
+    TrashBaseTest::SetUp();
+
+    // The TrashService launches a sandboxed process to perform parsing in, in
+    // unit tests this is not possible. So instead override the launcher to
+    // start an in-process TrashService and have `LaunchTrashService` invoke it.
+    chromeos::trash_service::SetTrashServiceLaunchOverrideForTesting(
+        base::BindRepeating(
+            &RestoreToDestinationIOTaskTest::CreateInProcessTrashService,
+            base::Unretained(this)));
+  }
+
+  mojo::PendingRemote<chromeos::trash_service::mojom::TrashService>
+  CreateInProcessTrashService() {
+    mojo::PendingRemote<chromeos::trash_service::mojom::TrashService> remote;
+    trash_service_impl_ =
+        std::make_unique<chromeos::trash_service::TrashServiceImpl>(
+            remote.InitWithNewPipeAndPassReceiver());
+    return remote;
+  }
+
+  std::string GenerateTrashInfoContents(const std::string& restore_path) {
+    return base::StrCat({"[Trash Info]\nPath=", restore_path, "\nDeletionDate=",
+                         base::TimeToISO8601(base::Time::UnixEpoch())});
+  }
+
+ private:
+  // Maintains ownership fo the in-process parsing service.
+  std::unique_ptr<chromeos::trash_service::TrashServiceImpl>
+      trash_service_impl_;
+};
+
+TEST_F(RestoreToDestinationIOTaskTest,
+       RestorePathWithDifferentNameInTrashInfoSucceeds) {
+  EnsureTrashDirectorySetup(downloads_dir_);
+
+  // Setup the destination directory where the file will be restored to.
+  base::FilePath destination_path = temp_dir_.GetPath().Append("dest_folder");
+  ASSERT_TRUE(base::CreateDirectory(destination_path));
+
+  // Setup the contents for files in the Trash directory.
+  std::string foo_contents = base::RandBytesAsString(kTestFileSize);
+  std::string foo_metadata_contents =
+      GenerateTrashInfoContents("/Downloads/bar/baz.txt");
+
+  // Write contents to the files in the trash directory.
+  const base::FilePath trash_path =
+      downloads_dir_.Append(trash::kTrashFolderName);
+  const base::FilePath info_file_path =
+      trash_path.Append(trash::kInfoFolderName).Append("foo.txt.trashinfo");
+  ASSERT_TRUE(base::WriteFile(info_file_path, foo_metadata_contents));
+  const base::FilePath files_path =
+      trash_path.Append(trash::kFilesFolderName).Append("foo.txt");
+  ASSERT_TRUE(base::WriteFile(files_path, foo_contents));
+
+  // Setup source and destination locations.
+  base::RunLoop run_loop;
+  std::vector<storage::FileSystemURL> source_urls = {
+      CreateFileSystemURL(info_file_path),
+  };
+  auto dest = file_system_context_->CreateCrackedFileSystemURL(
+      kTestStorageKey, storage::kFileSystemTypeTest,
+      destination_path.BaseName());
+
+  base::MockRepeatingCallback<void(const ProgressStatus&)> progress_callback;
+  base::MockOnceCallback<void(ProgressStatus)> complete_callback;
+
+  EXPECT_CALL(progress_callback, Run(_)).Times(0);
+  EXPECT_CALL(complete_callback,
+              Run(Field(&ProgressStatus::state, State::kSuccess)))
+      .WillOnce(RunClosure(run_loop.QuitClosure()));
+
+  RestoreToDestinationIOTask task(source_urls, dest, profile_.get(),
+                                  file_system_context_, temp_dir_.GetPath(),
+                                  /*show_notification=*/true);
+  task.Execute(progress_callback.Get(), complete_callback.Get());
+  run_loop.Run();
+
+  EXPECT_TRUE(base::PathExists(destination_path.Append("baz.txt")));
+  std::string contents;
+  ASSERT_TRUE(
+      base::ReadFileToString(destination_path.Append("baz.txt"), &contents));
+  EXPECT_EQ(foo_contents, contents);
+}
+
+}  // namespace
+}  // namespace file_manager::io_task
diff --git a/chrome/browser/ash/file_manager/trash_io_task.cc b/chrome/browser/ash/file_manager/trash_io_task.cc
index 586b2dd..ede8d1f3 100644
--- a/chrome/browser/ash/file_manager/trash_io_task.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task.cc
@@ -84,8 +84,10 @@
     std::vector<storage::FileSystemURL> file_urls,
     Profile* profile,
     scoped_refptr<storage::FileSystemContext> file_system_context,
-    const base::FilePath base_path)
-    : profile_(profile),
+    const base::FilePath base_path,
+    bool show_notification)
+    : IOTask(show_notification),
+      profile_(profile),
       file_system_context_(file_system_context),
       base_path_(base_path) {
   progress_.state = State::kQueued;
diff --git a/chrome/browser/ash/file_manager/trash_io_task.h b/chrome/browser/ash/file_manager/trash_io_task.h
index bc331bf..c8581218 100644
--- a/chrome/browser/ash/file_manager/trash_io_task.h
+++ b/chrome/browser/ash/file_manager/trash_io_task.h
@@ -75,7 +75,8 @@
   TrashIOTask(std::vector<storage::FileSystemURL> file_urls,
               Profile* profile,
               scoped_refptr<storage::FileSystemContext> file_system_context,
-              const base::FilePath base_path);
+              const base::FilePath base_path,
+              bool show_notification = true);
   ~TrashIOTask() override;
 
   // Starts trash trask.
diff --git a/chrome/browser/ash/file_manager/zip_io_task.cc b/chrome/browser/ash/file_manager/zip_io_task.cc
index ff97c6f4..52c4e8f 100644
--- a/chrome/browser/ash/file_manager/zip_io_task.cc
+++ b/chrome/browser/ash/file_manager/zip_io_task.cc
@@ -66,8 +66,9 @@
 ZipIOTask::ZipIOTask(
     std::vector<storage::FileSystemURL> source_urls,
     storage::FileSystemURL parent_folder,
-    scoped_refptr<storage::FileSystemContext> file_system_context)
-    : file_system_context_(file_system_context) {
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    bool show_notification)
+    : IOTask(show_notification), file_system_context_(file_system_context) {
   progress_.state = State::kQueued;
   progress_.type = OperationType::kZip;
   progress_.destination_folder = std::move(parent_folder);
diff --git a/chrome/browser/ash/file_manager/zip_io_task.h b/chrome/browser/ash/file_manager/zip_io_task.h
index 8dbbf57..99d92af5 100644
--- a/chrome/browser/ash/file_manager/zip_io_task.h
+++ b/chrome/browser/ash/file_manager/zip_io_task.h
@@ -29,7 +29,8 @@
   // used as the filename of the archive. Otherwise 'Archive.zip' will be used.
   ZipIOTask(std::vector<storage::FileSystemURL> source_urls,
             storage::FileSystemURL parent_folder,
-            scoped_refptr<storage::FileSystemContext> file_system_context);
+            scoped_refptr<storage::FileSystemContext> file_system_context,
+            bool show_notification = true);
   ~ZipIOTask() override;
 
   void Execute(ProgressCallback progress_callback,
diff --git a/chrome/browser/ash/guest_os/DEPS b/chrome/browser/ash/guest_os/DEPS
new file mode 100644
index 0000000..c1636fe
--- /dev/null
+++ b/chrome/browser/ash/guest_os/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/xdg_shared_mime_info",
+]
diff --git a/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc b/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
index 6acb541..531a67f 100644
--- a/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
+++ b/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
@@ -17,6 +17,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "third_party/xdg_shared_mime_info/mime_cache.h"
 
 namespace guest_os {
 
@@ -117,7 +118,13 @@
 
   base::Value exts(base::Value::Type::DICTIONARY);
   for (const auto& mapping : mime_type_mappings.mime_type_mappings()) {
-    exts.SetStringKey(mapping.first, mapping.second);
+    // Only store mappings from container that are different to host.
+    std::string type;
+    if (!xdg_shared_mime_info::GetMimeCacheTypeFromExtension(mapping.first,
+                                                             &type) ||
+        mapping.second != type) {
+      exts.SetStringKey(mapping.first, mapping.second);
+    }
   }
   VLOG(1) << "UpdateMimeTypes(" << mime_type_mappings.vm_name() << ", "
           << mime_type_mappings.container_name() << ")=" << exts;
diff --git a/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc b/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
index 12d2a5b..09e2884 100644
--- a/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
+++ b/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
@@ -77,11 +77,12 @@
 };
 
 TEST_F(GuestOsMimeTypesServiceTest, SetAndGetMimeTypes) {
+  // 'text/plain' is already mapped by system, so we will not store it.
   std::vector<std::string> file_extensions = {
-      "foo", "bar", "gz", "xz", "tar.gz", "c", "C", "z", "🦈x"};
-  std::vector<std::string> mime_types = {"x/foo", "x/bar",    "x/gz",
-                                         "x/xz",  "x/tar.gz", "x/c",
-                                         "x/C",   "x/z",      "x/shark"};
+      "foo", "bar", "gz", "xz", "tar.gz", "c", "C", "z", "🦈x", "txt"};
+  std::vector<std::string> mime_types = {
+      "x/foo", "x/bar", "x/gz", "x/xz",    "x/tar.gz",
+      "x/c",   "x/C",   "x/z",  "x/shark", "text/plain"};
 
   // Mime types not registered yet.
   EXPECT_EQ("", GetMimeType("test.foo"));
@@ -103,6 +104,8 @@
   EXPECT_EQ("x/tar.gz", GetMimeType("test.tar.GZ"));
   // Support unicode.
   EXPECT_EQ("x/shark", GetMimeType("test.🦈X"));
+  // We only store items different to platform.
+  EXPECT_EQ("", GetMimeType("test.txt"));
 }
 
 // Test that UpdateMimeTypes doesn't clobber MIME types from different VMs or
diff --git a/chrome/browser/ash/hats/hats_notification_controller.cc b/chrome/browser/ash/hats/hats_notification_controller.cc
index aa50219..a87fb74 100644
--- a/chrome/browser/ash/hats/hats_notification_controller.cc
+++ b/chrome/browser/ash/hats/hats_notification_controller.cc
@@ -27,7 +27,9 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
+#include "chromeos/ash/components/network/network_handler.h"
 #include "chromeos/ash/components/network/network_state.h"
+#include "chromeos/ash/components/network/network_state_handler.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/gaia/gaia_auth_util.h"
@@ -120,8 +122,8 @@
 
   base::UmaHistogramEnumeration("Browser.ChromeOS.HatsStatus", state_);
 
-  if (network_portal_detector::IsInitialized())
-    network_portal_detector::GetInstance()->RemoveObserver(this);
+  if (NetworkHandler::IsInitialized())
+    NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
 }
 
 void HatsNotificationController::Initialize(bool is_new_device) {
@@ -136,9 +138,19 @@
     return;
   }
 
-  // Add self as an observer to be notified when an internet connection is
-  // available.
-  network_portal_detector::GetInstance()->AddAndFireObserver(this);
+  if (NetworkHandler::IsInitialized()) {
+    // Observe NetworkStateHandler to be notified when an internet connection
+    // is available.
+    NetworkStateHandler* handler =
+        ash::NetworkHandler::Get()->network_state_handler();
+    handler->AddObserver(this);
+    // Create an immediate update for the current default network.
+    const NetworkState* default_network = handler->DefaultNetwork();
+    NetworkState::PortalState portal_state =
+        default_network ? default_network->GetPortalState()
+                        : NetworkState::PortalState::kUnknown;
+    PortalStateChanged(default_network, portal_state);
+  }
 }
 
 // static
@@ -211,7 +223,7 @@
   state_ = HatsState::kNotificationClicked;
 
   // Remove the notification.
-  network_portal_detector::GetInstance()->RemoveObserver(this);
+  ash::NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
   notification_.reset(nullptr);
   NotificationDisplayService::GetForProfile(profile_)->Close(
       NotificationHandler::Type::TRANSIENT, kNotificationId);
@@ -223,21 +235,21 @@
 
   if (by_user) {
     UpdateLastInteractionTime();
-    network_portal_detector::GetInstance()->RemoveObserver(this);
+    ash::NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
     notification_.reset(nullptr);
     state_ = HatsState::kNotificationDismissed;
   }
 }
 
-// NetworkPortalDetector::Observer override:
-void HatsNotificationController::OnPortalDetectionCompleted(
-    const NetworkState* network,
-    const NetworkPortalDetector::CaptivePortalStatus status) {
+// NetworkStateHandlerObserver override:
+void HatsNotificationController::PortalStateChanged(
+    const ash::NetworkState* default_network,
+    ash::NetworkState::PortalState portal_state) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  VLOG(1) << "HatsController::OnPortalDetectionCompleted(): "
-          << "network=" << (network ? network->path() : "") << ", "
-          << "status=" << status;
-  if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
+  VLOG(1) << "PortalStateChanged: default_network="
+          << (default_network ? default_network->path() : "")
+          << ", portal_state=" << portal_state;
+  if (portal_state == NetworkState::PortalState::kOnline) {
     // Create and display the notification for the user.
     if (!notification_) {
       notification_ = CreateSystemNotification(
@@ -265,6 +277,10 @@
   }
 }
 
+void HatsNotificationController::OnShuttingDown() {
+  NetworkHandler::Get()->network_state_handler()->RemoveObserver(this);
+}
+
 void HatsNotificationController::UpdateLastInteractionTime() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
diff --git a/chrome/browser/ash/hats/hats_notification_controller.h b/chrome/browser/ash/hats/hats_notification_controller.h
index c95ae10f..1e329377d 100644
--- a/chrome/browser/ash/hats/hats_notification_controller.h
+++ b/chrome/browser/ash/hats/hats_notification_controller.h
@@ -8,7 +8,7 @@
 #include "base/containers/flat_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/weak_ptr.h"
-#include "chromeos/ash/components/network/portal_detector/network_portal_detector.h"
+#include "chromeos/ash/components/network/network_state_handler_observer.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
 
@@ -27,7 +27,7 @@
 // managing the HaTS notification that is displayed to the user.
 // This class lives on the UI thread.
 class HatsNotificationController : public message_center::NotificationDelegate,
-                                   public NetworkPortalDetector::Observer {
+                                   public NetworkStateHandlerObserver {
  public:
   static const char kNotificationId[];
 
@@ -79,16 +79,17 @@
     kMaxValue = kNotificationClicked
   };
 
-  // NotificationDelegate overrides:
   void Initialize(bool is_new_device);
+
+  // NotificationDelegate overrides:
   void Close(bool by_user) override;
   void Click(const absl::optional<int>& button_index,
              const absl::optional<std::u16string>& reply) override;
 
-  // NetworkPortalDetector::Observer override:
-  void OnPortalDetectionCompleted(
-      const NetworkState* network,
-      const NetworkPortalDetector::CaptivePortalStatus status) override;
+  // NetworkStateHandlerObserver override:
+  void PortalStateChanged(const ash::NetworkState* default_network,
+                          ash::NetworkState::PortalState portal_state) override;
+  void OnShuttingDown() override;
 
   void UpdateLastInteractionTime();
 
diff --git a/chrome/browser/ash/hats/hats_notification_controller_unittest.cc b/chrome/browser/ash/hats/hats_notification_controller_unittest.cc
index 6433526..f18e105 100644
--- a/chrome/browser/ash/hats/hats_notification_controller_unittest.cc
+++ b/chrome/browser/ash/hats/hats_notification_controller_unittest.cc
@@ -13,9 +13,8 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chromeos/ash/components/network/network_handler_test_helper.h"
 #include "chromeos/ash/components/network/network_state.h"
-#include "chromeos/ash/components/network/portal_detector/mock_network_portal_detector.h"
-#include "chromeos/ash/components/network/portal_detector/network_portal_detector.h"
 #include "components/image_fetcher/core/request_metadata.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -50,15 +49,15 @@
 
     display_service_ =
         std::make_unique<NotificationDisplayServiceTester>(profile());
-    network_portal_detector::InitializeForTesting(
-        &mock_network_portal_detector_);
+    helper_ = std::make_unique<NetworkHandlerTestHelper>();
   }
 
   void TearDown() override {
-    // The notifications may be deleted async.
-    base::RunLoop loop;
-    loop.RunUntilIdle();
-    network_portal_detector::InitializeForTesting(nullptr);
+    helper_.reset();
+    display_service_.reset();
+    // Notifications may be deleted async.
+    base::RunLoop().RunUntilIdle();
+
     BrowserWithTestWindowTest::TearDown();
   }
 
@@ -72,23 +71,18 @@
     // HatsController::IsNewDevice() is run on a blocking thread.
     content::RunAllTasksUntilIdle();
 
-    // Send a callback to the observer to simulate internet connectivity is
-    // present on device.
-    ON_CALL(mock_network_portal_detector_,
-            AddAndFireObserver(hats_notification_controller.get()))
-        .WillByDefault(Invoke([](NetworkPortalDetector::Observer* observer) {
-          NetworkState network_state("");
-          observer->OnPortalDetectionCompleted(
-              &network_state,
-              NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE);
-        }));
-
     return hats_notification_controller;
   }
 
-  NiceMock<MockNetworkPortalDetector> mock_network_portal_detector_;
+  void SendPortalState(scoped_refptr<HatsNotificationController>& controller,
+                       NetworkState::PortalState portal_state) {
+    NetworkState network_state("");
+    controller->PortalStateChanged(&network_state, portal_state);
+    base::RunLoop().RunUntilIdle();
+  }
 
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
+  std::unique_ptr<NetworkHandlerTestHelper> helper_;
 };
 
 TEST_F(HatsNotificationControllerTest, NewDevice_ShouldNotShowNotification) {
@@ -108,27 +102,15 @@
   ASSERT_TRUE(base::Time::FromInternalValue(current_timestamp) >
               base::Time::FromInternalValue(initial_timestamp));
 
-  // Destructor for HatsController removes self from observer list.
-  EXPECT_CALL(mock_network_portal_detector_,
-              RemoveObserver(hats_notification_controller.get()))
-      .Times(1);
-
   EXPECT_FALSE(display_service_->GetNotification(
       HatsNotificationController::kNotificationId));
 }
 
 TEST_F(HatsNotificationControllerTest, OldDevice_ShouldShowNotification) {
   auto hats_notification_controller = InstantiateHatsController();
-
-  // On initialization, HatsNotificationController adds itself as an observer to
-  // NetworkPortalDetector to detect internet connectivity.
-  EXPECT_CALL(mock_network_portal_detector_,
-              AddAndFireObserver(hats_notification_controller.get()))
-      .Times(1);
-
   hats_notification_controller->Initialize(false);
 
-  // Finally check if notification was launched to confirm initialization.
+  // Ensure notification was launched to confirm initialization.
   EXPECT_TRUE(display_service_->GetNotification(
       HatsNotificationController::kNotificationId));
 
@@ -141,27 +123,23 @@
 TEST_F(HatsNotificationControllerTest, NoInternet_DoNotShowNotification) {
   auto hats_notification_controller = InstantiateHatsController();
 
-  // Upon destruction HatsNotificationController removes itself as an observer
-  // from NetworkPortalDetector. This will only be called once from the
-  // destructor.
-  EXPECT_CALL(mock_network_portal_detector_,
-              RemoveObserver(hats_notification_controller.get()))
-      .Times(1);
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kUnknown);
+  EXPECT_FALSE(display_service_->GetNotification(
+      HatsNotificationController::kNotificationId));
 
-  NetworkState network_state("");
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state, NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN);
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kNoInternet);
+  EXPECT_FALSE(display_service_->GetNotification(
+      HatsNotificationController::kNotificationId));
 
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state, NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE);
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kPortal);
+  EXPECT_FALSE(display_service_->GetNotification(
+      HatsNotificationController::kNotificationId));
 
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state, NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL);
-
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state,
-      NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED);
-
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kProxyAuthRequired);
   EXPECT_FALSE(display_service_->GetNotification(
       HatsNotificationController::kNotificationId));
 }
@@ -173,36 +151,20 @@
 
   auto hats_notification_controller = InstantiateHatsController();
 
-  // HatsController removed as a network observer when user closes notification.
-  EXPECT_CALL(mock_network_portal_detector_,
-              RemoveObserver(hats_notification_controller.get()))
-      .Times(1);
-
   // Simulate closing notification via user interaction.
   hats_notification_controller->Close(true);
 
   int64_t new_timestamp =
       pref_service->GetInt64(prefs::kHatsLastInteractionTimestamp);
   // The flag should be updated to a new timestamp.
-  ASSERT_TRUE(base::Time::FromInternalValue(new_timestamp) >
+  EXPECT_TRUE(base::Time::FromInternalValue(new_timestamp) >
               base::Time::FromInternalValue(now_timestamp));
-
-  // Destructor for HatsController removes self from observer list.
-  EXPECT_CALL(mock_network_portal_detector_,
-              RemoveObserver(hats_notification_controller.get()))
-      .Times(1);
 }
 
 TEST_F(HatsNotificationControllerTest,
        Disconnected_RemoveNotification_Connected_AddNotification) {
   auto hats_notification_controller = InstantiateHatsController();
 
-  // On initialization, HatsNotificationController adds itself as an observer to
-  // NetworkPortalDetector to detect internet connectivity.
-  EXPECT_CALL(mock_network_portal_detector_,
-              AddAndFireObserver(hats_notification_controller.get()))
-      .Times(1);
-
   hats_notification_controller->Initialize(false);
 
   // Notification is launched.
@@ -210,15 +172,14 @@
       HatsNotificationController::kNotificationId));
 
   // Notification is removed when Internet connection is lost.
-  NetworkState network_state("");
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state, NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE);
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kNoInternet);
   EXPECT_FALSE(display_service_->GetNotification(
       HatsNotificationController::kNotificationId));
 
   // Notification is launched again when Internet connection is regained.
-  hats_notification_controller->OnPortalDetectionCompleted(
-      &network_state, NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE);
+  SendPortalState(hats_notification_controller,
+                  NetworkState::PortalState::kOnline);
   EXPECT_TRUE(display_service_->GetNotification(
       HatsNotificationController::kNotificationId));
 
diff --git a/chrome/browser/ash/kerberos/OWNERS b/chrome/browser/ash/kerberos/OWNERS
index bfe96c1..cf144fc 100644
--- a/chrome/browser/ash/kerberos/OWNERS
+++ b/chrome/browser/ash/kerberos/OWNERS
@@ -6,7 +6,7 @@
 fsandrade@chromium.org
 
 # Secondary owner(s)
-rsorokin@chromium.org
+rsorokin@google.com
 
 # Previous owners (for general questions, if current owners are not available)
 # Commented out so automatic tools don't prefer.
diff --git a/chrome/browser/ash/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc b/chrome/browser/ash/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
index 8ab12546..db20cd8 100644
--- a/chrome/browser/ash/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
+++ b/chrome/browser/ash/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
@@ -39,6 +39,7 @@
 #include "components/crx_file/id_util.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/common/extension.h"
@@ -359,7 +360,7 @@
 
     base::FilePath user_profile_path =
         user_data_dir_.GetPath().Append(ProfileHelper::Get()->GetUserProfileDir(
-            ProfileHelper::GetUserIdHashByUserIdForTesting(kPrimaryUser)));
+            user_manager::FakeUserManager::GetFakeUsernameHash(account_id)));
     auto profile = std::make_unique<TestingProfile>(user_profile_path);
     primary_profile_ = profile.get();
     profile_manager_->RegisterTestingProfile(std::move(profile),
diff --git a/chrome/browser/ash/login/crash_restore_browsertest.cc b/chrome/browser/ash/login/crash_restore_browsertest.cc
index c1af28b..eb344fd 100644
--- a/chrome/browser/ash/login/crash_restore_browsertest.cc
+++ b/chrome/browser/ash/login/crash_restore_browsertest.cc
@@ -35,6 +35,7 @@
 #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
 #include "components/account_id/account_id.h"
 #include "components/session_manager/core/session_manager.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
@@ -208,10 +209,9 @@
     base::FilePath user_data_dir;
     ASSERT_TRUE(base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
 
-    const char* kTestUserIds[] = {kUserId1, kUserId2, kUserId3};
-    for (auto* user_id : kTestUserIds) {
+    for (const auto& account_id : {account_id1_, account_id2_, account_id3_}) {
       const std::string user_id_hash =
-          ProfileHelper::GetUserIdHashByUserIdForTesting(user_id);
+          user_manager::FakeUserManager::GetFakeUsernameHash(account_id);
       const base::FilePath user_profile_path =
           user_data_dir.Append(ProfileHelper::GetUserProfileDir(user_id_hash));
       ASSERT_TRUE(base::CreateDirectory(user_profile_path));
diff --git a/chrome/browser/ash/login/enrollment/OWNERS b/chrome/browser/ash/login/enrollment/OWNERS
index f1f531d..c308060 100644
--- a/chrome/browser/ash/login/enrollment/OWNERS
+++ b/chrome/browser/ash/login/enrollment/OWNERS
@@ -1,7 +1,7 @@
 antrim@chromium.org
 emaxx@chromium.org
 pmarko@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 
 per-file *auto_enrollment*=igorcov@chromium.org
 per-file *auto_enrollment*=mpolzer@google.com
diff --git a/chrome/browser/ash/login/lock_screen_utils.cc b/chrome/browser/ash/login/lock_screen_utils.cc
index 7a31180..6eb6595 100644
--- a/chrome/browser/ash/login/lock_screen_utils.cc
+++ b/chrome/browser/ash/login/lock_screen_utils.cc
@@ -111,10 +111,10 @@
 
 void EnforceDevicePolicyInputMethods(std::string user_input_method_id) {
   auto* cros_settings = CrosSettings::Get();
-  const base::ListValue* login_screen_input_methods = nullptr;
+  const base::Value::List* login_screen_input_methods = nullptr;
   if (!cros_settings->GetList(kDeviceLoginScreenInputMethods,
                               &login_screen_input_methods) ||
-      login_screen_input_methods->GetListDeprecated().empty()) {
+      login_screen_input_methods->empty()) {
     StopEnforcingPolicyInputMethods();
     return;
   }
@@ -126,8 +126,7 @@
     allowed_input_method_ids.push_back(user_input_method_id);
   }
 
-  for (const auto& input_method_entry :
-       login_screen_input_methods->GetListDeprecated()) {
+  for (const auto& input_method_entry : *login_screen_input_methods) {
     if (input_method_entry.is_string())
       allowed_input_method_ids.push_back(input_method_entry.GetString());
   }
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
index 903dd03..3b36445 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/BUILD.gn
@@ -60,6 +60,7 @@
   ]
   sources = [
     "fast_pair_advertiser_unittest.cc",
+    "incoming_connection_unittest.cc",
     "target_device_connection_broker_impl_unittest.cc",
     "target_fido_controller_unittest.cc",
   ]
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc
index 0fe026e..497e3d3 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.cc
@@ -4,14 +4,30 @@
 
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
 
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 #include "crypto/random.h"
-
 namespace ash::quick_start {
 
-IncomingConnection::IncomingConnection() {
+IncomingConnection::IncomingConnection(RandomSessionId session_id)
+    : random_session_id_(session_id) {
   crypto::RandBytes(shared_secret_);
 }
 
+IncomingConnection::IncomingConnection(RandomSessionId session_id,
+                                       std::array<uint8_t, 32> shared_secret)
+    : random_session_id_(session_id), shared_secret_(shared_secret) {}
+
 IncomingConnection::~IncomingConnection() = default;
 
+std::vector<uint8_t> IncomingConnection::GetQrCodeData() const {
+  // TODO(b/234655072): Align with Android on whether |random_session_id_| and
+  // |shared_secret_| should be encoded as hex strings here.
+  std::string url = "https://signin.google/qs/" +
+                    random_session_id_.ToString() +
+                    "?key=" + base::HexEncode(shared_secret_);
+
+  return std::vector<uint8_t>(url.begin(), url.end());
+}
+
 }  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h
index 58fc1d1..7876592 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h
@@ -8,6 +8,7 @@
 #include <array>
 
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
 
 namespace ash::quick_start {
 
@@ -15,12 +16,24 @@
 // remote source device.
 class IncomingConnection : public Connection {
  public:
-  IncomingConnection();
+  explicit IncomingConnection(RandomSessionId session_id);
+
+  // An alternate constructor that accepts a shared_secret for testing purposes
+  // or for resuming a connection after a critical update.
+  IncomingConnection(RandomSessionId session_id,
+                     std::array<uint8_t, 32> shared_secret);
+
   IncomingConnection(IncomingConnection&) = delete;
   IncomingConnection& operator=(IncomingConnection&) = delete;
   ~IncomingConnection() override;
 
+  // Returns a deep link URL as a vector of bytes that will form the QR code
+  // used to authenticate the connection.
+  std::vector<uint8_t> GetQrCodeData() const;
+
  private:
+  RandomSessionId random_session_id_;
+
   // A secret represented in a 32-byte array that gets generated and sent to the
   // source device so it can be used later to authenticate the connection.
   std::array<uint8_t, 32> shared_secret_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc
new file mode 100644
index 0000000..dc2339c
--- /dev/null
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection_unittest.cc
@@ -0,0 +1,85 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/incoming_connection.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ash/login/oobe_quick_start/connectivity/random_session_id.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash::quick_start {
+
+namespace {
+
+// Base qr code url ("https://signin.google/qs/") represented in a 25 byte
+// array.
+constexpr std::array<uint8_t, 25> kBaseUrl = {
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73,
+    0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2e, 0x67, 0x6f, 0x6f,
+    0x67, 0x6c, 0x65, 0x2f, 0x71, 0x73, 0x2f};
+
+// Qr code key param ("?key=") represented in a 5 byte array.
+constexpr std::array<uint8_t, 5> kUrlKeyParam = {0x3f, 0x6b, 0x65, 0x79, 0x3d};
+
+// 10 random bytes to use as the RandomSessionId.
+constexpr std::array<uint8_t, 10> kRandomSessionId = {
+    0x6b, 0xb3, 0x85, 0x27, 0xbb, 0x28, 0xb4, 0x59, 0x16, 0xca};
+
+// Hex representation of kRandomSessionId. kRandomSessionId is converted into a
+// hex string, then each character of that string is represented as a byte
+// below.
+constexpr std::array<uint8_t, 20> kRandomSessionIdHex = {
+    0x36, 0x42, 0x42, 0x33, 0x38, 0x35, 0x32, 0x37, 0x42, 0x42,
+    0x32, 0x38, 0x42, 0x34, 0x35, 0x39, 0x31, 0x36, 0x43, 0x41};
+
+// 32 random bytes to use as the shared secret.
+constexpr std::array<uint8_t, 32> kSharedSecret = {
+    0x54, 0xbd, 0x40, 0xcf, 0x8a, 0x7c, 0x2f, 0x6a, 0xca, 0x15, 0x59,
+    0xcf, 0xf3, 0xeb, 0x31, 0x08, 0x90, 0x73, 0xef, 0xda, 0x87, 0xd4,
+    0x23, 0xc0, 0x55, 0xd5, 0x83, 0x5b, 0x04, 0x28, 0x49, 0xf2};
+
+// Hex representation of kSharedSecret. kSharedSecret is converted into a hex
+// string, then each character of that string is represented as a byte below.
+constexpr std::array<uint8_t, 64> kSharedSecretHex = {
+    0x35, 0x34, 0x42, 0x44, 0x34, 0x30, 0x43, 0x46, 0x38, 0x41, 0x37,
+    0x43, 0x32, 0x46, 0x36, 0x41, 0x43, 0x41, 0x31, 0x35, 0x35, 0x39,
+    0x43, 0x46, 0x46, 0x33, 0x45, 0x42, 0x33, 0x31, 0x30, 0x38, 0x39,
+    0x30, 0x37, 0x33, 0x45, 0x46, 0x44, 0x41, 0x38, 0x37, 0x44, 0x34,
+    0x32, 0x33, 0x43, 0x30, 0x35, 0x35, 0x44, 0x35, 0x38, 0x33, 0x35,
+    0x42, 0x30, 0x34, 0x32, 0x38, 0x34, 0x39, 0x46, 0x32};
+
+}  // namespace
+
+class IncomingConnectionTest : public testing::Test {
+ public:
+  IncomingConnectionTest(const IncomingConnectionTest&) = delete;
+  IncomingConnectionTest& operator=(const IncomingConnectionTest&) = delete;
+
+ protected:
+  IncomingConnectionTest() = default;
+
+  void SetUp() override {
+    RandomSessionId session_id(kRandomSessionId);
+    incoming_connection_ =
+        std::make_unique<IncomingConnection>(session_id, kSharedSecret);
+  }
+
+  std::unique_ptr<IncomingConnection> incoming_connection_;
+};
+
+TEST_F(IncomingConnectionTest, TestGetQrCodeData) {
+  std::vector<uint8_t> expected_data(std::begin(kBaseUrl), std::end(kBaseUrl));
+  expected_data.insert(expected_data.end(), std::begin(kRandomSessionIdHex),
+                       std::end(kRandomSessionIdHex));
+  expected_data.insert(expected_data.end(), std::begin(kUrlKeyParam),
+                       std::end(kUrlKeyParam));
+  expected_data.insert(expected_data.end(), std::begin(kSharedSecretHex),
+                       std::end(kSharedSecretHex));
+
+  std::vector<uint8_t> actual_data = incoming_connection_->GetQrCodeData();
+
+  EXPECT_EQ(expected_data, actual_data);
+}
+
+}  // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.cc
index b342430..cf7d198 100644
--- a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.cc
+++ b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.cc
@@ -223,6 +223,8 @@
     return FingerprintLocation::RIGHT_SIDE;
   if (location_info == "left-side")
     return FingerprintLocation::LEFT_SIDE;
+  if (location_info == "left-of-power-button-top-right")
+    return FingerprintLocation::LEFT_OF_POWER_BUTTON_TOP_RIGHT;
   NOTREACHED() << "Not handled value: " << location_info;
   return default_location;
 }
@@ -274,6 +276,12 @@
       resource_id_dark = IDR_FINGERPRINT_LAPTOP_BOTTOM_LEFT_ANIMATION_DARK;
       resource_id_light = IDR_FINGERPRINT_LAPTOP_BOTTOM_LEFT_ANIMATION_LIGHT;
       break;
+    case FingerprintLocation::LEFT_OF_POWER_BUTTON_TOP_RIGHT:
+      resource_id_dark =
+          IDR_FINGERPRINT_LAPTOP_LEFT_OF_POWER_BUTTON_TOP_RIGHT_ANIMATION_DARK;
+      resource_id_light =
+          IDR_FINGERPRINT_LAPTOP_LEFT_OF_POWER_BUTTON_TOP_RIGHT_ANIMATION_LIGHT;
+      break;
     case FingerprintLocation::KEYBOARD_TOP_RIGHT:
     case FingerprintLocation::RIGHT_SIDE:
     case FingerprintLocation::LEFT_SIDE:
diff --git a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
index 15e4b7c..954c137 100644
--- a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
+++ b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
@@ -49,7 +49,8 @@
   KEYBOARD_TOP_RIGHT = 3,
   RIGHT_SIDE = 4,
   LEFT_SIDE = 5,
-  UNKNOWN = 6,
+  LEFT_OF_POWER_BUTTON_TOP_RIGHT = 6,
+  UNKNOWN = 7,
 };
 
 // Override quick unlock checks for testing.
diff --git a/chrome/browser/ash/login/saml/OWNERS b/chrome/browser/ash/login/saml/OWNERS
index bcf288a..0eeb7f4a 100644
--- a/chrome/browser/ash/login/saml/OWNERS
+++ b/chrome/browser/ash/login/saml/OWNERS
@@ -2,6 +2,6 @@
 xiyuan@chromium.org
 
 # (in CET)
-rsorokin@chromium.org
+rsorokin@google.com
 
 per-file *security_token*=emaxx@chromium.org
diff --git a/chrome/browser/ash/login/screens/consolidated_consent_screen.cc b/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
index d6331c5..974fb09 100644
--- a/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
+++ b/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
@@ -11,7 +11,9 @@
 #include "base/command_line.h"
 #include "base/hash/sha1.h"
 #include "base/i18n/timezone.h"
+#include "base/memory/weak_ptr.h"
 #include "base/strings/stringprintf.h"
+#include "base/values.h"
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/optin/arc_optin_preference_handler.h"
 #include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h"
@@ -55,6 +57,7 @@
 namespace ash {
 namespace {
 constexpr const char kBackDemoButtonClicked[] = "back";
+constexpr const char kAcceptButtonClicked[] = "tos-accept";
 
 std::string GetGoogleEulaOnlineUrl() {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -94,32 +97,20 @@
 }
 
 ConsolidatedConsentScreen::ConsolidatedConsentScreen(
-    ConsolidatedConsentScreenView* view,
+    base::WeakPtr<ConsolidatedConsentScreenView> view,
     const ScreenExitCallback& exit_callback)
     : BaseScreen(ConsolidatedConsentScreenView::kScreenId,
                  OobeScreenPriority::DEFAULT),
-      view_(view),
+      view_(std::move(view)),
       exit_callback_(exit_callback) {
   DCHECK(view_);
-  if (view_)
-    view_->Bind(this);
 }
 
 ConsolidatedConsentScreen::~ConsolidatedConsentScreen() {
-  if (view_) {
-    view_->Unbind();
-  }
-
   for (auto& observer : observer_list_)
     observer.OnConsolidatedConsentScreenDestroyed();
 }
 
-void ConsolidatedConsentScreen::OnViewDestroyed(
-    ConsolidatedConsentScreenView* view) {
-  if (view_ == view)
-    view_ = nullptr;
-}
-
 bool ConsolidatedConsentScreen::MaybeSkip(WizardContext& context) {
   if (context.skip_post_login_screens_for_tests) {
     if (features::IsOobeConsolidatedConsentEnabled())
@@ -173,27 +164,47 @@
       base::BindOnce(&ConsolidatedConsentScreen::OnOwnershipStatusCheckDone,
                      weak_factory_.GetWeakPtr()));
 
-  ConsolidatedConsentScreenView::ScreenConfig config;
-  config.is_arc_enabled = arc::IsArcTermsOfServiceOobeNegotiationNeeded();
-  config.is_demo = arc::IsArcDemoModeSetupFlow();
-  config.is_tos_hidden = chrome::enterprise_util::IsProfileAffiliated(profile);
-  config.is_child_account = is_child_account_;
-  config.country_code = base::CountryCodeForCurrentTimezone();
-  config.google_eula_url = GetGoogleEulaOnlineUrl();
-  config.cros_eula_url = GetCrosEulaOnlineUrl();
-  view_->Show(config);
+  base::Value::Dict data;
+
+  // If ARC is enabled, show the ARC ToS and the related opt-ins.
+  data.Set("isArcEnabled", arc::IsArcTermsOfServiceOobeNegotiationNeeded());
+  // In demo mode, don't show any opt-ins related to ARC and allow showing the
+  // offline ARC ToS if the online version failed to load.
+  data.Set("isDemo", arc::IsArcDemoModeSetupFlow());
+  // Child accounts have alternative strings for the opt-ins.
+  data.Set("isChildAccount", is_child_account_);
+  // If the user is affiliated with the device management domain, ToS should be
+  // hidden.
+  data.Set("isTosHidden",
+           chrome::enterprise_util::IsProfileAffiliated(profile));
+  // Country code is needed to load the ARC ToS.
+  data.Set("countryCode", base::CountryCodeForCurrentTimezone());
+  // URL for EULA, the URL should include the locale.
+  data.Set("googleEulaUrl", GetGoogleEulaOnlineUrl());
+  // URL for Chrome and ChromeOS additional terms of service, the URL should
+  // include the locale.
+  data.Set("crosEulaUrl", GetCrosEulaOnlineUrl());
+  view_->Show(std::move(data));
 }
 
 void ConsolidatedConsentScreen::HideImpl() {
   pref_handler_.reset();
 }
 
-void ConsolidatedConsentScreen::OnUserActionDeprecated(
-    const std::string& action_id) {
-  if (action_id == kBackDemoButtonClicked)
+void ConsolidatedConsentScreen::OnUserAction(const base::Value::List& args) {
+  const std::string& action_id = args[0].GetString();
+  if (action_id == kBackDemoButtonClicked) {
     exit_callback_.Run(Result::BACK_DEMO);
-  else
-    BaseScreen::OnUserActionDeprecated(action_id);
+  } else if (action_id == kAcceptButtonClicked) {
+    CHECK_EQ(args.size(), 5);
+    const bool enable_usage = args[1].GetBool();
+    const bool enable_backup = args[2].GetBool();
+    const bool enable_location = args[3].GetBool();
+    const std::string& tos_content = args[4].GetString();
+    OnAccept(enable_usage, enable_backup, enable_location, tos_content);
+  } else {
+    BaseScreen::OnUserAction(args);
+  }
 }
 
 void ConsolidatedConsentScreen::AddObserver(Observer* observer) {
diff --git a/chrome/browser/ash/login/screens/consolidated_consent_screen.h b/chrome/browser/ash/login/screens/consolidated_consent_screen.h
index 1391315..375cce045 100644
--- a/chrome/browser/ash/login/screens/consolidated_consent_screen.h
+++ b/chrome/browser/ash/login/screens/consolidated_consent_screen.h
@@ -50,7 +50,7 @@
   using TView = ConsolidatedConsentScreenView;
   using ScreenExitCallback = base::RepeatingCallback<void(Result result)>;
 
-  ConsolidatedConsentScreen(ConsolidatedConsentScreenView* view,
+  ConsolidatedConsentScreen(base::WeakPtr<ConsolidatedConsentScreenView> view,
                             const ScreenExitCallback& exit_callback);
   ~ConsolidatedConsentScreen() override;
   ConsolidatedConsentScreen(const ConsolidatedConsentScreen&) = delete;
@@ -59,10 +59,6 @@
 
   static std::string GetResultString(Result result);
 
-  // Called when the screen is being destroyed. This should call Unbind() on the
-  // associated View if this class is destroyed before that.
-  void OnViewDestroyed(ConsolidatedConsentScreenView* view);
-
   void set_exit_callback_for_testing(const ScreenExitCallback& exit_callback) {
     exit_callback_ = exit_callback;
   }
@@ -89,7 +85,7 @@
   bool MaybeSkip(WizardContext& context) override;
   void ShowImpl() override;
   void HideImpl() override;
-  void OnUserActionDeprecated(const std::string& action_id) override;
+  void OnUserAction(const base::Value::List& args) override;
   ScreenExitCallback* exit_callback() { return &exit_callback_; }
 
  private:
@@ -129,7 +125,7 @@
 
   std::unique_ptr<arc::ArcOptInPreferenceHandler> pref_handler_;
 
-  ConsolidatedConsentScreenView* view_ = nullptr;
+  base::WeakPtr<ConsolidatedConsentScreenView> view_;
 
   ScreenExitCallback exit_callback_;
 
diff --git a/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.cc b/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.cc
index d10e683..526cdd4 100644
--- a/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.cc
+++ b/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.cc
@@ -4,35 +4,25 @@
 
 #include "chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h"
 
+#include "base/memory/weak_ptr.h"
+
 namespace ash {
 
 MockConsolidatedConsentScreen::MockConsolidatedConsentScreen(
-    ConsolidatedConsentScreenView* view,
+    base::WeakPtr<ConsolidatedConsentScreenView> view,
     const ScreenExitCallback& exit_callback)
-    : ConsolidatedConsentScreen(view, exit_callback) {}
+    : ConsolidatedConsentScreen(std::move(view), exit_callback) {}
 
-MockConsolidatedConsentScreen::~MockConsolidatedConsentScreen() {}
+MockConsolidatedConsentScreen::~MockConsolidatedConsentScreen() = default;
 
 void MockConsolidatedConsentScreen::ExitScreen(Result result) {
   exit_callback()->Run(result);
 }
 
-MockConsolidatedConsentScreenView::MockConsolidatedConsentScreenView() {}
+MockConsolidatedConsentScreenView::MockConsolidatedConsentScreenView() =
+    default;
 
-MockConsolidatedConsentScreenView::~MockConsolidatedConsentScreenView() {
-  if (screen_)
-    screen_->OnViewDestroyed(this);
-}
-
-void MockConsolidatedConsentScreenView::Bind(
-    ConsolidatedConsentScreen* screen) {
-  screen_ = screen;
-  MockBind(screen);
-}
-
-void MockConsolidatedConsentScreenView::Unbind() {
-  screen_ = nullptr;
-  MockUnbind();
-}
+MockConsolidatedConsentScreenView::~MockConsolidatedConsentScreenView() =
+    default;
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h b/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h
index 94097d62..8cc5854 100644
--- a/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h
+++ b/chrome/browser/ash/login/screens/mock_consolidated_consent_screen.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_CONSOLIDATED_CONSENT_SCREEN_H_
 #define CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_CONSOLIDATED_CONSENT_SCREEN_H_
 
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
 #include "chrome/browser/ash/login/screens/consolidated_consent_screen.h"
 #include "chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -13,8 +15,9 @@
 
 class MockConsolidatedConsentScreen : public ConsolidatedConsentScreen {
  public:
-  MockConsolidatedConsentScreen(ConsolidatedConsentScreenView* view,
-                                const ScreenExitCallback& exit_callback);
+  MockConsolidatedConsentScreen(
+      base::WeakPtr<ConsolidatedConsentScreenView> view,
+      const ScreenExitCallback& exit_callback);
   ~MockConsolidatedConsentScreen() override;
 
   MOCK_METHOD(void, ShowImpl, ());
@@ -28,22 +31,13 @@
   MockConsolidatedConsentScreenView();
   ~MockConsolidatedConsentScreenView() override;
 
-  void Bind(ConsolidatedConsentScreen* screen) override;
-  void Unbind() override;
-
-  MOCK_METHOD(void, Show, (const ScreenConfig& config));
+  MOCK_METHOD(void, Show, (base::Value::Dict data));
   MOCK_METHOD(void, Hide, ());
-
-  MOCK_METHOD(void, MockBind, (ConsolidatedConsentScreen * screen));
-  MOCK_METHOD(void, MockUnbind, ());
   MOCK_METHOD(void, SetUsageMode, (bool enabled, bool managed));
   MOCK_METHOD(void, SetBackupMode, (bool enabled, bool managed));
   MOCK_METHOD(void, SetLocationMode, (bool enabled, bool managed));
   MOCK_METHOD(void, SetIsDeviceOwner, (bool is_owner));
   MOCK_METHOD(void, SetUsageOptinOptinHidden, (bool hidden));
-
- private:
-  ConsolidatedConsentScreen* screen_ = nullptr;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/signin_fatal_error_screen.cc b/chrome/browser/ash/login/screens/signin_fatal_error_screen.cc
index 92b497e..0c66b0a 100644
--- a/chrome/browser/ash/login/screens/signin_fatal_error_screen.cc
+++ b/chrome/browser/ash/login/screens/signin_fatal_error_screen.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/login/screens/signin_fatal_error_screen.h"
 
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/ui/login_display_host.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_fatal_error_screen_handler.h"
@@ -60,7 +61,7 @@
   if (!view_)
     return;
 
-  view_->Show(error_state_, base::OptionalOrNullptr(extra_error_info_));
+  view_->Show(error_state_, base::OptionalToPtr(extra_error_info_));
 }
 
 void SignInFatalErrorScreen::HideImpl() {}
diff --git a/chrome/browser/ash/login/screens/sync_consent_screen.cc b/chrome/browser/ash/login/screens/sync_consent_screen.cc
index e5d7387..1957a68c 100644
--- a/chrome/browser/ash/login/screens/sync_consent_screen.cc
+++ b/chrome/browser/ash/login/screens/sync_consent_screen.cc
@@ -12,7 +12,9 @@
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
 #include "base/check.h"
+#include "base/check_is_test.h"
 #include "base/command_line.h"
+#include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "chrome/browser/ash/account_manager/account_apps_availability.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
@@ -42,6 +44,12 @@
 #include "components/unified_consent/unified_consent_service.h"
 #include "components/user_manager/user_manager.h"
 
+namespace {
+
+constexpr char kUserActionContinue[] = "continue";
+
+}  // namespace
+
 namespace ash {
 namespace {
 
@@ -135,19 +143,15 @@
   }
 }
 
-SyncConsentScreen::SyncConsentScreen(SyncConsentScreenView* view,
+SyncConsentScreen::SyncConsentScreen(base::WeakPtr<SyncConsentScreenView> view,
                                      const ScreenExitCallback& exit_callback)
     : BaseScreen(SyncConsentScreenView::kScreenId, OobeScreenPriority::DEFAULT),
-      view_(view),
+      view_(std::move(view)),
       exit_callback_(exit_callback) {
   DCHECK(view_);
-  view_->Bind(this);
 }
 
-SyncConsentScreen::~SyncConsentScreen() {
-  if (view_)
-    view_->Bind(nullptr);
-}
+SyncConsentScreen::~SyncConsentScreen() = default;
 
 void SyncConsentScreen::Init(const WizardContext& context) {
   if (is_initialized_)
@@ -222,13 +226,13 @@
   // Show the entire screen.
   // If SyncScreenBehavior is show, this should show the sync consent screen.
   // If SyncScreenBehavior is unknown, this should show the loading throbber.
-  view_->Show(is_arc_restricted);
+  if (view_)
+    view_->Show(is_arc_restricted);
 }
 
 void SyncConsentScreen::HideImpl() {
   sync_service_observation_.Reset();
   timeout_waiter_.AbandonAndStop();
-  view_->Hide();
 }
 
 void SyncConsentScreen::OnStateChanged(syncer::SyncService* sync) {
@@ -352,7 +356,9 @@
 
   if (behavior_ == SyncScreenBehavior::kShow) {
     PrepareScreenBasedOnCapability();
-    view_->ShowLoadedStep();
+    if (view_) {
+      view_->ShowLoadedStep();
+    }
     GetSyncService(profile_)->RemoveObserver(this);
     timeout_waiter_.AbandonAndStop();
     base::UmaHistogramCustomTimes("OOBE.SyncConsentScreen.LoadingTime",
@@ -418,7 +424,9 @@
   // Turn on "sync everything" toggle for non-minor users; turn off all data
   // types for minor users.
   SetSyncEverythingEnabled(!is_minor_mode);
-  view_->SetIsMinorMode(is_minor_mode);
+  if (view_) {
+    view_->SetIsMinorMode(is_minor_mode);
+  }
 }
 
 void SyncConsentScreen::SetSyncEverythingEnabled(bool enabled) {
@@ -445,4 +453,44 @@
   sync_engine_initialized_for_test = value;
 }
 
+void SyncConsentScreen::HandleContinue(
+    const bool opted_in,
+    const bool review_sync,
+    const base::Value::List& consent_description_list,
+    const std::string& consent_confirmation) {
+  auto consent_description =
+      ::login::ConvertToStringList(consent_description_list);
+  std::vector<int> consent_description_ids;
+  int consent_confirmation_id;
+  if (view_) {
+    view_->RetrieveConsentIDs(consent_description, consent_confirmation,
+                              consent_description_ids, consent_confirmation_id);
+    OnContinue(opted_in, review_sync, consent_description_ids,
+               consent_confirmation_id);
+  }
+  // IN-TEST
+  SyncConsentScreen::SyncConsentScreenTestDelegate* test_delegate =
+      GetDelegateForTesting();  // IN-TEST
+  if (test_delegate) {
+    CHECK_IS_TEST();
+    test_delegate->OnConsentRecordedStrings(consent_description,
+                                            consent_confirmation);
+  }
+}
+
+void SyncConsentScreen::OnUserAction(const base::Value::List& args) {
+  const std::string& action_id = args[0].GetString();
+  if (action_id == kUserActionContinue) {
+    CHECK_EQ(args.size(), 5);
+    const bool opted_in = args[1].GetBool();
+    const bool review_sync = args[2].GetBool();
+    const base::Value::List& consent_description_list = args[3].GetList();
+    const std::string& consent_confirmation = args[4].GetString();
+    HandleContinue(opted_in, review_sync, consent_description_list,
+                   consent_confirmation);
+    return;
+  }
+  BaseScreen::OnUserAction(args);
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/sync_consent_screen.h b/chrome/browser/ash/login/screens/sync_consent_screen.h
index 22dff03f..c19cf7f 100644
--- a/chrome/browser/ash/login/screens/sync_consent_screen.h
+++ b/chrome/browser/ash/login/screens/sync_consent_screen.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/auto_reset.h"
+#include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
@@ -88,7 +89,7 @@
   // them after completing OOBE.
   static void MaybeLaunchSyncConsentSettings(Profile* profile);
 
-  SyncConsentScreen(SyncConsentScreenView* view,
+  SyncConsentScreen(base::WeakPtr<SyncConsentScreenView> view,
                     const ScreenExitCallback& exit_callback);
 
   SyncConsentScreen(const SyncConsentScreen&) = delete;
@@ -114,6 +115,11 @@
   // Called when sync engine initialization timed out.
   void OnTimeout();
 
+  void HandleContinue(const bool opted_in,
+                      const bool review_sync,
+                      const base::Value::List& consent_description_list,
+                      const std::string& consent_confirmation);
+
   // Sets internal condition "Sync disabled by policy" for tests.
   static void SetProfileSyncDisabledByPolicyForTesting(bool value);
 
@@ -141,6 +147,7 @@
   bool MaybeSkip(WizardContext& context) override;
   void ShowImpl() override;
   void HideImpl() override;
+  void OnUserAction(const base::Value::List& args) override;
 
   // Returns new SyncScreenBehavior value.
   SyncScreenBehavior GetSyncScreenBehavior(const WizardContext& context) const;
@@ -172,7 +179,7 @@
   // Spinner is shown until sync status has been decided.
   SyncScreenBehavior behavior_ = SyncScreenBehavior::kUnknown;
 
-  SyncConsentScreenView* const view_;
+  base::WeakPtr<SyncConsentScreenView> view_;
   ScreenExitCallback exit_callback_;
 
   // Manages sync service observer lifetime.
diff --git a/chrome/browser/ash/login/session/user_session_initializer.cc b/chrome/browser/ash/login/session/user_session_initializer.cc
index 0741419..636be11 100644
--- a/chrome/browser/ash/login/session/user_session_initializer.cc
+++ b/chrome/browser/ash/login/session/user_session_initializer.cc
@@ -255,7 +255,7 @@
 
     if (ash::features::AreGlanceablesEnabled()) {
       // Must be called after CalenderKeyedServiceFactory is initialized.
-      ChromeGlanceablesDelegate::Get()->OnPrimaryUserSessionStarted();
+      ChromeGlanceablesDelegate::Get()->OnPrimaryUserSessionStarted(profile);
     }
 
     // Ensure that PhoneHubManager and EcheAppManager are created for the
diff --git a/chrome/browser/ash/login/ui/login_display_host_mojo.cc b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
index 6df1c103..0c4c13e 100644
--- a/chrome/browser/ash/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
@@ -85,10 +85,10 @@
   if (allow_family_link)
     return false;
 
-  const base::ListValue* allowlist = nullptr;
+  const base::Value::List* allowlist = nullptr;
   if (!cros_settings->GetList(kAccountsPrefUsers, &allowlist) || !allowlist)
     return false;
-  for (const base::Value& i : allowlist->GetListDeprecated()) {
+  for (const base::Value& i : *allowlist) {
     const std::string* allowlisted_user = i.GetIfString();
     // NB: Wildcards in the allowlist are also detected as not present here.
     if (!allowlisted_user || !user_manager::UserManager::Get()->IsKnownUser(
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.cc b/chrome/browser/ash/login/ui/login_display_host_webui.cc
index d324324..6f2db56 100644
--- a/chrome/browser/ash/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_webui.cc
@@ -334,18 +334,18 @@
 // if no policy-specified locale is set.
 std::string GetManagedLoginScreenLocale() {
   auto* cros_settings = CrosSettings::Get();
-  const base::ListValue* login_screen_locales = nullptr;
+  const base::Value::List* login_screen_locales = nullptr;
   if (!cros_settings->GetList(kDeviceLoginScreenLocales, &login_screen_locales))
     return std::string();
 
   // Currently, only the first element is used. The setting is a list for future
   // compatibility, if dynamically switching locales on the login screen will be
   // implemented.
-  if (login_screen_locales->GetListDeprecated().empty() ||
-      !login_screen_locales->GetListDeprecated()[0].is_string())
+  if (login_screen_locales->empty() ||
+      !login_screen_locales->front().is_string())
     return std::string();
 
-  return login_screen_locales->GetListDeprecated()[0].GetString();
+  return login_screen_locales->front().GetString();
 }
 
 // Disables virtual keyboard overscroll. Login UI will scroll user pods
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
index f43e27e..c84be48 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_impl.cc
@@ -697,9 +697,12 @@
   job_.reset();
 
   const user_manager::User* user = GetUser();
+  if (!user) {
+    return;
+  }
   // If the user image for the currently logged-in user became managed, stop the
   // sync observer so that the policy-set image does not get synced out.
-  if (user && user->is_logged_in())
+  if (user->is_logged_in())
     user_image_sync_observer_.reset();
 
   user_manager_->NotifyUserImageIsEnterpriseManagedChanged(
@@ -712,8 +715,12 @@
     return;
 
   has_managed_image_ = false;
-  user_manager_->NotifyUserImageIsEnterpriseManagedChanged(
-      *GetUser(), /*is_enterprise_managed=*/false);
+
+  const auto* user = GetUser();
+  if (user) {
+    user_manager_->NotifyUserImageIsEnterpriseManagedChanged(
+        *user, /*is_enterprise_managed=*/false);
+  }
   SetInitialUserImage();
   TryToCreateImageSyncObserver();
 }
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_util.cc b/chrome/browser/ash/login/users/chrome_user_manager_util.cc
index 1ac144b..d654bf15 100644
--- a/chrome/browser/ash/login/users/chrome_user_manager_util.cc
+++ b/chrome/browser/ash/login/users/chrome_user_manager_util.cc
@@ -42,9 +42,8 @@
   for (user_manager::User* user : users) {
     const bool is_user_allowlisted =
         user->HasGaiaAccount() &&
-        CrosSettings::FindEmailInList(allowlist->GetListDeprecated(),
-                                      user->GetAccountId().GetUserEmail(),
-                                      nullptr);
+        CrosSettings::FindEmailInList(
+            allowlist->GetList(), user->GetAccountId().GetUserEmail(), nullptr);
     const bool is_allowed_because_family_link =
         allow_family_link && user->IsChild();
     const bool is_gaia_user_allowed =
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
index f9819c8d..a0e5d2c 100644
--- a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/login/login_state/login_state.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/known_user.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_image/user_image.h"
@@ -109,8 +110,8 @@
   user_manager::User* user =
       user_manager::User::CreateRegularUser(account_id, user_type);
   user->SetAffiliation(is_affiliated);
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      account_id.GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   user->SetStubImage(
       std::make_unique<user_manager::UserImage>(
           *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
@@ -128,8 +129,8 @@
 user_manager::User* FakeChromeUserManager::AddKioskAppUser(
     const AccountId& account_id) {
   user_manager::User* user = user_manager::User::CreateKioskAppUser(account_id);
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      account_id.GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   users_.push_back(user);
   return user;
 }
@@ -138,8 +139,8 @@
     const AccountId& account_id) {
   user_manager::User* user =
       user_manager::User::CreateArcKioskAppUser(account_id);
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      account_id.GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   users_.push_back(user);
   return user;
 }
@@ -148,8 +149,8 @@
     const AccountId& account_id) {
   user_manager::User* user =
       user_manager::User::CreateWebKioskAppUser(account_id);
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      account_id.GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   users_.push_back(user);
   return user;
 }
@@ -157,8 +158,8 @@
 user_manager::User* FakeChromeUserManager::AddGuestUser() {
   user_manager::User* user =
       user_manager::User::CreateGuestUser(GetGuestAccountId());
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      GetGuestAccountId().GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(user->GetAccountId()));
   users_.push_back(user);
   return user;
 }
@@ -167,8 +168,8 @@
     const AccountId& account_id) {
   user_manager::User* user =
       user_manager::User::CreatePublicAccountUser(account_id);
-  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
-      account_id.GetUserEmail()));
+  user->set_username_hash(
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   user->SetStubImage(
       std::make_unique<user_manager::UserImage>(
           *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
@@ -194,10 +195,9 @@
 
 void FakeChromeUserManager::LoginUser(const AccountId& account_id,
                                       bool set_profile_created_flag) {
-  UserLoggedIn(
-      account_id,
-      ProfileHelper::GetUserIdHashByUserIdForTesting(account_id.GetUserEmail()),
-      false /* browser_restart */, false /* is_child */);
+  UserLoggedIn(account_id,
+               user_manager::FakeUserManager::GetFakeUsernameHash(account_id),
+               false /* browser_restart */, false /* is_child */);
 
   if (!set_profile_created_flag)
     return;
@@ -265,8 +265,7 @@
 void FakeChromeUserManager::SwitchActiveUser(const AccountId& account_id) {
   active_account_id_ = account_id;
   ProfileHelper::Get()->ActiveUserHashChanged(
-      ProfileHelper::GetUserIdHashByUserIdForTesting(
-          account_id.GetUserEmail()));
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id));
   active_user_ = nullptr;
   if (!users_.empty() && active_account_id_.is_valid()) {
     for (user_manager::User* const user : users_) {
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index 5266cb4..f482893 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -634,7 +634,7 @@
       base::BindRepeating(&WizardController::OnTermsOfServiceScreenExit,
                           weak_factory_.GetWeakPtr())));
   append(std::make_unique<SyncConsentScreen>(
-      oobe_ui->GetView<SyncConsentScreenHandler>(),
+      oobe_ui->GetView<SyncConsentScreenHandler>()->AsWeakPtr(),
       base::BindRepeating(&WizardController::OnSyncConsentScreenExit,
                           weak_factory_.GetWeakPtr())));
   append(std::make_unique<ArcTermsOfServiceScreen>(
@@ -773,7 +773,7 @@
 
   if (chromeos::features::IsOobeConsolidatedConsentEnabled()) {
     append(std::make_unique<ConsolidatedConsentScreen>(
-        oobe_ui->GetView<ConsolidatedConsentScreenHandler>(),
+        oobe_ui->GetView<ConsolidatedConsentScreenHandler>()->AsWeakPtr(),
         base::BindRepeating(&WizardController::OnConsolidatedConsentScreenExit,
                             weak_factory_.GetWeakPtr())));
 
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc
index 3f39cee9..18a6e19 100644
--- a/chrome/browser/ash/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -647,7 +647,7 @@
         std::make_unique<MockConsolidatedConsentScreenView>();
     mock_consolidated_consent_screen_ = MockScreenExpectLifecycle(
         std::make_unique<MockConsolidatedConsentScreen>(
-            mock_consolidated_consent_screen_view_.get(),
+            mock_consolidated_consent_screen_view_.get()->AsWeakPtr(),
             base::BindRepeating(
                 &WizardController::OnConsolidatedConsentScreenExit,
                 base::Unretained(wizard_controller))));
diff --git a/chrome/browser/ash/net/network_diagnostics/dns_latency_routine.cc b/chrome/browser/ash/net/network_diagnostics/dns_latency_routine.cc
index e7cc9dd7..ecfe1b5 100644
--- a/chrome/browser/ash/net/network_diagnostics/dns_latency_routine.cc
+++ b/chrome/browser/ash/net/network_diagnostics/dns_latency_routine.cc
@@ -155,7 +155,11 @@
 
   start_resolution_time_ = tick_clock_->NowTicks();
 
-  host_resolver_->ResolveHost(net::HostPortPair(hostname, kHttpPort),
+  // Intentionally using a HostPortPair not to trigger ERR_DNS_NAME_HTTPS_ONLY
+  // error while resolving http:// scheme host when a HTTPS resource record
+  // exists.
+  host_resolver_->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                                  net::HostPortPair(hostname, kHttpPort)),
                               net::NetworkIsolationKey::CreateTransient(),
                               std::move(parameters),
                               receiver_.BindNewPipeAndPassRemote());
diff --git a/chrome/browser/ash/net/network_diagnostics/dns_latency_routine_unittest.cc b/chrome/browser/ash/net/network_diagnostics/dns_latency_routine_unittest.cc
index bf03a41..c643e1f 100644
--- a/chrome/browser/ash/net/network_diagnostics/dns_latency_routine_unittest.cc
+++ b/chrome/browser/ash/net/network_diagnostics/dns_latency_routine_unittest.cc
@@ -78,7 +78,7 @@
   ~FakeHostResolver() override {}
 
   // network::mojom::HostResolver
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine.cc b/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine.cc
index 5f91eaa..5ee4c4c 100644
--- a/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine.cc
+++ b/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine.cc
@@ -98,7 +98,11 @@
   parameters->cache_usage =
       network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
 
-  host_resolver_->ResolveHost(net::HostPortPair(kHostname, kHttpPort),
+  // Intentionally using a HostPortPair not to trigger ERR_DNS_NAME_HTTPS_ONLY
+  // error while resolving http:// scheme host when a HTTPS resource record
+  // exists.
+  host_resolver_->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                                  net::HostPortPair(kHostname, kHttpPort)),
                               net::NetworkIsolationKey::CreateTransient(),
                               std::move(parameters),
                               receiver_.BindNewPipeAndPassRemote());
diff --git a/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine_unittest.cc b/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine_unittest.cc
index 9996aab..fcab24e 100644
--- a/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine_unittest.cc
+++ b/chrome/browser/ash/net/network_diagnostics/dns_resolution_routine_unittest.cc
@@ -53,7 +53,7 @@
   ~FakeHostResolver() override {}
 
   // network::mojom::HostResolver
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.cc b/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.cc
index 915b975b..14229dc 100644
--- a/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.cc
+++ b/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.cc
@@ -34,7 +34,7 @@
 FakeHostResolver::~FakeHostResolver() = default;
 
 void FakeHostResolver::ResolveHost(
-    const net::HostPortPair& host,
+    network::mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     network::mojom::ResolveHostParametersPtr optional_parameters,
     mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.h b/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.h
index 35144c9..48e0f22 100644
--- a/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.h
+++ b/chrome/browser/ash/net/network_diagnostics/fake_host_resolver.h
@@ -40,7 +40,7 @@
   ~FakeHostResolver() override;
 
   // network::mojom::HostResolver
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/ash/net/network_diagnostics/host_resolver.cc b/chrome/browser/ash/net/network_diagnostics/host_resolver.cc
index e17170a..f0fa77c 100644
--- a/chrome/browser/ash/net/network_diagnostics/host_resolver.cc
+++ b/chrome/browser/ash/net/network_diagnostics/host_resolver.cc
@@ -45,9 +45,13 @@
   parameters->cache_usage =
       network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
 
+  // Intentionally using a HostPortPair not to trigger ERR_DNS_NAME_HTTPS_ONLY
+  // error while resolving http:// scheme host when a HTTPS resource record
+  // exists.
   host_resolver_->ResolveHost(
-      host_port_pair, net::NetworkIsolationKey::CreateTransient(),
-      std::move(parameters), receiver_.BindNewPipeAndPassRemote());
+      network::mojom::HostResolverHost::NewHostPortPair(host_port_pair),
+      net::NetworkIsolationKey::CreateTransient(), std::move(parameters),
+      receiver_.BindNewPipeAndPassRemote());
 }
 
 HostResolver::~HostResolver() = default;
diff --git a/chrome/browser/ash/net/network_diagnostics/https_latency_routine.cc b/chrome/browser/ash/net/network_diagnostics/https_latency_routine.cc
index 7a9bde4..5c84f65 100644
--- a/chrome/browser/ash/net/network_diagnostics/https_latency_routine.cc
+++ b/chrome/browser/ash/net/network_diagnostics/https_latency_routine.cc
@@ -127,7 +127,10 @@
   parameters->cache_usage =
       network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
 
-  host_resolver_->ResolveHost(net::HostPortPair::FromURL(url),
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
+  host_resolver_->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                                  net::HostPortPair::FromURL(url)),
                               net::NetworkIsolationKey::CreateTransient(),
                               std::move(parameters),
                               receiver_.BindNewPipeAndPassRemote());
diff --git a/chrome/browser/ash/net/network_diagnostics/https_latency_routine_unittest.cc b/chrome/browser/ash/net/network_diagnostics/https_latency_routine_unittest.cc
index 39ca1359..92a497f 100644
--- a/chrome/browser/ash/net/network_diagnostics/https_latency_routine_unittest.cc
+++ b/chrome/browser/ash/net/network_diagnostics/https_latency_routine_unittest.cc
@@ -64,7 +64,7 @@
   ~FakeHostResolver() override {}
 
   // network::mojom::HostResolver
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.cc b/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.cc
index 147a4c7..12f183e 100644
--- a/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.cc
+++ b/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.cc
@@ -9,6 +9,10 @@
 #include "base/system/sys_info.h"
 #include "base/test/scoped_running_on_chromeos.h"
 #include "base/time/time.h"
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
+#include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
+#include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h"
 #include "chrome/browser/ash/login/users/mock_user_manager.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_features.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_pref_names.h"
@@ -31,6 +35,9 @@
 const char kDomain[] = "example.com";
 const char kDeviceId[] = "device_id";
 
+// Arbitrary container value used for updating the GuestOsRegistryService.
+const char kPluginVmContainer[] = "PluginVmContainer";
+
 // For adding a fake shelf item without requiring opening an actual window.
 class FakeShelfItemDelegate : public ash::ShelfItemDelegate {
  public:
@@ -130,6 +137,10 @@
     : testing_profile_(testing_profile) {
   testing_profile_->ScopedCrosSettingsTestHelper()
       ->ReplaceDeviceSettingsProviderWithStub();
+
+  current_apps_.set_vm_name(kPluginVmName);
+  current_apps_.set_container_name(kPluginVmContainer);
+  current_apps_.set_vm_type(guest_os::VmType::PLUGIN_VM);
 }
 
 PluginVmTestHelper::~PluginVmTestHelper() = default;
@@ -201,4 +212,28 @@
   ChromeShelfController::instance()->Close(ash::ShelfID(kPluginVmShelfAppId));
 }
 
+void PluginVmTestHelper::AddApp(const vm_tools::apps::App& app) {
+  for (int i = 0; i < current_apps_.apps_size(); ++i) {
+    if (current_apps_.apps(i).desktop_file_id() == app.desktop_file_id()) {
+      *current_apps_.mutable_apps(i) = app;
+      UpdateRegistry();
+      return;
+    }
+  }
+  *current_apps_.add_apps() = app;
+  UpdateRegistry();
+}
+
+// static
+std::string PluginVmTestHelper::GenerateAppId(const std::string& app_name) {
+  return guest_os::GuestOsRegistryService::GenerateAppId(
+      app_name, /*vm_name=*/kPluginVmName,
+      /*container_name=*/kPluginVmContainer);
+}
+
+void PluginVmTestHelper::UpdateRegistry() {
+  guest_os::GuestOsRegistryServiceFactory::GetForProfile(testing_profile_)
+      ->UpdateApplicationList(current_apps_);
+}
+
 }  // namespace plugin_vm
diff --git a/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h b/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h
index ecb9b61..d713f61 100644
--- a/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h
+++ b/chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h
@@ -7,6 +7,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h"
+#include "chromeos/ash/components/dbus/vm_applications/apps.pb.h"
 
 class TestingProfile;
 
@@ -57,8 +58,18 @@
   void OpenShelfItem();
   void CloseShelfItem();
 
+  // Adds an app in the default container. Replaces an existing app with the
+  // same app name if one exists.
+  void AddApp(const vm_tools::apps::App& app);
+
+  // Returns the app id that the registry would use for the given app name.
+  static std::string GenerateAppId(const std::string& app_name);
+
  private:
+  void UpdateRegistry();
+
   TestingProfile* testing_profile_;
+  vm_tools::apps::ApplicationList current_apps_;
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<base::test::ScopedRunningOnChromeOS> running_on_chromeos_;
diff --git a/chrome/browser/ash/policy/core/device_local_account.cc b/chrome/browser/ash/policy/core/device_local_account.cc
index f7a26ade..3af5bdd 100644
--- a/chrome/browser/ash/policy/core/device_local_account.cc
+++ b/chrome/browser/ash/policy/core/device_local_account.cc
@@ -238,14 +238,13 @@
   // TODO(https://crbug.com/984021): handle TYPE_SAML_PUBLIC_SESSION
   std::vector<DeviceLocalAccount> accounts;
 
-  const base::ListValue* list = NULL;
-  cros_settings->GetList(ash::kAccountsPrefDeviceLocalAccounts, &list);
-  if (!list)
+  const base::Value::List* list = nullptr;
+  if (!cros_settings->GetList(ash::kAccountsPrefDeviceLocalAccounts, &list))
     return accounts;
 
   std::set<std::string> account_ids;
-  for (size_t i = 0; i < list->GetListDeprecated().size(); ++i) {
-    const base::Value& entry = list->GetListDeprecated()[i];
+  for (size_t i = 0; i < list->size(); ++i) {
+    const base::Value& entry = (*list)[i];
     if (!entry.is_dict()) {
       LOG(ERROR) << "Corrupt entry in device-local account list at index " << i
                  << ".";
diff --git a/chrome/browser/ash/policy/display/display_resolution_handler.cc b/chrome/browser/ash/policy/display/display_resolution_handler.cc
index 7a248b8..12c52b0 100644
--- a/chrome/browser/ash/policy/display/display_resolution_handler.cc
+++ b/chrome/browser/ash/policy/display/display_resolution_handler.cc
@@ -46,12 +46,10 @@
   // Get settings for the internal display from
   // |ash::kDeviceDisplayResolution| setting value.
   static std::unique_ptr<InternalDisplaySettings> FromPolicySetting(
-      const base::DictionaryValue* pref) {
-    const base::Value* scale_value =
-        pref->FindKeyOfType(ash::kDeviceDisplayResolutionKeyInternalScale,
-                            base::Value::Type::INTEGER);
-    return scale_value ? std::make_unique<InternalDisplaySettings>(
-                             scale_value->GetInt())
+      const base::Value::Dict* pref) {
+    const absl::optional<int> scale_value =
+        pref->FindInt(ash::kDeviceDisplayResolutionKeyInternalScale);
+    return scale_value ? std::make_unique<InternalDisplaySettings>(*scale_value)
                        : nullptr;
   }
 };
@@ -112,34 +110,27 @@
   // Get settings for the external displays from
   // |ash::kDeviceDisplayResolution| setting value;
   static std::unique_ptr<ExternalDisplaySettings> FromPolicySetting(
-      const base::DictionaryValue* pref) {
-    const base::Value* width_value =
-        pref->FindKeyOfType(ash::kDeviceDisplayResolutionKeyExternalWidth,
-                            base::Value::Type::INTEGER);
-    const base::Value* height_value =
-        pref->FindKeyOfType(ash::kDeviceDisplayResolutionKeyExternalHeight,
-                            base::Value::Type::INTEGER);
-    const base::Value* scale_value =
-        pref->FindKeyOfType(ash::kDeviceDisplayResolutionKeyExternalScale,
-                            base::Value::Type::INTEGER);
-    const base::Value* use_native_value =
-        pref->FindKeyOfType(ash::kDeviceDisplayResolutionKeyExternalUseNative,
-                            base::Value::Type::BOOLEAN);
-
+      const base::Value::Dict* pref) {
     auto result = std::make_unique<ExternalDisplaySettings>();
 
     // Scale can be used for both native and non-native modes
-    if (scale_value)
-      result->scale_percentage = scale_value->GetInt();
+    result->scale_percentage =
+        pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalScale);
 
-    if (use_native_value && use_native_value->GetBool()) {
+    const absl::optional<bool> use_native_value =
+        pref->FindBool(ash::kDeviceDisplayResolutionKeyExternalUseNative);
+    if (use_native_value && *use_native_value) {
       result->use_native = true;
       return result;
     }
 
+    const absl::optional<int> width_value =
+        pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalWidth);
+    const absl::optional<int> height_value =
+        pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalHeight);
     if (width_value && height_value) {
-      result->width = width_value->GetInt();
-      result->height = height_value->GetInt();
+      result->width = *width_value;
+      result->height = *height_value;
       return result;
     }
 
@@ -160,7 +151,7 @@
 // |internal_display_settings_|. Also updates |policy_enabled_| flag.
 void DisplayResolutionHandler::OnSettingUpdate() {
   policy_enabled_ = false;
-  const base::DictionaryValue* resolution_pref = nullptr;
+  const base::Value::Dict* resolution_pref = nullptr;
   ash::CrosSettings::Get()->GetDictionary(ash::kDeviceDisplayResolution,
                                           &resolution_pref);
   if (!resolution_pref)
@@ -173,11 +164,11 @@
 
   bool new_recommended = false;
   policy_enabled_ = new_external_config || new_internal_config;
-  const base::Value* recommended_value = resolution_pref->FindKeyOfType(
-      ash::kDeviceDisplayResolutionKeyRecommended, base::Value::Type::BOOLEAN);
+  const absl::optional<bool> recommended_value =
+      resolution_pref->FindBool(ash::kDeviceDisplayResolutionKeyRecommended);
 
   if (recommended_value)
-    new_recommended = recommended_value->GetBool();
+    new_recommended = *recommended_value;
 
   // We should reset locally stored settings and clear list of already updated
   // displays if any of the policy values were updated.
diff --git a/chrome/browser/ash/policy/display/display_resolution_handler_browsertest.cc b/chrome/browser/ash/policy/display/display_resolution_handler_browsertest.cc
index d982d53d..93f4e00 100644
--- a/chrome/browser/ash/policy/display/display_resolution_handler_browsertest.cc
+++ b/chrome/browser/ash/policy/display/display_resolution_handler_browsertest.cc
@@ -64,35 +64,22 @@
 const int kDefaultDisplayScale = 100;
 
 PolicyValue GetPolicySetting() {
-  const base::DictionaryValue* resolution_pref = nullptr;
+  const base::Value::Dict* resolution_pref = nullptr;
   ash::CrosSettings::Get()->GetDictionary(ash::kDeviceDisplayResolution,
                                           &resolution_pref);
   EXPECT_TRUE(resolution_pref) << "DeviceDisplayResolution setting is not set";
-  const base::Value* width = resolution_pref->FindKeyOfType(
-      {ash::kDeviceDisplayResolutionKeyExternalWidth},
-      base::Value::Type::INTEGER);
-  const base::Value* height = resolution_pref->FindKeyOfType(
-      {ash::kDeviceDisplayResolutionKeyExternalHeight},
-      base::Value::Type::INTEGER);
-  const base::Value* external_scale = resolution_pref->FindKeyOfType(
-      {ash::kDeviceDisplayResolutionKeyExternalScale},
-      base::Value::Type::INTEGER);
-  const base::Value* use_native = resolution_pref->FindKeyOfType(
-      {ash::kDeviceDisplayResolutionKeyExternalUseNative},
-      base::Value::Type::BOOLEAN);
-  const base::Value* internal_scale = resolution_pref->FindKeyOfType(
-      {ash::kDeviceDisplayResolutionKeyInternalScale},
-      base::Value::Type::INTEGER);
   PolicyValue result;
-  if (width)
-    result.external_width = width->GetInt();
-  if (height)
-    result.external_height = height->GetInt();
-  if (external_scale)
-    result.external_scale_percentage = external_scale->GetInt();
-  if (internal_scale)
-    result.internal_scale_percentage = internal_scale->GetInt();
-  if (use_native && use_native->GetBool())
+  result.external_width =
+      resolution_pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalWidth);
+  result.external_height =
+      resolution_pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalHeight);
+  result.external_scale_percentage =
+      resolution_pref->FindInt(ash::kDeviceDisplayResolutionKeyExternalScale);
+  result.internal_scale_percentage =
+      resolution_pref->FindInt(ash::kDeviceDisplayResolutionKeyInternalScale);
+  const absl::optional<bool> use_native = resolution_pref->FindBool(
+      ash::kDeviceDisplayResolutionKeyExternalUseNative);
+  if (use_native && *use_native)
     result.use_native = true;
   return result;
 }
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
index b0acd838..ede5266 100644
--- a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
+++ b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
@@ -346,8 +346,7 @@
       std::make_unique<PolicyServiceImpl>(std::move(providers));
   builder.SetPolicyService(std::move(policy_service));
   builder.SetPath(ash::ProfileHelper::Get()->GetProfilePathByUserIdHash(
-      ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-          account_id.GetUserEmail())));
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id)));
 
   profile_ = builder.Build();
   profile_->set_profile_name(account_id.GetUserEmail());
@@ -386,7 +385,7 @@
       std::make_unique<PolicyServiceImpl>(std::move(providers));
   builder.SetPolicyService(std::move(policy_service));
   builder.SetPath(ash::ProfileHelper::Get()->GetProfilePathByUserIdHash(
-      ash::ProfileHelper::GetUserIdHashByUserIdForTesting(kRegularUserID)));
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id)));
 
   profile_ = builder.Build();
   profile_->set_profile_name(kRegularUserID);
diff --git a/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc
index df2f4e2c..5fc2d91 100644
--- a/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc
+++ b/chrome/browser/ash/policy/handlers/bluetooth_policy_handler.cc
@@ -58,7 +58,7 @@
     scoped_refptr<device::BluetoothAdapter> adapter) {
   // Get the updated policy.
   bool allow_bluetooth = true;
-  const base::ListValue* allowed_services_list = nullptr;
+  const base::Value::List* allowed_services_list = nullptr;
   std::vector<device::BluetoothUUID> allowed_services;
 
   cros_settings_->GetBoolean(ash::kAllowBluetooth, &allow_bluetooth);
@@ -74,7 +74,7 @@
   // returns an empty list even if the policy did not set.
   if (cros_settings_->GetList(ash::kDeviceAllowedBluetoothServices,
                               &allowed_services_list)) {
-    for (const auto& list_value : allowed_services_list->GetListDeprecated()) {
+    for (const auto& list_value : *allowed_services_list) {
       if (!list_value.is_string())
         continue;
 
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc
index 4d8f7aa..572e5f3c 100644
--- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc
+++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler.cc
@@ -224,24 +224,24 @@
     return;
   }
 
-  const base::DictionaryValue* policy_value;
+  const base::Value::Dict* policy_value;
   if (!cros_settings_->GetDictionary(ash::kDeviceMinimumVersion,
                                      &policy_value)) {
     VLOG(1) << "Revoke policy - policy is unset or value is incorrect.";
     HandleUpdateNotRequired();
     return;
   }
-  const base::Value* entries = policy_value->FindListKey(kRequirements);
-  if (!entries || entries->GetListDeprecated().empty()) {
+  const base::Value::List* entries = policy_value->FindList(kRequirements);
+  if (!entries || entries->empty()) {
     VLOG(1) << "Revoke policy - empty policy requirements.";
     HandleUpdateNotRequired();
     return;
   }
-  auto restricted = policy_value->FindBoolKey(kUnmanagedUserRestricted);
+  auto restricted = policy_value->FindBool(kUnmanagedUserRestricted);
   unmanaged_user_restricted_ = restricted.value_or(false);
 
   std::vector<std::unique_ptr<MinimumVersionRequirement>> configs;
-  for (const auto& item : entries->GetListDeprecated()) {
+  for (const auto& item : *entries) {
     const base::DictionaryValue* dict;
     if (item.GetAsDictionary(&dict)) {
       std::unique_ptr<MinimumVersionRequirement> instance =
diff --git a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
index fe9e5510..f4093d5 100644
--- a/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
+++ b/chrome/browser/ash/policy/networking/network_policy_application_browsertest.cc
@@ -16,7 +16,6 @@
 #include "base/test/values_test_util.h"
 #include "chrome/browser/ash/login/login_manager_test.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
-#include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/scoped_test_system_nss_key_slot_mixin.h"
 #include "chromeos/ash/components/dbus/shill/shill_device_client.h"
 #include "chromeos/ash/components/dbus/shill/shill_manager_client.h"
@@ -33,6 +32,8 @@
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/policy_constants.h"
+#include "components/user_manager/user.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
 #include "crypto/scoped_nss_types.h"
 #include "dbus/object_path.h"
@@ -483,9 +484,10 @@
   // updates (regression test for https://crbug.com/936677).
   shill_service_client_test_->SetHoldBackServicePropertyUpdates(true);
 
-  std::string user_hash = ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-      test_account_id_.GetUserEmail());
   LoginUser(test_account_id_);
+  const std::string user_hash = user_manager::UserManager::Get()
+                                    ->FindUser(test_account_id_)
+                                    ->username_hash();
   shill_profile_client_test_->AddProfile(kUserProfilePath, user_hash);
 
   // When AutoConnectHandler triggers ScanAndConnectToBestServices, shill should
@@ -925,9 +927,10 @@
       kServiceWifi1, shill::kSecurityClassProperty,
       base::Value(shill::kSecurityClass8021x));
 
-  std::string user_hash = ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-      test_account_id_.GetUserEmail());
   LoginUser(test_account_id_);
+  const std::string user_hash = user_manager::UserManager::Get()
+                                    ->FindUser(test_account_id_)
+                                    ->username_hash();
   shill_profile_client_test_->AddProfile(kUserProfilePath, user_hash);
 
   const char kUserONC1[] = R"(
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
index 06ad69e..3896277 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h
@@ -49,7 +49,7 @@
 
     bool IsAffiliated(Profile* profile) const override;
 
-    bool IsDeprovisioned() const override;
+    virtual bool IsDeprovisioned() const;
   };
 
   static std::unique_ptr<MetricReportingManager> Create(
diff --git a/chrome/browser/ash/profiles/profile_helper.cc b/chrome/browser/ash/profiles/profile_helper.cc
index ecd883e..4607c66 100644
--- a/chrome/browser/ash/profiles/profile_helper.cc
+++ b/chrome/browser/ash/profiles/profile_helper.cc
@@ -35,9 +35,6 @@
 namespace ash {
 namespace {
 
-// As defined in /chromeos/ash/components/dbus/cryptohome/cryptohome_client.cc.
-static const char kUserIdHashSuffix[] = "-hash";
-
 class UsernameHashMatcher {
  public:
   explicit UsernameHashMatcher(const std::string& h) : username_hash(h) {}
@@ -97,8 +94,6 @@
       const Profile* profile) const override;
   user_manager::User* GetUserByProfile(Profile* profile) const override;
 
-  void SetActiveUserIdForTesting(const std::string& user_id) override;
-
   void FlushProfile(Profile* profile) override;
 
   void SetProfileToUserMappingForTesting(user_manager::User* user) override;
@@ -302,12 +297,6 @@
   ProfileHelper::SetProfileToUserForTestingEnabled(value);
 }
 
-// static
-std::string ProfileHelper::GetUserIdHashByUserIdForTesting(
-    const std::string& user_id) {
-  return user_id + kUserIdHashSuffix;
-}
-
 ProfileHelperImpl::ProfileHelperImpl(
     std::unique_ptr<BrowserContextHelper::Delegate> delegate)
     : browser_context_helper_(
@@ -487,10 +476,6 @@
     user_list_for_testing_.erase(it);
 }
 
-void ProfileHelperImpl::SetActiveUserIdForTesting(const std::string& user_id) {
-  active_user_id_hash_ = GetUserIdHashByUserIdForTesting(user_id);
-}
-
 void ProfileHelperImpl::FlushProfile(Profile* profile) {
   if (!profile_flusher_)
     profile_flusher_ = std::make_unique<FileFlusher>();
diff --git a/chrome/browser/ash/profiles/profile_helper.h b/chrome/browser/ash/profiles/profile_helper.h
index 230622fe26..09d9a6f8 100644
--- a/chrome/browser/ash/profiles/profile_helper.h
+++ b/chrome/browser/ash/profiles/profile_helper.h
@@ -141,15 +141,10 @@
       const Profile* profile) const = 0;
   virtual user_manager::User* GetUserByProfile(Profile* profile) const = 0;
 
-  static std::string GetUserIdHashByUserIdForTesting(
-      const std::string& user_id);
-
   // Enables/disables testing GetUserByProfile() by always returning
   // primary user.
   static void SetAlwaysReturnPrimaryUserForTesting(bool value);
 
-  virtual void SetActiveUserIdForTesting(const std::string& user_id) = 0;
-
   // Flushes all files of |profile|.
   virtual void FlushProfile(Profile* profile) = 0;
 
diff --git a/chrome/browser/ash/remote_apps/remote_apps_manager.cc b/chrome/browser/ash/remote_apps/remote_apps_manager.cc
index b67b052f..0f20aa1 100644
--- a/chrome/browser/ash/remote_apps/remote_apps_manager.cc
+++ b/chrome/browser/ash/remote_apps/remote_apps_manager.cc
@@ -354,13 +354,12 @@
   return icon;
 }
 
-apps::mojom::MenuItemsPtr RemoteAppsManager::GetMenuModel(
-    const std::string& id) {
+apps::MenuItems RemoteAppsManager::GetMenuModel(const std::string& id) {
   apps::MenuItems menu_items;
   // TODO(b/236785623): Temporary string for menu item.
   apps::AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC,
                        menu_items);
-  return ConvertMenuItemsToMojomMenuItems(menu_items);
+  return menu_items;
 }
 
 void RemoteAppsManager::OnSyncModelUpdated() {
diff --git a/chrome/browser/ash/remote_apps/remote_apps_manager.h b/chrome/browser/ash/remote_apps/remote_apps_manager.h
index 1d8a6bd..e816277 100644
--- a/chrome/browser/ash/remote_apps/remote_apps_manager.h
+++ b/chrome/browser/ash/remote_apps/remote_apps_manager.h
@@ -30,6 +30,10 @@
 class ChromeAppListItem;
 class Profile;
 
+namespace apps {
+struct MenuItems;
+}  // namespace apps
+
 namespace gfx {
 class ImageSkia;
 }  // namespace gfx
@@ -158,7 +162,7 @@
   gfx::ImageSkia GetIcon(const std::string& id) override;
   gfx::ImageSkia GetPlaceholderIcon(const std::string& id,
                                     int32_t size_hint_in_dip) override;
-  apps::mojom::MenuItemsPtr GetMenuModel(const std::string& id) override;
+  apps::MenuItems GetMenuModel(const std::string& id) override;
 
   // app_list::AppListSyncableService::Observer:
   void OnSyncModelUpdated() override;
diff --git a/chrome/browser/ash/scanning/scan_service.cc b/chrome/browser/ash/scanning/scan_service.cc
index 61a46c53..1615267 100644
--- a/chrome/browser/ash/scanning/scan_service.cc
+++ b/chrome/browser/ash/scanning/scan_service.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "ash/constants/ash_features.h"
+#include "ash/webui/scanning/mojom/scanning_type_converters.h"
 #include "ash/webui/scanning/scanning_uma.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
@@ -28,7 +29,6 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/scanning/lorgnette_scanner_manager.h"
 #include "chrome/browser/ash/scanning/scanning_file_path_helper.h"
-#include "chrome/browser/ash/scanning/scanning_type_converters.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h"
 #include "chromeos/utils/pdf_conversion.h"
@@ -538,12 +538,7 @@
     return;
   }
 
-  // TODO(crbug.com/1234861): Setup mojo TypeMaps so we can remove calling the
-  // EnumTraits directly.
-  scan_job_observer_->OnMultiPageScanFail(
-      mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                       lorgnette::ScanFailureMode>::
-          ToMojom(static_cast<lorgnette::ScanFailureMode>(failure_mode)));
+  scan_job_observer_->OnMultiPageScanFail(failure_mode);
 
   base::UmaHistogramEnumeration("Scanning.MultiPageScan.PageScanResult",
                                 GetScanJobFailureReason(failure_mode));
@@ -579,10 +574,7 @@
     scanned_file_paths_.clear();
   }
 
-  scan_job_observer_->OnScanComplete(
-      mojo::EnumTraits<ash::scanning::mojom::ScanResult,
-                       lorgnette::ScanFailureMode>::ToMojom(failure_mode),
-      scanned_file_paths_);
+  scan_job_observer_->OnScanComplete(failure_mode, scanned_file_paths_);
   HoldingSpaceKeyedService* holding_space_keyed_service =
       HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(context_);
   if (holding_space_keyed_service) {
diff --git a/chrome/browser/ash/scanning/scan_service_unittest.cc b/chrome/browser/ash/scanning/scan_service_unittest.cc
index b877fa4..19604a6 100644
--- a/chrome/browser/ash/scanning/scan_service_unittest.cc
+++ b/chrome/browser/ash/scanning/scan_service_unittest.cc
@@ -53,6 +53,8 @@
 
 namespace mojo_ipc = scanning::mojom;
 
+using ProtoScanFailureMode = lorgnette::ScanFailureMode;
+
 // Path to the user's "My files" folder.
 constexpr char kMyFilesPath[] = "/home/chronos/user/MyFiles";
 
@@ -206,7 +208,7 @@
   }
 
   void OnScanComplete(
-      mojo_ipc::ScanResult result,
+      ProtoScanFailureMode result,
       const std::vector<base::FilePath>& scanned_file_paths) override {
     scan_result_ = result;
     scanned_file_paths_ = scanned_file_paths;
@@ -216,7 +218,7 @@
     cancel_scan_success_ = success;
   }
 
-  void OnMultiPageScanFail(mojo_ipc::ScanResult result) override {
+  void OnMultiPageScanFail(ProtoScanFailureMode result) override {
     multi_page_scan_result_ = result;
   }
 
@@ -234,7 +236,7 @@
   // Returns true if the scan completed successfully.
   bool scan_success() const {
     return progress_ == 100 && page_complete_ &&
-           scan_result_ == mojo_ipc::ScanResult::kSuccess;
+           scan_result_ == ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE;
   }
 
   // Returns true if the cancel scan request completed successfully.
@@ -243,10 +245,10 @@
   uint32_t new_page_index() const { return new_page_index_; }
 
   // Returns the result of the scan job.
-  mojo_ipc::ScanResult scan_result() const { return scan_result_; }
+  ProtoScanFailureMode scan_result() const { return scan_result_; }
 
   // Returns the result of the multi-page scan job.
-  mojo_ipc::ScanResult multi_page_scan_result() const {
+  ProtoScanFailureMode multi_page_scan_result() const {
     return multi_page_scan_result_;
   }
 
@@ -259,9 +261,10 @@
   uint32_t progress_ = 0;
   bool page_complete_ = false;
   uint32_t new_page_index_ = UINT32_MAX;
-  mojo_ipc::ScanResult scan_result_ = mojo_ipc::ScanResult::kUnknownError;
-  mojo_ipc::ScanResult multi_page_scan_result_ =
-      mojo_ipc::ScanResult::kUnknownError;
+  ProtoScanFailureMode scan_result_ =
+      ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN;
+  ProtoScanFailureMode multi_page_scan_result_ =
+      ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN;
   bool cancel_scan_success_ = false;
   std::vector<base::FilePath> scanned_file_paths_;
   mojo::Receiver<mojo_ipc::ScanJobObserver> receiver_{this};
@@ -545,7 +548,7 @@
       EXPECT_TRUE(base::PathExists(saved_scan_path));
 
     EXPECT_TRUE(fake_scan_job_observer_.scan_success());
-    EXPECT_EQ(mojo_ipc::ScanResult::kSuccess,
+    EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE,
               fake_scan_job_observer_.scan_result());
     EXPECT_EQ(scan_data.size() - 1, fake_scan_job_observer_.new_page_index());
     EXPECT_EQ(saved_scan_paths, fake_scan_job_observer_.scanned_file_paths());
@@ -607,7 +610,7 @@
 
   EXPECT_TRUE(StartScan(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kDeviceBusy,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY,
             fake_scan_job_observer_.scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
 }
@@ -626,7 +629,7 @@
 
   EXPECT_TRUE(StartScan(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kDeviceBusy,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY,
             fake_scan_job_observer_.scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
 
@@ -649,7 +652,7 @@
     EXPECT_TRUE(base::PathExists(saved_scan_path));
 
   EXPECT_TRUE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kSuccess,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE,
             fake_scan_job_observer_.scan_result());
   EXPECT_EQ(saved_scan_paths, fake_scan_job_observer_.scanned_file_paths());
   EXPECT_EQ(scan_data.size() - 1, fake_scan_job_observer_.new_page_index());
@@ -683,7 +686,7 @@
     EXPECT_TRUE(base::PathExists(saved_scan_path));
 
   EXPECT_TRUE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kSuccess,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE,
             fake_scan_job_observer_.scan_result());
   EXPECT_EQ(saved_scan_paths, fake_scan_job_observer_.scanned_file_paths());
   EXPECT_EQ(scan_data.size() - 1, fake_scan_job_observer_.new_page_index());
@@ -694,7 +697,7 @@
 
   EXPECT_TRUE(StartScan(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kDeviceBusy,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY,
             fake_scan_job_observer_.scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
 }
@@ -754,7 +757,7 @@
         CreateScanSettings(scanned_files_mount_->GetRootPath(), type);
     EXPECT_TRUE(StartScan(scanners[0]->id, settings.Clone()));
     EXPECT_TRUE(fake_scan_job_observer_.scan_success());
-    EXPECT_EQ(mojo_ipc::ScanResult::kSuccess,
+    EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_NO_FAILURE,
               fake_scan_job_observer_.scan_result());
     EXPECT_EQ(saved_scan_paths, fake_scan_job_observer_.scanned_file_paths());
 
@@ -775,7 +778,7 @@
 
     EXPECT_TRUE(StartScan(scanners[0]->id, settings.Clone()));
     EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-    EXPECT_EQ(mojo_ipc::ScanResult::kDeviceBusy,
+    EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY,
               fake_scan_job_observer_.scan_result());
     EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
 
@@ -856,7 +859,7 @@
   // The first scan should pass with no failure.
   EXPECT_TRUE(StartMultiPageScan(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kUnknownError,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN,
             fake_scan_job_observer_.multi_page_scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
   EXPECT_EQ(0u, fake_scan_job_observer_.new_page_index());
@@ -866,7 +869,7 @@
   fake_lorgnette_scanner_manager_.SetScanResponse({});
   EXPECT_TRUE(ScanNextPage(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kDeviceBusy,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_DEVICE_BUSY,
             fake_scan_job_observer_.multi_page_scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
 
@@ -894,7 +897,7 @@
   // The first scan should pass with no failure.
   EXPECT_TRUE(StartMultiPageScan(scanners[0]->id, settings.Clone()));
   EXPECT_FALSE(fake_scan_job_observer_.scan_success());
-  EXPECT_EQ(mojo_ipc::ScanResult::kUnknownError,
+  EXPECT_EQ(ProtoScanFailureMode::SCAN_FAILURE_MODE_UNKNOWN,
             fake_scan_job_observer_.multi_page_scan_result());
   EXPECT_TRUE(fake_scan_job_observer_.scanned_file_paths().empty());
   EXPECT_EQ(0u, fake_scan_job_observer_.new_page_index());
diff --git a/chrome/browser/ash/settings/cros_settings.cc b/chrome/browser/ash/settings/cros_settings.cc
index a6aeba7..449a23a4 100644
--- a/chrome/browser/ash/settings/cros_settings.cc
+++ b/chrome/browser/ash/settings/cros_settings.cc
@@ -171,23 +171,24 @@
 }
 
 bool CrosSettings::GetList(const std::string& path,
-                           const base::ListValue** out_value) const {
+                           const base::Value::List** out_value) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const base::Value* value = GetPref(path);
   if (value && value->is_list()) {
-    *out_value = &base::Value::AsListValue(*value);
+    *out_value = &value->GetList();
     return true;
   }
   return false;
 }
 
-bool CrosSettings::GetDictionary(
-    const std::string& path,
-    const base::DictionaryValue** out_value) const {
+bool CrosSettings::GetDictionary(const std::string& path,
+                                 const base::Value::Dict** out_value) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const base::Value* value = GetPref(path);
-  if (value)
-    return value->GetAsDictionary(out_value);
+  if (value && value->is_dict()) {
+    *out_value = &value->GetDict();
+    return true;
+  }
   return false;
 }
 
@@ -218,18 +219,18 @@
                                    bool* wildcard_match) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  const base::ListValue* list;
+  const base::Value::List* list;
   if (!GetList(path, &list)) {
     if (wildcard_match)
       *wildcard_match = false;
     return false;
   }
 
-  return FindEmailInList(list->GetListDeprecated(), email, wildcard_match);
+  return FindEmailInList(*list, email, wildcard_match);
 }
 
 // static
-bool CrosSettings::FindEmailInList(const base::Value::ConstListView& list,
+bool CrosSettings::FindEmailInList(const base::Value::List& list,
                                    const std::string& email,
                                    bool* wildcard_match) {
   std::string canonicalized_email(
diff --git a/chrome/browser/ash/settings/cros_settings.h b/chrome/browser/ash/settings/cros_settings.h
index e2dc7f9..89b61ac 100644
--- a/chrome/browser/ash/settings/cros_settings.h
+++ b/chrome/browser/ash/settings/cros_settings.h
@@ -89,9 +89,9 @@
   bool GetDouble(const std::string& path, double* out_value) const;
   bool GetString(const std::string& path, std::string* out_value) const;
   bool GetList(const std::string& path,
-               const base::ListValue** out_value) const;
+               const base::Value::List** out_value) const;
   bool GetDictionary(const std::string& path,
-                     const base::DictionaryValue** out_value) const;
+                     const base::Value::Dict** out_value) const;
 
   // Checks if the given username is on the list of users allowed to sign-in to
   // this device. |wildcard_match| may be nullptr. If it's present, it'll be set
@@ -112,7 +112,7 @@
                        bool* wildcard_match) const;
 
   // Same as above, but receives already populated user list.
-  static bool FindEmailInList(const base::Value::ConstListView& list,
+  static bool FindEmailInList(const base::Value::List& list,
                               const std::string& email,
                               bool* wildcard_match);
 
diff --git a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
index a5c7de6..ad88a65 100644
--- a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
+++ b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
@@ -25,7 +25,6 @@
 #include "base/timer/wall_clock_timer.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/users/mock_user_manager.h"
-#include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/system/automatic_reboot_manager_observer.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -36,6 +35,7 @@
 #include "components/prefs/testing_pref_service.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/session_manager/session_manager_types.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -572,8 +572,8 @@
   const AccountId account_id =
       AccountId::FromUserEmailGaiaId("email", "123456");
   session_manager_.CreateSession(
-      account_id, ProfileHelper::GetUserIdHashByUserIdForTesting("email"),
-      true);
+      account_id,
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id), true);
   session_manager_.SessionStarted();
   session_manager_.SetSessionState(session_manager::SessionState::ACTIVE);
 }
diff --git a/chrome/browser/ash/web_applications/personalization_app/enterprise_policy_delegate_impl.cc b/chrome/browser/ash/web_applications/personalization_app/enterprise_policy_delegate_impl.cc
index 3c4f0d27..4ab2c6fe 100644
--- a/chrome/browser/ash/web_applications/personalization_app/enterprise_policy_delegate_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/enterprise_policy_delegate_impl.cc
@@ -42,7 +42,7 @@
 
 bool EnterprisePolicyDelegateImpl::IsWallpaperEnterpriseManaged() const {
   return WallpaperController::Get()->IsWallpaperControlledByPolicy(
-      GetUser(profile_)->GetAccountId());
+      GetAccountId(profile_));
 }
 
 void EnterprisePolicyDelegateImpl::AddObserver(
@@ -59,7 +59,7 @@
     const user_manager::User& user,
     bool is_enterprise_managed) {
   // Filter out updates from other users.
-  if (user.GetAccountId() != GetUser(profile_)->GetAccountId()) {
+  if (user.GetAccountId() != GetAccountId(profile_)) {
     return;
   }
 
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_notification_controller_unittest.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_notification_controller_unittest.cc
index 251d18b..8977d55 100644
--- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_notification_controller_unittest.cc
+++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_notification_controller_unittest.cc
@@ -70,14 +70,14 @@
     // The created profile is owned by ProfileManager.
     Profile* profile = profile_manager_.CreateTestingProfile(kProfileName);
     profile_manager_.UpdateLastUser(profile);
-    ProfileHelper::Get()->SetActiveUserIdForTesting(kProfileName);
 
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::make_unique<FakeChromeUserManager>());
 
     auto account = AccountId::FromUserEmail(kProfileName);
-    GetFakeUserManager()->AddUser(account);
+    auto* user = GetFakeUserManager()->AddUser(account);
     GetFakeUserManager()->LoginUser(account);
+    ProfileHelper::Get()->ActiveUserHashChanged(user->username_hash());
 
     service_tester_ =
         std::make_unique<NotificationDisplayServiceTester>(profile);
diff --git a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_desktop_browsertest.cc b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_desktop_browsertest.cc
index 510d2951..ee4456c 100644
--- a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_desktop_browsertest.cc
+++ b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_desktop_browsertest.cc
@@ -59,15 +59,14 @@
 // Tests download navigation.
 IN_PROC_BROWSER_TEST_F(BreadcrumbManagerTabHelperBrowserTest, Download) {
   const size_t num_startup_breadcrumbs =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size();
+      breadcrumb_service_->GetEvents().size();
 
   const GURL url =
       ui_test_utils::GetTestUrl(base::FilePath().AppendASCII("downloads"),
                                 base::FilePath().AppendASCII("a_zip_file.zip"));
   ui_test_utils::DownloadURL(browser(), url);
 
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   // Breadcrumbs should have been logged for starting and finishing the
   // navigation, and the navigation should be labeled as a download.
   ASSERT_EQ(2ul, events.size() - num_startup_breadcrumbs);
@@ -125,7 +124,7 @@
       browser(), https_server_.GetURL("/ssl/google.html")));
 
   // The breadcrumb event for broken authentication should have been logged.
-  auto events = breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  auto events = breadcrumb_service_->GetEvents();
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded));
   events.pop_back();
diff --git a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
index 64f6082..9c03b657 100644
--- a/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
+++ b/chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper_unittest.cc
@@ -96,22 +96,20 @@
 // Tests that BreadcrumbManagerTabHelper events are logged to the
 // associated BreadcrumbManagerKeyedService.
 TEST_F(BreadcrumbManagerTabHelperTest, EventsLogged) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(), web_contents());
   simulator->Start();
 
-  std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbDidStartNavigation))
       << events.back();
 
   simulator->Commit();
-  events = breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -131,8 +129,7 @@
   auto second_simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(), web_contents());
   second_simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_STRNE(events.front().c_str(), events.back().c_str());
   EXPECT_NE(std::string::npos,
@@ -145,13 +142,11 @@
 
 // Tests metadata for www.google.com navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, GoogleNavigationStart) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL("https://www.google.com"), web_contents());
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.front().find(breadcrumbs::kBreadcrumbGoogleNavigation))
@@ -160,13 +155,11 @@
 
 // Tests metadata for https://play.google.com/ navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, GooglePlayNavigationStart) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL("https://play.google.com/"), web_contents());
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   // #google is useful to indicate SRP. There is no need to know URLs of other
   // visited google properties.
@@ -180,13 +173,11 @@
 #if !BUILDFLAG(IS_ANDROID)
 // Tests metadata for chrome://newtab NTP navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, ChromeNewTabNavigationStart) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(chrome::kChromeUINewTabURL), web_contents());
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.front().find(base::StringPrintf(
@@ -201,14 +192,12 @@
 
 // Tests unique ID in DidStartNavigation and DidFinishNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, NavigationUniqueId) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   // DidStartNavigation
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL("https://test"), web_contents());
   simulator->Start();
-  std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   const int64_t navigation_id =
       simulator->GetNavigationHandle()->GetNavigationId();
@@ -219,7 +208,7 @@
       << events.front();
   // DidFinishNavigation
   simulator->Commit();
-  events = breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -234,15 +223,13 @@
 
 // Tests renderer initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, RendererInitiatedByUser) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateRendererInitiated(
       GURL(), web_contents()->GetPrimaryMainFrame());
   simulator->SetHasUserGesture(true);
   simulator->SetTransition(ui::PAGE_TRANSITION_LINK);
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find("#link")) << events.back();
   EXPECT_NE(std::string::npos,
@@ -259,14 +246,12 @@
 
 // Tests renderer initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, RendererInitiatedByScript) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateRendererInitiated(
       GURL(), web_contents()->GetPrimaryMainFrame());
   simulator->SetHasUserGesture(false);
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find("#link")) << events.back();
   EXPECT_NE(std::string::npos,
@@ -283,14 +268,12 @@
 
 // Tests browser initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, BrowserInitiatedByScript) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(), web_contents());
   simulator->SetTransition(ui::PAGE_TRANSITION_TYPED);
   simulator->Start();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find("#typed")) << events.back();
   EXPECT_NE(std::string::npos,
@@ -307,14 +290,12 @@
 
 // Tests PDF load.
 TEST_F(BreadcrumbManagerTabHelperTest, PdfLoad) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(), web_contents());
   simulator->SetContentsMimeType("application/pdf");
   simulator->Commit();
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -326,12 +307,10 @@
 
 // Tests page load succeess.
 TEST_F(BreadcrumbManagerTabHelperTest, PageLoadSuccess) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(),
                                                              GURL());
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -346,14 +325,12 @@
   auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
       GURL(), web_contents());
   simulator->Start();
-  ASSERT_EQ(1ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(1ul, breadcrumb_service_->GetEvents().size());
 
   static_cast<content::TestWebContents*>(web_contents())
       ->GetPrimaryMainFrame()
       ->DidFailLoadWithError(GURL(), net::ERR_ABORTED);
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -368,12 +345,10 @@
 // Tests NTP page load.
 #if !BUILDFLAG(IS_ANDROID)
 TEST_F(BreadcrumbManagerTabHelperTest, NtpPageLoad) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   content::NavigationSimulator::NavigateAndCommitFromBrowser(
       web_contents(), GURL(chrome::kChromeUINewTabURL));
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbPageLoaded))
@@ -390,12 +365,10 @@
 
 // Tests navigation error.
 TEST_F(BreadcrumbManagerTabHelperTest, NavigationError) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   content::NavigationSimulator::NavigateAndFailFromBrowser(
       web_contents(), GURL("https://test"), net::ERR_INTERNET_DISCONNECTED);
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbDidFinishNavigation))
@@ -407,13 +380,11 @@
 
 // Tests that adding an infobar logs the expected breadcrumb.
 TEST_F(BreadcrumbManagerTabHelperTest, AddInfobar) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   const auto identifier = InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier));
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -423,8 +394,7 @@
 
 // Tests that infobar breadcrumbs specify the infobar type.
 TEST_F(BreadcrumbManagerTabHelperTest, InfobarTypes) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   // Add and remove first infobar.
   const auto first_identifier =
       InfoBarDelegate::InfoBarIdentifier::SESSION_CRASHED_INFOBAR_DELEGATE_IOS;
@@ -437,8 +407,7 @@
       InfoBarDelegate::InfoBarIdentifier::SYNC_ERROR_INFOBAR_DELEGATE_IOS;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(second_identifier));
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(events.front(), events.back());
   EXPECT_NE(std::string::npos, events.front().find(base::StringPrintf(
@@ -454,15 +423,13 @@
 // Tests that removing an infobar without animation logs the expected breadcrumb
 // event.
 TEST_F(BreadcrumbManagerTabHelperTest, RemoveInfobarNotAnimated) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   const auto identifier = InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier));
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->RemoveAllInfoBars(/*animate=*/false);
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -476,15 +443,13 @@
 // Tests that removing an infobar with animation logs the expected breadcrumb
 // event.
 TEST_F(BreadcrumbManagerTabHelperTest, RemoveInfobarAnimated) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   const auto identifier = InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier));
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->RemoveAllInfoBars(/*animate=*/true);
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -497,16 +462,14 @@
 
 // Tests that replacing an infobar logs the expected breadcrumb event.
 TEST_F(BreadcrumbManagerTabHelperTest, ReplaceInfobar) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   const auto identifier = InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier));
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier),
                    /*replace_existing=*/true);
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -517,8 +480,7 @@
 // Tests that replacing an infobar many times only logs the replaced infobar
 // breadcrumb at major increments.
 TEST_F(BreadcrumbManagerTabHelperTest, SequentialInfobarReplacements) {
-  ASSERT_EQ(0ul,
-            breadcrumb_service_->GetEvents(/*event_count_limit=*/0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   const auto identifier = InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
   infobars::ContentInfoBarManager::FromWebContents(web_contents())
       ->AddInfoBar(CreateInfoBar(identifier));
@@ -527,8 +489,7 @@
         ->AddInfoBar(CreateInfoBar(identifier),
                      /*replace_existing=*/true);
   }
-  const std::list<std::string> events =
-      breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+  const std::list<std::string> events = breadcrumb_service_->GetEvents();
   // Replacing the infobar 500 times should only log breadcrumbs on the 1st,
   // 2nd, 5th, 20th, 100th, 200th replacement.
   ASSERT_EQ(7ul, events.size());
diff --git a/chrome/browser/breadcrumbs/crash_reporter_breadcrumb_observer_unittest.cc b/chrome/browser/breadcrumbs/crash_reporter_breadcrumb_observer_unittest.cc
index 9e9c73fc..7e7b1cc 100644
--- a/chrome/browser/breadcrumbs/crash_reporter_breadcrumb_observer_unittest.cc
+++ b/chrome/browser/breadcrumbs/crash_reporter_breadcrumb_observer_unittest.cc
@@ -89,7 +89,7 @@
 
   breadcrumb_service->AddEvent(std::string("Breadcrumb Event"));
 
-  const std::list<std::string> events = breadcrumb_service->GetEvents(0);
+  const std::list<std::string> events = breadcrumb_service->GetEvents();
   std::string expected_breadcrumbs;
   for (const auto& event : events)
     expected_breadcrumbs += event + "\n";
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 3a00a6f..eda3425 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -214,6 +214,8 @@
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_LAPTOP_BOTTOM_LEFT_ANIMATION_LIGHT" file="resources\chromeos\quick_unlock\fingerprint_laptop_bottom_left_light.json"/>
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_LAPTOP_BOTTOM_RIGHT_ANIMATION_DARK" file="resources\chromeos\quick_unlock\fingerprint_laptop_bottom_right_dark.json"/>
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_LAPTOP_BOTTOM_RIGHT_ANIMATION_LIGHT" file="resources\chromeos\quick_unlock\fingerprint_laptop_bottom_right_light.json"/>
+        <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_LAPTOP_LEFT_OF_POWER_BUTTON_TOP_RIGHT_ANIMATION_LIGHT" file="resources\chromeos\quick_unlock\fingerprint_left_of_power_button_top_right_light.json"/>
+        <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_LAPTOP_LEFT_OF_POWER_BUTTON_TOP_RIGHT_ANIMATION_DARK" file="resources\chromeos\quick_unlock\fingerprint_left_of_power_button_top_right_dark.json"/>
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_TABLET_ANIMATION_DARK" file="resources\chromeos\quick_unlock\fingerprint_tablet_dark.json"/>
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_TABLET_ANIMATION_LIGHT" file="resources\chromeos\quick_unlock\fingerprint_tablet_light.json"/>
         <include type="BINDATA" compress="gzip" name="IDR_FINGERPRINT_DEFAULT_ANIMATION_DARK" file="resources\chromeos\quick_unlock\fingerprint_default_dark.json"/>
diff --git a/chrome/browser/chrome_plugin_browsertest.cc b/chrome/browser/chrome_plugin_browsertest.cc
deleted file mode 100644
index a742923b..0000000
--- a/chrome/browser/chrome_plugin_browsertest.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2012 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 <stddef.h>
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/containers/flat_set.h"
-#include "base/process/process.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/branding_buildflags.h"
-#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/nacl/common/buildflags.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/plugin_service.h"
-#include "content/public/common/webplugininfo.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-
-namespace {
-
-void GetPluginsInfoCallback(
-    std::vector<content::WebPluginInfo>* rv,
-    base::OnceClosure quit_task,
-    const std::vector<content::WebPluginInfo>& plugins) {
-  *rv = plugins;
-  std::move(quit_task).Run();
-}
-
-std::vector<content::WebPluginInfo> GetPlugins() {
-  std::vector<content::WebPluginInfo> plugins;
-  base::RunLoop run_loop;
-  auto callback =
-      base::BindOnce(&GetPluginsInfoCallback, &plugins, run_loop.QuitClosure());
-  content::PluginService::GetInstance()->GetPlugins(std::move(callback));
-  run_loop.Run();
-  return plugins;
-}
-
-}  // namespace
-
-using ChromePluginTest = InProcessBrowserTest;
-
-// Verify a known subset of plugins for the build configuration.
-// TODO(https://crbug.com/1297566): Fix and re-eanble test.
-IN_PROC_BROWSER_TEST_F(ChromePluginTest, DISABLED_InstalledPlugins) {
-  base::flat_set<std::string> expected = {
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-    "Chrome PDF Plugin",
-
-#if BUILDFLAG(ENABLE_NACL)
-    "Native Client",
-#endif  // BUILDFLAG(ENABLE_NACL)
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
-  };
-
-  auto actual = GetPlugins();
-  for (const auto& cur_actual : actual) {
-    expected.erase(base::UTF16ToASCII(cur_actual.name));
-  }
-
-  for (const auto& not_found : expected) {
-    ADD_FAILURE() << "Didn't find " << not_found;
-  }
-}
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 612d215..3c2da7d 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1740,8 +1740,6 @@
     "../ash/scanning/scanner_detector.h",
     "../ash/scanning/scanning_file_path_helper.cc",
     "../ash/scanning/scanning_file_path_helper.h",
-    "../ash/scanning/scanning_type_converters.cc",
-    "../ash/scanning/scanning_type_converters.h",
     "../ash/scanning/zeroconf_scanner_detector.cc",
     "../ash/scanning/zeroconf_scanner_detector.h",
     "../ash/scanning/zeroconf_scanner_detector_utils.cc",
@@ -2964,6 +2962,7 @@
     "../ash/file_manager/io_task_controller_unittest.cc",
     "../ash/file_manager/path_util_unittest.cc",
     "../ash/file_manager/restore_io_task_unittest.cc",
+    "../ash/file_manager/restore_to_destination_io_task_unittest.cc",
     "../ash/file_manager/speedometer_unittest.cc",
     "../ash/file_manager/trash_io_task_unittest.cc",
     "../ash/file_manager/trash_unittest_base.cc",
@@ -3400,7 +3399,6 @@
     "../ash/scanning/scan_service_factory_unittest.cc",
     "../ash/scanning/scan_service_unittest.cc",
     "../ash/scanning/scanning_file_path_helper_unittest.cc",
-    "../ash/scanning/scanning_type_converters_unittest.cc",
     "../ash/scanning/zeroconf_scanner_detector_unittest.cc",
     "../ash/scheduler_configuration_manager_unittest.cc",
     "../ash/secure_channel/nearby_connection_broker_impl_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index 90bda29..97a0905b 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -1328,6 +1328,7 @@
   event_status.task_id = status.task_id;
   event_status.type = GetIOTaskType(status.type);
   event_status.state = GetIOTaskState(status.state);
+  event_status.show_notification = status.show_notification;
 
   // Speedometer can produce infinite result which can't be serialized to JSON
   // when sending the status via private API.
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
index 895381d5..dce41c6 100644
--- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
@@ -663,7 +663,7 @@
 
   // If there are any SWA windows open, we remove the progress in system
   // notification.
-  if (DoFilesSwaWindowsExist()) {
+  if (!status.show_notification || DoFilesSwaWindowsExist()) {
     GetNotificationDisplayService()->Close(NotificationHandler::Type::TRANSIENT,
                                            id);
     return;
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
index 811c5c9d..c4695e1 100644
--- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
@@ -147,8 +147,7 @@
     display_service_ = std::make_unique<NotificationDisplayServiceTester>(
         browser()->profile());
 
-    user_manager_.AddUser(AccountId::FromUserEmailGaiaId(
-        browser()->profile()->GetProfileUserName(), "12345"));
+    user_manager_.AddUser(AccountId::FromUserEmailGaiaId("test@test", "12345"));
   }
 
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
index 8ee6ca55..22b2fe8 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
@@ -63,13 +63,13 @@
     // Make sure the Google extension is allowed for every OEM.
     ExtensionInfoTestParams(
         /*extension_id=*/"gogonhoemckpdpadfnjnpgbjpbjnodgc",
-        /*pwa_page_url=*/"https://www.google.com",
-        /*matches_origin=*/"*://www.google.com/*",
+        /*pwa_page_url=*/"https://googlechromelabs.github.io/",
+        /*matches_origin=*/"*://googlechromelabs.github.io/*",
         /*manufacturer=*/"HP"),
     ExtensionInfoTestParams(
         /*extension_id=*/"gogonhoemckpdpadfnjnpgbjpbjnodgc",
-        /*pwa_page_url=*/"https://www.google.com",
-        /*matches_origin=*/"*://www.google.com/*",
+        /*pwa_page_url=*/"https://googlechromelabs.github.io/",
+        /*matches_origin=*/"*://googlechromelabs.github.io/*",
         /*manufacturer=*/"ASUS"),
     // Make sure the extensions of each OEM are allowed on their device.
     ExtensionInfoTestParams(
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
index bfe6ce96..9b55f725 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
@@ -85,11 +85,11 @@
 }
 
 std::string BaseTelemetryExtensionBrowserTest::pwa_page_url() const {
-  return "http://www.google.com";
+  return "http://googlechromelabs.github.io";
 }
 
 std::string BaseTelemetryExtensionBrowserTest::matches_origin() const {
-  return "*://www.google.com/*";
+  return "*://googlechromelabs.github.io/*";
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
index 80c66865..bf2e479 100644
--- a/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
@@ -70,9 +70,10 @@
                .SetManifestKey(
                    "externally_connectable",
                    extensions::DictionaryBuilder()
-                       .Set("matches", extensions::ListBuilder()
-                                           .Append("*://www.google.com/*")
-                                           .Build())
+                       .Set("matches",
+                            extensions::ListBuilder()
+                                .Append("*://googlechromelabs.github.io/*")
+                                .Build())
                        .Build())
                .SetID(kChromeOSSystemExtensionId)  // only allowlisted id
                .SetLocation(ManifestLocation::kInternal)
diff --git a/chrome/browser/chromeos/extensions/wm/wm_desks_private_api.cc b/chrome/browser/chromeos/extensions/wm/wm_desks_private_api.cc
index ec3be0b..46ed4ec 100644
--- a/chrome/browser/chromeos/extensions/wm/wm_desks_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wm/wm_desks_private_api.cc
@@ -18,6 +18,8 @@
 
 namespace {
 
+constexpr char kInvalidUuidError[] = "Invalid template UUID.";
+
 api::wm_desks_private::Desk FromAshDesk(const ash::Desk& ash_desk) {
   api::wm_desks_private::Desk target;
   target.desk_name = base::UTF16ToUTF8(ash_desk.name());
@@ -38,8 +40,12 @@
       api::wm_desks_private::GetDeskTemplateJson::Params::Create(args()));
   EXTENSION_FUNCTION_VALIDATE(params);
 
+  base::GUID uuid = base::GUID::ParseCaseInsensitive(params->template_uuid);
+  if (!uuid.is_valid())
+    return RespondNow(Error(kInvalidUuidError));
+
   DesksClient::Get()->GetTemplateJson(
-      params->template_uuid, Profile::FromBrowserContext(browser_context()),
+      uuid, Profile::FromBrowserContext(browser_context()),
       base::BindOnce(
           &WmDesksPrivateGetDeskTemplateJsonFunction::OnGetDeskTemplateJson,
           this));
diff --git a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
index cb5285b..356502c 100644
--- a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
+++ b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
@@ -288,7 +288,8 @@
       return;
     }
     head_.response_start = base::TimeTicks::Now();
-    client_->OnReceiveResponse(head_.Clone(), std::move(consumer_handle));
+    client_->OnReceiveResponse(head_.Clone(), std::move(consumer_handle),
+                               absl::nullopt);
 
     data_producer_ = std::make_unique<FileSystemReaderDataPipeProducer>(
         std::move(producer_handle), std::move(stream_reader), size,
diff --git a/chrome/browser/chromeos/reporting/metric_reporting_manager_delegate_base.h b/chrome/browser/chromeos/reporting/metric_reporting_manager_delegate_base.h
index 987a13d..3e8a652 100644
--- a/chrome/browser/chromeos/reporting/metric_reporting_manager_delegate_base.h
+++ b/chrome/browser/chromeos/reporting/metric_reporting_manager_delegate_base.h
@@ -99,9 +99,6 @@
   // otherwise.
   virtual bool IsAffiliated(Profile* profile) const;
 
-  // Returns true if device is deprovisioned. False otherwise.
-  virtual bool IsDeprovisioned() const = 0;
-
   // Returns the delay interval used with `MetricReportingManager`
   // initialization.
   base::TimeDelta GetInitDelay() const;
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index 175a245..dccfd47 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -159,10 +159,13 @@
     DCHECK(!receiver_.is_bound());
 
     net::HostPortPair host_port_pair(host, port);
+    // Intentionally using a HostPortPair because scheme isn't specified.
     // Use a transient NetworkIsolationKey, as there's no need to share cached
     // DNS results from this request with anything else.
     profile->GetDefaultStoragePartition()->GetNetworkContext()->ResolveHost(
-        host_port_pair, net::NetworkIsolationKey::CreateTransient(), nullptr,
+        network::mojom::HostResolverHost::NewHostPortPair(
+            std::move(host_port_pair)),
+        net::NetworkIsolationKey::CreateTransient(), nullptr,
         receiver_.BindNewPipeAndPassRemote());
     receiver_.set_disconnect_handler(
         base::BindOnce(&PortForwardingHostResolver::OnComplete,
diff --git a/chrome/browser/devtools/device/tcp_device_provider.cc b/chrome/browser/devtools/device/tcp_device_provider.cc
index 1089c913..2aa73d7f 100644
--- a/chrome/browser/devtools/device/tcp_device_provider.cc
+++ b/chrome/browser/devtools/device/tcp_device_provider.cc
@@ -55,11 +55,14 @@
                                                   std::move(pending_receiver));
                        },
                        resolver.BindNewPipeAndPassReceiver()));
+    // Intentionally using a HostPortPair because scheme isn't specified.
     // Fine to use a transient NetworkIsolationKey here - this is for debugging,
     // so performance doesn't matter, and it doesn't need to share a DNS cache
     // with anything else.
-    resolver->ResolveHost(address, net::NetworkIsolationKey::CreateTransient(),
-                          nullptr, receiver_.BindNewPipeAndPassRemote());
+    resolver->ResolveHost(
+        network::mojom::HostResolverHost::NewHostPortPair(address),
+        net::NetworkIsolationKey::CreateTransient(), nullptr,
+        receiver_.BindNewPipeAndPassRemote());
     receiver_.set_disconnect_handler(
         base::BindOnce(&ResolveHostAndOpenSocket::OnComplete,
                        base::Unretained(this), net::ERR_NAME_NOT_RESOLVED,
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index 4f7b2e09..003f9dbe 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -1810,7 +1810,7 @@
   EXPECT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
             MOJO_RESULT_OK);
   params->client->OnReceiveResponse(std::move(response),
-                                    std::move(consumer_handle));
+                                    std::move(consumer_handle), absl::nullopt);
   params->client->OnComplete(network::URLLoaderCompletionStatus());
   return true;
 }
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 18492a4d..07bbbd0 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -42,7 +42,6 @@
 #include "chrome/browser/download/mixed_content_download_blocking.h"
 #include "chrome/browser/download/save_package_file_picker.h"
 #include "chrome/browser/enterprise/connectors/common.h"
-#include "chrome/browser/enterprise/connectors/file_system/rename_handler.h"
 #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
 #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h"
 #include "chrome/browser/platform_util.h"
@@ -1713,18 +1712,6 @@
       &ChromeDownloadManagerDelegate::ConnectToQuarantineService);
 }
 
-std::unique_ptr<download::DownloadItemRenameHandler>
-ChromeDownloadManagerDelegate::GetRenameHandlerForDownload(
-    download::DownloadItem* download_item) {
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
-    BUILDFLAG(IS_MAC)
-  return enterprise_connectors::FileSystemRenameHandler::CreateIfNeeded(
-      download_item);
-#else
-  return nullptr;
-#endif
-}
-
 void ChromeDownloadManagerDelegate::CheckSavePackageAllowed(
     download::DownloadItem* download_item,
     base::flat_map<base::FilePath, base::FilePath> save_package_files,
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index cf76ae3..d994ade8 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -138,8 +138,6 @@
       content::CheckDownloadAllowedCallback check_download_allowed_cb) override;
   download::QuarantineConnectionCallback GetQuarantineConnectionCallback()
       override;
-  std::unique_ptr<download::DownloadItemRenameHandler>
-  GetRenameHandlerForDownload(download::DownloadItem* download_item) override;
   void CheckSavePackageAllowed(
       download::DownloadItem* download_item,
       base::flat_map<base::FilePath, base::FilePath> save_package_files,
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index 5a88913b..3f87e5b 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -249,8 +249,8 @@
     ASSERT_EQ(MOJO_RESULT_OK, result);
     ASSERT_EQ(data.size(), write_size);
     ASSERT_TRUE(consumer_handle.is_valid());
-    params->client->OnReceiveResponse(std::move(head),
-                                      std::move(consumer_handle));
+    params->client->OnReceiveResponse(
+        std::move(head), std::move(consumer_handle), absl::nullopt);
   }
 
   const std::map<std::string, Handler> handlers_;
diff --git a/chrome/browser/enterprise/connectors/connectors_prefs.cc b/chrome/browser/enterprise/connectors/connectors_prefs.cc
index 7f3b0db..6b0271a 100644
--- a/chrome/browser/enterprise/connectors/connectors_prefs.cc
+++ b/chrome/browser/enterprise/connectors/connectors_prefs.cc
@@ -8,6 +8,7 @@
 
 #include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/connectors_service.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/browser/enterprise/connectors/file_system/account_info_utils.h"
 #include "chrome/browser/enterprise/connectors/service_provider_config.h"
 
@@ -32,13 +33,6 @@
 
 const char kOnSecurityEventPref[] = "enterprise_connectors.on_security_event";
 
-const char kContextAwareAccessSignalsAllowlistPref[] =
-    "enterprise_connectors.device_trust.origins";
-#if BUILDFLAG(IS_MAC)
-const char kDeviceTrustDisableKeyCreationPref[] =
-    "enterprise_connectors.device_trust.disable_key_creation";
-#endif
-
 const char kOnFileAttachedScopePref[] =
     "enterprise_connectors.scope.on_file_attached";
 const char kOnFileDownloadedScopePref[] =
@@ -85,14 +79,13 @@
   registry->RegisterIntegerPref(kOnFileTransferScopePref, 0);
 #endif
   registry->RegisterIntegerPref(kOnSecurityEventScopePref, 0);
-  registry->RegisterListPref(kContextAwareAccessSignalsAllowlistPref);
-
+  RegisterDeviceTrustConnectorProfilePrefs(registry);
   RegisterFileSystemPrefs(registry);
 }
 
 #if BUILDFLAG(IS_MAC)
 void RegisterLocalPrefs(PrefRegistrySimple* registry) {
-  registry->RegisterBooleanPref(kDeviceTrustDisableKeyCreationPref, false);
+  RegisterDeviceTrustConnectorLocalPrefs(registry);
 }
 #endif
 
diff --git a/chrome/browser/enterprise/connectors/connectors_prefs.h b/chrome/browser/enterprise/connectors/connectors_prefs.h
index bd915ed4..13c1d38 100644
--- a/chrome/browser/enterprise/connectors/connectors_prefs.h
+++ b/chrome/browser/enterprise/connectors/connectors_prefs.h
@@ -35,9 +35,6 @@
 // Pref that maps to the "OnSecurityEventEnterpriseConnector" policy.
 extern const char kOnSecurityEventPref[];
 
-// Pref that maps to the "ContextAwareAccessSignalsAllowlistPref" policy.
-extern const char kContextAwareAccessSignalsAllowlistPref[];
-
 // Prefs that map to the scope of each policy using a
 // EnterpriseConnectorsPolicyHandler.
 extern const char kOnFileAttachedScopePref[];
@@ -49,15 +46,6 @@
 #endif
 extern const char kOnSecurityEventScopePref[];
 
-#if BUILDFLAG(IS_MAC)
-// The pref on whether the device trust key creation is disabled for the
-// current user. The device trust key creation is disabled when a key for
-// the device is already present on the Server but a key upload is
-// requested with a another key not signed by the previous one. The key
-// creation is enabled by default.
-extern const char kDeviceTrustDisableKeyCreationPref[];
-#endif
-
 void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
 #if BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
index ecf3be8..e7c0dec 100644
--- a/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
@@ -94,6 +94,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr char kTestGaiaId[] = "123";
+constexpr char kTestEmail[] = "test@test";
 #endif
 
 std::string ExpectedOsPlatform() {
@@ -176,8 +177,7 @@
     // Remove cached user from ProfileHelper so it does not interfere with other
     // workflows
     ash::ProfileHelper::Get()->RemoveUserFromListForTesting(
-        AccountId::FromUserEmailGaiaId(
-            browser()->profile()->GetProfileUserName(), kTestGaiaId));
+        AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId));
     user_manager_enabler_.reset();
 #endif
   }
@@ -228,8 +228,8 @@
     auto* fake_user_manager = new ash::FakeChromeUserManager();
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         base::WrapUnique(fake_user_manager));
-    AccountId account_id = AccountId::FromUserEmailGaiaId(
-        browser()->profile()->GetProfileUserName(), kTestGaiaId);
+    AccountId account_id =
+        AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId);
     fake_user_manager->AddUserWithAffiliationAndTypeAndProfile(
         account_id, management_status() == ManagementStatus::AFFILIATED,
         user_manager::USER_TYPE_REGULAR,
diff --git a/chrome/browser/enterprise/connectors/device_trust/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/BUILD.gn
index ac4e57b..4115de4 100644
--- a/chrome/browser/enterprise/connectors/device_trust/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/BUILD.gn
@@ -10,6 +10,14 @@
   public_deps = [ "//base" ]
 }
 
+source_set("prefs") {
+  sources = [ "prefs.cc" ]
+
+  public = [ "prefs.h" ]
+
+  deps = [ "//components/prefs" ]
+}
+
 source_set("test_support") {
   testonly = true
   sources = [
@@ -29,6 +37,7 @@
   ]
 
   deps = [
+    ":prefs",
     "//components/pref_registry",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
diff --git a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.cc
index d643f74..fd9e472 100644
--- a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.h"
 
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/browser/browser_device_trust_connector_service.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "components/enterprise/browser/device_trust/device_trust_key_manager.h"
 #include "components/prefs/pref_service.h"
 
@@ -27,4 +27,10 @@
          !local_prefs_->GetBoolean(kDeviceTrustDisableKeyCreationPref);
 }
 
+void MacDeviceTrustConnectorService::OnConnectorEnabled() {
+  if (!local_prefs_->GetBoolean(kDeviceTrustDisableKeyCreationPref)) {
+    BrowserDeviceTrustConnectorService::OnConnectorEnabled();
+  }
+}
+
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.h b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.h
index 350e99e..1bd3818 100644
--- a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service.h
@@ -34,6 +34,10 @@
   // Returns whether the Device Trust connector is enabled or not.
   bool IsConnectorEnabled() const override;
 
+  // Hook that is called to notify that the policy changed and the connector
+  // became, or is still, enabled.
+  void OnConnectorEnabled() override;
+
  private:
   base::raw_ptr<PrefService> local_prefs_;
 };
diff --git a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service_unittest.cc
index 25f2db2..56710f7 100644
--- a/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/browser/mac_device_trust_connector_service_unittest.cc
@@ -6,9 +6,9 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/mock_device_trust_key_manager.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -33,8 +33,8 @@
       public ::testing::WithParamInterface<std::tuple<bool, bool, bool>> {
  protected:
   void SetUp() override {
-    RegisterProfilePrefs(profile_prefs_.registry());
-    RegisterLocalPrefs(local_prefs_.registry());
+    RegisterDeviceTrustConnectorProfilePrefs(profile_prefs_.registry());
+    RegisterDeviceTrustConnectorLocalPrefs(local_prefs_.registry());
     feature_list_.InitWithFeatureState(kDeviceTrustConnectorEnabled,
                                        is_flag_enabled());
     UpdateAllowlistProfilePreference();
@@ -43,15 +43,15 @@
 
   void UpdateAllowlistProfilePreference() {
     is_policy_enabled()
-        ? profile_prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                                     base::Value(GetOrigins()))
-        : profile_prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                                     base::Value(base::Value::List()));
+        ? profile_prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                                        base::Value(GetOrigins()))
+        : profile_prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                                        base::Value(base::Value::List()));
   }
 
   void UpdateKeyCreationLocalPreference() {
-    local_prefs_.SetUserPref(kDeviceTrustDisableKeyCreationPref,
-                             base::Value(!is_key_creation_enabled()));
+    local_prefs_.SetManagedPref(kDeviceTrustDisableKeyCreationPref,
+                                base::Value(!is_key_creation_enabled()));
   }
 
   std::unique_ptr<MacDeviceTrustConnectorService> CreateService() {
@@ -80,6 +80,15 @@
   EXPECT_EQ(is_attestation_flow_enabled(), service->IsConnectorEnabled());
 }
 
+// Tests that key manager is initialized only when key creation is not disabled.
+TEST_P(MacDeviceTrustConnectorServiceTest, OnConnectorEnabled) {
+  auto service = CreateService();
+  EXPECT_CALL(mock_key_manager_, StartInitialization())
+      .Times(is_key_creation_enabled() ? 1 : 0);
+
+  service->OnConnectorEnabled();
+}
+
 INSTANTIATE_TEST_SUITE_P(,
                          MacDeviceTrustConnectorServiceTest,
                          testing::Combine(testing::Bool(),
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
index ec6d7fe..9d18e98 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
@@ -13,7 +13,6 @@
 #include "base/values.h"
 #include "build/branding_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/connectors_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/common/metrics_utils.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
@@ -21,6 +20,7 @@
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/browser/enterprise/signals/device_info_fetcher.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/policy/dm_token_utils.h"
@@ -31,6 +31,8 @@
 #include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
 #include "components/enterprise/browser/enterprise_switches.h"
 #include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/policy_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/navigation_handle.h"
@@ -157,6 +159,13 @@
                     embedded_test_server()->StartAndReturnHandle());
   }
 
+  void SetUpInProcessBrowserTestFixture() override {
+    provider_.SetDefaultReturns(
+        /*is_initialization_complete_return=*/true,
+        /*is_first_policy_load_complete_return=*/true);
+    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
+  }
+
 #if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
   void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
     InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
@@ -169,16 +178,29 @@
     InProcessBrowserTest::TearDownOnMainThread();
   }
 
-  void PopulatePref(bool as_empty_list = false,
-                    Browser* active_browser = nullptr) {
+  void SetPolicy(bool as_empty_list = false,
+                 Browser* active_browser = nullptr) {
+    policy::PolicyMap policy_map;
     base::Value list_value(base::Value::Type::LIST);
 
     if (!as_empty_list) {
       list_value.Append(kAllowedHost);
     }
 
-    prefs(active_browser)
-        ->Set(kContextAwareAccessSignalsAllowlistPref, std::move(list_value));
+    policy_map.Set(policy::key::kContextAwareAccessSignalsAllowlist,
+                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+                   policy::POLICY_SOURCE_CLOUD, std::move(list_value), nullptr);
+
+    EXPECT_NO_FATAL_FAILURE(provider_.UpdateChromePolicy(policy_map));
+    base::RunLoop().RunUntilIdle();
+
+    EXPECT_EQ(prefs(active_browser)
+                  ->GetValueList(kContextAwareAccessSignalsAllowlistPref)
+                  .empty(),
+              as_empty_list);
+    EXPECT_TRUE(
+        prefs(active_browser)
+            ->IsManagedPreference(kContextAwareAccessSignalsAllowlistPref));
   }
 
   void NavigateToUrl(const GURL& url) {
@@ -253,6 +275,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   base::HistogramTester histogram_tester_;
   std::unique_ptr<policy::FakeBrowserDMTokenStorage> browser_dm_token_storage_;
+  testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_;
   absl::optional<const net::test_server::HttpRequest>
       initial_attestation_request_;
   absl::optional<const net::test_server::HttpRequest>
@@ -270,7 +293,7 @@
   TestNavigationManager first_navigation(web_contents(), redirect_url);
 
   // Add allowed domain to Prefs and trigger a navigation to it.
-  PopulatePref();
+  SetPolicy();
   NavigateToUrl(redirect_url);
 
   first_navigation.WaitForNavigationFinished();
@@ -340,7 +363,7 @@
   TestNavigationManager navigation_manager(web_contents(), navigation_url);
 
   // Add allowed domain to Prefs and trigger a navigation to another domain.
-  PopulatePref();
+  SetPolicy();
   NavigateToUrl(navigation_url);
 
   navigation_manager.WaitForNavigationFinished();
@@ -362,7 +385,7 @@
   TestNavigationManager navigation_manager(web_contents(), navigation_url);
 
   // Set the allow-list Pref to an empty list and trigger a navigation.
-  PopulatePref(/*as_empty_list=*/true);
+  SetPolicy(/*as_empty_list=*/true);
   NavigateToUrl(navigation_url);
 
   navigation_manager.WaitForNavigationFinished();
@@ -407,7 +430,7 @@
       web_contents(incognito_browser));
 
   // Add allowed domain to Prefs.
-  PopulatePref(true, incognito_browser);
+  SetPolicy(false, incognito_browser);
 
   // Try to create the device trust navigation throttle.
   EXPECT_TRUE(enterprise_connectors::DeviceTrustNavigationThrottle::
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
index 685b943..141129a 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h"
 
 #include "base/check.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "components/prefs/pref_service.h"
 #include "components/url_matcher/url_matcher.h"
 #include "components/url_matcher/url_util.h"
@@ -16,16 +16,15 @@
 
 namespace {
 
-// TODO when adding this service to the login-screen: Check if the preference is
-// unmanaged, while we are in sign-in profile to address
-// security-/privacy-concerns
-const base::Value::List& GetPolicyUrlPatterns(PrefService* prefs) {
-  return prefs->GetValueList(kContextAwareAccessSignalsAllowlistPref);
+const base::Value::List* GetPolicyUrlPatterns(PrefService* prefs) {
+  if (!prefs->IsManagedPreference(kContextAwareAccessSignalsAllowlistPref))
+    return nullptr;
+  return &prefs->GetValueList(kContextAwareAccessSignalsAllowlistPref);
 }
 
 bool ConnectorPolicyHasValues(PrefService* profile_prefs) {
-  const auto& list = GetPolicyUrlPatterns(profile_prefs);
-  return !list.empty();
+  const auto* list = GetPolicyUrlPatterns(profile_prefs);
+  return list && !list->empty();
 }
 
 }  // namespace
@@ -74,16 +73,16 @@
 void DeviceTrustConnectorService::OnPolicyUpdated() {
   DCHECK(IsDeviceTrustConnectorFeatureEnabled());
 
-  const base::Value::List& url_patterns = GetPolicyUrlPatterns(profile_prefs_);
+  const base::Value::List* url_patterns = GetPolicyUrlPatterns(profile_prefs_);
 
   if (!matcher_ || !matcher_->IsEmpty()) {
     // Reset the matcher.
     matcher_ = std::make_unique<url_matcher::URLMatcher>();
   }
 
-  if (!url_patterns.empty()) {
+  if (url_patterns && !url_patterns->empty()) {
     // Add the new endpoints to the conditions.
-    url_matcher::util::AddAllowFilters(matcher_.get(), url_patterns);
+    url_matcher::util::AddAllowFilters(matcher_.get(), *url_patterns);
 
     // Call the hook which signals that the connector has been enabled.
     OnConnectorEnabled();
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
index b00c856..994c3fe 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
@@ -6,8 +6,8 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -47,7 +47,7 @@
       public ::testing::WithParamInterface<std::tuple<bool, bool>> {
  protected:
   void SetUp() override {
-    RegisterProfilePrefs(prefs_.registry());
+    RegisterDeviceTrustConnectorProfilePrefs(prefs_.registry());
 
     feature_list_.InitWithFeatureState(kDeviceTrustConnectorEnabled,
                                        is_flag_enabled());
@@ -60,18 +60,18 @@
   }
 
   void EnableServicePolicy() {
-    prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                       base::Value(GetOrigins()));
+    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                          base::Value(GetOrigins()));
   }
 
   void UpdateServicePolicy() {
-    prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                       base::Value(GetMoreOrigins()));
+    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                          base::Value(GetMoreOrigins()));
   }
 
   void DisableServicePolicy() {
-    prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                       base::Value(base::Value::List()));
+    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                          base::Value(base::Value::List()));
   }
 
   std::unique_ptr<DeviceTrustConnectorService> CreateService() {
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc
index 6da2b80d..67c239d 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc
@@ -15,10 +15,10 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/values.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/browser/enterprise/connectors/device_trust/signals/mock_signals_service.h"
 #include "components/device_signals/core/common/signals_constants.h"
 #include "components/prefs/testing_pref_service.h"
@@ -85,7 +85,7 @@
       public ::testing::WithParamInterface<std::tuple<bool, bool>> {
  protected:
   void SetUp() override {
-    RegisterProfilePrefs(prefs_.registry());
+    RegisterDeviceTrustConnectorProfilePrefs(prefs_.registry());
 
     feature_list_.InitWithFeatureState(kDeviceTrustConnectorEnabled,
                                        is_flag_enabled());
@@ -98,13 +98,13 @@
   }
 
   void EnableServicePolicy() {
-    prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                       base::Value(GetOrigins()));
+    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                          base::Value(GetOrigins()));
   }
 
   void DisableServicePolicy() {
-    prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref,
-                       base::Value(base::Value::List()));
+    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                          base::Value(base::Value::List()));
   }
 
   std::unique_ptr<DeviceTrustService> CreateService() {
diff --git a/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc
index b0da21b..d9eb582 100644
--- a/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.h"
 
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 
@@ -18,8 +18,8 @@
 
 void FakeDeviceTrustConnectorService::update_policy(
     base::Value::List new_urls) {
-  test_prefs_->SetList(kContextAwareAccessSignalsAllowlistPref,
-                       std::move(new_urls));
+  test_prefs_->SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
+                              base::Value(std::move(new_urls)));
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/BUILD.gn
index 8b67ecf..e5eee331 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/BUILD.gn
@@ -29,6 +29,7 @@
     "//chrome/browser/enterprise/connectors/device_trust/key_management/core:util",
     "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence",
     "//components/policy/core/common",
+    "//components/prefs",
     "//crypto",
     "//services/network/public/cpp",
     "//services/network/public/cpp:cpp_base",
@@ -75,6 +76,7 @@
     "//components/enterprise:test_support",
     "//components/policy/core/common",
     "//components/policy/core/common:test_support",
+    "//components/prefs:test_support",
     "//services/network:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
index 4c6fd09..e710bff 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
@@ -15,6 +15,7 @@
   public_deps = [ "//base" ]
 
   deps = [
+    "//components/prefs",
     "//services/network/public/cpp",
     "//third_party/abseil-cpp:absl",
   ]
@@ -48,6 +49,7 @@
       "mac_key_rotation_command.h",
     ]
     deps += [
+      "//chrome/browser/enterprise/connectors/device_trust:prefs",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/mac",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/installer:elevated_rotation",
@@ -72,6 +74,7 @@
 
   public_deps = [
     ":commands",
+    "//components/prefs",
     "//services/network/public/cpp",
     "//testing/gmock",
     "//third_party/abseil-cpp:absl",
@@ -109,11 +112,14 @@
     sources = [ "mac_key_rotation_command_unittest.cc" ]
 
     deps += [
+      "//chrome/browser",
+      "//chrome/browser/enterprise/connectors/device_trust:prefs",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/mac",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/mac:test_support",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network:test_support",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/installer:elevated_rotation",
+      "//components/prefs:test_support",
     ]
   }
 }
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.cc
index 1ddcd36..ab510d53 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.cc
@@ -8,6 +8,7 @@
 #include "base/notreached.h"
 #include "build/build_config.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command.h"
+#include "components/prefs/pref_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -42,13 +43,15 @@
 }
 
 std::unique_ptr<KeyRotationCommand> KeyRotationCommandFactory::CreateCommand(
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+    PrefService* local_prefs) {
 #if BUILDFLAG(IS_WIN)
   return std::make_unique<WinKeyRotationCommand>();
 #elif BUILDFLAG(IS_LINUX)
   return std::make_unique<LinuxKeyRotationCommand>(url_loader_factory);
 #elif BUILDFLAG(IS_MAC)
-  return std::make_unique<MacKeyRotationCommand>(url_loader_factory);
+  return std::make_unique<MacKeyRotationCommand>(url_loader_factory,
+                                                 local_prefs);
 #else
   return nullptr;
 #endif  // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.h
index 95f888d..c95a8b43 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command_factory.h
@@ -9,6 +9,8 @@
 
 #include "base/memory/scoped_refptr.h"
 
+class PrefService;
+
 namespace network {
 class SharedURLLoaderFactory;
 }  // namespace network
@@ -24,10 +26,12 @@
   static KeyRotationCommandFactory* GetInstance();
 
   // Creates a platform-specific key rotation command
-  // object. This object takes in a shared url loader factory as
-  // a parameter, which is used for mojo support in the linux key rotation.
+  // object. The shared `url_loader_factory` is used in both the linux and mac
+  // key rotation for mojo support, and the `local_prefs` is needed in the mac
+  // key rotation exclusively for updating a local preference.
   virtual std::unique_ptr<KeyRotationCommand> CreateCommand(
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      PrefService* local_prefs);
 
  protected:
   static void SetFactoryInstanceForTesting(KeyRotationCommandFactory* factory);
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.cc
index 7d6ae13..5237b87 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.cc
@@ -13,7 +13,9 @@
 #include "base/syslog_logging.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mojo_key_network_delegate.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/common/channel_info.h"
+#include "components/prefs/pref_service.h"
 #include "components/version_info/channel.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "url/gurl.h"
@@ -29,19 +31,48 @@
          host_name == kStableChannelHostName;
 }
 
+// Processes the `result` of the key rotation and returns it to the
+// rotation `callback`. In the case of a key conflict error the `local_prefs`
+// is used to disable the key creation process. The `key_rotation_manager` is
+// given to keep the object that carries out the key rotation alive.
+void OnKeyRotated(PrefService* local_prefs,
+                  std::unique_ptr<KeyRotationManager> key_rotation_manager,
+                  KeyRotationCommand::Callback callback,
+                  KeyRotationManager::Result result) {
+  if (result == KeyRotationManager::Result::FAILED) {
+    SYSLOG(ERROR) << "Device trust key rotation failed.";
+    std::move(callback).Run(KeyRotationCommand::Status::FAILED);
+    return;
+  }
+
+  if (result == KeyRotationManager::Result::FAILED_KEY_CONFLICT) {
+    SYSLOG(ERROR) << "Device trust key rotation failed. Conflict "
+                     "with the key that exists on the server.";
+    local_prefs->SetBoolean(kDeviceTrustDisableKeyCreationPref, true);
+    std::move(callback).Run(KeyRotationCommand::Status::FAILED);
+    return;
+  }
+
+  std::move(callback).Run(KeyRotationCommand::Status::SUCCEEDED);
+}
+
 }  // namespace
 
 MacKeyRotationCommand::MacKeyRotationCommand(
+    PrefService* local_prefs,
     std::unique_ptr<KeyRotationManager> key_rotation_manager)
-    : key_rotation_manager_(std::move(key_rotation_manager)),
+    : local_prefs_(local_prefs),
+      key_rotation_manager_(std::move(key_rotation_manager)),
       client_(SecureEnclaveClient::Create()) {
   DCHECK(key_rotation_manager_);
   DCHECK(client_);
 }
 
 MacKeyRotationCommand::MacKeyRotationCommand(
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-    : key_rotation_manager_(
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+    PrefService* local_prefs)
+    : local_prefs_(local_prefs),
+      key_rotation_manager_(
           KeyRotationManager::Create(std::make_unique<MojoKeyNetworkDelegate>(
               std::move(url_loader_factory.get())))),
       client_(SecureEnclaveClient::Create()) {
@@ -74,20 +105,11 @@
     std::move(callback).Run(KeyRotationCommand::Status::FAILED);
     return;
   }
-
+  // TODO: b/243652906 update the rotation to happen from within a thread pool.
   key_rotation_manager_.get()->Rotate(
       dm_server_url, params.dm_token, params.nonce,
-      base::BindOnce(
-          [](std::unique_ptr<KeyRotationManager> manager, Callback callback,
-             bool result) {
-            if (!result) {
-              SYSLOG(ERROR) << "Device trust key rotation failed.";
-              std::move(callback).Run(KeyRotationCommand::Status::FAILED);
-              return;
-            }
-            std::move(callback).Run(KeyRotationCommand::Status::SUCCEEDED);
-          },
-          std::move(key_rotation_manager_), std::move(callback)));
+      base::BindOnce(OnKeyRotated, local_prefs_,
+                     std::move(key_rotation_manager_), std::move(callback)));
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.h b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.h
index c4cd946..505618db 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command.h
@@ -11,6 +11,8 @@
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_client.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
 
+class PrefService;
+
 namespace network {
 class SharedURLLoaderFactory;
 }  // namespace network
@@ -19,8 +21,9 @@
 
 class MacKeyRotationCommand : public KeyRotationCommand {
  public:
-  explicit MacKeyRotationCommand(
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+  MacKeyRotationCommand(
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      PrefService* local_prefs);
 
   ~MacKeyRotationCommand() override;
 
@@ -30,9 +33,12 @@
  private:
   friend class MacKeyRotationCommandTest;
 
-  explicit MacKeyRotationCommand(
+  MacKeyRotationCommand(
+      PrefService* local_prefs,
       std::unique_ptr<KeyRotationManager> key_rotation_manager);
 
+  base::raw_ptr<PrefService> local_prefs_;
+
   std::unique_ptr<KeyRotationManager> key_rotation_manager_;
 
   // Used to issue Keychain APIs.
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command_unittest.cc
index eb78244..ba5c8cef 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mac_key_rotation_command_unittest.cc
@@ -15,6 +15,8 @@
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
+#include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -47,6 +49,7 @@
     "7C1.2.3&request=browser_public_key_upload";
 constexpr HttpResponseCode kSuccessCode = 200;
 constexpr HttpResponseCode kFailureCode = 400;
+constexpr HttpResponseCode kSignatureFailureCode = 409;
 
 }  // namespace
 
@@ -68,10 +71,13 @@
     mock_network_delegate_ = mock_network_delegate.get();
     mock_persistence_delegate_ = mock_persistence_delegate.get();
     EXPECT_CALL(*mock_persistence_delegate_, LoadKeyPair());
-    rotation_command_ = absl::WrapUnique(
-        new MacKeyRotationCommand(KeyRotationManager::CreateForTesting(
-            std::move(mock_network_delegate),
-            std::move(mock_persistence_delegate))));
+
+    RegisterDeviceTrustConnectorLocalPrefs(local_prefs_.registry());
+
+    rotation_command_ = absl::WrapUnique(new MacKeyRotationCommand(
+        &local_prefs_, KeyRotationManager::CreateForTesting(
+                           std::move(mock_network_delegate),
+                           std::move(mock_persistence_delegate))));
   }
 
  protected:
@@ -81,6 +87,7 @@
   MockKeyPersistenceDelegate* mock_persistence_delegate_ = nullptr;
   test::ScopedKeyPersistenceDelegateFactory scoped_factory_;
   KeyRotationCommand::Params params;
+  TestingPrefServiceSimple local_prefs_;
   base::test::TaskEnvironment task_environment_;
 };
 
@@ -104,6 +111,7 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 // Tests a failed key rotation due to an invalid command to rotate.
@@ -118,6 +126,7 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 // Tests a failed key rotation due to failure creating a new signing key pair.
@@ -135,6 +144,7 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 // Tests a failed key rotation due to a store key failure.
@@ -153,6 +163,37 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
+}
+
+// Tests a failed key rotation when uploading a the key to the dm server fails
+// due to a signature failure.
+TEST_F(MacKeyRotationCommandTest, RotateFailure_InvalidSignatureFailure) {
+  InSequence s;
+  EXPECT_CALL(*mock_secure_enclave_client_, VerifyKeychainUnlocked())
+      .WillOnce(Return(true));
+  EXPECT_CALL(*mock_secure_enclave_client_, VerifySecureEnclaveSupported())
+      .WillOnce(Return(true));
+  EXPECT_CALL(*mock_persistence_delegate_, CheckRotationPermissions())
+      .WillOnce(Return(true));
+  EXPECT_CALL(*mock_persistence_delegate_, CreateKeyPair());
+  EXPECT_CALL(*mock_persistence_delegate_, StoreKeyPair(_, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(
+      *mock_network_delegate_,
+      SendPublicKeyToDmServer(GURL(kFakeDmServerUrl), kFakeDMToken, _, _))
+      .WillOnce(Invoke([](const GURL& url, const std::string& dm_token,
+                          const std::string& body,
+                          base::OnceCallback<void(int)> callback) {
+        std::move(callback).Run(kSignatureFailureCode);
+      }));
+  EXPECT_CALL(*mock_persistence_delegate_, StoreKeyPair(_, _))
+      .WillOnce(Return(true));
+
+  base::test::TestFuture<KeyRotationCommand::Status> future;
+  rotation_command_->Trigger(params, future.GetCallback());
+  EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_TRUE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 // Tests a failed key rotation due to a failure sending the key to the dm
@@ -182,6 +223,7 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::FAILED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 // Tests when the key rotation is successful.
@@ -208,6 +250,7 @@
   base::test::TestFuture<KeyRotationCommand::Status> future;
   rotation_command_->Trigger(params, future.GetCallback());
   EXPECT_EQ(KeyRotationCommand::Status::SUCCEEDED, future.Get());
+  EXPECT_FALSE(local_prefs_.GetBoolean(kDeviceTrustDisableKeyCreationPref));
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.cc
index 2db718d..2d7e86d 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.cc
@@ -9,6 +9,7 @@
 
 #include "base/check.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/mock_key_rotation_command.h"
+#include "components/prefs/pref_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -30,7 +31,8 @@
 
 std::unique_ptr<KeyRotationCommand>
 ScopedKeyRotationCommandFactory::CreateCommand(
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+    PrefService* local_prefs) {
   if (mock_key_rotation_command_) {
     return std::move(mock_key_rotation_command_);
   }
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.h
index 8eb3a7a..cc5a076 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/scoped_key_rotation_command_factory.h
@@ -13,6 +13,8 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+class PrefService;
+
 namespace enterprise_connectors {
 
 namespace test {
@@ -29,8 +31,8 @@
 
   // KeyRotationCommandFactory:
   std::unique_ptr<KeyRotationCommand> CreateCommand(
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-      override;
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      PrefService* local_prefs) override;
 
  private:
   std::unique_ptr<test::MockKeyRotationCommand> mock_key_rotation_command_;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.cc
index afb549f..ab7f4e4 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.cc
@@ -9,6 +9,7 @@
 
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.h"
+#include "components/prefs/pref_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 // #include
 // "components/enterprise/browser/controller/browser_dm_token_storage.h"
@@ -20,10 +21,11 @@
 std::unique_ptr<KeyRotationLauncher> KeyRotationLauncher::Create(
     policy::BrowserDMTokenStorage* dm_token_storage,
     policy::DeviceManagementService* device_management_service,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+    PrefService* local_prefs) {
   return std::make_unique<KeyRotationLauncherImpl>(
       dm_token_storage, device_management_service,
-      std::move(url_loader_factory));
+      std::move(url_loader_factory), local_prefs);
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.h b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.h
index ffe160161..f59d6619 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.h
@@ -11,6 +11,8 @@
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/key_rotation_command.h"
 
+class PrefService;
+
 namespace network {
 class SharedURLLoaderFactory;
 }  // namespace network
@@ -27,7 +29,8 @@
   static std::unique_ptr<KeyRotationLauncher> Create(
       policy::BrowserDMTokenStorage* dm_token_storage,
       policy::DeviceManagementService* device_management_service,
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      PrefService* local_prefs);
 
   virtual ~KeyRotationLauncher() = default;
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.cc
index ab3f1c49..c8feb5c2 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.cc
@@ -14,6 +14,7 @@
 #include "components/policy/core/common/cloud/device_management_service.h"
 #include "components/policy/core/common/cloud/dm_auth.h"
 #include "components/policy/core/common/cloud/dmserver_job_configurations.h"
+#include "components/prefs/pref_service.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
@@ -22,13 +23,16 @@
 KeyRotationLauncherImpl::KeyRotationLauncherImpl(
     policy::BrowserDMTokenStorage* dm_token_storage,
     policy::DeviceManagementService* device_management_service,
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+    PrefService* local_prefs)
     : dm_token_storage_(dm_token_storage),
       device_management_service_(device_management_service),
-      url_loader_factory_(std::move(url_loader_factory)) {
+      url_loader_factory_(std::move(url_loader_factory)),
+      local_prefs_(local_prefs) {
   DCHECK(dm_token_storage_);
   DCHECK(device_management_service_);
   DCHECK(url_loader_factory_);
+  DCHECK(local_prefs_);
 }
 KeyRotationLauncherImpl::~KeyRotationLauncherImpl() = default;
 
@@ -62,7 +66,7 @@
 
   KeyRotationCommand::Params params{dm_token.value(), dm_server_url, nonce};
   auto command = KeyRotationCommandFactory::GetInstance()->CreateCommand(
-      url_loader_factory_);
+      url_loader_factory_, local_prefs_);
   if (!command) {
     // Command can be nullptr if trying to create a key on a unsupported
     // platform.
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.h b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.h
index 63fdfef..1413296 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_impl.h
@@ -12,6 +12,8 @@
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher.h"
 
+class PrefService;
+
 namespace network {
 class SharedURLLoaderFactory;
 }  // namespace network
@@ -28,7 +30,8 @@
   KeyRotationLauncherImpl(
       policy::BrowserDMTokenStorage* dm_token_storage,
       policy::DeviceManagementService* device_management_service,
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      PrefService* local_prefs);
   ~KeyRotationLauncherImpl() override;
 
   // KeyRotationLauncher:
@@ -39,6 +42,7 @@
   raw_ptr<policy::BrowserDMTokenStorage> dm_token_storage_;
   raw_ptr<policy::DeviceManagementService> device_management_service_;
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+  base::raw_ptr<PrefService> local_prefs_;
 };
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_unittest.cc
index 07e61343..fdc87c0f 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_rotation_launcher_unittest.cc
@@ -20,6 +20,7 @@
 #include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
 #include "components/policy/core/common/cloud/mock_device_management_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -49,9 +50,9 @@
   }
 
   std::unique_ptr<KeyRotationLauncher> CreateLauncher() {
-    return KeyRotationLauncher::Create(&fake_dm_token_storage_,
-                                       &fake_device_management_service_,
-                                       test_shared_loader_factory_);
+    return KeyRotationLauncher::Create(
+        &fake_dm_token_storage_, &fake_device_management_service_,
+        test_shared_loader_factory_, &local_prefs_);
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
@@ -65,6 +66,7 @@
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_ =
       base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
           &test_url_loader_factory_);
+  TestingPrefServiceSimple local_prefs_;
 };
 
 TEST_F(KeyRotationLauncherTest, LaunchKeyRotation) {
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key.cc
index 6ec18d8..162b7f70 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key.cc
@@ -123,8 +123,9 @@
 SecureEnclaveSigningKeyProvider::FromWrappedSigningKeySlowly(
     base::span<const uint8_t> wrapped_key_label) {
   // Verifying wrapped key label matches the provider key type.
-  if (provider_key_type_ !=
-      SecureEnclaveClient::GetTypeFromWrappedKey(wrapped_key_label))
+  if (wrapped_key_label.empty() ||
+      provider_key_type_ !=
+          SecureEnclaveClient::GetTypeFromWrappedKey(wrapped_key_label))
     return nullptr;
 
   auto client = SecureEnclaveClient::Create();
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key_unittest.mm b/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key_unittest.mm
index bf8b529..a90bd72 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key_unittest.mm
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/mac/secure_enclave_signing_key_unittest.mm
@@ -104,6 +104,32 @@
   EXPECT_FALSE(unexportable_key);
 }
 
+// Tests that the FromWrappedSigningKeySlowly returns a nullptr when the wrapped
+// key label is empty.
+TEST_F(SecureEnclaveSigningKeyTest,
+       FromWrappedSigningKeySlowly_EmptyWrappedKey) {
+  auto permanent_key_provider = SecureEnclaveSigningKeyProvider(
+      (SecureEnclaveClient::KeyType::kPermanent));
+  base::span<const uint8_t> empty_span;
+  EXPECT_FALSE(permanent_key_provider.FromWrappedSigningKeySlowly(empty_span));
+}
+
+// Tests that the FromWrappedSigningKeySlowly returns a nullptr when the wrapped
+// key label is invalid and does not match the provider key type.
+TEST_F(SecureEnclaveSigningKeyTest,
+       FromWrappedSigningKeySlowly_InvalidWrappedKeyLabel) {
+  auto permanent_key_provider = SecureEnclaveSigningKeyProvider(
+      (SecureEnclaveClient::KeyType::kPermanent));
+  EXPECT_FALSE(permanent_key_provider.FromWrappedSigningKeySlowly(
+      base::as_bytes(base::make_span(
+          std::string(constants::kTemporaryDeviceTrustSigningKeyLabel)))));
+
+  auto temp_key_provider = SecureEnclaveSigningKeyProvider(
+      (SecureEnclaveClient::KeyType::kTemporary));
+  EXPECT_FALSE(temp_key_provider.FromWrappedSigningKeySlowly(base::as_bytes(
+      base::make_span(std::string(constants::kDeviceTrustSigningKeyLabel)))));
+}
+
 // Tests that the FromWrappedSigningKeySlowly invokes the SE client's
 // CopyStoredKey method only when the wrapped key label matches the key
 // provider type and the provider is a permanent key provider.
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.cc
index 4006c2d6..a941d56 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.cc
@@ -6,6 +6,15 @@
 
 namespace enterprise_connectors {
 
+namespace {
+
+// This error occurs when a public key already exists on the server for the
+// current device, and the key in the upload request is not signed by the key
+// that already exists.
+constexpr KeyNetworkDelegate::HttpResponseCode kKeyConflictCode = 409;
+
+}  // namespace
+
 class KeyNetworkDelegate;
 
 UploadKeyStatus ParseUploadKeyStatus(
@@ -14,8 +23,11 @@
   if (status_leading_digit == 2)
     return UploadKeyStatus::kSucceeded;
 
-  if (status_leading_digit == 4)
-    return UploadKeyStatus::kFailed;
+  if (status_leading_digit == 4) {
+    return response_code == kKeyConflictCode
+               ? UploadKeyStatus::kFailedKeyConflict
+               : UploadKeyStatus::kFailed;
+  }
 
   return UploadKeyStatus::kFailedRetryable;
 }
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h
index a65ebce..d671c949 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h
@@ -13,6 +13,7 @@
 enum class UploadKeyStatus {
   kSucceeded,
   kFailed,
+  kFailedKeyConflict,
   kFailedRetryable,
 };
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
index e319188..49d529e 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
@@ -34,6 +34,14 @@
   // to permanent key storage when failure occurs during the key rotation. This
   // is because key storage is handled by the SecureEnclaveSigningKey upon key
   // creation.
+  if (trust_level == BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED) {
+    DCHECK_EQ(wrapped.size(), 0u);
+
+    // A previous signing key did not exist so the newly created signing key
+    // stored in the permanent key storage is deleted.
+    return client_->DeleteKey(SecureEnclaveClient::KeyType::kPermanent);
+  }
+
   auto key_type = SecureEnclaveClient::GetTypeFromWrappedKey(
       base::make_span(wrapped.data(), wrapped.size()));
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate_unittest.mm b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate_unittest.mm
index 19592a7..ea078c6 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate_unittest.mm
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate_unittest.mm
@@ -115,42 +115,17 @@
 }
 
 // Tests that storing a key with an unspecified trust level invokes the clients'
-// UpdateStoredKeyLabel method when the wrapped data is correct.
+// DeleteKey method with the correct key type.
 TEST_F(MacKeyPersistenceDelegateTest, StoreKeyPair_UnspecifiedKey_Success) {
   InSequence s;
 
-  EXPECT_CALL(*mock_secure_enclave_client_, UpdateStoredKeyLabel(_, _))
-      .Times(0);
-  EXPECT_TRUE(persistence_delegate_->StoreKeyPair(
-      BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED,
-      CreateWrappedKeyLabel(constants::kDeviceTrustSigningKeyLabel)));
-
-  // Correct wrapped data consists of the wrapped temporary key label.
-  EXPECT_CALL(*mock_secure_enclave_client_, UpdateStoredKeyLabel(_, _))
-      .WillOnce([](SecureEnclaveClient::KeyType current_key_type,
-                   SecureEnclaveClient::KeyType new_key_type) {
-        EXPECT_EQ(SecureEnclaveClient::KeyType::kTemporary, current_key_type);
-        EXPECT_EQ(SecureEnclaveClient::KeyType::kPermanent, new_key_type);
+  EXPECT_CALL(*mock_secure_enclave_client_, DeleteKey(_))
+      .WillOnce([](SecureEnclaveClient::KeyType current_key_type) {
+        EXPECT_EQ(SecureEnclaveClient::KeyType::kPermanent, current_key_type);
         return true;
       });
   EXPECT_TRUE(persistence_delegate_->StoreKeyPair(
-      BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED,
-      CreateWrappedKeyLabel(constants::kTemporaryDeviceTrustSigningKeyLabel)));
-}
-
-// Tests that storing a key with an unspecified trust level fails when the
-// clients' UpdateStoredKeyLabel method returns false.
-TEST_F(MacKeyPersistenceDelegateTest, StoreKeyPair_UnspecifiedKey_Failure) {
-  EXPECT_CALL(*mock_secure_enclave_client_, UpdateStoredKeyLabel(_, _))
-      .WillOnce([](SecureEnclaveClient::KeyType current_key_type,
-                   SecureEnclaveClient::KeyType new_key_type) {
-        EXPECT_EQ(SecureEnclaveClient::KeyType::kTemporary, current_key_type);
-        EXPECT_EQ(SecureEnclaveClient::KeyType::kPermanent, new_key_type);
-        return false;
-      });
-  EXPECT_FALSE(persistence_delegate_->StoreKeyPair(
-      BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED,
-      CreateWrappedKeyLabel(constants::kTemporaryDeviceTrustSigningKeyLabel)));
+      BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()));
 }
 
 // Tests that storing a hardware generated key invokes the clients'
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h
index db3e290..333f51a 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h
@@ -21,6 +21,13 @@
 // installer.
 class KeyRotationManager {
  public:
+  //  Status of the key rotation.
+  enum class Result {
+    SUCCEEDED,
+    FAILED,
+    FAILED_KEY_CONFLICT,
+  };
+
   virtual ~KeyRotationManager() = default;
 
   static std::unique_ptr<KeyRotationManager> Create(
@@ -40,7 +47,7 @@
   virtual void Rotate(const GURL& dm_server_url,
                       const std::string& dm_token,
                       const std::string& nonce,
-                      base::OnceCallback<void(bool)> result_callback) = 0;
+                      base::OnceCallback<void(Result)> result_callback) = 0;
 };
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
index 89d9f33..f857164e 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
@@ -58,17 +58,17 @@
     const GURL& dm_server_url,
     const std::string& dm_token,
     const std::string& nonce,
-    base::OnceCallback<void(bool)> result_callback) {
+    base::OnceCallback<void(Result)> result_callback) {
   if (dm_token.size() > kMaxDMTokenLength) {
     SYSLOG(ERROR) << "DMToken length out of bounds";
-    std::move(result_callback).Run(false);
+    std::move(result_callback).Run(Result::FAILED);
     return;
   }
 
   if (!persistence_delegate_->CheckRotationPermissions()) {
     RecordRotationStatus(nonce,
                          RotationStatus::FAILURE_INCORRECT_FILE_PERMISSIONS);
-    std::move(result_callback).Run(false);
+    std::move(result_callback).Run(Result::FAILED);
     return;
   }
 
@@ -78,7 +78,7 @@
                          RotationStatus::FAILURE_CANNOT_GENERATE_NEW_KEY);
     SYSLOG(ERROR) << "Device trust key rotation failed. Could not generate a "
                      "new signing key.";
-    std::move(result_callback).Run(false);
+    std::move(result_callback).Run(Result::FAILED);
     return;
   }
 
@@ -87,7 +87,7 @@
     RecordRotationStatus(nonce, RotationStatus::FAILURE_CANNOT_STORE_KEY);
     SYSLOG(ERROR) << "Device trust key rotation failed. Could not write to "
                      "signing key storage.";
-    std::move(result_callback).Run(false);
+    std::move(result_callback).Run(Result::FAILED);
     return;
   }
 
@@ -98,7 +98,7 @@
     RecordRotationStatus(nonce, RotationStatus::FAILURE_CANNOT_BUILD_REQUEST);
     SYSLOG(ERROR) << "Device trust key rotation failed. Could not build the "
                      "upload key request.";
-    std::move(result_callback).Run(false);
+    std::move(result_callback).Run(Result::FAILED);
     return;
   }
 
@@ -150,7 +150,7 @@
 void KeyRotationManagerImpl::OnDmServerResponse(
     const std::string& nonce,
     std::unique_ptr<SigningKeyPair> new_key_pair,
-    base::OnceCallback<void(bool)> result_callback,
+    base::OnceCallback<void(Result)> result_callback,
     KeyNetworkDelegate::HttpResponseCode response_code) {
   RecordUploadCode(nonce, response_code);
   auto upload_key_status = ParseUploadKeyStatus(response_code);
@@ -178,13 +178,19 @@
     RecordRotationStatus(nonce, status);
     SYSLOG(ERROR) << "Device trust key rotation failed. Could not send public "
                      "key to DM server.";
-    std::move(result_callback).Run(false);
+    if (upload_key_status == UploadKeyStatus::kFailedKeyConflict) {
+      std::move(result_callback)
+          .Run(KeyRotationManager::Result::FAILED_KEY_CONFLICT);
+      return;
+    }
+
+    std::move(result_callback).Run(KeyRotationManager::Result::FAILED);
     return;
   }
   persistence_delegate_->CleanupTemporaryKeyData();
   key_pair_ = std::move(new_key_pair);
   RecordRotationStatus(nonce, RotationStatus::SUCCESS);
-  std::move(result_callback).Run(true);
+  std::move(result_callback).Run(KeyRotationManager::Result::SUCCEEDED);
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h
index 7b40034..dbd6d25 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h
@@ -33,7 +33,7 @@
   void Rotate(const GURL& dm_server_url,
               const std::string& dm_token,
               const std::string& nonce,
-              base::OnceCallback<void(bool)> result_callback) override;
+              base::OnceCallback<void(Result)> result_callback) override;
 
  private:
   // Builds the protobuf message needed to tell DM server about the new public
@@ -51,7 +51,7 @@
   // created during the rotation process.
   void OnDmServerResponse(const std::string& nonce,
                           std::unique_ptr<SigningKeyPair> new_key_pair,
-                          base::OnceCallback<void(bool)> result_callback,
+                          base::OnceCallback<void(Result)> result_callback,
                           KeyNetworkDelegate::HttpResponseCode response_code);
 
   std::unique_ptr<KeyNetworkDelegate> network_delegate_;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
index 20961f04..3458906 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
@@ -48,6 +48,7 @@
 
 constexpr HttpResponseCode kSuccessCode = 200;
 constexpr HttpResponseCode kHardFailureCode = 400;
+constexpr HttpResponseCode kKeyConflictFailureCode = 409;
 constexpr HttpResponseCode kTransientFailureCode = 500;
 
 }  // namespace
@@ -116,14 +117,14 @@
             captured_body = body;
             std::move(callback).Run(kSuccessCode);
           }));
-  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData());
+  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData()).Times(1);
 
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_TRUE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::SUCCEEDED, future.Get());
 
   // Validate body.
   enterprise_management::DeviceManagementRequest request;
@@ -172,14 +173,14 @@
                           base::OnceCallback<void(int)> callback) {
         std::move(callback).Run(kSuccessCode);
       }));
-  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData());
+  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData()).Times(1);
 
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_TRUE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::SUCCEEDED, future.Get());
 
   // Should expect one successful attempt to rotate a key.
   histogram_tester.ExpectUniqueSample(status_histogram_name(),
@@ -215,14 +216,14 @@
                           base::OnceCallback<void(int)> callback) {
         std::move(callback).Run(kSuccessCode);
       }));
-  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData());
+  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData()).Times(1);
 
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_TRUE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::SUCCEEDED, future.Get());
 
   // Should expect one successful attempt to rotate a key.
   histogram_tester.ExpectUniqueSample(status_histogram_name(),
@@ -260,9 +261,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key on first try.
   histogram_tester.ExpectUniqueSample(
@@ -299,9 +300,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key on first try.
   histogram_tester.ExpectUniqueSample(
@@ -311,10 +312,10 @@
 }
 
 // Tests a failed key rotation flow when a hardware key provider is available
-// and no key previously existed and the network request permanetly failed.
-// Also, in this case the registry should be cleared.
+// and no key previously existed and the network request permanently failed.
+// Also, in this case the persisted key should be cleared.
 TEST_P(KeyRotationManagerTest,
-       Rotate_Hw_WithoutKey_NetworkFails_ClearRegistry) {
+       Rotate_Hw_WithoutKey_NetworkFails_ClearPersistedKey) {
   base::HistogramTester histogram_tester;
 
   // The factory creates instances backed by fake hardware keys.
@@ -355,9 +356,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key on first try.
   histogram_tester.ExpectUniqueSample(
@@ -368,10 +369,68 @@
 }
 
 // Tests a failed key rotation flow when a hardware key provider is available
-// and no key previously existed and the network request transiently
-// fails. Also, in this case the registry should be cleared.
+// and no key previously existed and the network request permanently failed
+// because of a key signature error. Also, in this case the persisted key should
+// be cleared.
 TEST_P(KeyRotationManagerTest,
-       Rotate_Hw_WithoutKey_ExhaustedNetworkFails_ClearRegistry) {
+       Rotate_Hw_WithoutKey_NetworkFails_InvalidSignature_ClearPersistedKey) {
+  base::HistogramTester histogram_tester;
+
+  // The factory creates instances backed by fake hardware keys.
+  auto mock_persistence_delegate =
+      scoped_factory_.CreateMockedHardwareDelegate();
+
+  InSequence s;
+
+  // The mocked delegate is already set-up to return a working hardware key
+  // and provider. Force it to not return a key.
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()).WillOnce(Invoke([]() {
+    return nullptr;
+  }));
+
+  EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions())
+      .WillOnce(Return(true));
+
+  EXPECT_CALL(*mock_persistence_delegate, CreateKeyPair());
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_HW_KEY, _))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServer(dm_server_url, kDmToken, _, _))
+      .WillOnce(Invoke([](const GURL& url, const std::string& dm_token,
+                          const std::string& body,
+                          base::OnceCallback<void(int)> callback) {
+        std::move(callback).Run(kKeyConflictFailureCode);
+      }));
+
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()))
+      .WillOnce(Return(true));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  base::test::TestFuture<KeyRotationManager::Result> future;
+  manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED_KEY_CONFLICT, future.Get());
+
+  // Should expect one failed attempt to rotate a key on first try.
+  histogram_tester.ExpectUniqueSample(
+      status_histogram_name(), RotationStatus::FAILURE_CANNOT_UPLOAD_KEY, 1);
+  histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0);
+  histogram_tester.ExpectUniqueSample(http_code_histogram_name(),
+                                      kKeyConflictFailureCode, 1);
+}
+
+// Tests a failed key rotation flow when a hardware key provider is available
+// and no key previously existed and the network request transiently
+// fails. Also, in this case the persisted key should be cleared.
+TEST_P(KeyRotationManagerTest,
+       Rotate_Hw_WithoutKey_ExhaustedNetworkFails_ClearPersistedKey) {
   base::HistogramTester histogram_tester;
 
   // The factory creates instances backed by fake hardware keys.
@@ -411,9 +470,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key with max tries.
   histogram_tester.ExpectUniqueSample(
@@ -448,14 +507,14 @@
                           base::OnceCallback<void(int)> callback) {
         std::move(callback).Run(kSuccessCode);
       }));
-  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData());
+  EXPECT_CALL(*mock_persistence_delegate, CleanupTemporaryKeyData()).Times(1);
 
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_TRUE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::SUCCEEDED, future.Get());
 
   // Should expect one successful attempt to rotate a key.
   histogram_tester.ExpectUniqueSample(status_histogram_name(),
@@ -489,9 +548,9 @@
 
   GURL dm_server_url(kDmServerUrl);
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key.
   histogram_tester.ExpectUniqueSample(
@@ -526,6 +585,52 @@
                           base::OnceCallback<void(int)> callback) {
         std::move(callback).Run(kHardFailureCode);
       }));
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY,
+                           Not(original_key_wrapped)))
+      .WillOnce(Return(false));  // Restore of old key fails.
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+  base::test::TestFuture<KeyRotationManager::Result> future;
+  manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
+
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
+  // Should expect one failed attempt to rotate a key on first try.
+  histogram_tester.ExpectUniqueSample(
+      status_histogram_name(),
+      RotationStatus::FAILURE_CANNOT_UPLOAD_KEY_RESTORE_FAILED, 1);
+  histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0);
+}
+
+// Tests a key rotation flow where the network request fails and the subsequent
+// attempt to restore the old key also fails because of an invalid signature
+// error.
+TEST_P(KeyRotationManagerTest,
+       Rotate_NoHw_WithKey_NetworkFails_InvalidSignature_RestoreFails) {
+  base::HistogramTester histogram_tester;
+
+  auto mock_persistence_delegate = scoped_factory_.CreateMockedECDelegate();
+  auto original_key_wrapped = scoped_factory_.ec_wrapped_key();
+  InSequence s;
+
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair());
+  EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions())
+      .WillOnce(Return(true));
+  EXPECT_CALL(*mock_persistence_delegate, CreateKeyPair());
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, Not(original_key_wrapped)))
+      .WillOnce(Return(true));  // Store of new key fails.
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServer(dm_server_url, kDmToken, _, _))
+      .WillOnce(Invoke([](const GURL& url, const std::string& dm_token,
+                          const std::string& body,
+                          base::OnceCallback<void(int)> callback) {
+        std::move(callback).Run(kKeyConflictFailureCode);
+      }));
 
   EXPECT_CALL(*mock_persistence_delegate,
               StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY,
@@ -534,9 +639,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED_KEY_CONFLICT, future.Get());
 
   // Should expect one failed attempt to rotate a key on first try.
   histogram_tester.ExpectUniqueSample(
@@ -583,9 +688,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one failed attempt to rotate a key with max tries.
   histogram_tester.ExpectUniqueSample(
@@ -618,9 +723,9 @@
   auto manager = KeyRotationManager::CreateForTesting(
       std::move(mock_network_delegate), std::move(mock_persistence_delegate));
 
-  base::test::TestFuture<bool> future;
+  base::test::TestFuture<KeyRotationManager::Result> future;
   manager->Rotate(dm_server_url, kDmToken, nonce(), future.GetCallback());
-  EXPECT_FALSE(future.Get());
+  EXPECT_EQ(KeyRotationManager::Result::FAILED, future.Get());
 
   // Should expect one successful attempt to rotate a key.
   histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util.cc
index 1faa324..a0fa2c2c 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util.cc
@@ -85,8 +85,8 @@
       dm_server_url, *dm_token, *decoded_nonce,
       base::BindOnce(
           [](bool& rotation_result, base::OnceClosure quit_closure,
-             bool result) {
-            rotation_result = result;
+             KeyRotationManager::Result result) {
+            rotation_result = (result == KeyRotationManager::Result::SUCCEEDED);
             std::move(quit_closure).Run();
           },
           std::ref(rotation_result), run_loop.QuitClosure()));
diff --git a/chrome/browser/enterprise/connectors/device_trust/prefs.cc b/chrome/browser/enterprise/connectors/device_trust/prefs.cc
new file mode 100644
index 0000000..4f54cd5
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/prefs.cc
@@ -0,0 +1,27 @@
+// 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/enterprise/connectors/device_trust/prefs.h"
+
+namespace enterprise_connectors {
+
+const char kContextAwareAccessSignalsAllowlistPref[] =
+    "enterprise_connectors.device_trust.origins";
+
+#if BUILDFLAG(IS_MAC)
+const char kDeviceTrustDisableKeyCreationPref[] =
+    "enterprise_connectors.device_trust.disable_key_creation";
+#endif
+
+void RegisterDeviceTrustConnectorProfilePrefs(PrefRegistrySimple* registry) {
+  registry->RegisterListPref(kContextAwareAccessSignalsAllowlistPref);
+}
+
+#if BUILDFLAG(IS_MAC)
+void RegisterDeviceTrustConnectorLocalPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(kDeviceTrustDisableKeyCreationPref, false);
+}
+#endif
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/prefs.h b/chrome/browser/enterprise/connectors/device_trust/prefs.h
new file mode 100644
index 0000000..b8d72ff1
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/prefs.h
@@ -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.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_PREFS_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_PREFS_H_
+
+#include "build/build_config.h"
+#include "components/prefs/pref_registry_simple.h"
+
+namespace enterprise_connectors {
+
+// Pref that maps to the "ContextAwareAccessSignalsAllowlistPref" policy.
+extern const char kContextAwareAccessSignalsAllowlistPref[];
+
+#if BUILDFLAG(IS_MAC)
+// The pref on whether the device trust key creation is disabled for the
+// current user. The device trust key creation is disabled when a key for
+// the device is already present on the Server but a key upload is
+// requested with a another key not signed by the previous one. The key
+// creation is enabled by default.
+extern const char kDeviceTrustDisableKeyCreationPref[];
+#endif
+
+// Registers the device trust connectors profile preferences.
+void RegisterDeviceTrustConnectorProfilePrefs(PrefRegistrySimple* registry);
+
+// Registers the device trust connectors local preferences.
+#if BUILDFLAG(IS_MAC)
+void RegisterDeviceTrustConnectorLocalPrefs(PrefRegistrySimple* registry);
+#endif
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_PREFS_H_
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
index b5e1a3c..d4af072 100644
--- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc
+++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -351,10 +351,10 @@
   // TOOD(huangs): Figure out how to do the following in Lacros, which does not
   // have access to ash::CrosSettings (https://crbug.com/1219329).
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  const base::ListValue* policy_list;
+  const base::Value::List* policy_list;
   if (ash::CrosSettings::Get()->GetList(ash::kUsbDetachableAllowlist,
                                         &policy_list)) {
-    for (const auto& entry : policy_list->GetListDeprecated()) {
+    for (const auto& entry : *policy_list) {
       if (entry.FindIntKey(ash::kUsbDetachableAllowlistKeyVid) == vid &&
           entry.FindIntKey(ash::kUsbDetachableAllowlistKeyPid) == pid) {
         return true;
diff --git a/chrome/browser/extensions/api/quick_unlock_private/OWNERS b/chrome/browser/extensions/api/quick_unlock_private/OWNERS
index 25fff6ea8..23a0bd38 100644
--- a/chrome/browser/extensions/api/quick_unlock_private/OWNERS
+++ b/chrome/browser/extensions/api/quick_unlock_private/OWNERS
@@ -1,4 +1,4 @@
 alemate@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 
 file://chrome/browser/resources/settings/chromeos/OWNERS
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index 11afe54d..3410970 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -804,6 +804,8 @@
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[ash::prefs::kUserMicrophoneAllowed] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_allowlist)[ash::prefs::kUserGeolocationAllowed] =
+      settings_api::PrefType::PREF_TYPE_BOOLEAN;
 #else
   // System settings.
   (*s_allowlist)[::prefs::kBackgroundModeEnabled] =
diff --git a/chrome/browser/extensions/api/web_authentication_proxy/value_conversions_unittest.cc b/chrome/browser/extensions/api/web_authentication_proxy/value_conversions_unittest.cc
index bdd5204..f84471b 100644
--- a/chrome/browser/extensions/api/web_authentication_proxy/value_conversions_unittest.cc
+++ b/chrome/browser/extensions/api/web_authentication_proxy/value_conversions_unittest.cc
@@ -101,7 +101,9 @@
       /*min_pin_length_requested=*/true,
       blink::mojom::RemoteDesktopClientOverride::New(
           url::Origin::Create(GURL(kOrigin)),
-          /*same_origin_with_ancestors=*/true));
+          /*same_origin_with_ancestors=*/true),
+      // TODO(crbug.com/1356340): support devicePubKey in JSON when it's stable.
+      /*device_public_key=*/nullptr);
 
   base::Value value = ToValue(options);
   std::string json;
@@ -128,7 +130,9 @@
       /*get_cred_blob=*/true,
       blink::mojom::RemoteDesktopClientOverride::New(
           url::Origin::Create(GURL(kOrigin)),
-          /*same_origin_with_ancestors=*/true));
+          /*same_origin_with_ancestors=*/true),
+      // TODO: support devicePubKey in JSON when it's stable.
+      /*device_public_key=*/nullptr);
 
   base::Value value = ToValue(options);
   std::string json;
@@ -196,7 +200,9 @@
       /*public_key_algo=*/-7,
       /*echo_cred_props=*/true, /*has_cred_props_rk=*/true,
       /*cred_props_rk=*/true, /*echo_large_blob=*/true,
-      /*supports_large_blob=*/true);
+      /*supports_large_blob=*/true,
+      // TODO: support devicePubKey in JSON when it's stable.
+      /*device_public_key=*/nullptr);
 
   EXPECT_EQ(response->info, expected->info);
   EXPECT_EQ(response->authenticator_attachment,
@@ -277,7 +283,9 @@
       /*echo_large_blob=*/true,
       /*large_blob=*/kLargeBlob, /*echo_large_blob_written=*/true,
       /*large_blob_written=*/true,
-      /*get_cred_blob=*/kCredBlob);
+      /*get_cred_blob=*/kCredBlob,
+      // TODO: support devicePubKey in JSON when it's stable.
+      /*device_public_key=*/nullptr);
 
   EXPECT_EQ(response->info, expected->info);
   EXPECT_EQ(response->authenticator_attachment,
diff --git a/chrome/browser/extensions/chrome_url_request_util.cc b/chrome/browser/extensions/chrome_url_request_util.cc
index 717f3ca1..c4c47cec 100644
--- a/chrome/browser/extensions/chrome_url_request_util.cc
+++ b/chrome/browser/extensions/chrome_url_request_util.cc
@@ -177,7 +177,8 @@
       head->headers->AddHeader(net::HttpRequestHeaders::kContentType,
                                head->mime_type.c_str());
     }
-    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                               absl::nullopt);
 
     uint32_t write_size = data->size();
     MojoResult result = producer_handle->WriteData(data->front(), &write_size,
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index a51bef2..c4e528f 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -124,7 +124,7 @@
     // from a read-only rootfs partition, so it is safe to set
     // |gzip_permission| to kAllowForTrustedSource.
     bool localized = extension_l10n_util::LocalizeExtension(
-        root_directory, manifest.get(),
+        root_directory, &manifest->GetDict(),
         extension_l10n_util::GzippedMessagesPermission::kAllowForTrustedSource,
         &error);
     CHECK(localized) << error;
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.cc b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
index 8d2759fa..f2c5e8d 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.cc
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
@@ -216,22 +216,24 @@
     return false;
 
   DictionaryPrefUpdate shared_extensions(local_state, kSharedExtensions);
+  base::Value::Dict& shared_extension_dict = shared_extensions->GetDict();
+
   std::vector<std::string> extensions;
-  extensions.reserve(shared_extensions->DictSize());
-  for (const auto it : shared_extensions->DictItems())
+  extensions.reserve(shared_extension_dict.size());
+  for (const auto it : shared_extension_dict)
     extensions.push_back(it.first);
 
   for (const std::string& id : extensions) {
-    base::Value* extension_info = shared_extensions->FindDictKey(id);
+    base::Value::Dict* extension_info = shared_extension_dict.FindDict(id);
     if (!extension_info) {
       NOTREACHED();
       return false;
     }
-    if (!CleanUpExtension(id, extension_info, live_extension_paths)) {
+    if (!CleanUpExtension(id, *extension_info, live_extension_paths)) {
       return false;
     }
-    if (extension_info->DictEmpty())
-      shared_extensions->RemoveKey(id);
+    if (extension_info->empty())
+      shared_extension_dict.Remove(id);
   }
 
   return true;
@@ -429,35 +431,34 @@
 
   PrefService* local_state = g_browser_process->local_state();
   DictionaryPrefUpdate shared_extensions(local_state, kSharedExtensions);
-  base::Value* extension_info = shared_extensions->FindDictKey(id);
+  base::Value::Dict& shared_extensions_dict = shared_extensions->GetDict();
+  base::Value::Dict* extension_info = shared_extensions_dict.FindDict(id);
   if (!extension_info) {
     NOTREACHED();
     return;
   }
 
   std::vector<std::string> versions;
-  versions.reserve(extension_info->DictSize());
-  for (const auto kv : extension_info->DictItems()) {
+  versions.reserve(extension_info->size());
+  for (const auto kv : *extension_info) {
     versions.push_back(kv.first);
   }
 
   base::Value user_name(profile->GetProfileUserName());
   for (std::vector<std::string>::const_iterator it = versions.begin();
        it != versions.end(); it++) {
-    base::Value* version_info = extension_info->FindDictKey(*it);
+    base::Value::Dict* version_info = extension_info->FindDict(*it);
     if (!version_info) {
       NOTREACHED();
       continue;
     }
-    base::Value* users = version_info->FindListKey(kSharedExtensionUsers);
+    base::Value::List* users = version_info->FindList(kSharedExtensionUsers);
     if (!users) {
       NOTREACHED();
       continue;
     }
-    if (users->EraseListValue(user_name) &&
-        users->GetListDeprecated().empty()) {
-      std::string* shared_path =
-          version_info->FindStringKey(kSharedExtensionPath);
+    if (users->EraseValue(user_name) && users->empty()) {
+      std::string* shared_path = version_info->FindString(kSharedExtensionPath);
       if (!shared_path) {
         NOTREACHED();
         continue;
@@ -466,11 +467,11 @@
           FROM_HERE,
           base::BindOnce(&ExtensionAssetsManagerChromeOS::DeleteSharedVersion,
                          base::FilePath(*shared_path)));
-      extension_info->RemoveKey(*it);
+      extension_info->Remove(*it);
     }
   }
-  if (extension_info->DictEmpty()) {
-    shared_extensions->RemoveKey(id);
+  if (extension_info->empty()) {
+    shared_extensions_dict.Remove(id);
     // Don't remove extension dir in shared location. It will be removed by GC
     // when it is safe to do so, and this avoids a race condition between
     // concurrent uninstall by one user and install by another.
@@ -487,7 +488,7 @@
 // static
 bool ExtensionAssetsManagerChromeOS::CleanUpExtension(
     const std::string& id,
-    base::Value* extension_info,
+    base::Value::Dict& extension_info,
     std::multimap<std::string, base::FilePath>* live_extension_paths) {
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   if (!user_manager) {
@@ -496,28 +497,28 @@
   }
 
   std::vector<std::string> versions;
-  versions.reserve(extension_info->DictSize());
-  for (const auto it : extension_info->DictItems()) {
+  versions.reserve(extension_info.size());
+  for (const auto it : extension_info) {
     versions.push_back(it.first);
   }
 
   for (std::vector<std::string>::const_iterator it = versions.begin();
        it != versions.end(); it++) {
-    base::Value* version_info = extension_info->FindDictKey(*it);
+    base::Value::Dict* version_info = extension_info.FindDict(*it);
     if (!version_info) {
       NOTREACHED();
       return false;
     }
-    base::Value* users = version_info->FindListKey(kSharedExtensionUsers);
+    base::Value::List* users_list =
+        version_info->FindList(kSharedExtensionUsers);
     const std::string* shared_path =
-        version_info->FindStringKey(kSharedExtensionPath);
-    if (!users || !shared_path) {
+        version_info->FindString(kSharedExtensionPath);
+    if (!users_list || !shared_path) {
       NOTREACHED();
       return false;
     }
-    base::Value::List& users_list = users->GetList();
 
-    for (auto iter = users_list.begin(); iter != users_list.end();) {
+    for (auto iter = users_list->begin(); iter != users_list->end();) {
       const std::string* user_id = iter->GetIfString();
       if (!user_id) {
         NOTREACHED();
@@ -548,14 +549,14 @@
       }
 
       if (not_used) {
-        iter = users_list.erase(iter);
+        iter = users_list->erase(iter);
       } else {
         ++iter;
       }
     }
 
-    if (users_list.empty()) {
-      extension_info->RemoveKey(*it);
+    if (users_list->empty()) {
+      extension_info.Remove(*it);
     } else {
       live_extension_paths->insert(
           std::make_pair(id, base::FilePath(*shared_path)));
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.h b/chrome/browser/extensions/extension_assets_manager_chromeos.h
index c161613..06d7970 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.h
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.h
@@ -7,6 +7,7 @@
 
 #include <map>
 
+#include "base/values.h"
 #include "chrome/browser/extensions/extension_assets_manager.h"
 
 namespace base {
@@ -15,10 +16,6 @@
 
 class PrefRegistrySimple;
 
-namespace base {
-class Value;
-}
-
 namespace extensions {
 
 // Chrome OS specific implementation of assets manager that shares default apps
@@ -125,7 +122,7 @@
   // Clean shared extension with given |id|.
   static bool CleanUpExtension(
       const std::string& id,
-      base::Value* extension_info,
+      base::Value::Dict& extension_info,
       std::multimap<std::string, base::FilePath>* live_extension_paths);
 };
 
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc
index 9ed999f5..42d55778 100644
--- a/chrome/browser/extensions/extension_nacl_browsertest.cc
+++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -11,9 +11,9 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/nacl/common/nacl_constants.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_frame_host.h"
@@ -127,7 +127,7 @@
       run_loop.Run();
     }
 
-    static const base::FilePath path(ChromeContentClient::kNaClPluginFileName);
+    static const base::FilePath path(nacl::kInternalNaClPluginFileName);
     content::WebPluginInfo info;
     return PluginService::GetInstance()->GetPluginInfoByPath(path, &info);
   }
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index 2ead222ac..5b77d51 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -97,18 +97,15 @@
   EXTERNAL_ITEM_MAX_ITEMS
 };
 
-bool IsManifestCorrupt(const base::DictionaryValue* manifest) {
-  if (!manifest)
-    return false;
-
+bool IsManifestCorrupt(const base::DictionaryValue& manifest) {
   // Because of bug #272524 sometimes manifests got mangled in the preferences
   // file, one particularly bad case resulting in having both a background page
   // and background scripts values. In those situations we want to reload the
   // manifest from the extension to fix this.
   const base::Value* background_page;
   const base::Value* background_scripts;
-  return manifest->Get(manifest_keys::kBackgroundPage, &background_page) &&
-      manifest->Get(manifest_keys::kBackgroundScripts, &background_scripts);
+  return manifest.Get(manifest_keys::kBackgroundPage, &background_page) &&
+         manifest.Get(manifest_keys::kBackgroundScripts, &background_scripts);
 }
 
 ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
@@ -117,13 +114,16 @@
   if (Manifest::IsUnpackedLocation(info.extension_location))
     return UNPACKED_DIR;
 
+  if (!info.extension_manifest)
+    return NOT_NEEDED;
+
   // Reload the manifest if it needs to be relocalized.
   if (extension_l10n_util::ShouldRelocalizeManifest(
-          info.extension_manifest.get()))
+          info.extension_manifest->GetDict()))
     return NEEDS_RELOCALIZATION;
 
   // Reload if the copy of the manifest in the preferences is corrupt.
-  if (IsManifestCorrupt(info.extension_manifest.get()))
+  if (IsManifestCorrupt(*info.extension_manifest))
     return CORRUPT_PREFERENCES;
 
   return NOT_NEEDED;
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc
index 9f80b3f..37011fba 100644
--- a/chrome/browser/extensions/plugin_manager.cc
+++ b/chrome/browser/extensions/plugin_manager.cc
@@ -11,10 +11,9 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/plugin_service.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/manifest_handlers/mime_types_handler.h"
 #include "net/base/mime_util.h"
@@ -140,33 +139,30 @@
   // MIME type to plugins which handle NaCl modules in order to allow the
   // individual modules to handle these types.
   static const base::NoDestructor<base::FilePath> path(
-      ChromeContentClient::kNaClPluginFileName);
-  const content::PepperPluginInfo* pepper_info =
-      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(*path);
-  if (!pepper_info)
+      nacl::kInternalNaClPluginFileName);
+  const content::ContentPluginInfo* registered_info =
+      PluginService::GetInstance()->GetRegisteredPluginInfo(*path);
+  if (!registered_info)
     return;
 
-  std::vector<content::WebPluginMimeType>::const_iterator mime_iter;
   // Check each MIME type the plugins handle for the NaCl MIME type.
-  for (mime_iter = pepper_info->mime_types.begin();
-       mime_iter != pepper_info->mime_types.end(); ++mime_iter) {
-    if (mime_iter->mime_type == nacl::kNaClPluginMimeType) {
+  for (const auto& mime_type : registered_info->mime_types) {
+    if (mime_type.mime_type == nacl::kNaClPluginMimeType) {
       // This plugin handles "application/x-nacl".
 
-      PluginService::GetInstance()->UnregisterInternalPlugin(pepper_info->path);
+      PluginService::GetInstance()->UnregisterInternalPlugin(
+          registered_info->path);
 
-      content::WebPluginInfo info = pepper_info->ToWebPluginInfo();
+      content::WebPluginInfo info = registered_info->ToWebPluginInfo();
 
-      for (NaClModuleInfo::List::const_iterator iter =
-               nacl_module_list_.begin();
-           iter != nacl_module_list_.end(); ++iter) {
+      for (const auto& nacl_module : nacl_module_list_) {
         // Add the MIME type specified in the extension to this NaCl plugin,
         // With an extra "nacl" argument to specify the location of the NaCl
         // manifest file.
         content::WebPluginMimeType mime_type_info;
-        mime_type_info.mime_type = iter->mime_type;
+        mime_type_info.mime_type = nacl_module.mime_type;
         mime_type_info.additional_params.emplace_back(
-            u"nacl", base::UTF8ToUTF16(iter->url.spec()));
+            u"nacl", base::UTF8ToUTF16(nacl_module.url.spec()));
         info.mime_types.emplace_back(std::move(mime_type_info));
       }
 
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc
index 91e3bcf..31dcb47 100644
--- a/chrome/browser/extensions/unpacked_installer.cc
+++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -266,7 +266,8 @@
 
   return extension() &&
          extension_l10n_util::ValidateExtensionLocales(
-             extension_path_, extension()->manifest()->value(), error) &&
+             extension_path_, extension()->manifest()->value()->GetDict(),
+             error) &&
          IndexAndPersistRulesIfNeeded(error);
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index c851a28..ec4dc0f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -579,11 +579,6 @@
     "expiry_milestone": 107
   },
   {
-    "name": "autofill-remove-card-expiry-from-downstream-suggestion",
-    "owners": [ "siyua", "siashah" ],
-    "expiry_milestone": 112
-  },
-  {
     "name": "autofill-save-card-dismiss-on-navigation",
     "owners": [ "sczs", "bling-flags@google.com" ],
     "expiry_milestone": 82
@@ -591,7 +586,7 @@
   {
     "name": "autofill-show-manual-fallbacks-in-context-menu",
     "owners": [ "vidhanj", "koerber"],
-    "expiry_milestone": 106
+    "expiry_milestone": 112
   },
   {
     "name": "autofill-type-specific-popup-width",
@@ -2732,7 +2727,7 @@
   {
     "name": "enable-prerender2",
     "owners": [ "//content/browser/preloading/prerender/OWNERS" ],
-    "expiry_milestone": 106
+    "expiry_milestone": 109
   },
   {
     "name": "enable-projector",
@@ -3929,6 +3924,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "infobar-scroll-optimization",
+    "owners": [ "lazzzis@google.com", "mdjones", "twellington" ],
+    "expiry_milestone": 121
+  },
+  {
     "name": "initial-navigation-entry",
     "owners": [ "rakina", "chrome-security-architecture@google.com" ],
     "expiry_milestone": 105
@@ -4954,7 +4954,7 @@
   {
     "name": "omnibox-trigger-for-prerender2",
     "owners": [ "//content/browser/preloading/prerender/OWNERS" ],
-    "expiry_milestone": 106
+    "expiry_milestone": 109
   },
   {
     "name": "omnibox-ui-max-autocomplete-matches",
@@ -5171,8 +5171,8 @@
   },
   {
     "name": "password-edit-dialog-with-details",
-    "owners": ["atsvirchkova"],
-    "expiry_milestone": 106
+    "owners": ["atsvirchkova@google.com", "ioanap"],
+    "expiry_milestone": 109
   },
   {
     "name": "password-import",
@@ -5753,7 +5753,7 @@
   {
     "name": "search-suggestion-for-prerender2",
     "owners": [ "//content/browser/preloading/prerender/OWNERS" ],
-    "expiry_milestone": 106
+    "expiry_milestone": 109
   },
   {
     "name": "secondary-google-account-usage",
@@ -6025,11 +6025,6 @@
     "expiry_milestone": 105
   },
   {
-    "name": "smart-sorting-new-destinations",
-    "owners": [ "bwwilliams@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 111
-  },
-  {
     "name": "smart-sorting-new-overflow-menu",
     "owners": [ "bwwilliams@google.com", "bling-flags@google.com" ],
     "expiry_milestone": 108
@@ -6266,11 +6261,6 @@
     "expiry_milestone": 112
   },
   {
-    "name": "throttle-foreground-timers",
-    "owners": [ "fdoray", "scheduler-dev" ],
-    "expiry_milestone": 102
-  },
-  {
     "name": "tint-composited-content",
     "owners": [ "chromeos-gfx@google.com" ],
     // This flag is used for QA & development on ChromeOS, which has no way to
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index f889481b..b2d9cd9 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -507,12 +507,6 @@
     "When enabled, Autofill will attempt to fill merchant promo/coupon/gift "
     "code fields when data is available.";
 
-const char kAutofillRemoveCardExpiryFromDownstreamSuggestionName[] =
-    "Remove card expiration date from the Autofill card suggestions";
-const char kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription[] =
-    "When enabled, card expiration date will no longer be displayed in "
-    "a card suggestion.";
-
 const char kAutofillHighlightOnlyChangedValuesInPreviewModeName[] =
     "Highlight only changed values in preview mode.";
 const char kAutofillHighlightOnlyChangedValuesInPreviewModeDescription[] =
@@ -1705,6 +1699,10 @@
     "Enables Incognito screenshots on Android. It will also make Incognito "
     "thumbnails visible.";
 
+const char kInfobarScrollOptimizationName[] = "Infobar scroll optimiaztion";
+const char kInfobarScrollOptimizationDescription[] =
+    "Optimize Infobar scroll on Android.";
+
 const char kInitialNavigationEntryName[] = "Initial NavigationEntry";
 const char kInitialNavigationEntryDescription[] =
     "Enables creation of initial NavigationEntry on tab creation.";
@@ -2811,12 +2809,6 @@
     "this can dramatically hurt scrolling performance of most websites and is "
     "intended for testing purposes only.";
 
-const char kThrottleForegroundTimersName[] =
-    "Throttle Foreground Timers to 30 Hz";
-const char kThrottleForegroundTimersDescription[] =
-    "On foreground pages, run DOM timers with a non-zero delay on a periodic "
-    "30 Hz tick, instead of as soon as their delay has passed.";
-
 const char kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesName[] =
     "Throttle non-visible cross-origin iframes";
 const char
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index ae5d6a2..1c56bdb 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -289,10 +289,6 @@
 extern const char kAutofillPreventOverridingPrefilledValuesName[];
 extern const char kAutofillPreventOverridingPrefilledValuesDescription[];
 
-extern const char kAutofillRemoveCardExpiryFromDownstreamSuggestionName[];
-extern const char
-    kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription[];
-
 extern const char kAutofillSaveAndFillVPAName[];
 extern const char kAutofillSaveAndFillVPADescription[];
 
@@ -952,6 +948,9 @@
 extern const char kIncognitoScreenshotName[];
 extern const char kIncognitoScreenshotDescription[];
 
+extern const char kInfobarScrollOptimizationName[];
+extern const char kInfobarScrollOptimizationDescription[];
+
 extern const char kInitialNavigationEntryName[];
 extern const char kInitialNavigationEntryDescription[];
 
@@ -1588,9 +1587,6 @@
 extern const char kThreadedScrollingName[];
 extern const char kThreadedScrollingDescription[];
 
-extern const char kThrottleForegroundTimersName[];
-extern const char kThrottleForegroundTimersDescription[];
-
 extern const char
     kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesName[];
 extern const char
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index fda83d4a..1169e02 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -247,6 +247,7 @@
     &kImmersiveUiMode,
     &kIncognitoReauthenticationForAndroid,
     &kIncognitoScreenshot,
+    &kInfobarScrollOptimization,
     &kInstanceSwitcher,
     &kInstantStart,
     &kIsVoiceSearchEnabledCache,
@@ -703,6 +704,9 @@
 const base::Feature kIncognitoScreenshot{"IncognitoScreenshot",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kInfobarScrollOptimization{
+    "InfobarScrollOptimization", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kInstantStart{"InstantStart",
                                   base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -725,7 +729,7 @@
     "SearchEnginePromo.NewDeviceVer2", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kMostRecentTabOnBackgroundCloseTab{
-    "MostRecentTabOnBackgroundCloseTab", base::FEATURE_DISABLED_BY_DEFAULT};
+    "MostRecentTabOnBackgroundCloseTab", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kNewInstanceFromDraggedLink{
     "NewInstanceFromDraggedLink", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 2b360ec..d0bdc23 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -100,6 +100,7 @@
 extern const base::Feature kImmersiveUiMode;
 extern const base::Feature kIncognitoReauthenticationForAndroid;
 extern const base::Feature kIncognitoScreenshot;
+extern const base::Feature kInfobarScrollOptimization;
 extern const base::Feature kImprovedA2HS;
 extern const base::Feature kInstanceSwitcher;
 extern const base::Feature kInstantStart;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index bec914c3..00f5ccf 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -377,6 +377,7 @@
     public static final String INCOGNITO_REAUTHENTICATION_FOR_ANDROID =
             "IncognitoReauthenticationForAndroid";
     public static final String INCOGNITO_SCREENSHOT = "IncognitoScreenshot";
+    public static final String INFOBAR_SCROLL_OPTIMIZATION = "InfobarScrollOptimization";
     public static final String INSTALLABLE_AMBIENT_BADGE_INFOBAR = "InstallableAmbientBadgeInfoBar";
     public static final String INSTALLABLE_AMBIENT_BADGE_MESSAGE = "InstallableAmbientBadgeMessage";
     public static final String INSTANCE_SWITCHER = "InstanceSwitcher";
diff --git a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediator.java b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediator.java
index 16435b73..9d181552 100644
--- a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediator.java
+++ b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersMediator.java
@@ -62,6 +62,7 @@
 
     // The number of items past the last visible one we want to have loaded at any give point.
     static final int REMAINING_ITEM_BUFFER_SIZE = 25;
+    static final int MIN_EXPANDED_CLUSTER_SIZE = 2;
 
     interface Clock {
         long currentTimeMillis();
@@ -345,19 +346,26 @@
         VisitMetadata visitMetadata = mVisitMetadataMap.get(visit);
         if (visitMetadata == null) return;
         ListItem visitListItem = visitMetadata.visitListItem;
+        List<ListItem> visitsAndRelatedSearches = visitMetadata.visitsAndRelatedSearches;
+        boolean deletedModelHadDivider =
+                visitListItem.model.get(HistoryClustersItemProperties.DIVIDER_VISIBLE);
         assert mModelList.indexOf(visitListItem) != -1
-                && visitMetadata.visitsAndRelatedSearches.indexOf(visitListItem) != -1;
+                && visitsAndRelatedSearches.indexOf(visitListItem) != -1;
         mModelList.remove(visitListItem);
-        visitMetadata.visitsAndRelatedSearches.remove(visitListItem);
-        if (visitMetadata.visitsAndRelatedSearches.size() == 1
-                && visitMetadata.visitsAndRelatedSearches.get(0).type
-                        == ItemType.RELATED_SEARCHES) {
-            mModelList.remove(visitMetadata.visitsAndRelatedSearches.get(0));
-            visitMetadata.visitsAndRelatedSearches.clear();
+        visitsAndRelatedSearches.remove(visitListItem);
+        if (visitsAndRelatedSearches.size() == 1
+                && visitsAndRelatedSearches.get(0).type == ItemType.RELATED_SEARCHES) {
+            mModelList.remove(visitsAndRelatedSearches.get(0));
+            visitsAndRelatedSearches.clear();
         }
 
-        if (visitMetadata.visitsAndRelatedSearches.isEmpty()) {
+        if (visitsAndRelatedSearches.isEmpty()) {
             mModelList.remove(visitMetadata.clusterListItem);
+        } else if (deletedModelHadDivider) {
+            PropertyModel modelOfNewLastVisit =
+                    visitsAndRelatedSearches.get(visitsAndRelatedSearches.size() - 1).model;
+            modelOfNewLastVisit.set(HistoryClustersItemProperties.DIVIDER_VISIBLE, true);
+            modelOfNewLastVisit.set(HistoryClustersItemProperties.DIVIDER_IS_THICK, true);
         }
 
         mVisitMetadataMap.remove(visit);
@@ -395,7 +403,6 @@
             if (existingModel == null) {
                 Drawable journeysDrawable =
                         AppCompatResources.getDrawable(mContext, R.drawable.ic_journeys);
-                mLabelToModelMap.put(rawLabel, existingModel);
                 existingModel =
                         new PropertyModel.Builder(HistoryClustersItemProperties.ALL_KEYS)
                                 .with(HistoryClustersItemProperties.ICON_DRAWABLE, journeysDrawable)
@@ -413,6 +420,7 @@
                                                 -> setQueryState(QueryState.forQuery(rawLabel,
                                                         mDelegate.getSearchEmptyString())))
                                 .build();
+                mLabelToModelMap.put(rawLabel, existingModel);
                 ListItem clusterItem = new ListItem(ItemType.CLUSTER, existingModel);
                 mModelList.add(clusterItem);
             }
@@ -430,6 +438,10 @@
         List<HistoryCluster> clusters = result.getClusters();
         for (int clusterIdx = 0; clusterIdx < clusters.size(); clusterIdx++) {
             HistoryCluster cluster = clusters.get(clusterIdx);
+            if (cluster.getVisits().size() < MIN_EXPANDED_CLUSTER_SIZE) {
+                continue;
+            }
+
             PropertyModel clusterModel =
                     new PropertyModel.Builder(HistoryClustersItemProperties.ALL_KEYS)
                             .with(HistoryClustersItemProperties.TITLE,
diff --git a/chrome/browser/lacros/browser_launcher.cc b/chrome/browser/lacros/browser_launcher.cc
new file mode 100644
index 0000000..ff2da510
--- /dev/null
+++ b/chrome/browser/lacros/browser_launcher.cc
@@ -0,0 +1,84 @@
+// 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/lacros/browser_launcher.h"
+
+#include "base/auto_reset.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/startup/startup_browser_creator.h"
+#include "chrome/common/chrome_switches.h"
+
+namespace {
+
+// User data key for BrowserLauncher.
+const void* const kBrowserLauncherKey = &kBrowserLauncherKey;
+
+}  // namespace
+
+BrowserLauncher::BrowserLauncher(Profile* profile) : profile_(profile) {}
+
+// static.
+BrowserLauncher* BrowserLauncher::GetForProfile(Profile* profile) {
+  if (!profile)
+    return nullptr;
+
+  if (!profile->GetUserData(kBrowserLauncherKey)) {
+    profile->SetUserData(kBrowserLauncherKey,
+                         std::make_unique<BrowserLauncher>(profile));
+  }
+  return static_cast<BrowserLauncher*>(
+      profile->GetUserData(kBrowserLauncherKey));
+}
+
+void BrowserLauncher::LaunchForFullRestore(bool skip_crash_restore) {
+  DCHECK(!is_launching_for_full_restore_);
+
+  // There must not be any previously opened browsers as this could change the
+  // list of profiles returned from `GetLastOpenedProfiles()` below.
+  if (BrowserList::GetInstance()->size() != 0) {
+    LOG(ERROR) << "Cannot full restore with pre-existing browser instances.";
+    return;
+  }
+
+  base::AutoReset<bool> resetter(&is_launching_for_full_restore_, true);
+
+  // Ensure that we do not start with the profile picker.
+  StartupProfileInfo profile_info{profile_, StartupProfileMode::kBrowserWindow};
+
+  // Get the last opened profiles from the last session. This is only valid
+  // before any browsers have been opened for the current session as opening /
+  // closing browsers will cause the last opened profiles to change.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+
+  // Currently the kNoStartupWindow flag is set when lacros-chrome is launched
+  // with crosapi::mojom::InitialBrowserAction::kDoNotOpenWindow. The intention
+  // is to prevent lacros-chrome from launching a window during startup. However
+  // this flag remains set throughout the life of the browser process.
+  // This leads to issues where browsers can no longer be opened by the startup
+  // browser creator (such as below and in SessionService::RestoreIfNecessary).
+  // As a temporary workaround remove the kNoStartupWindow switch from the
+  // command line when launching for full restore. This is safe as by this point
+  // the browser process has already been started in its windowless state and
+  // the flag is no longer required.
+  base::CommandLine* lacros_command_line =
+      base::CommandLine::ForCurrentProcess();
+  lacros_command_line->RemoveSwitch(switches::kNoStartupWindow);
+
+  // Modify the command line to restore browser sessions.
+  lacros_command_line->AppendSwitch(switches::kRestoreLastSession);
+
+  if (skip_crash_restore)
+    lacros_command_line->AppendSwitch(switches::kHideCrashRestoreBubble);
+
+  StartupBrowserCreator browser_creator;
+  browser_creator.LaunchBrowserForLastProfiles(
+      *lacros_command_line, base::FilePath(),
+      chrome::startup::IsProcessStartup::kYes, chrome::startup::IsFirstRun::kNo,
+      profile_info, last_opened_profiles);
+}
diff --git a/chrome/browser/lacros/browser_launcher.h b/chrome/browser/lacros/browser_launcher.h
new file mode 100644
index 0000000..b15ef6f
--- /dev/null
+++ b/chrome/browser/lacros/browser_launcher.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 CHROME_BROWSER_LACROS_BROWSER_LAUNCHER_H_
+#define CHROME_BROWSER_LACROS_BROWSER_LAUNCHER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/supports_user_data.h"
+
+class Profile;
+
+// Responsible for creating and launching new instances of lacros-chrome.
+class BrowserLauncher : public base::SupportsUserData::Data {
+ public:
+  explicit BrowserLauncher(Profile* profile);
+  BrowserLauncher(const BrowserLauncher&) = delete;
+  BrowserLauncher& operator=(const BrowserLauncher&) = delete;
+  ~BrowserLauncher() override = default;
+
+  // Creates the BrowserLauncher instance if it does not already exist.
+  static BrowserLauncher* GetForProfile(Profile* profile);
+
+  // Launches lacros-chrome for full restore. This method should be called
+  // before any lacros browser windows have been created while the process is in
+  // the background / windowless state.
+  void LaunchForFullRestore(bool skip_crash_restore);
+
+  bool is_launching_for_full_restore() const {
+    return is_launching_for_full_restore_;
+  }
+
+ private:
+  // Tracks whether the BrowserLauncher is in the process of performing a Full
+  // Restore launch of lacros-chrome.
+  bool is_launching_for_full_restore_ = false;
+
+  const raw_ptr<Profile> profile_;
+};
+
+#endif  // CHROME_BROWSER_LACROS_BROWSER_LAUNCHER_H_
diff --git a/chrome/browser/lacros/browser_launcher_browsertest.cc b/chrome/browser/lacros/browser_launcher_browsertest.cc
new file mode 100644
index 0000000..acb2169
--- /dev/null
+++ b/chrome/browser/lacros/browser_launcher_browsertest.cc
@@ -0,0 +1,542 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/containers/contains.h"
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/lacros/browser_service_lacros.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/prefs/session_startup_pref.h"
+#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
+#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_test_util.h"
+#include "chrome/browser/sessions/exit_type_service.h"
+#include "chrome/browser/sessions/session_restore.h"
+#include "chrome/browser/sessions/session_restore_test_utils.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/profile_picker.h"
+#include "chrome/browser/ui/profile_ui_test_utils.h"
+#include "chrome/browser/ui/views/session_crashed_bubble_view.h"
+#include "chrome/browser/ui/web_applications/app_browser_controller.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/keep_alive_registry/keep_alive_types.h"
+#include "components/keep_alive_registry/scoped_keep_alive.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+web_app::AppId InstallPWA(Profile* profile, const GURL& start_url) {
+  auto web_app_info = std::make_unique<WebAppInstallInfo>();
+  web_app_info->start_url = start_url;
+  web_app_info->scope = start_url.GetWithoutFilename();
+  web_app_info->user_display_mode = web_app::UserDisplayMode::kStandalone;
+  web_app_info->title = u"A Web App";
+  return web_app::test::InstallWebApp(profile, std::move(web_app_info));
+}
+
+}  // namespace
+
+class BrowserLauncherTest : public InProcessBrowserTest {
+ public:
+  BrowserLauncherTest() {
+    // Suppress the test-created about blank tab to be more representative of
+    // the startup and launch environment for testing.
+    set_open_about_blank_on_browser_launch(false);
+  }
+  BrowserLauncherTest(const BrowserLauncherTest&) = delete;
+  BrowserLauncherTest& operator=(const BrowserLauncherTest&) = delete;
+  ~BrowserLauncherTest() override = default;
+
+  // InProcessBrowserTest:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+    // The kNoStartupWindow is applied when launching lacros-chrome with the
+    // kDoNotOpenWindow initial browser action.
+    command_line->AppendSwitch(switches::kNoStartupWindow);
+  }
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+    browser_service_ = std::make_unique<BrowserServiceLacros>();
+  }
+
+  void NewWindowSync(bool incognito, bool should_trigger_session_restore) {
+    base::RunLoop run_loop;
+    browser_service()->NewWindow(incognito, should_trigger_session_restore,
+                                 run_loop.QuitClosure());
+    run_loop.Run();
+  }
+
+  void DisableWelcomePages(const std::vector<Profile*>& profiles) {
+    for (Profile* profile : profiles)
+      profile->GetPrefs()->SetBoolean(prefs::kHasSeenWelcomePage, true);
+
+    // Also disable What's New.
+    PrefService* pref_service = g_browser_process->local_state();
+    pref_service->SetInteger(prefs::kLastWhatsNewVersion, CHROME_VERSION_MAJOR);
+  }
+
+  // Creates a new profile with a URLS startup preference and an open tab.
+  void SetupSingleProfileWithURLSPreference() {
+    ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    // Create two profiles.
+    base::FilePath dest_path = profile_manager->user_data_dir();
+
+    Profile* profile = nullptr;
+    {
+      base::ScopedAllowBlockingForTesting allow_blocking;
+      profile = profile_manager->GetProfile(
+          dest_path.Append(FILE_PATH_LITERAL("New Profile")));
+      ASSERT_TRUE(profile);
+    }
+    DisableWelcomePages({profile});
+
+    // Don't delete Profile too early.
+    ScopedProfileKeepAlive profile_keep_alive(
+        profile, ProfileKeepAliveOrigin::kBrowserWindow);
+
+    // Open some urls in the browser.
+    Browser* browser = Browser::Create(
+        Browser::CreateParams(Browser::TYPE_NORMAL, profile, true));
+    chrome::NewTab(browser);
+    ASSERT_TRUE(ui_test_utils::NavigateToURL(
+        browser, embedded_test_server()->GetURL("/empty.html")));
+
+    // Establish the startup preference.
+    std::vector<GURL> urls;
+    urls.push_back(ui_test_utils::GetTestUrl(
+        base::FilePath(base::FilePath::kCurrentDirectory),
+        base::FilePath(FILE_PATH_LITERAL("title1.html"))));
+    urls.push_back(ui_test_utils::GetTestUrl(
+        base::FilePath(base::FilePath::kCurrentDirectory),
+        base::FilePath(FILE_PATH_LITERAL("title2.html"))));
+
+    // Set different startup preferences for the profile.
+    SessionStartupPref pref(SessionStartupPref::URLS);
+    pref.urls = urls;
+    SessionStartupPref::SetStartupPref(profile, pref);
+    profile->GetPrefs()->CommitPendingWrite();
+
+    // Ensure the session ends with the profile created above.
+    auto last_opened_profiles =
+        g_browser_process->profile_manager()->GetLastOpenedProfiles();
+    EXPECT_EQ(1u, last_opened_profiles.size());
+    EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
+  }
+
+  BrowserServiceLacros* browser_service() const {
+    return browser_service_.get();
+  }
+
+ private:
+  std::unique_ptr<BrowserServiceLacros> browser_service_;
+};
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest, PRE_FullRestoreWithTwoProfiles) {
+  // Simulate a full restore by creating the profiles in a PRE_ test.
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Create two profiles.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  Profile* profile2 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+
+    profile2 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
+    ASSERT_TRUE(profile2);
+  }
+  DisableWelcomePages({profile1, profile2});
+
+  // Don't delete Profiles too early.
+  ScopedProfileKeepAlive profile1_keep_alive(
+      profile1, ProfileKeepAliveOrigin::kBrowserWindow);
+  ScopedProfileKeepAlive profile2_keep_alive(
+      profile2, ProfileKeepAliveOrigin::kBrowserWindow);
+
+  // Open some urls with the browsers, and close them.
+  Browser* browser1 = Browser::Create(
+      Browser::CreateParams(Browser::TYPE_NORMAL, profile1, true));
+  chrome::NewTab(browser1);
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser1, embedded_test_server()->GetURL("/empty.html")));
+
+  Browser* browser2 = Browser::Create(
+      Browser::CreateParams(Browser::TYPE_NORMAL, profile2, true));
+  chrome::NewTab(browser2);
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser2, embedded_test_server()->GetURL("/form.html")));
+
+  // Set different startup preferences for the 2 profiles.
+  std::vector<GURL> urls1;
+  urls1.push_back(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(FILE_PATH_LITERAL("title1.html"))));
+  std::vector<GURL> urls2;
+  urls2.push_back(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(FILE_PATH_LITERAL("title2.html"))));
+
+  // Set different startup preferences for the 2 profiles.
+  SessionStartupPref pref1(SessionStartupPref::URLS);
+  pref1.urls = urls1;
+  SessionStartupPref::SetStartupPref(profile1, pref1);
+  SessionStartupPref pref2(SessionStartupPref::URLS);
+  pref2.urls = urls2;
+  SessionStartupPref::SetStartupPref(profile2, pref2);
+
+  profile1->GetPrefs()->CommitPendingWrite();
+  profile2->GetPrefs()->CommitPendingWrite();
+
+  // Ensure the session ends with the above two profiles.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(2u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile1));
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile2));
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest, FullRestoreWithTwoProfiles) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  // Open the two profiles.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  Profile* profile2 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+
+    profile2 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
+    ASSERT_TRUE(profile2);
+  }
+
+  // The profiles to be restored should match those setup in the PRE_ test.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(2u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile1));
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile2));
+
+  // Trigger Lacros full restore.
+  base::RunLoop run_loop;
+  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 2);
+  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/true);
+  run_loop.Run();
+
+  // The startup URLs are ignored, and instead the last open sessions are
+  // restored.
+  EXPECT_TRUE(profile1->restored_last_session());
+  EXPECT_TRUE(profile2->restored_last_session());
+
+  Browser* new_browser = nullptr;
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile1));
+  new_browser = chrome::FindBrowserWithProfile(profile1);
+  ASSERT_TRUE(new_browser);
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile2));
+  new_browser = chrome::FindBrowserWithProfile(profile2);
+  ASSERT_TRUE(new_browser);
+  tab_strip = new_browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/form.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest,
+                       PRE_FullRestoreWillRestoreWebAppsIfPreviouslyOpen) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  auto* profile =
+      profile_manager->GetProfile(profile_manager->GetPrimaryUserProfilePath());
+
+  // Don't delete the profile too early.
+  ScopedProfileKeepAlive profile_keep_alive(
+      profile, ProfileKeepAliveOrigin::kBrowserWindow);
+
+  // Set the startup pref to restore the last session.
+  SessionStartupPref pref(SessionStartupPref::LAST);
+  SessionStartupPref::SetStartupPref(profile, pref);
+  profile->GetPrefs()->CommitPendingWrite();
+
+  // Install and launch a PWA.
+  web_app::AppId app_id = InstallPWA(profile, GURL("http://www.example.com"));
+  Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile, app_id);
+  ASSERT_NE(app_browser, nullptr);
+  ASSERT_EQ(app_browser->type(), Browser::Type::TYPE_APP);
+  ASSERT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id));
+
+  // Launch a browser.
+  Browser* browser = Browser::Create(
+      Browser::CreateParams(Browser::TYPE_NORMAL, profile, true));
+  chrome::NewTab(browser);
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser, embedded_test_server()->GetURL("/empty.html")));
+
+  // Verify the state of the browser's tab strip.
+  TabStripModel* tab_strip = browser->tab_strip_model();
+  EXPECT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+
+  // Ensure the session ends with the profile in last profiles.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(1u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest,
+                       FullRestoreWillRestoreWebAppsIfPreviouslyOpen) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  auto* profile =
+      profile_manager->GetProfile(profile_manager->GetPrimaryUserProfilePath());
+
+  // The profile should match the one set up in the PRE_ test.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(1u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
+
+  // Trigger Lacros full restore.
+  EXPECT_FALSE(profile->restored_last_session());
+  base::RunLoop run_loop;
+  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 1);
+  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/true);
+  run_loop.Run();
+
+  // The last session should be logged as restored.
+  EXPECT_TRUE(profile->restored_last_session());
+
+  // A tabbed browser and app browser should have been restored.
+  ASSERT_EQ(2u, chrome::GetBrowserCount(profile));
+  Browser* tabbed_browser =
+      chrome::FindAllTabbedBrowsersWithProfile(profile)[0];
+  TabStripModel* tab_strip = tabbed_browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+
+  Browser* app_browser = nullptr;
+  for (auto* browser : *BrowserList::GetInstance()) {
+    if (browser->type() != Browser::Type::TYPE_APP)
+      continue;
+    EXPECT_FALSE(app_browser);
+    app_browser = browser;
+  }
+  ASSERT_TRUE(app_browser);
+}
+
+// Lacros Apps should only be restored when launching for full restore. Ensure
+// Apps are not restored when performing a non-full-restore session restore for
+// the browser (i.e. if all lacros windows are closed and a browser window is
+// later re-opened we should trigger a session restore, but not restore any
+// previously open app windows).
+IN_PROC_BROWSER_TEST_F(
+    BrowserLauncherTest,
+    SessionRestoreDoesNotTriggerAppRestoreWhenOpeningNewWindows) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  auto* profile =
+      profile_manager->GetProfile(profile_manager->GetPrimaryUserProfilePath());
+
+  // Keep the browser process running while the browsers are closed.
+  ScopedKeepAlive keep_alive(KeepAliveOrigin::BROWSER,
+                             KeepAliveRestartOption::DISABLED);
+  ScopedProfileKeepAlive profile_keep_alive(
+      profile, ProfileKeepAliveOrigin::kBrowserWindow);
+
+  // Install and launch a PWA.
+  web_app::AppId app_id = InstallPWA(profile, GURL("http://www.example.com"));
+  Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile, app_id);
+  ASSERT_NE(app_browser, nullptr);
+  ASSERT_EQ(app_browser->type(), Browser::Type::TYPE_APP);
+  ASSERT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id));
+
+  // Launch a browser.
+  Browser* browser = Browser::Create(
+      Browser::CreateParams(Browser::TYPE_NORMAL, profile, true));
+  chrome::NewTab(browser);
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser, embedded_test_server()->GetURL("/empty.html")));
+
+  // Verify the state of the browser's tab strip.
+  TabStripModel* tab_strip = browser->tab_strip_model();
+  EXPECT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+
+  // Close all browser windows and wait for the operation to complete.
+  size_t browser_count = chrome::GetTotalBrowserCount();
+  chrome::CloseAllBrowsers();
+  for (size_t i = 0; i < browser_count; ++i)
+    ui_test_utils::WaitForBrowserToClose();
+  ASSERT_EQ(0u, BrowserList::GetInstance()->size());
+
+  // Trigger a new window with session restore.
+  base::RunLoop run_loop;
+  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 1);
+  NewWindowSync(/*incognito=*/false, /*should_trigger_session_restore=*/true);
+  run_loop.Run();
+
+  // The browser window should be restored but app browser should not.
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile));
+  browser = chrome::FindAllTabbedBrowsersWithProfile(profile)[0];
+  tab_strip = browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest,
+                       PRE_FullRestoreDoNotSkipCrashRestore) {
+  // Simulate a full restore by setting up a profile in a PRE_ test.
+  SetupSingleProfileWithURLSPreference();
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest, FullRestoreDoNotSkipCrashRestore) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  // Open the profile.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile")));
+    ASSERT_TRUE(profile);
+  }
+
+  // The profile to be restored should match the one in the PRE_ test.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(1u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
+
+  // Disable the profile picker and set the exit type to crashed.
+  g_browser_process->local_state()->SetInteger(
+      prefs::kBrowserProfilePickerAvailabilityOnStartup,
+      static_cast<int>(ProfilePicker::AvailabilityOnStartup::kDisabled));
+  ExitTypeService::GetInstanceForProfile(profile)
+      ->SetLastSessionExitTypeForTest(ExitType::kCrashed);
+
+  // Trigger Lacros full restore but do not skip crash restore prompts.
+  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/false);
+
+  // The browser should not be restored but instead we should have the browser's
+  // crash restore bubble prompt.
+  Browser* new_browser = nullptr;
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile));
+  new_browser = chrome::FindBrowserWithProfile(profile);
+  ASSERT_TRUE(new_browser);
+
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_TRUE(content::WaitForLoadStop(tab_strip->GetWebContentsAt(0)));
+
+  views::BubbleDialogDelegate* crash_bubble_delegate =
+      SessionCrashedBubbleView::GetInstanceForTest();
+  EXPECT_TRUE(crash_bubble_delegate);
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest, PRE_FullRestoreSkipCrashRestore) {
+  // Simulate a full restore by setting up a profile in a PRE_ test.
+  SetupSingleProfileWithURLSPreference();
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserLauncherTest, FullRestoreSkipCrashRestore) {
+  // Browser launch should be suppressed with the kNoStartupWindow switch.
+  ASSERT_FALSE(browser());
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  // Open the profile.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile")));
+    ASSERT_TRUE(profile);
+  }
+
+  // The profile to be restored should match the one in the PRE_ test.
+  auto last_opened_profiles =
+      g_browser_process->profile_manager()->GetLastOpenedProfiles();
+  EXPECT_EQ(1u, last_opened_profiles.size());
+  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
+
+  // Disable the profile picker and set the exit type to crashed.
+  g_browser_process->local_state()->SetInteger(
+      prefs::kBrowserProfilePickerAvailabilityOnStartup,
+      static_cast<int>(ProfilePicker::AvailabilityOnStartup::kDisabled));
+  ExitTypeService::GetInstanceForProfile(profile)
+      ->SetLastSessionExitTypeForTest(ExitType::kCrashed);
+
+  // Trigger Lacros full restore and skip crash restore prompts.
+  base::RunLoop run_loop;
+  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 1);
+  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/true);
+  run_loop.Run();
+
+  // The browser should be restored (ignoring startup preference).
+  Browser* new_browser = nullptr;
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile));
+  new_browser = chrome::FindBrowserWithProfile(profile);
+  ASSERT_TRUE(new_browser);
+
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ("/empty.html",
+            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
+}
diff --git a/chrome/browser/lacros/browser_service_lacros.cc b/chrome/browser/lacros/browser_service_lacros.cc
index cb49d370..4cb3bd9 100644
--- a/chrome/browser/lacros/browser_service_lacros.cc
+++ b/chrome/browser/lacros/browser_service_lacros.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/chromeos/arc/arc_web_contents_data.h"
 #include "chrome/browser/feedback/feedback_dialog_utils.h"
 #include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
+#include "chrome/browser/lacros/browser_launcher.h"
 #include "chrome/browser/lacros/feedback_util.h"
 #include "chrome/browser/lacros/system_logs/lacros_system_log_fetcher.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -41,7 +42,6 @@
 #include "chrome/browser/ui/profile_picker.h"
 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/browser/ui/startup/lacros_first_run_service.h"
-#include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/startup/startup_tab.h"
 #include "chrome/browser/ui/views/tabs/tab_scrubber_chromeos.h"
 #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h"
@@ -711,48 +711,8 @@
                     "Aborting the requested action.";
     return;
   }
-
-  // There must not be any previously opened browsers as this could change the
-  // list of profiles returned from `GetLastOpenedProfiles()` below.
-  if (BrowserList::GetInstance()->size() != 0) {
-    LOG(ERROR) << "Cannot full restore with pre-existing browser instances.";
-    return;
-  }
-
-  // Ensure that we do not start with the profile picker.
-  StartupProfileInfo profile_info{profile, StartupProfileMode::kBrowserWindow};
-
-  // Get the last opened profiles from the last session. This is only valid
-  // before any browsers have been opened for the current session as opening /
-  // closing browsers will cause the last opened profiles to change.
-  auto last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
-
-  // Currently the kNoStartupWindow flag is set when lacros-chrome is launched
-  // with crosapi::mojom::InitialBrowserAction::kDoNotOpenWindow. The intention
-  // is to prevent lacros-chrome from launching a window during startup. However
-  // this flag remains set throughout the life of the browser process.
-  // This leads to issues where browsers can no longer be opened by the startup
-  // browser creator (such as below and in SessionService::RestoreIfNecessary).
-  // As a temporary workaround remove the kNoStartupWindow switch from the
-  // command line when launching for full restore. This is safe as by this point
-  // the browser process has already been started in its windowless state and
-  // the flag is no longer required.
-  base::CommandLine* lacros_command_line =
-      base::CommandLine::ForCurrentProcess();
-  lacros_command_line->RemoveSwitch(switches::kNoStartupWindow);
-
-  // Modify the command line to restore browser sessions.
-  lacros_command_line->AppendSwitch(switches::kRestoreLastSession);
-
-  if (skip_crash_restore)
-    lacros_command_line->AppendSwitch(switches::kHideCrashRestoreBubble);
-
-  StartupBrowserCreator browser_creator;
-  browser_creator.LaunchBrowserForLastProfiles(
-      *lacros_command_line, base::FilePath(),
-      chrome::startup::IsProcessStartup::kYes, chrome::startup::IsFirstRun::kNo,
-      profile_info, last_opened_profiles);
+  BrowserLauncher::GetForProfile(profile)->LaunchForFullRestore(
+      skip_crash_restore);
 }
 
 void BrowserServiceLacros::UpdateComponentPolicy(
diff --git a/chrome/browser/lacros/browser_service_lacros_browsertest.cc b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
index 21674b1..bf70237 100644
--- a/chrome/browser/lacros/browser_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/containers/contains.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
@@ -14,7 +13,6 @@
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
 #include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
-#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_test_util.h"
 #include "chrome/browser/sessions/exit_type_service.h"
@@ -306,57 +304,6 @@
     PrefService* pref_service = g_browser_process->local_state();
     pref_service->SetInteger(prefs::kLastWhatsNewVersion, CHROME_VERSION_MAJOR);
   }
-
-  // Creates a new profile with a URLS startup preference and an open tab.
-  void SetupSingleProfileWithURLSPreference() {
-    ProfileManager* profile_manager = g_browser_process->profile_manager();
-
-    ASSERT_TRUE(embedded_test_server()->Start());
-
-    // Create two profiles.
-    base::FilePath dest_path = profile_manager->user_data_dir();
-
-    Profile* profile = nullptr;
-    {
-      base::ScopedAllowBlockingForTesting allow_blocking;
-      profile = profile_manager->GetProfile(
-          dest_path.Append(FILE_PATH_LITERAL("New Profile")));
-      ASSERT_TRUE(profile);
-    }
-    DisableWelcomePages({profile});
-
-    // Don't delete Profile too early.
-    ScopedProfileKeepAlive profile_keep_alive(
-        profile, ProfileKeepAliveOrigin::kBrowserWindow);
-
-    // Open some urls in the browser.
-    Browser* browser = Browser::Create(
-        Browser::CreateParams(Browser::TYPE_NORMAL, profile, true));
-    chrome::NewTab(browser);
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(
-        browser, embedded_test_server()->GetURL("/empty.html")));
-
-    // Establish the startup preference.
-    std::vector<GURL> urls;
-    urls.push_back(ui_test_utils::GetTestUrl(
-        base::FilePath(base::FilePath::kCurrentDirectory),
-        base::FilePath(FILE_PATH_LITERAL("title1.html"))));
-    urls.push_back(ui_test_utils::GetTestUrl(
-        base::FilePath(base::FilePath::kCurrentDirectory),
-        base::FilePath(FILE_PATH_LITERAL("title2.html"))));
-
-    // Set different startup preferences for the profile.
-    SessionStartupPref pref(SessionStartupPref::URLS);
-    pref.urls = urls;
-    SessionStartupPref::SetStartupPref(profile, pref);
-    profile->GetPrefs()->CommitPendingWrite();
-
-    // Ensure the session ends with the profile created above.
-    auto last_opened_profiles =
-        g_browser_process->profile_manager()->GetLastOpenedProfiles();
-    EXPECT_EQ(1u, last_opened_profiles.size());
-    EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
-  }
 };
 
 IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
@@ -387,248 +334,6 @@
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       PRE_FullRestoreWithTwoProfiles) {
-  // Simulate a full restore by creating the profiles in a PRE_ test.
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-
-  ASSERT_TRUE(embedded_test_server()->Start());
-
-  // Create two profiles.
-  base::FilePath dest_path = profile_manager->user_data_dir();
-
-  Profile* profile1 = nullptr;
-  Profile* profile2 = nullptr;
-  {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    profile1 = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
-    ASSERT_TRUE(profile1);
-
-    profile2 = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
-    ASSERT_TRUE(profile2);
-  }
-  DisableWelcomePages({profile1, profile2});
-
-  // Don't delete Profiles too early.
-  ScopedProfileKeepAlive profile1_keep_alive(
-      profile1, ProfileKeepAliveOrigin::kBrowserWindow);
-  ScopedProfileKeepAlive profile2_keep_alive(
-      profile2, ProfileKeepAliveOrigin::kBrowserWindow);
-
-  // Open some urls with the browsers, and close them.
-  Browser* browser1 = Browser::Create(
-      Browser::CreateParams(Browser::TYPE_NORMAL, profile1, true));
-  chrome::NewTab(browser1);
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser1, embedded_test_server()->GetURL("/empty.html")));
-
-  Browser* browser2 = Browser::Create(
-      Browser::CreateParams(Browser::TYPE_NORMAL, profile2, true));
-  chrome::NewTab(browser2);
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser2, embedded_test_server()->GetURL("/form.html")));
-
-  // Set different startup preferences for the 2 profiles.
-  std::vector<GURL> urls1;
-  urls1.push_back(ui_test_utils::GetTestUrl(
-      base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(FILE_PATH_LITERAL("title1.html"))));
-  std::vector<GURL> urls2;
-  urls2.push_back(ui_test_utils::GetTestUrl(
-      base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(FILE_PATH_LITERAL("title2.html"))));
-
-  // Set different startup preferences for the 2 profiles.
-  SessionStartupPref pref1(SessionStartupPref::URLS);
-  pref1.urls = urls1;
-  SessionStartupPref::SetStartupPref(profile1, pref1);
-  SessionStartupPref pref2(SessionStartupPref::URLS);
-  pref2.urls = urls2;
-  SessionStartupPref::SetStartupPref(profile2, pref2);
-
-  profile1->GetPrefs()->CommitPendingWrite();
-  profile2->GetPrefs()->CommitPendingWrite();
-
-  // Ensure the session ends with the above two profiles.
-  auto last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
-  EXPECT_EQ(2u, last_opened_profiles.size());
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile1));
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile2));
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       FullRestoreWithTwoProfiles) {
-  // Browser launch should be suppressed with the kNoStartupWindow switch.
-  ASSERT_FALSE(browser());
-
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-
-  // Open the two profiles.
-  base::FilePath dest_path = profile_manager->user_data_dir();
-
-  Profile* profile1 = nullptr;
-  Profile* profile2 = nullptr;
-  {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    profile1 = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
-    ASSERT_TRUE(profile1);
-
-    profile2 = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile 2")));
-    ASSERT_TRUE(profile2);
-  }
-
-  // The profiles to be restored should match those setup in the PRE_ test.
-  auto last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
-  EXPECT_EQ(2u, last_opened_profiles.size());
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile1));
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile2));
-
-  // Trigger Lacros full restore.
-  base::RunLoop run_loop;
-  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 2);
-  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/true);
-  run_loop.Run();
-
-  // The startup URLs are ignored, and instead the last open sessions are
-  // restored.
-  EXPECT_TRUE(profile1->restored_last_session());
-  EXPECT_TRUE(profile2->restored_last_session());
-
-  Browser* new_browser = nullptr;
-  ASSERT_EQ(1u, chrome::GetBrowserCount(profile1));
-  new_browser = chrome::FindBrowserWithProfile(profile1);
-  ASSERT_TRUE(new_browser);
-  TabStripModel* tab_strip = new_browser->tab_strip_model();
-  ASSERT_EQ(1, tab_strip->count());
-  EXPECT_EQ("/empty.html",
-            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
-
-  ASSERT_EQ(1u, chrome::GetBrowserCount(profile2));
-  new_browser = chrome::FindBrowserWithProfile(profile2);
-  ASSERT_TRUE(new_browser);
-  tab_strip = new_browser->tab_strip_model();
-  ASSERT_EQ(1, tab_strip->count());
-  EXPECT_EQ("/form.html",
-            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       PRE_FullRestoreDoNotSkipCrashRestore) {
-  // Simulate a full restore by setting up a profile in a PRE_ test.
-  SetupSingleProfileWithURLSPreference();
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       FullRestoreDoNotSkipCrashRestore) {
-  // Browser launch should be suppressed with the kNoStartupWindow switch.
-  ASSERT_FALSE(browser());
-
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-
-  // Open the profile.
-  base::FilePath dest_path = profile_manager->user_data_dir();
-
-  Profile* profile = nullptr;
-  {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    profile = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile")));
-    ASSERT_TRUE(profile);
-  }
-
-  // The profile to be restored should match the one in the PRE_ test.
-  auto last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
-  EXPECT_EQ(1u, last_opened_profiles.size());
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
-
-  // Disable the profile picker and set the exit type to crashed.
-  g_browser_process->local_state()->SetInteger(
-      prefs::kBrowserProfilePickerAvailabilityOnStartup,
-      static_cast<int>(ProfilePicker::AvailabilityOnStartup::kDisabled));
-  ExitTypeService::GetInstanceForProfile(profile)
-      ->SetLastSessionExitTypeForTest(ExitType::kCrashed);
-
-  // Trigger Lacros full restore but do not skip crash restore prompts.
-  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/false);
-
-  // The browser should not be restored but instead we should have the browser's
-  // crash restore bubble prompt.
-  Browser* new_browser = nullptr;
-  ASSERT_EQ(1u, chrome::GetBrowserCount(profile));
-  new_browser = chrome::FindBrowserWithProfile(profile);
-  ASSERT_TRUE(new_browser);
-
-  TabStripModel* tab_strip = new_browser->tab_strip_model();
-  ASSERT_EQ(1, tab_strip->count());
-  EXPECT_TRUE(content::WaitForLoadStop(tab_strip->GetWebContentsAt(0)));
-
-  views::BubbleDialogDelegate* crash_bubble_delegate =
-      SessionCrashedBubbleView::GetInstanceForTest();
-  EXPECT_TRUE(crash_bubble_delegate);
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       PRE_FullRestoreSkipCrashRestore) {
-  // Simulate a full restore by setting up a profile in a PRE_ test.
-  SetupSingleProfileWithURLSPreference();
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
-                       FullRestoreSkipCrashRestore) {
-  // Browser launch should be suppressed with the kNoStartupWindow switch.
-  ASSERT_FALSE(browser());
-
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-
-  // Open the profile.
-  base::FilePath dest_path = profile_manager->user_data_dir();
-
-  Profile* profile = nullptr;
-  {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    profile = profile_manager->GetProfile(
-        dest_path.Append(FILE_PATH_LITERAL("New Profile")));
-    ASSERT_TRUE(profile);
-  }
-
-  // The profile to be restored should match the one in the PRE_ test.
-  auto last_opened_profiles =
-      g_browser_process->profile_manager()->GetLastOpenedProfiles();
-  EXPECT_EQ(1u, last_opened_profiles.size());
-  EXPECT_TRUE(base::Contains(last_opened_profiles, profile));
-
-  // Disable the profile picker and set the exit type to crashed.
-  g_browser_process->local_state()->SetInteger(
-      prefs::kBrowserProfilePickerAvailabilityOnStartup,
-      static_cast<int>(ProfilePicker::AvailabilityOnStartup::kDisabled));
-  ExitTypeService::GetInstanceForProfile(profile)
-      ->SetLastSessionExitTypeForTest(ExitType::kCrashed);
-
-  // Trigger Lacros full restore and skip crash restore prompts.
-  base::RunLoop run_loop;
-  testing::SessionsRestoredWaiter restore_waiter(run_loop.QuitClosure(), 1);
-  browser_service()->OpenForFullRestore(/*skip_crash_restore=*/true);
-  run_loop.Run();
-
-  // The browser should be restored (ignoring startup preference).
-  Browser* new_browser = nullptr;
-  ASSERT_EQ(1u, chrome::GetBrowserCount(profile));
-  new_browser = chrome::FindBrowserWithProfile(profile);
-  ASSERT_TRUE(new_browser);
-
-  TabStripModel* tab_strip = new_browser->tab_strip_model();
-  ASSERT_EQ(1, tab_strip->count());
-  EXPECT_EQ("/empty.html",
-            tab_strip->GetWebContentsAt(0)->GetLastCommittedURL().path());
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosWindowlessBrowserTest,
                        NewTab_OpensWindowWithSessionRestore) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index dc5fe83..476d21b90 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -117,13 +117,12 @@
 bool SetLocaleForNextStart(PrefService* local_state) {
   // If a policy mandates the login screen locale, use it.
   ash::CrosSettings* cros_settings = ash::CrosSettings::Get();
-  const base::ListValue* login_screen_locales = nullptr;
+  const base::Value::List* login_screen_locales = nullptr;
   if (cros_settings->GetList(ash::kDeviceLoginScreenLocales,
                              &login_screen_locales) &&
-      !login_screen_locales->GetListDeprecated().empty() &&
-      login_screen_locales->GetListDeprecated()[0].is_string()) {
-    std::string login_screen_locale =
-        login_screen_locales->GetListDeprecated()[0].GetString();
+      !login_screen_locales->empty() &&
+      login_screen_locales->front().is_string()) {
+    std::string login_screen_locale = login_screen_locales->front().GetString();
     local_state->SetString(language::prefs::kApplicationLocale,
                            login_screen_locale);
     return true;
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_browsertest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_browsertest.cc
index 0e0722f..eb36b35 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_browsertest.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_browsertest.cc
@@ -44,8 +44,8 @@
 class AccessCodeCastSinkServiceBrowserTest
     : public AccessCodeCastIntegrationBrowserTest {};
 
-// TODO(b/242928209): Saved device tests are flaky on linux-rel.
-#if BUILDFLAG(IS_LINUX)
+// TODO(b/242928209): Saved device tests are flaky on linux-rel/Mac.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 #define MAYBE_PRE_InstantExpiration DISABLED_PRE_InstantExpiration
 #define MAYBE_InstantExpiration DISABLED_InstantExpiration
 #else
@@ -130,8 +130,8 @@
           weak_ptr_factory_.GetWeakPtr()));
 }
 
-// TODO(b/242928209): Saved device tests are flaky on linux-rel.
-#if BUILDFLAG(IS_LINUX)
+// TODO(b/242928209): Saved device tests are flaky on linux-rel/Mac.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 #define MAYBE_PRE_SavedDevice DISABLED_PRE_SavedDevice
 #define MAYBE_SavedDevice DISABLED_SavedDevice
 #else
diff --git a/chrome/browser/nearby_sharing/file_attachment_unittest.cc b/chrome/browser/nearby_sharing/file_attachment_unittest.cc
index 08bbceca..1de13da 100644
--- a/chrome/browser/nearby_sharing/file_attachment_unittest.cc
+++ b/chrome/browser/nearby_sharing/file_attachment_unittest.cc
@@ -3,28 +3,80 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/nearby_sharing/file_attachment.h"
+#include "chrome/browser/nearby_sharing/share_target.h"
 
 #include "base/files/file_path.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
-const int64_t kFileSize = 2048;
-const char kFileName[] = "secure_file_name.html";
-base::FilePath kFilePath = base::FilePath();
-const char kMimeType[] = "text/html";
-FileAttachment::Type kMetadataType =
-    sharing::mojom::FileMetadata::Type::kUnknown;
+base::FilePath kFilePath = base::FilePath("test.html");
+
+struct FileShareType {
+  std::string file_name;
+  nearby_share::mojom::ShareType share_type;
+} kFileTypes[] = {
+  {"test.jpg", nearby_share::mojom::ShareType::kImageFile},
+  {"test.mp4", nearby_share::mojom::ShareType::kVideoFile},
+  {"test.wav", nearby_share::mojom::ShareType::kAudioFile},
+  {"test.pdf", nearby_share::mojom::ShareType::kPdfFile},
+  {"test.other", nearby_share::mojom::ShareType::kUnknownFile}
+};
+
+struct GoogleAppsFileShareType {
+  std::string file_name;
+  std::string mime_type;
+  nearby_share::mojom::ShareType share_type;
+} kGoogleAppsFileTypes[] = {
+  {"test.gdoc", "application/vnd.google-apps.document", nearby_share::mojom::ShareType::kGoogleDocsFile},
+  {"test.gsheet", "application/vnd.google-apps.spreadsheet", nearby_share::mojom::ShareType::kGoogleSheetsFile},
+  {"test.gslides", "application/vnd.google-apps.presentation", nearby_share::mojom::ShareType::kGoogleSlidesFile}
+};
+
 }  // namespace
 
-TEST(FileAttachmentTest, FileAttachmentTest) {
-  FileAttachment attachment(/*id=*/0, kFileSize, kFileName, kMimeType,
-                            kMetadataType);
+class FileAttachmentShareTypeTest : public testing::TestWithParam<FileShareType> { };
 
-  EXPECT_EQ(attachment.size(), kFileSize);
-  EXPECT_EQ(attachment.file_name(), kFileName);
-  EXPECT_EQ(attachment.mime_type(), kMimeType);
-  EXPECT_EQ(attachment.type(), kMetadataType);
+class FileAttachmentGoogleAppsShareTypeTest : public testing::TestWithParam<GoogleAppsFileShareType> { };
 
-  attachment.set_file_path(kFilePath);
-  EXPECT_EQ(attachment.file_path(), kFilePath);
+TEST(FileAttachmentTest, CreateFileAttachment) {
+    FileAttachment attachment = FileAttachment(kFilePath);
+
+    EXPECT_EQ(attachment.size(), 0u);
+    EXPECT_EQ(attachment.file_name(), "test.html");
+    EXPECT_EQ(attachment.mime_type(), "text/html");
+    EXPECT_EQ(attachment.type(), FileAttachment::Type::kUnknown);
+    EXPECT_EQ(attachment.file_path(), kFilePath);
+    EXPECT_EQ(attachment.GetDescription(), "test.html");
 }
+
+TEST(FileAttachmentTest, MoveShareTarget) {
+  FileAttachment attachment = FileAttachment(kFilePath);
+  ShareTarget target;
+  EXPECT_EQ(target.file_attachments.size(), 0u);
+  attachment.MoveToShareTarget(target);
+  EXPECT_EQ(target.file_attachments.size(), 1u);
+}
+
+TEST_P(FileAttachmentShareTypeTest, GetShareType) {
+  FileShareType fileTypePair = GetParam();
+  FileAttachment attachment = FileAttachment(base::FilePath(fileTypePair.file_name));
+  EXPECT_EQ(attachment.GetShareType(), fileTypePair.share_type);
+}
+
+INSTANTIATE_TEST_SUITE_P(FileAttachmentTest, FileAttachmentShareTypeTest,
+                         testing::ValuesIn(kFileTypes));
+
+TEST_P(FileAttachmentGoogleAppsShareTypeTest, GetShareType) {
+  GoogleAppsFileShareType fileType = GetParam();
+
+  FileAttachment attachment = FileAttachment(/*id=*/ 0u,
+                                             /*size=*/ 0u,
+                                             fileType.file_name,
+                                             fileType.mime_type,
+                                             FileAttachment::Type::kUnknown);
+
+  EXPECT_EQ(attachment.GetShareType(), fileType.share_type);
+}
+
+INSTANTIATE_TEST_SUITE_P(FileAttachmentTest, FileAttachmentGoogleAppsShareTypeTest,
+                         testing::ValuesIn(kGoogleAppsFileTypes));
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
index 2824253..8fc42e3 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
@@ -1660,10 +1660,13 @@
 
     holding_space_controller_ = std::make_unique<ash::HoldingSpaceController>();
     profile_manager_ = CreateTestingProfileManager();
-    const AccountId account_id(AccountId::FromUserEmail(""));
+    constexpr char kEmail[] = "test@test";
+    const AccountId account_id(AccountId::FromUserEmail(kEmail));
     user_manager_->AddUser(account_id);
     user_manager_->LoginUser(account_id);
-    profile_ = profile_manager_->CreateTestingProfile("");
+    profile_ = profile_manager_->CreateTestingProfile(kEmail);
+    static_cast<ash::SessionObserver*>(holding_space_controller_.get())
+        ->OnActiveUserSessionChanged(account_id);
   }
 
   ~NearbyFilesHoldingSpaceTest() override = default;
diff --git a/chrome/browser/net/chrome_report_sender_unittest.cc b/chrome/browser/net/chrome_report_sender_unittest.cc
index e5726161..f09de7d 100644
--- a/chrome/browser/net/chrome_report_sender_unittest.cc
+++ b/chrome/browser/net/chrome_report_sender_unittest.cc
@@ -47,8 +47,8 @@
     head->headers =
         net::HttpResponseHeaders::TryToCreate("HTTP/1.1 200 OK\n\n");
     head->mime_type = "text/html";
-    client_remote->OnReceiveResponse(std::move(head),
-                                     mojo::ScopedDataPipeConsumerHandle());
+    client_remote->OnReceiveResponse(
+        std::move(head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
     client_remote->OnComplete(network::URLLoaderCompletionStatus());
   }
 
diff --git a/chrome/browser/net/dns_probe_runner.cc b/chrome/browser/net/dns_probe_runner.cc
index b5644ef5..eef7b23b 100644
--- a/chrome/browser/net/dns_probe_runner.cc
+++ b/chrome/browser/net/dns_probe_runner.cc
@@ -98,9 +98,12 @@
   parameters->cache_usage =
       network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
 
+  // Intentionally using a HostPortPair not to trigger HTTPS DNS resource
+  // record query.
   // Use transient NIKs - don't want cached responses anyways, so no benefit
   // from sharing a cache, beyond multiple probes not evicting anything.
-  host_resolver_->ResolveHost(net::HostPortPair(kKnownGoodHostname, 80),
+  host_resolver_->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                                  net::HostPortPair(kKnownGoodHostname, 443)),
                               net::NetworkIsolationKey::CreateTransient(),
                               std::move(parameters),
                               receiver_.BindNewPipeAndPassRemote());
diff --git a/chrome/browser/net/dns_probe_test_util.cc b/chrome/browser/net/dns_probe_test_util.cc
index 90c3bb7..763791f 100644
--- a/chrome/browser/net/dns_probe_test_util.cc
+++ b/chrome/browser/net/dns_probe_test_util.cc
@@ -63,7 +63,7 @@
 FakeHostResolver::~FakeHostResolver() = default;
 
 void FakeHostResolver::ResolveHost(
-    const net::HostPortPair& host,
+    network::mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     network::mojom::ResolveHostParametersPtr optional_parameters,
     mojo::PendingRemote<network::mojom::ResolveHostClient>
@@ -94,7 +94,7 @@
 HangingHostResolver::~HangingHostResolver() = default;
 
 void HangingHostResolver::ResolveHost(
-    const net::HostPortPair& host,
+    network::mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     network::mojom::ResolveHostParametersPtr optional_parameters,
     mojo::PendingRemote<network::mojom::ResolveHostClient> response_client) {
diff --git a/chrome/browser/net/dns_probe_test_util.h b/chrome/browser/net/dns_probe_test_util.h
index a3d92cb..4beae01b 100644
--- a/chrome/browser/net/dns_probe_test_util.h
+++ b/chrome/browser/net/dns_probe_test_util.h
@@ -49,7 +49,7 @@
 
   ~FakeHostResolver() override;
 
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
@@ -73,7 +73,7 @@
       mojo::PendingReceiver<network::mojom::HostResolver> resolver_receiver);
   ~HangingHostResolver() override;
 
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/browser/notifications/notifier_state_tracker.cc b/chrome/browser/notifications/notifier_state_tracker.cc
index 465f3be..fb84660 100644
--- a/chrome/browser/notifications/notifier_state_tracker.cc
+++ b/chrome/browser/notifications/notifier_state_tracker.cc
@@ -131,25 +131,22 @@
   DCHECK(pref_name != NULL);
 
   ListPrefUpdate update(profile_->GetPrefs(), pref_name);
+  base::Value::List& update_list = update->GetList();
   if (add_new_item) {
-    if (!base::Contains(update->GetListDeprecated(), id))
-      update->Append(std::move(id));
+    if (!base::Contains(update_list, id))
+      update_list.Append(std::move(id));
   } else {
-    update->EraseListValue(id);
+    update_list.EraseValue(id);
   }
 }
 
 void NotifierStateTracker::OnStringListPrefChanged(
     const char* pref_name, std::set<std::string>* ids_field) {
   ids_field->clear();
-  // Separate GetPrefs()->GetListDeprecated() to analyze the crash. See
-  // crbug.com/322320
-  const PrefService* pref_service = profile_->GetPrefs();
-  CHECK(pref_service);
-  const base::Value* pref_list = pref_service->GetList(pref_name);
-  base::Value::ConstListView pref_list_view = pref_list->GetListDeprecated();
-  for (size_t i = 0; i < pref_list_view.size(); ++i) {
-    const std::string* element = pref_list_view[i].GetIfString();
+  const base::Value::List& pref_list =
+      profile_->GetPrefs()->GetValueList(pref_name);
+  for (size_t i = 0; i < pref_list.size(); ++i) {
+    const std::string* element = pref_list[i].GetIfString();
     if (element && !element->empty())
       ids_field->insert(*element);
     else
diff --git a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
index 76920f1..bb6f4dd 100644
--- a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
@@ -170,8 +170,10 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     response_body_ = std::move(body);
     observer_->OnReceiveResponse(std::move(response_head));
   }
@@ -182,8 +184,6 @@
     observer_->OnReceiveRedirect(redirect_info.new_url);
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
 
   void OnUploadProgress(int64_t current_position,
diff --git a/chrome/browser/offline_pages/offline_page_url_loader.cc b/chrome/browser/offline_pages/offline_page_url_loader.cc
index 4ac6dca..58877c7 100644
--- a/chrome/browser/offline_pages/offline_page_url_loader.cc
+++ b/chrome/browser/offline_pages/offline_page_url_loader.cc
@@ -283,7 +283,7 @@
   response_head->content_length = file_size;
 
   client_->OnReceiveResponse(std::move(response_head),
-                             std::move(consumer_handle));
+                             std::move(consumer_handle), absl::nullopt);
 
   handle_watcher_ = std::make_unique<mojo::SimpleWatcher>(
       FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL,
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
index ddf816c..926971594 100644
--- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
+++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -561,8 +561,14 @@
   run_loop.Run();
 }
 
+#if !defined(NDEBUG)
+// Flaky timeout in debug builds (crbug.com/1338408).
+#define MAYBE_NoVisitsForUrlInHistory DISABLED_NoVisitsForUrlInHistory
+#else
+#define MAYBE_NoVisitsForUrlInHistory NoVisitsForUrlInHistory
+#endif
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
-                       NoVisitsForUrlInHistory) {
+                       MAYBE_NoVisitsForUrlInHistory) {
   HistoryVisit history_visit;
   history_visit.url = GURL("https://probablynotarealurl.com/");
   history_visit.text_to_annotate = "sometext";
@@ -611,8 +617,14 @@
   }
 }
 
+#if !defined(NDEBUG)
+// Flaky timeout in debug builds (crbug.com/1338408).
+#define MAYBE_OgImagePresent DISABLED_OgImagePresent
+#else
+#define MAYBE_OgImagePresent OgImagePresent
+#endif
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
-                       OgImagePresent) {
+                       MAYBE_OgImagePresent) {
   base::HistogramTester histogram_tester;
 
   GURL url(embedded_test_server()->GetURL("a.com", "/og_image.html"));
@@ -627,8 +639,14 @@
       1);
 }
 
+#if !defined(NDEBUG)
+// Flaky timeout in debug builds (crbug.com/1338408).
+#define MAYBE_OgImagePresentButMalformed DISABLED_OgImagePresentButMalformed
+#else
+#define MAYBE_OgImagePresentButMalformed OgImagePresentButMalformed
+#endif
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
-                       OgImagePresentButMalformed) {
+                       MAYBE_OgImagePresentButMalformed) {
   base::HistogramTester histogram_tester;
 
   GURL url(embedded_test_server()->GetURL("a.com", "/og_image_malformed.html"));
@@ -644,8 +662,14 @@
       1);
 }
 
+#if !defined(NDEBUG)
+// Flaky timeout in debug builds (crbug.com/1338408).
+#define MAYBE_OgImageNotPresent DISABLED_OgImageNotPresent
+#else
+#define MAYBE_OgImageNotPresent OgImageNotPresent
+#endif
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
-                       OgImageNotPresent) {
+                       MAYBE_OgImageNotPresent) {
   base::HistogramTester histogram_tester;
 
   GURL url(embedded_test_server()->GetURL("a.com", "/no_og_image.html"));
@@ -1077,7 +1101,8 @@
 };
 
 // Flaky on Win 7 Tests x64: crbug.com/1223172
-#if BUILDFLAG(IS_WIN)
+// Flaky timeout in debug builds: crbug.com/1338408.
+#if BUILDFLAG(IS_WIN) || !defined(NDEBUG)
 #define MAYBE_ModelNotAvailableForFirstNavigation \
   DISABLED_ModelNotAvailableForFirstNavigation
 #else
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
index 7797761..871d3bc 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -394,13 +394,14 @@
     was_hidden_ = true;
   }
 
-  // Record the CLS metrics when the tab is first hidden after it is first
-  // shown in foreground, in case that OnComplete is not called.
+  // Record the CLS and LCP metrics when the tab is first hidden after it is
+  // first shown in foreground, in case that OnComplete is not called.
   // last_time_shown_ is set when the page starts in the foreground or the page
   // becomes foregrounded.
   if (!was_hidden_after_first_show_in_foreground &&
       !last_time_shown_.is_null()) {
     ReportLayoutInstabilityAfterFirstForeground();
+    ReportLargestContentfulPaintAfterFirstForeground();
     was_hidden_after_first_show_in_foreground = true;
   }
   return CONTINUE_OBSERVING;
@@ -1102,6 +1103,31 @@
           GetDelegate().GetPageRenderData().layout_shift_score));
 }
 
+void UkmPageLoadMetricsObserver::
+    ReportLargestContentfulPaintAfterFirstForeground() {
+  DCHECK(!last_time_shown_.is_null());
+
+  const page_load_metrics::ContentfulPaintTimingInfo&
+      all_frames_largest_contentful_paint =
+          GetDelegate()
+              .GetLargestContentfulPaintHandler()
+              .MergeMainFrameAndSubframes();
+
+  if (all_frames_largest_contentful_paint.ContainsValidTime() &&
+      WasStartedInForegroundOptionalEventInForeground(
+          all_frames_largest_contentful_paint.Time(), GetDelegate())) {
+    ukm::builders::PageLoad builder(GetDelegate().GetPageUkmSourceId());
+    builder.SetPaintTiming_NavigationToLargestContentfulPaint2AtFirstOnHidden(
+        all_frames_largest_contentful_paint.Time().value().InMilliseconds());
+
+    PAGE_LOAD_HISTOGRAM(
+        "PageLoad.PaintTiming."
+        "NavigationToLargestContentfulPaint2AtFirstOnHidden",
+        all_frames_largest_contentful_paint.Time().value());
+    builder.Record(ukm::UkmRecorder::Get());
+  }
+}
+
 void UkmPageLoadMetricsObserver::RecordAbortMetrics(
     const page_load_metrics::mojom::PageLoadTiming& timing,
     base::TimeTicks page_end_time,
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h
index f22e832..6aa877c5 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h
@@ -204,6 +204,11 @@
   // background.
   void ReportLayoutInstabilityAfterFirstForeground();
 
+  // Record some largest contentful paint metrics that have occurred on the
+  // page until the first time the page starts in the foreground and moves to
+  // the background.
+  void ReportLargestContentfulPaintAfterFirstForeground();
+
   // Guaranteed to be non-null during the lifetime of |this|.
   raw_ptr<network::NetworkQualityTracker> network_quality_tracker_;
 
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
index 3f653a36..5d7a141 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
@@ -101,6 +101,11 @@
 class UkmPageLoadMetricsObserverTest
     : public page_load_metrics::PageLoadMetricsObserverTestHarness {
  protected:
+  template <typename... TaskEnvironmentTraits>
+  explicit UkmPageLoadMetricsObserverTest(TaskEnvironmentTraits&&... traits)
+      : page_load_metrics::PageLoadMetricsObserverTestHarness(
+            std::forward<TaskEnvironmentTraits>(traits)...) {}
+
   void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
     std::unique_ptr<UkmPageLoadMetricsObserver> observer =
         std::make_unique<UkmPageLoadMetricsObserver>(
@@ -273,6 +278,14 @@
   MockNetworkQualityProvider mock_network_quality_provider_;
 };
 
+class UkmPageLoadMetricsObserverWithMockTimeTest
+    : public UkmPageLoadMetricsObserverTest {
+ protected:
+  UkmPageLoadMetricsObserverWithMockTimeTest()
+      : UkmPageLoadMetricsObserverTest(
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
+};
+
 TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) {
   EXPECT_EQ(0ul, tester()->test_ukm_recorder().sources_count());
   EXPECT_EQ(0ul, tester()->test_ukm_recorder().entries_count());
@@ -2023,6 +2036,83 @@
               testing::ElementsAre(base::Bucket(10, 1)));
 }
 
+TEST_F(UkmPageLoadMetricsObserverWithMockTimeTest,
+       LargestContentfulPaintRecordOnHidden) {
+  page_load_metrics::mojom::PageLoadTiming timing;
+  page_load_metrics::InitPageLoadTimingForTest(&timing);
+  timing.navigation_start = base::Time::FromDoubleT(1);
+  timing.paint_timing->largest_contentful_paint->largest_image_paint =
+      base::Milliseconds(60);
+  timing.paint_timing->largest_contentful_paint->largest_image_paint_size = 50u;
+
+  PopulateExperimentalLCP(timing.paint_timing);
+  PopulateRequiredTimingFields(&timing);
+  NavigateAndCommit(GURL(kTestUrl1));
+  tester()->SimulateTimingUpdate(timing);
+
+  task_environment()->FastForwardBy(base::Milliseconds(1000));
+  web_contents()->WasHidden();
+
+  const auto& ukm_recorder = tester()->test_ukm_recorder();
+  std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
+      ukm_recorder.GetMergedEntriesByName(PageLoad::kEntryName);
+  EXPECT_EQ(1ul, merged_entries.size());
+
+  const ukm::mojom::UkmEntry* entry = merged_entries.begin()->second.get();
+  ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl1));
+  ukm_recorder.ExpectEntryMetric(
+      entry,
+      PageLoad::
+          kPaintTiming_NavigationToLargestContentfulPaint2AtFirstOnHiddenName,
+      60);
+  EXPECT_THAT(tester()->histogram_tester().GetAllSamples(
+                  "PageLoad.PaintTiming."
+                  "NavigationToLargestContentfulPaint2AtFirstOnHidden"),
+              testing::ElementsAre(base::Bucket(60, 1)));
+}
+
+TEST_F(UkmPageLoadMetricsObserverWithMockTimeTest,
+       LargestContentfulPaintRecordOnPageOpenBackground) {
+  // Open the page at the background.
+  web_contents()->WasHidden();
+  NavigateAndCommit(GURL(kTestUrl1));
+
+  // Bring the tab to the foreground and simulate an image paint.
+  web_contents()->WasShown();
+  page_load_metrics::mojom::PageLoadTiming timing;
+  page_load_metrics::InitPageLoadTimingForTest(&timing);
+  timing.navigation_start = base::Time::FromDoubleT(1);
+  PopulateRequiredTimingFields(&timing);
+
+  timing.paint_timing->largest_contentful_paint->largest_image_paint =
+      base::Milliseconds(60);
+  timing.paint_timing->largest_contentful_paint->largest_image_paint_size = 50u;
+  PopulateExperimentalLCP(timing.paint_timing);
+  tester()->SimulateTimingUpdate(timing);
+
+  // Simulate hiding the tab and check we should not record LCP for pages that
+  // are started at the background.
+  task_environment()->FastForwardBy(base::Milliseconds(1000));
+  web_contents()->WasHidden();
+
+  const auto& ukm_recorder = tester()->test_ukm_recorder();
+  std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
+      ukm_recorder.GetMergedEntriesByName(PageLoad::kEntryName);
+  EXPECT_EQ(1ul, merged_entries.size());
+  const ukm::mojom::UkmEntry* entry = merged_entries.begin()->second.get();
+  ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl1));
+  EXPECT_FALSE(tester()->test_ukm_recorder().EntryHasMetric(
+      entry, PageLoad::kPaintTiming_NavigationToLargestContentfulPaint2Name));
+  EXPECT_FALSE(tester()->test_ukm_recorder().EntryHasMetric(
+      entry,
+      PageLoad::
+          kPaintTiming_NavigationToLargestContentfulPaint2AtFirstOnHiddenName));
+  tester()->histogram_tester().ExpectTotalCount(
+      "PageLoad.PaintTiming."
+      "NavigationToLargestContentfulPaint2AtFirstOnHidden",
+      0);
+}
+
 TEST_F(UkmPageLoadMetricsObserverTest, SiteInstanceRenderProcessAssignment) {
   NavigateAndCommit(GURL(kTestUrl1));
 
diff --git a/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogControllerTest.java b/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogControllerTest.java
index ac534b45..02ba7944 100644
--- a/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogControllerTest.java
+++ b/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogControllerTest.java
@@ -107,15 +107,49 @@
      */
     @Test
     @EnableFeatures(ChromeFeatureList.PASSWORD_EDIT_DIALOG_WITH_DETAILS)
-    public void testUpdatePasswordDialogPropertiesFeatureEnabled() {
+    public void testUpdatePasswordDialogWithMultipleCredentialsPropertiesFeatureEnabled() {
         createAndShowDialog(true);
         Resources r = RuntimeEnvironment.getApplication().getResources();
 
         Assert.assertEquals(
                 mModalDialogManager.getShownDialogModel().get(ModalDialogProperties.TITLE),
+                r.getString(R.string.confirm_username_dialog_title));
+        Assert.assertThat("Usernames don't match",
+                mCustomViewModel.get(PasswordEditDialogProperties.USERNAMES), contains(USERNAMES));
+        Assert.assertEquals("Selected username doesn't match", INITIAL_USERNAME,
+                mCustomViewModel.get(PasswordEditDialogProperties.USERNAME));
+        Assert.assertEquals("Password doesn't match", INITIAL_PASSWORD,
+                mCustomViewModel.get(PasswordEditDialogProperties.PASSWORD));
+        Assert.assertNotNull(
+                "Footer is empty", mCustomViewModel.get(PasswordEditDialogProperties.FOOTER));
+        Assert.assertNotNull("There should be a title icon",
+                mModalDialogManager.getShownDialogModel().get(ModalDialogProperties.TITLE_ICON));
+        Assert.assertEquals(mModalDialogManager.getShownDialogModel().get(
+                                    ModalDialogProperties.POSITIVE_BUTTON_TEXT),
+                r.getString(R.string.password_manager_update_button));
+        if (mIsSignedIn) {
+            Assert.assertTrue("Footer should contain user account name",
+                    mCustomViewModel.get(PasswordEditDialogProperties.FOOTER)
+                            .contains(ACCOUNT_NAME));
+        }
+    }
+
+    /**
+     * Tests that properties of update modal dialog and custom view are set correctly
+     * based on passed parameters when the details feature is enabled.
+     */
+    @Test
+    @EnableFeatures(ChromeFeatureList.PASSWORD_EDIT_DIALOG_WITH_DETAILS)
+    public void testUpdatePasswordDialogWithSingleCredentialPropertiesFeatureEnabled() {
+        createUpdatePasswordDialogWithSingleUsername();
+        Resources r = RuntimeEnvironment.getApplication().getResources();
+
+        Assert.assertEquals(
+                mModalDialogManager.getShownDialogModel().get(ModalDialogProperties.TITLE),
                 r.getString(R.string.password_update_dialog_title));
         Assert.assertThat("Usernames don't match",
-                mCustomViewModel.get(PasswordEditDialogProperties.USERNAMES), contains(USERNAMES));
+                mCustomViewModel.get(PasswordEditDialogProperties.USERNAMES),
+                contains(INITIAL_USERNAME));
         Assert.assertEquals("Selected username doesn't match", INITIAL_USERNAME,
                 mCustomViewModel.get(PasswordEditDialogProperties.USERNAME));
         Assert.assertEquals("Password doesn't match", INITIAL_PASSWORD,
@@ -282,4 +316,14 @@
         mModalDialogModel = mDialogCoordinator.getDialogModelForTesting();
         mCustomViewModel = mDialogCoordinator.getDialogViewModelForTesting();
     }
+
+    private void createUpdatePasswordDialogWithSingleUsername() {
+        mDialogCoordinator = new PasswordEditDialogCoordinator(RuntimeEnvironment.getApplication(),
+                mModalDialogManager, mDialogViewMock, mDelegateMock);
+        mDialogCoordinator.showUpdatePasswordDialog(
+                new String[] {INITIAL_USERNAME}, 0, INITIAL_PASSWORD, ACCOUNT_NAME);
+
+        mModalDialogModel = mDialogCoordinator.getDialogModelForTesting();
+        mCustomViewModel = mDialogCoordinator.getDialogViewModelForTesting();
+    }
 }
diff --git a/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogCoordinator.java b/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogCoordinator.java
index 10b122cd..571f2f42 100644
--- a/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogCoordinator.java
+++ b/chrome/browser/password_edit_dialog/android/java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogCoordinator.java
@@ -143,7 +143,10 @@
      */
     void showUpdatePasswordDialog(@NonNull String[] usernames, int selectedUsernameIndex,
             @NonNull String password, @Nullable String account) {
-        mDialogModel = createModalDialogModel(mIsDialogWithDetailsFeatureEnabled
+        // If there is more than one username possible,
+        // the user is asked to confirm the one to be saved.
+        // Otherwise, they are just asked if they want to update the password.
+        mDialogModel = createModalDialogModel(usernames.length < 2
                         ? R.string.password_update_dialog_title
                         : R.string.confirm_username_dialog_title,
                 R.string.password_manager_update_button);
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
index c9e774f..0474ca7b 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
@@ -148,12 +148,7 @@
 
   update_password_ = update_password;
 
-  bool use_followup_button_text = false;
-  if (update_password) {
-    std::vector<std::u16string> usernames;
-    GetDisplayUsernames(&usernames);
-    use_followup_button_text = usernames.size() > 1;
-  }
+  bool use_followup_button_text = HasMultipleCredentialsStored();
   message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(
       GetPrimaryButtonTextId(update_password, use_followup_button_text)));
 
@@ -166,18 +161,22 @@
         ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_INFOBAR_SAVE_PASSWORD));
   }
 
-  if (!update_password)
-    SetupCogMenu(message_);
+  // With detailed dialog feature enabled the cog button is always shown
+  // (it was shown only for Save password dialog before)
+  if (!update_password ||
+      base::FeatureList::IsEnabled(kPasswordEditDialogWithDetails))
+    SetupCogMenu(message_, update_password);
 }
 
 void SaveUpdatePasswordMessageDelegate::SetupCogMenu(
-    std::unique_ptr<messages::MessageWrapper>& message) {
+    std::unique_ptr<messages::MessageWrapper>& message,
+    bool update_password) {
   message->SetSecondaryIconResourceId(
       ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_SETTINGS));
   if (base::FeatureList::IsEnabled(kPasswordEditDialogWithDetails)) {
     message->SetSecondaryActionCallback(base::BindRepeating(
         &SaveUpdatePasswordMessageDelegate::DisplayEditDialog,
-        base::Unretained(this)));
+        base::Unretained(this), update_password));
     return;
   }
 
@@ -242,79 +241,6 @@
   return IDS_PASSWORD_MANAGER_CONTINUE_BUTTON;
 }
 
-void SaveUpdatePasswordMessageDelegate::HandleMessageDismissed(
-    messages::DismissReason dismiss_reason) {
-  message_.reset();
-  if (password_edit_dialog_) {
-    // The user triggered password edit dialog. Don't cleanup internal
-    // datastructures, dialog dismiss callback will perform cleanup.
-    return;
-  }
-  // Record metrics and cleanup state.
-  RecordDismissalReasonMetrics(
-      MessageDismissReasonToPasswordManagerUIDismissalReason(dismiss_reason));
-  ClearState();
-}
-
-void SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked() {
-  passwords_state_.form_manager()->Save();
-}
-
-void SaveUpdatePasswordMessageDelegate::DisplayEditDialog() {
-  const std::u16string& current_username =
-      passwords_state_.form_manager()->GetPendingCredentials().username_value;
-  const std::u16string& current_password =
-      passwords_state_.form_manager()->GetPendingCredentials().password_value;
-  DisplaySavePasswordDialog(std::move(current_username),
-                            std::move(current_password));
-  DismissSaveUpdatePasswordMessage(messages::DismissReason::SECONDARY_ACTION);
-}
-
-void SaveUpdatePasswordMessageDelegate::DisplaySavePasswordDialog(
-    std::u16string current_username,
-    std::u16string current_password) {
-  CreatePasswordEditDialog();
-
-  // Password edit dialog factory method can return nullptr when web_contents
-  // is not attached to a window. See crbug.com/1049090 for details.
-  if (!password_edit_dialog_)
-    return;
-
-  password_edit_dialog_->ShowSavePasswordDialog(
-      current_username, current_password, account_email_);
-}
-
-void SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked() {
-  passwords_state_.form_manager()->Blocklist();
-  DismissSaveUpdatePasswordMessage(messages::DismissReason::SECONDARY_ACTION);
-}
-
-void SaveUpdatePasswordMessageDelegate::HandleUpdateButtonClicked() {
-  std::vector<std::u16string> usernames;
-  int selected_username_index = GetDisplayUsernames(&usernames);
-  if (usernames.size() > 1) {
-    DisplayUpdatePasswordDialog(std::move(usernames), selected_username_index);
-  } else {
-    passwords_state_.form_manager()->Save();
-  }
-}
-
-void SaveUpdatePasswordMessageDelegate::DisplayUpdatePasswordDialog(
-    std::vector<std::u16string> usernames,
-    int selected_username_index) {
-  CreatePasswordEditDialog();
-
-  // Password edit dialog factory method can return nullptr when web_contents
-  // is not attached to a window. See crbug.com/1049090 for details.
-  if (!password_edit_dialog_)
-    return;
-
-  password_edit_dialog_->ShowUpdatePasswordDialog(
-      usernames, selected_username_index,
-      passwords_state_.form_manager()->GetPendingCredentials().password_value,
-      account_email_);
-}
-
 unsigned int SaveUpdatePasswordMessageDelegate::GetDisplayUsernames(
     std::vector<std::u16string>* usernames) {
   unsigned int selected_username_index = 0;
@@ -341,6 +267,74 @@
   return selected_username_index;
 }
 
+void SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked() {
+  passwords_state_.form_manager()->Save();
+}
+
+void SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked() {
+  passwords_state_.form_manager()->Blocklist();
+  DismissSaveUpdatePasswordMessage(messages::DismissReason::SECONDARY_ACTION);
+}
+
+void SaveUpdatePasswordMessageDelegate::HandleUpdateButtonClicked() {
+  std::vector<std::u16string> usernames;
+  if (HasMultipleCredentialsStored()) {
+    DisplayEditDialog(/*update_password=*/true);
+  } else {
+    passwords_state_.form_manager()->Save();
+  }
+}
+
+void SaveUpdatePasswordMessageDelegate::DisplayEditDialog(
+    bool update_password) {
+  const std::u16string& current_username =
+      passwords_state_.form_manager()->GetPendingCredentials().username_value;
+  const std::u16string& current_password =
+      passwords_state_.form_manager()->GetPendingCredentials().password_value;
+
+  CreatePasswordEditDialog();
+
+  // Password edit dialog factory method can return nullptr when web_contents
+  // is not attached to a window. See crbug.com/1049090 for details.
+  if (!password_edit_dialog_)
+    return;
+
+  if (update_password) {
+    std::vector<std::u16string> usernames;
+    int selected_username_index = GetDisplayUsernames(&usernames);
+    password_edit_dialog_->ShowUpdatePasswordDialog(
+        usernames, selected_username_index, current_password, account_email_);
+  } else {
+    password_edit_dialog_->ShowSavePasswordDialog(
+        current_username, current_password, account_email_);
+  }
+
+  DismissSaveUpdatePasswordMessage(messages::DismissReason::SECONDARY_ACTION);
+}
+
+void SaveUpdatePasswordMessageDelegate::HandleMessageDismissed(
+    messages::DismissReason dismiss_reason) {
+  message_.reset();
+  if (password_edit_dialog_) {
+    // The user triggered password edit dialog. Don't cleanup internal
+    // datastructures, dialog dismiss callback will perform cleanup.
+    return;
+  }
+  // Record metrics and cleanup state.
+  RecordDismissalReasonMetrics(
+      MessageDismissReasonToPasswordManagerUIDismissalReason(dismiss_reason));
+  ClearState();
+}
+
+bool SaveUpdatePasswordMessageDelegate::HasMultipleCredentialsStored() {
+  // TODO(crbug.com/1054410): Fix the update logic to use all best matches,
+  // rather than current_forms which is best_matches without PSL-matched
+  // credentials.
+  const std::vector<std::unique_ptr<password_manager::PasswordForm>>&
+      password_forms = passwords_state_.GetCurrentForms();
+  return password_forms.size() > 1;
+}
+
 void SaveUpdatePasswordMessageDelegate::CreatePasswordEditDialog() {
   // Binding with base::Unretained(this) is safe here because
   // SaveUpdatePasswordMessageDelegate owns password_edit_dialog_. Callbacks
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.h b/chrome/browser/password_manager/android/save_update_password_message_delegate.h
index 5255452..24adf392 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate.h
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/callback.h"
+#include "base/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/password_edit_dialog/android/password_edit_dialog_bridge.h"
 #include "chrome/browser/ui/passwords/manage_passwords_state.h"
@@ -64,7 +65,8 @@
       absl::optional<AccountInfo> account_info,
       bool update_password);
   void CreateMessage(bool update_password);
-  void SetupCogMenu(std::unique_ptr<messages::MessageWrapper>& message);
+  void SetupCogMenu(std::unique_ptr<messages::MessageWrapper>& message,
+                    bool update_password);
 
   // Returns the message description depending on whether the password is being
   // saved or updated and if unified password manager is enabled.
@@ -88,16 +90,13 @@
   void HandleSaveButtonClicked();
   void HandleNeverSaveClicked();
   void HandleUpdateButtonClicked();
-  void DisplayEditDialog();
-  void DisplaySavePasswordDialog(std::u16string current_username,
-                                 std::u16string current_password);
-  void DisplayUpdatePasswordDialog(std::vector<std::u16string> usernames,
-                                   int selected_username_index);
+  void DisplayEditDialog(bool update_password);
   void HandleMessageDismissed(messages::DismissReason dismiss_reason);
-  void HandleSavePasswordFromDialog(const std::u16string& username,
-                                    const std::u16string& password);
+  bool HasMultipleCredentialsStored();
   void CreatePasswordEditDialog();
   void HandleDialogDismissed(bool dialogAccepted);
+  void HandleSavePasswordFromDialog(const std::u16string& username,
+                                    const std::u16string& password);
 
   void ClearState();
 
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
index 4d055428..74425e1 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
@@ -706,6 +706,50 @@
 }
 
 // Verifies that:
+// 1. Update password dialog is shown after clicking on cog button (secondary
+// action) in the message.
+// 2. Updating the password form is executed after clicking on Update button of
+// the dialog.
+TEST_P(SaveUpdatePasswordMessageDelegateTest,
+       TriggerUpdateMessage_CogButton_Accept) {
+  base::test::ScopedFeatureList scoped_feature_state;
+  scoped_feature_state.InitAndEnableFeature(
+      password_manager::features::kPasswordEditDialogWithDetails);
+
+  base::HistogramTester histogram_tester;
+  ukm::TestAutoSetUkmRecorder test_ukm_recorder;
+
+  auto form_manager =
+      CreateFormManager(GURL(kDefaultUrl), empty_best_matches());
+  MockPasswordFormManagerForUI* form_manager_pointer = form_manager.get();
+  MockPasswordEditDialog* mock_dialog = PreparePasswordEditDialog();
+
+  EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true,
+                 /*update_password=*/true);
+  EXPECT_NE(nullptr, GetMessageWrapper());
+  EXPECT_CALL(*mock_dialog, ShowUpdatePasswordDialog);
+  TriggerPasswordEditDialog();
+
+  EXPECT_EQ(nullptr, GetMessageWrapper());
+  EXPECT_CALL(*form_manager_pointer, Save());
+  TriggerDialogAcceptedCallback(/*username=*/kUsername,
+                                /*password=*/kPassword);
+
+  // The real password edit dialog triggers dialog dismissed delegate inside.
+  // Here we use the mock that doesn't do this, so the dismiss is called
+  // manually here.
+  TriggerDialogDismissedCallback(/*dialog_accepted=*/true);
+
+  CommitPasswordFormMetrics();
+  VerifyUkmMetrics(
+      test_ukm_recorder,
+      PasswordFormMetricsRecorder::BubbleDismissalReason::kAccepted);
+  histogram_tester.ExpectUniqueSample(
+      kUpdateUIDismissalReasonHistogramName,
+      password_manager::metrics_util::CLICKED_ACCEPT, 1);
+}
+
+// Verifies that:
 // 1. Save password dialog is shown after clicking on cog button (secondary
 // action) in the message
 // 2. The dialog is dismissed with negative result after clicking on Cancel
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 0c966f93..0b12ae6 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -3201,15 +3201,9 @@
   WaitForSavedPdf(save_path);
 }
 
-// Flaky, http://crbug.com/1269103
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_SaveWithPolicyUniqueTimeSuffix \
-  DISABLED_SaveWithPolicyUniqueTimeSuffix
-#else
-#define MAYBE_SaveWithPolicyUniqueTimeSuffix SaveWithPolicyUniqueTimeSuffix
-#endif
+// TODO(crbug.com/1269103): Make this test non-flaky.
 IN_PROC_BROWSER_TEST_F(PDFExtensionSaveWithPolicyTest,
-                       MAYBE_SaveWithPolicyUniqueTimeSuffix) {
+                       DISABLED_SaveWithPolicyUniqueTimeSuffix) {
   base::ScopedAllowBlockingForTesting allow_blocking;
 
   CreateConflictingFilenames(GetDownloadDir().AppendASCII("combobox_form.pdf"),
diff --git a/chrome/browser/platform_util_mac.mm b/chrome/browser/platform_util_mac.mm
index 31835c7..d299971 100644
--- a/chrome/browser/platform_util_mac.mm
+++ b/chrome/browser/platform_util_mac.mm
@@ -10,11 +10,13 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "base/mac/foundation_util.h"
 #include "base/mac/mac_logging.h"
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/browser/platform_util_internal.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/base/mac/url_conversions.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
 
@@ -22,33 +24,30 @@
 
 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
   DCHECK([NSThread isMainThread]);
-  NSString* path_string = base::SysUTF8ToNSString(full_path.value());
-  if (!path_string || ![[NSWorkspace sharedWorkspace] selectFile:path_string
-                                        inFileViewerRootedAtPath:@""])
-    LOG(WARNING) << "NSWorkspace failed to select file " << full_path.value();
+  NSURL* url = base::mac::FilePathToNSURL(full_path);
+  [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[ url ]];
 }
 
 void OpenFileOnMainThread(const base::FilePath& full_path) {
   DCHECK([NSThread isMainThread]);
-  NSString* path_string = base::SysUTF8ToNSString(full_path.value());
-  if (!path_string)
-    return;
-
-  // On Mavericks or later, NSWorkspaceLaunchWithErrorPresentation will
-  // properly handle Finder activation for quarantined files
-  // (http://crbug.com/32921) and unassociated file types
-  // (http://crbug.com/50263).
-  NSURL* url = [NSURL fileURLWithPath:path_string];
+  NSURL* url = base::mac::FilePathToNSURL(full_path);
   if (!url)
     return;
 
-  const NSWorkspaceLaunchOptions launch_options =
-      NSWorkspaceLaunchAsync | NSWorkspaceLaunchWithErrorPresentation;
-  [[NSWorkspace sharedWorkspace] openURLs:@[ url ]
-                  withAppBundleIdentifier:nil
-                                  options:launch_options
-           additionalEventParamDescriptor:nil
-                        launchIdentifiers:NULL];
+  if (@available(macOS 10.15, *)) {
+    [[NSWorkspace sharedWorkspace]
+                  openURL:url
+            configuration:[NSWorkspaceOpenConfiguration configuration]
+        completionHandler:nil];
+  } else {
+    const NSWorkspaceLaunchOptions launch_options =
+        NSWorkspaceLaunchAsync | NSWorkspaceLaunchWithErrorPresentation;
+    [[NSWorkspace sharedWorkspace] openURLs:@[ url ]
+                    withAppBundleIdentifier:nil
+                                    options:launch_options
+             additionalEventParamDescriptor:nil
+                          launchIdentifiers:nil];
+  }
 }
 
 namespace internal {
@@ -60,13 +59,14 @@
           FROM_HERE, base::BindOnce(&OpenFileOnMainThread, path));
       return;
     case OPEN_FOLDER:
-      NSString* path_string = base::SysUTF8ToNSString(path.value());
-      if (!path_string)
+      NSURL* url = base::mac::FilePathToNSURL(path);
+      if (!url)
         return;
+
       // Note that there exists a TOCTOU race between the time that |path| was
       // verified as being a directory and when NSWorkspace invokes Finder (or
       // alternative) to open |path_string|.
-      [[NSWorkspace sharedWorkspace] openFile:path_string];
+      [[NSWorkspace sharedWorkspace] openURL:url];
       return;
   }
 }
@@ -75,8 +75,7 @@
 
 void OpenExternal(Profile* profile, const GURL& url) {
   DCHECK([NSThread isMainThread]);
-  NSString* url_string = base::SysUTF8ToNSString(url.spec());
-  NSURL* ns_url = [NSURL URLWithString:url_string];
+  NSURL* ns_url = net::NSURLWithGURL(url);
   if (!ns_url || ![[NSWorkspace sharedWorkspace] openURL:ns_url])
     LOG(WARNING) << "NSWorkspace failed to open URL " << url;
 }
diff --git a/chrome/browser/plugins/plugin_info_host_impl.h b/chrome/browser/plugins/plugin_info_host_impl.h
index a410abc0..8ff53b3 100644
--- a/chrome/browser/plugins/plugin_info_host_impl.h
+++ b/chrome/browser/plugins/plugin_info_host_impl.h
@@ -97,15 +97,15 @@
 
   static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
 
- private:
-  void ShutdownOnUIThread();
-
   // chrome::mojom::PluginInfoHost
   void GetPluginInfo(const GURL& url,
                      const url::Origin& origin,
                      const std::string& mime_type,
                      GetPluginInfoCallback callback) override;
 
+ private:
+  void ShutdownOnUIThread();
+
   // |params| wraps the parameters passed to |OnGetPluginInfo|, because
   // |base::Bind| doesn't support the required arity <http://crbug.com/98542>.
   void PluginsLoaded(const GetPluginInfo_Params& params,
diff --git a/chrome/browser/plugins/plugin_info_host_impl_browsertest.cc b/chrome/browser/plugins/plugin_info_host_impl_browsertest.cc
new file mode 100644
index 0000000..202c1b81
--- /dev/null
+++ b/chrome/browser/plugins/plugin_info_host_impl_browsertest.cc
@@ -0,0 +1,373 @@
+// Copyright 2022 The Chromium Authors.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/plugins/plugin_info_host_impl.h"
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/gmock_move_support.h"
+#include "base/test/mock_callback.h"
+#include "build/branding_buildflags.h"
+#include "chrome/browser/plugins/plugin_prefs.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_content_client.h"
+#include "chrome/common/plugin.mojom.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/nacl/common/buildflags.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/webplugininfo.h"
+#include "content/public/test/browser_test.h"
+#include "pdf/buildflags.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+#if BUILDFLAG(ENABLE_NACL)
+#include "components/nacl/common/nacl_constants.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#endif  // BUILDFLAG(ENABLE_NACL)
+
+#if BUILDFLAG(ENABLE_PDF)
+#include "chrome/common/pdf_util.h"
+#include "components/pdf/common/internal_plugin_helpers.h"
+#endif  // BUILDFLAG(ENABLE_PDF)
+
+namespace {
+
+using ::chrome::mojom::PluginInfo;
+using ::chrome::mojom::PluginInfoHost;
+using ::chrome::mojom::PluginInfoPtr;
+using ::chrome::mojom::PluginStatus;
+using ::content::WebPluginInfo;
+using ::content::WebPluginMimeType;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::SizeIs;
+
+#if BUILDFLAG(ENABLE_PDF)
+constexpr base::FilePath::CharType kPdfViewerExtensionPath[] =
+    FILE_PATH_LITERAL("chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/");
+#endif  // BUILDFLAG(ENABLE_PDF)
+
+}  // namespace
+
+class PluginInfoHostImplTest : public InProcessBrowserTest {
+ public:
+  void SetUpOnMainThread() override {
+    int active_render_process_id = browser()
+                                       ->tab_strip_model()
+                                       ->GetActiveWebContents()
+                                       ->GetPrimaryMainFrame()
+                                       ->GetProcess()
+                                       ->GetID();
+
+    plugin_info_host_impl_ = std::make_unique<PluginInfoHostImpl>(
+        active_render_process_id, browser()->profile());
+  }
+
+  void TearDownOnMainThread() override { plugin_info_host_impl_.reset(); }
+
+ protected:
+  PluginInfoPtr GetPluginInfo(const GURL& url,
+                              const url::Origin& origin,
+                              const std::string& mime_type) {
+    PluginInfoPtr plugin_info;
+
+    base::MockCallback<PluginInfoHost::GetPluginInfoCallback> mock_callback;
+    EXPECT_CALL(mock_callback, Run).WillOnce(MoveArg(&plugin_info));
+
+    base::RunLoop run_loop;
+    plugin_info_host_impl_->GetPluginInfo(
+        url, origin, mime_type,
+        mock_callback.Get().Then(run_loop.QuitClosure()));
+    run_loop.Run();
+
+    return plugin_info;
+  }
+
+  void SetAlwaysOpenPdfExternally() {
+    PluginPrefs::GetForProfile(browser()->profile())
+        ->SetAlwaysOpenPdfExternallyForTests(true);
+  }
+
+  std::unique_ptr<PluginInfoHostImpl> plugin_info_host_impl_;
+};
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest, CoverAllPlugins) {
+  // Note that "internal" plugins are the only type that can be registered with
+  // `content::PluginService` now.
+  std::vector<WebPluginInfo> plugins;
+  content::PluginService::GetInstance()->GetInternalPlugins(&plugins);
+
+  size_t expected_plugin_count = 0;
+
+#if BUILDFLAG(ENABLE_NACL)
+  EXPECT_THAT(plugins, Contains(Field(
+                           "path", &WebPluginInfo::path,
+                           base::FilePath(nacl::kInternalNaClPluginFileName))));
+  expected_plugin_count += 1;
+#endif  // BUILDFLAG_ENABLE_NACL)
+
+#if BUILDFLAG(ENABLE_PDF)
+  EXPECT_THAT(plugins,
+              Contains(Field("path", &WebPluginInfo::path,
+                             base::FilePath(kPdfViewerExtensionPath))));
+  EXPECT_THAT(
+      plugins,
+      Contains(Field("path", &WebPluginInfo::path,
+                     base::FilePath(ChromeContentClient ::kPDFPluginPath))));
+  expected_plugin_count += 2;
+#endif  // BUILDFLAG(ENABLE_PDF)
+
+  EXPECT_THAT(plugins, SizeIs(expected_plugin_count));
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest, GetPluginInfoForFlash) {
+  PluginInfoPtr plugin_info = GetPluginInfo(GURL("fake.swf"), url::Origin(),
+                                            "application/x-shockwave-flash");
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kNotFound, plugin_info->status);
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest, GetPluginInfoForFutureSplash) {
+  PluginInfoPtr plugin_info = GetPluginInfo(GURL("fake.spl"), url::Origin(),
+                                            "application/futuresplash");
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kNotFound, plugin_info->status);
+}
+
+#if BUILDFLAG(ENABLE_NACL)
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest, GetPluginInfoForNaCl) {
+  const std::u16string kPluginName = base::UTF8ToUTF16(nacl::kNaClPluginName);
+  const base::FilePath kPluginPath =
+      base::FilePath(nacl::kInternalNaClPluginFileName);
+
+  PluginInfoPtr plugin_info = GetPluginInfo(
+      GURL("fake-resource"), url::Origin(), nacl::kNaClPluginMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kPlayImportantContent, plugin_info->status);
+  EXPECT_EQ(nacl::kNaClPluginMimeType, plugin_info->actual_mime_type);
+
+  // Group ID and name synthesized by `PluginFinder::GetPluginMetadata()`.
+  EXPECT_EQ(kPluginPath.BaseName().AsUTF8Unsafe(),
+            plugin_info->group_identifier);
+  EXPECT_EQ(kPluginName, plugin_info->group_name);
+
+  // `WebPluginInfo` fields.
+  EXPECT_EQ(kPluginName, plugin_info->plugin.name);
+  EXPECT_EQ(kPluginPath, plugin_info->plugin.path);
+  EXPECT_EQ(u"", plugin_info->plugin.version);
+  EXPECT_EQ(u"", plugin_info->plugin.desc);
+  EXPECT_EQ(WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS,
+            plugin_info->plugin.type);
+  EXPECT_EQ(ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV,
+            plugin_info->plugin.pepper_permissions);
+  EXPECT_EQ(WebPluginInfo::kDefaultBackgroundColor,
+            plugin_info->plugin.background_color);
+
+  // Has both NaCl and Pnacl MIME types.
+  ASSERT_THAT(plugin_info->plugin.mime_types, SizeIs(2));
+
+  WebPluginMimeType nacl_mime_type = plugin_info->plugin.mime_types[0];
+  EXPECT_EQ(nacl::kNaClPluginMimeType, nacl_mime_type.mime_type);
+  EXPECT_THAT(nacl_mime_type.file_extensions,
+              ElementsAre(nacl::kNaClPluginExtension));
+  EXPECT_EQ(base::UTF8ToUTF16(nacl::kNaClPluginDescription),
+            nacl_mime_type.description);
+
+  // Depends on modules registered by `extensions::NaClModulesHandler`.
+  EXPECT_THAT(nacl_mime_type.additional_params, IsEmpty());
+
+  WebPluginMimeType pnacl_mime_type = plugin_info->plugin.mime_types[1];
+  EXPECT_EQ(nacl::kPnaclPluginMimeType, pnacl_mime_type.mime_type);
+  EXPECT_THAT(pnacl_mime_type.file_extensions,
+              ElementsAre(nacl::kPnaclPluginExtension));
+  EXPECT_EQ(base::UTF8ToUTF16(nacl::kPnaclPluginDescription),
+            pnacl_mime_type.description);
+  EXPECT_THAT(pnacl_mime_type.additional_params, IsEmpty());
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest, GetPluginInfoForPnacl) {
+  const std::u16string kPluginName = base::UTF8ToUTF16(nacl::kNaClPluginName);
+  const base::FilePath kPluginPath =
+      base::FilePath(nacl::kInternalNaClPluginFileName);
+
+  PluginInfoPtr plugin_info = GetPluginInfo(
+      GURL("fake-resource"), url::Origin(), nacl::kPnaclPluginMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kPlayImportantContent, plugin_info->status);
+  EXPECT_EQ(nacl::kPnaclPluginMimeType, plugin_info->actual_mime_type);
+
+  // Group ID and name synthesized by `PluginFinder::GetPluginMetadata()`.
+  EXPECT_EQ(kPluginPath.BaseName().AsUTF8Unsafe(),
+            plugin_info->group_identifier);
+  EXPECT_EQ(kPluginName, plugin_info->group_name);
+
+  // `WebPluginInfo` fields.
+  EXPECT_EQ(kPluginName, plugin_info->plugin.name);
+  EXPECT_EQ(kPluginPath, plugin_info->plugin.path);
+  EXPECT_EQ(u"", plugin_info->plugin.version);
+  EXPECT_EQ(u"", plugin_info->plugin.desc);
+  EXPECT_EQ(WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS,
+            plugin_info->plugin.type);
+  EXPECT_EQ(ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV,
+            plugin_info->plugin.pepper_permissions);
+  EXPECT_EQ(WebPluginInfo::kDefaultBackgroundColor,
+            plugin_info->plugin.background_color);
+
+  // Has both NaCl and Pnacl MIME types.
+  ASSERT_THAT(plugin_info->plugin.mime_types, SizeIs(2));
+
+  WebPluginMimeType nacl_mime_type = plugin_info->plugin.mime_types[0];
+  EXPECT_EQ(nacl::kNaClPluginMimeType, nacl_mime_type.mime_type);
+  EXPECT_THAT(nacl_mime_type.file_extensions,
+              ElementsAre(nacl::kNaClPluginExtension));
+  EXPECT_EQ(base::UTF8ToUTF16(nacl::kNaClPluginDescription),
+            nacl_mime_type.description);
+
+  // Depends on modules registered by `extensions::NaClModulesHandler`.
+  EXPECT_THAT(nacl_mime_type.additional_params, IsEmpty());
+
+  WebPluginMimeType pnacl_mime_type = plugin_info->plugin.mime_types[1];
+  EXPECT_EQ(nacl::kPnaclPluginMimeType, pnacl_mime_type.mime_type);
+  EXPECT_THAT(pnacl_mime_type.file_extensions,
+              ElementsAre(nacl::kPnaclPluginExtension));
+  EXPECT_EQ(base::UTF8ToUTF16(nacl::kPnaclPluginDescription),
+            pnacl_mime_type.description);
+
+  EXPECT_THAT(pnacl_mime_type.additional_params, IsEmpty());
+}
+#endif  // BUILDFLAG(ENABLE_NACL)
+
+#if BUILDFLAG(ENABLE_PDF)
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest,
+                       GetPluginInfoForPdfViewerExtension) {
+  const std::u16string kPluginName =
+      base::UTF8ToUTF16(ChromeContentClient::kPDFExtensionPluginName);
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  const std::string kGroupId = "google-chrome-pdf";
+#else
+  const std::string kGroupId = "chromium-pdf";
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+
+  PluginInfoPtr plugin_info =
+      GetPluginInfo(GURL("fake.pdf"), url::Origin(), kPDFMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kAllowed, plugin_info->status);
+  EXPECT_EQ(kPDFMimeType, plugin_info->actual_mime_type);
+
+  // Group ID and name defined by `IDR_PLUGIN_DB_JSON`.
+  EXPECT_EQ(kGroupId, plugin_info->group_identifier);
+  EXPECT_EQ(kPluginName, plugin_info->group_name);
+
+  // `WebPluginInfo` fields.
+  EXPECT_EQ(kPluginName, plugin_info->plugin.name);
+  EXPECT_EQ(base::FilePath(kPdfViewerExtensionPath), plugin_info->plugin.path);
+  EXPECT_EQ(u"", plugin_info->plugin.version);
+  EXPECT_EQ(u"", plugin_info->plugin.desc);
+  EXPECT_EQ(WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN,
+            plugin_info->plugin.type);
+  EXPECT_EQ(0, plugin_info->plugin.pepper_permissions);
+
+  // Background color hard-coded in `MimeTypesHandler::GetBackgroundColor()`.
+  EXPECT_EQ(SkColorSetRGB(82, 86, 89), plugin_info->plugin.background_color);
+
+  // Has PDF MIME type.
+  ASSERT_THAT(plugin_info->plugin.mime_types, SizeIs(1));
+
+  WebPluginMimeType mime_type = plugin_info->plugin.mime_types[0];
+  EXPECT_EQ(kPDFMimeType, mime_type.mime_type);
+  EXPECT_THAT(mime_type.file_extensions, ElementsAre("pdf"));
+  EXPECT_EQ(u"", mime_type.description);
+  EXPECT_THAT(mime_type.additional_params, IsEmpty());
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest,
+                       GetPluginInfoForPdfViewerExtensionWhenDisabled) {
+  SetAlwaysOpenPdfExternally();
+
+  PluginInfoPtr plugin_info =
+      GetPluginInfo(GURL("fake.pdf"), url::Origin(), kPDFMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  // PDF viewer extension is disabled by PDF content setting.
+  EXPECT_EQ(PluginStatus::kDisabled, plugin_info->status);
+  EXPECT_EQ(kPDFMimeType, plugin_info->actual_mime_type);
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest,
+                       GetPluginInfoForPdfInternalPlugin) {
+  const std::u16string kPluginName =
+      base::UTF8ToUTF16(ChromeContentClient::kPDFInternalPluginName);
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  const std::string kGroupId = "google-chrome-pdf-plugin";
+#else
+  const std::string kGroupId = "chromium-pdf-plugin";
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+
+  PluginInfoPtr plugin_info = GetPluginInfo(GURL("fake.pdf"), url::Origin(),
+                                            pdf::kInternalPluginMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  EXPECT_EQ(PluginStatus::kAllowed, plugin_info->status);
+  EXPECT_EQ(pdf::kInternalPluginMimeType, plugin_info->actual_mime_type);
+
+  // Group ID and name defined by `IDR_PLUGIN_DB_JSON`.
+  EXPECT_EQ(kGroupId, plugin_info->group_identifier);
+  EXPECT_EQ(kPluginName, plugin_info->group_name);
+
+  // `WebPluginInfo` fields.
+  EXPECT_EQ(kPluginName, plugin_info->plugin.name);
+  EXPECT_EQ(base::FilePath(ChromeContentClient::kPDFPluginPath),
+            plugin_info->plugin.path);
+  EXPECT_EQ(u"", plugin_info->plugin.version);
+  EXPECT_EQ(u"Portable Document Format", plugin_info->plugin.desc);
+  EXPECT_EQ(WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS,
+            plugin_info->plugin.type);
+  EXPECT_EQ(0, plugin_info->plugin.pepper_permissions);
+  EXPECT_EQ(WebPluginInfo::kDefaultBackgroundColor,
+            plugin_info->plugin.background_color);
+
+  // Has PDF MIME type.
+  ASSERT_THAT(plugin_info->plugin.mime_types, SizeIs(1));
+
+  WebPluginMimeType mime_type = plugin_info->plugin.mime_types[0];
+  EXPECT_EQ(pdf::kInternalPluginMimeType, mime_type.mime_type);
+  EXPECT_THAT(mime_type.file_extensions, ElementsAre("pdf"));
+  EXPECT_EQ(u"Portable Document Format", mime_type.description);
+  EXPECT_THAT(mime_type.additional_params, IsEmpty());
+}
+
+IN_PROC_BROWSER_TEST_F(PluginInfoHostImplTest,
+                       GetPluginInfoForPdfInternalPluginWhenDisabled) {
+  SetAlwaysOpenPdfExternally();
+
+  PluginInfoPtr plugin_info = GetPluginInfo(GURL("fake.pdf"), url::Origin(),
+                                            pdf::kInternalPluginMimeType);
+  ASSERT_TRUE(plugin_info);
+
+  // Internal PDF plugin is not affected by PDF content setting.
+  EXPECT_EQ(PluginStatus::kAllowed, plugin_info->status);
+  EXPECT_EQ(pdf::kInternalPluginMimeType, plugin_info->actual_mime_type);
+}
+#endif  // BUILDFLAG(ENABLE_PDF)
diff --git a/chrome/browser/plugins/plugin_prefs.h b/chrome/browser/plugins/plugin_prefs.h
index aac9591..2f08a1f5 100644
--- a/chrome/browser/plugins/plugin_prefs.h
+++ b/chrome/browser/plugins/plugin_prefs.h
@@ -69,6 +69,7 @@
  private:
   friend class base::RefCountedThreadSafe<PluginPrefs>;
   friend class PDFIFrameNavigationThrottleTest;
+  friend class PluginInfoHostImplTest;
   friend class PluginPrefsTest;
   friend class PrintPreviewDialogControllerBrowserTest;
 
diff --git a/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc b/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc
index f2dde31..106e345 100644
--- a/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc
+++ b/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc
@@ -249,7 +249,7 @@
     auto key_rotation_launcher =
         enterprise_connectors::KeyRotationLauncher::Create(
             BrowserDMTokenStorage::Get(), GetDeviceManagementService(),
-            GetSharedURLLoaderFactory());
+            GetSharedURLLoaderFactory(), g_browser_process->local_state());
     return std::make_unique<enterprise_connectors::DeviceTrustKeyManagerImpl>(
         std::move(key_rotation_launcher));
   }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index fdca93ea..78a82ccd 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -19,6 +19,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browsing_data/browsing_data_lifetime_policy_handler.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.h"
 #include "chrome/browser/first_party_sets/first_party_sets_pref_names.h"
 #include "chrome/browser/net/disk_cache_dir_policy_handler.h"
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc
index bab873a0..013eed616 100644
--- a/chrome/browser/policy/extension_policy_browsertest.cc
+++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -823,7 +823,10 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Verifies that if the cache entry contains inconsistent extension version,
 // the crx installation fails and download of a new crx file is attempted.
-IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, CrxVersionInconsistencyInCache) {
+//
+// TODO(crbug.com/1357637): Fix this test. It doesn't alway pass.
+IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest,
+                       DISABLED_CrxVersionInconsistencyInCache) {
   base::ScopedAllowBlockingForTesting allow_io;
   // Intercepts the call to download the crx file and responds with the test crx
   // file.
diff --git a/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc b/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc
index d98282b7..0d0ee3b 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc
@@ -84,11 +84,10 @@
         profile_->GetProfileUserName(), "12345"));
     const user_manager::User* user =
         mock_user_manager->AddPublicAccountUser(account_id);
-    ash::ProfileHelper::Get()->SetActiveUserIdForTesting(
-        profile_->GetProfileUserName());
     mock_user_manager->UserLoggedIn(account_id, user->username_hash(),
                                     /*browser_restart=*/false,
                                     /*is_child=*/false);
+    ash::ProfileHelper::Get()->ActiveUserHashChanged(user->username_hash());
     user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
         std::move(mock_user_manager));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/predictors/preconnect_manager_unittest.cc b/chrome/browser/predictors/preconnect_manager_unittest.cc
index 2a6638b..82257de 100644
--- a/chrome/browser/predictors/preconnect_manager_unittest.cc
+++ b/chrome/browser/predictors/preconnect_manager_unittest.cc
@@ -73,20 +73,23 @@
         << "Not all resolve host requests were satisfied";
   }
 
-  void ResolveHost(const net::HostPortPair& host_port,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
                        response_client) override {
-    const std::string& host = host_port.host();
-    EXPECT_FALSE(IsHangingHost(GURL(host)))
+    const std::string& hostname = host->is_host_port_pair()
+                                      ? host->get_host_port_pair().host()
+                                      : host->get_scheme_host_port().host();
+    EXPECT_FALSE(IsHangingHost(GURL(hostname)))
         << " Hosts marked as hanging should not be resolved.";
-    EXPECT_TRUE(resolve_host_clients_
-                    .emplace(ResolveHostClientKey{host, network_isolation_key},
-                             mojo::Remote<network::mojom::ResolveHostClient>(
-                                 std::move(response_client)))
-                    .second);
-    ResolveHostProxy(host);
+    EXPECT_TRUE(
+        resolve_host_clients_
+            .emplace(ResolveHostClientKey{hostname, network_isolation_key},
+                     mojo::Remote<network::mojom::ResolveHostClient>(
+                         std::move(response_client)))
+            .second);
+    ResolveHostProxy(hostname);
   }
 
   void LookUpProxyForURL(const GURL& url,
diff --git a/chrome/browser/predictors/resolve_host_client_impl.cc b/chrome/browser/predictors/resolve_host_client_impl.cc
index f53cbb2..30085e4 100644
--- a/chrome/browser/predictors/resolve_host_client_impl.cc
+++ b/chrome/browser/predictors/resolve_host_client_impl.cc
@@ -18,6 +18,7 @@
 #include "net/dns/public/resolve_error_info.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "url/gurl.h"
+#include "url/scheme_host_port.h"
 
 namespace predictors {
 
@@ -36,9 +37,14 @@
   parameters->purpose =
       network::mojom::ResolveHostParameters::Purpose::kPreconnect;
   resolve_host_start_time_ = base::TimeTicks::Now();
-  network_context->ResolveHost(net::HostPortPair::FromURL(url),
-                               network_isolation_key, std::move(parameters),
-                               receiver_.BindNewPipeAndPassRemote());
+  // Intentionally using a SchemeHostPort. Resolving http:// scheme host will
+  // fail when a HTTPS resource record exists due to DNS-based scheme upgrade
+  // functionality.
+  network_context->ResolveHost(
+      network::mojom::HostResolverHost::NewSchemeHostPort(
+          url::SchemeHostPort(url)),
+      network_isolation_key, std::move(parameters),
+      receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(base::BindOnce(
       &ResolveHostClientImpl::OnConnectionError, base::Unretained(this)));
 }
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker.cc b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker.cc
index 1bf8225..47690ec 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker.cc
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker.cc
@@ -390,9 +390,12 @@
                          weak_factory_.GetWeakPtr())),
       client_remote.InitWithNewPipeAndPassReceiver());
 
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
   profile_->GetDefaultStoragePartition()->GetNetworkContext()->ResolveHost(
-      net::HostPortPair::FromURL(url), nik, std::move(resolve_host_parameters),
-      std::move(client_remote));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair::FromURL(url)),
+      nik, std::move(resolve_host_parameters), std::move(client_remote));
 
   timeout_timer_ = std::make_unique<base::OneShotTimer>(tick_clock_);
   // base::Unretained is safe because |timeout_timer_| is owned by this.
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker_unittest.cc b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker_unittest.cc
index 148dbca1..a3d771a 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker_unittest.cc
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_canary_checker_unittest.cc
@@ -34,16 +34,22 @@
   explicit FakeNetworkContext(
       mojo::PendingReceiver<network::mojom::NetworkContext> receiver)
       : receiver_(this, std::move(receiver)) {}
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
                        response_client) override {
-    EXPECT_TRUE(pending_requests_.find(host) == pending_requests_.end());
+    net::HostPortPair host_port_pair =
+        host->is_host_port_pair()
+            ? host->get_host_port_pair()
+            : net::HostPortPair(host->get_scheme_host_port().host(),
+                                host->get_scheme_host_port().port());
+    EXPECT_TRUE(pending_requests_.find(host_port_pair) ==
+                pending_requests_.end());
     auto request = std::make_unique<ResolveHostRequest>(
-        this, host, std::move(response_client),
+        this, host_port_pair, std::move(response_client),
         std::move(optional_parameters->control_handle));
-    pending_requests_.emplace(host, std::move(request));
+    pending_requests_.emplace(host_port_pair, std::move(request));
     num_requests_made_++;
   }
 
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_from_string_url_loader.cc b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_from_string_url_loader.cc
index 7165b76..2ad9133 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_from_string_url_loader.cc
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_from_string_url_loader.cc
@@ -104,7 +104,8 @@
     return;
   }
 
-  client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle));
+  client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle),
+                             absl::nullopt);
 
   producer_handle_ = std::move(producer_handle);
 
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc
index 426b786..ed3bf8c 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc
@@ -25,6 +25,7 @@
 #include "services/network/public/mojom/tls_socket.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "url/origin.h"
+#include "url/scheme_host_port.h"
 
 namespace {
 
@@ -265,9 +266,12 @@
           url, std::move(callback), also_do_tls_connect)),
       client_remote.InitWithNewPipeAndPassReceiver());
 
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
   profile_->GetDefaultStoragePartition()->GetNetworkContext()->ResolveHost(
-      net::HostPortPair::FromURL(url), nik, std::move(resolve_host_parameters),
-      std::move(client_remote));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair::FromURL(url)),
+      nik, std::move(resolve_host_parameters), std::move(client_remote));
 }
 
 void PrefetchProxyOriginProber::OnDNSResolved(
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.cc b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.cc
index 6e189b0..e499943 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.cc
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.cc
@@ -179,11 +179,13 @@
 
 void PrefetchProxyProxyingURLLoaderFactory::InProgressRequest::
     OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                      mojo::ScopedDataPipeConsumerHandle body) {
+                      mojo::ScopedDataPipeConsumerHandle body,
+                      absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (head) {
     head_ = head->Clone();
   }
-  target_client_->OnReceiveResponse(std::move(head), std::move(body));
+  target_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                    std::move(cached_metadata));
 }
 
 void PrefetchProxyProxyingURLLoaderFactory::InProgressRequest::
@@ -202,11 +204,6 @@
 }
 
 void PrefetchProxyProxyingURLLoaderFactory::InProgressRequest::
-    OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  target_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
-void PrefetchProxyProxyingURLLoaderFactory::InProgressRequest::
     OnTransferSizeUpdated(int32_t transfer_size_diff) {
   target_client_->OnTransferSizeUpdated(transfer_size_diff);
 }
diff --git a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.h b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.h
index fcc5394..33ca6be 100644
--- a/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.h
+++ b/chrome/browser/preloading/prefetch/prefetch_proxy/prefetch_proxy_proxying_url_loader_factory.h
@@ -144,14 +144,15 @@
     // network::mojom::URLLoaderClient:
     void OnReceiveEarlyHints(
         network::mojom::EarlyHintsPtr early_hints) override;
-    void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                           mojo::ScopedDataPipeConsumerHandle body) override;
+    void OnReceiveResponse(
+        network::mojom::URLResponseHeadPtr head,
+        mojo::ScopedDataPipeConsumerHandle body,
+        absl::optional<mojo_base::BigBuffer> cached_metadata) override;
     void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                            network::mojom::URLResponseHeadPtr head) override;
     void OnUploadProgress(int64_t current_position,
                           int64_t total_size,
                           OnUploadProgressCallback callback) override;
-    void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
     void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
     void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.cc b/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.cc
index 62871fe..3dbeb49 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.cc
+++ b/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.cc
@@ -119,7 +119,8 @@
 
 void CacheAliasSearchPrefetchURLLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK(forwarding_client_);
   if (can_fallback_) {
     if (!head->headers) {
@@ -141,8 +142,12 @@
       search_prefetch_service_->UpdateServeTime(resource_request_->url);
   }
 
+  // Cached metadata is not supported for navigation loader.
+  cached_metadata.reset();
+
   can_fallback_ = false;
-  forwarding_client_->OnReceiveResponse(std::move(head), std::move(body));
+  forwarding_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                        absl::nullopt);
 }
 
 void CacheAliasSearchPrefetchURLLoader::OnReceiveRedirect(
@@ -165,11 +170,6 @@
   NOTREACHED();
 }
 
-void CacheAliasSearchPrefetchURLLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  // Do nothing. This is not supported for navigation loader.
-}
-
 void CacheAliasSearchPrefetchURLLoader::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   DCHECK(forwarding_client_);
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.h b/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.h
index 362f3f8..05961cf 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.h
+++ b/chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.h
@@ -56,14 +56,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc b/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
index d4a02fe..9ee51e50 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
+++ b/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
@@ -192,7 +192,8 @@
 
 void StreamingSearchPrefetchURLLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   bool can_be_served = CanServePrefetchRequest(head->headers);
 
   if (is_activated_) {
@@ -204,11 +205,15 @@
     base::UmaHistogramBoolean(histogram_name, can_be_served);
   }
 
+  // Cached metadata is not supported for navigation loader.
+  cached_metadata.reset();
+
   // Once we are using the fallback path, just forward calls.
   if (is_in_fallback_) {
     DCHECK(!streaming_prefetch_request_);
     DCHECK(forwarding_client_);
-    forwarding_client_->OnReceiveResponse(std::move(head), std::move(body));
+    forwarding_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                          absl::nullopt);
     return;
   }
 
@@ -231,7 +236,8 @@
   }
 
   if (forwarding_client_) {
-    forwarding_client_->OnReceiveResponse(std::move(head), std::move(body));
+    forwarding_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                          absl::nullopt);
     return;
   }
 
@@ -282,11 +288,6 @@
   NOTREACHED();
 }
 
-void StreamingSearchPrefetchURLLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  // Do nothing. This is not supported for navigation loader.
-}
-
 void StreamingSearchPrefetchURLLoader::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   if (forwarding_client_) {
@@ -350,8 +351,8 @@
       base::BindRepeating(&StreamingSearchPrefetchURLLoader::OnHandleReady,
                           weak_factory_.GetWeakPtr()));
 
-  forwarding_client_->OnReceiveResponse(std::move(resource_response_),
-                                        std::move(consumer_handle));
+  forwarding_client_->OnReceiveResponse(
+      std::move(resource_response_), std::move(consumer_handle), absl::nullopt);
 
   PushData();
 }
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h b/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
index 339db17d..22da09d 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
+++ b/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
@@ -78,14 +78,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 2025e4e..97afe423 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -666,12 +666,14 @@
   // Create an ephemeral profile.
   base::FilePath path_profile2 =
       profile_manager->GenerateNextProfileDirectoryPath();
-  base::RunLoop run_loop;
-  profile_manager->CreateProfileAsync(
-      path_profile2, base::BindOnce(&EphemeralProfileCreationComplete,
-                                    run_loop.QuitWhenIdleClosure()));
+  {
+    base::RunLoop run_loop;
+    profile_manager->CreateProfileAsync(
+        path_profile2, base::BindOnce(&EphemeralProfileCreationComplete,
+                                      run_loop.QuitWhenIdleClosure()));
 
-  run_loop.Run();
+    run_loop.Run();
+  }
 
   BrowserList* browser_list = BrowserList::GetInstance();
   ASSERT_EQ(initial_profile_count + 1U, storage.GetNumberOfProfiles());
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index c5d51e1..a0db558 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -74,6 +74,7 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_names.h"
@@ -255,8 +256,7 @@
   void RegisterUser(const AccountId& account_id) {
     ash::ProfileHelper* profile_helper = ash::ProfileHelper::Get();
     const std::string user_id_hash =
-        profile_helper->GetUserIdHashByUserIdForTesting(
-            account_id.GetUserEmail());
+        user_manager::FakeUserManager::GetFakeUsernameHash(account_id);
     user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
                                                    false /* browser_restart */,
                                                    false /* is_child */);
@@ -278,7 +278,7 @@
     const AccountId account_id =
         AccountId::FromUserEmailGaiaId(user_email, "1");
     const std::string user_id_hash =
-        profile_helper->GetUserIdHashByUserIdForTesting(user_email);
+        user_manager::FakeUserManager::GetFakeUsernameHash(account_id);
     const base::FilePath dest_path =
         profile_helper->GetProfilePathByUserIdHash(user_id_hash);
 
@@ -409,13 +409,13 @@
       ProfileManager::GetLastUsedProfile()->IsSameOrParent(signin_profile));
 
   // User signs in but user profile loading has not started.
-  const std::string user_id = "test-user@example.com";
-  const std::string gaia_id = "0123456789";
+  const AccountId account_id =
+      AccountId::FromUserEmailGaiaId("test-user@example.com", "0123456789");
   const std::string user_id_hash =
-      ProfileHelper::Get()->GetUserIdHashByUserIdForTesting(user_id);
-  user_manager::UserManager::Get()->UserLoggedIn(
-      AccountId::FromUserEmailGaiaId(user_id, gaia_id), user_id_hash,
-      false /* browser_restart */, false /* is_child */);
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id);
+  user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
+                                                 false /* browser_restart */,
+                                                 false /* is_child */);
 
   // Sign-in profile should be returned at this stage. Otherwise, login code
   // ends up in an invalid state. Strange things as in http://crbug.com/728683
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index 09a8c1e..ee918ea 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -83,6 +83,7 @@
 
   if (is_win || is_mac || is_linux || is_fuchsia) {
     public_deps += [
+      "app_home:resources",
       "app_settings:resources",
       "ntp4:apps_resources",
     ]
diff --git a/chrome/browser/resources/app_home/BUILD.gn b/chrome/browser/resources/app_home/BUILD.gn
new file mode 100644
index 0000000..0fcce60b
--- /dev/null
+++ b/chrome/browser/resources/app_home/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chrome/browser/resources/tools/build_webui.gni")
+
+assert(!is_android)
+assert(!is_chromeos)
+
+build_webui("build") {
+  grd_prefix = "app_home"
+
+  static_files = [ "app_home.html" ]
+
+  non_web_component_files = [ "browser_proxy.ts" ]
+
+  mojo_files_deps =
+      [ "//chrome/browser/ui/webui/app_home:mojo_bindings_webui_js" ]
+
+  mojo_files = [ "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/app_home/app_home.mojom-webui.js" ]
+
+  ts_composite = true
+  ts_deps = [
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources:library",
+  ]
+}
diff --git a/chrome/browser/resources/app_home/DIR_METADATA b/chrome/browser/resources/app_home/DIR_METADATA
new file mode 100644
index 0000000..6f93c68
--- /dev/null
+++ b/chrome/browser/resources/app_home/DIR_METADATA
@@ -0,0 +1 @@
+mixins: "//chrome/browser/web_applications/COMMON_METADATA"
diff --git a/chrome/browser/resources/app_home/OWNERS b/chrome/browser/resources/app_home/OWNERS
new file mode 100644
index 0000000..1255a2c
--- /dev/null
+++ b/chrome/browser/resources/app_home/OWNERS
@@ -0,0 +1 @@
+file://chrome/browser/web_applications/OWNERS
diff --git a/chrome/browser/resources/app_home/app_home.html b/chrome/browser/resources/app_home/app_home.html
new file mode 100644
index 0000000..a082f98
--- /dev/null
+++ b/chrome/browser/resources/app_home/app_home.html
@@ -0,0 +1,11 @@
+<!-- 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. -->
+
+<!doctype html>
+<html>
+  <head>
+  </head>
+  <body>
+  </body>
+</html>
diff --git a/chrome/browser/resources/app_home/browser_proxy.ts b/chrome/browser/resources/app_home/browser_proxy.ts
new file mode 100644
index 0000000..cd2b942
--- /dev/null
+++ b/chrome/browser/resources/app_home/browser_proxy.ts
@@ -0,0 +1,31 @@
+// 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 {PageCallbackRouter, PageHandlerFactory, PageHandlerInterface, PageHandlerRemote} from './app_home.mojom-webui.js';
+
+export class BrowserProxy {
+  callbackRouter: PageCallbackRouter;
+  handler: PageHandlerInterface;
+
+  constructor() {
+    this.callbackRouter = new PageCallbackRouter();
+
+    this.handler = new PageHandlerRemote();
+
+    const factory = PageHandlerFactory.getRemote();
+    factory.createPageHandler(
+        this.callbackRouter.$.bindNewPipeAndPassRemote(),
+        (this.handler as PageHandlerRemote).$.bindNewPipeAndPassReceiver());
+  }
+
+  static getInstance(): BrowserProxy {
+    return instance || (instance = new BrowserProxy());
+  }
+
+  static setInstance(obj: BrowserProxy) {
+    instance = obj;
+  }
+}
+
+let instance: BrowserProxy|null = null;
diff --git a/chrome/browser/resources/app_home/tsconfig_base.json b/chrome/browser/resources/app_home/tsconfig_base.json
new file mode 100644
index 0000000..3e71f763
--- /dev/null
+++ b/chrome/browser/resources/app_home/tsconfig_base.json
@@ -0,0 +1,9 @@
+{
+  "extends": "../../../../tools/typescript/tsconfig_base.json",
+  "compilerOptions": {
+    "allowJs": true,
+    "noUncheckedIndexedAccess": false,
+    "noUnusedLocals": false,
+    "strictPropertyInitialization": false
+  }
+}
diff --git a/chrome/browser/resources/app_settings/BUILD.gn b/chrome/browser/resources/app_settings/BUILD.gn
index 6b03ab0..ea07abf8 100644
--- a/chrome/browser/resources/app_settings/BUILD.gn
+++ b/chrome/browser/resources/app_settings/BUILD.gn
@@ -2,71 +2,27 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/browser/resources/tools/build_webui.gni")
 import("//chrome/common/features.gni")
-import("//tools/grit/grit_rule.gni")
-import("//tools/polymer/html_to_wrapper.gni")
-import("//tools/typescript/ts_library.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
-import("./app_settings.gni")
 
 assert(is_win || is_mac || is_linux || is_fuchsia)
 
-resources_grd_file = "$target_gen_dir/resources.grd"
+build_webui("build") {
+  grd_prefix = "app_settings"
 
-html_to_wrapper("html_wrapper_files") {
-  in_files = html_files
-}
+  static_files = [ "web_app_settings.html" ]
 
-ts_library("build_ts") {
-  root_dir = target_gen_dir
-  out_dir = "$target_gen_dir/tsc"
-  composite = true
-  tsconfig_base = "tsconfig_base.json"
-  in_files = ts_files + html_wrapper_files + [ "app_management.mojom-webui.js" ]
-  deps = [
+  web_component_files = [ "app.ts" ]
+
+  non_web_component_files = [ "web_app_settings.ts" ]
+
+  mojo_files_deps = [ "//ui/webui/resources/cr_components/app_management:mojo_bindings_js__generator" ]
+  mojo_files = [ "$root_gen_dir/mojom-webui/ui/webui/resources/cr_components/app_management/app_management.mojom-webui.js" ]
+
+  ts_composite = true
+  ts_deps = [
     "//third_party/polymer/v3_0:library",
     "//ui/webui/resources:library",
     "//ui/webui/resources/cr_components/app_management:build_ts",
   ]
-  extra_deps = [
-    ":copy_mojo",
-    ":copy_src",
-    ":html_wrapper_files",
-  ]
-}
-
-copy("copy_src") {
-  sources = ts_files
-  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
-}
-
-copy("copy_mojo") {
-  deps = [ "//ui/webui/resources/cr_components/app_management:mojo_bindings_js__generator" ]
-  sources = [ "$root_gen_dir/mojom-webui/ui/webui/resources/cr_components/app_management/app_management.mojom-webui.js" ]
-  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
-}
-
-generate_grd("build_grd") {
-  grd_prefix = "app_settings"
-  out_grd = resources_grd_file
-  input_files = [ "web_app_settings.html" ]
-  input_files_base_dir = rebase_path(".", "//")
-  deps = [ ":build_ts" ]
-  manifest_files =
-      filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
-}
-
-grit("resources") {
-  defines = chrome_grit_defines
-
-  enable_input_discovery_for_gn_analyze = false
-  source = resources_grd_file
-  deps = [ ":build_grd" ]
-  outputs = [
-    "grit/app_settings_resources.h",
-    "grit/app_settings_resources_map.cc",
-    "grit/app_settings_resources_map.h",
-    "app_settings_resources.pak",
-  ]
-  output_dir = "$root_gen_dir/chrome"
 }
diff --git a/chrome/browser/resources/app_settings/app_settings.gni b/chrome/browser/resources/app_settings/app_settings.gni
deleted file mode 100644
index e49a08d1..0000000
--- a/chrome/browser/resources/app_settings/app_settings.gni
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2022 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-_non_web_component_files = [ "web_app_settings.ts" ]
-
-# Files holding a Polymer element definition and have an equivalent .html file.
-_web_component_files = [ "app.ts" ]
-
-# Files that are passed as input to html_to_wrapper().
-html_files = []
-foreach(f, _web_component_files) {
-  html_files += [ string_replace(f, ".ts", ".html") ]
-}
-
-# Files that are generated by html_to_wrapper().
-html_wrapper_files = []
-foreach(f, html_files) {
-  html_wrapper_files += [ f + ".ts" ]
-}
-
-ts_files = _non_web_component_files + _web_component_files
diff --git a/chrome/browser/resources/bookmarks/command_manager.ts b/chrome/browser/resources/bookmarks/command_manager.ts
index f24552ca..0bbc342 100644
--- a/chrome/browser/resources/bookmarks/command_manager.ts
+++ b/chrome/browser/resources/bookmarks/command_manager.ts
@@ -11,7 +11,6 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import 'chrome://resources/polymer/v3_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
 import './edit_dialog.js';
 import './shared_style.css.js';
 import './strings.m.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js
index 21067c4c..6ec8c64 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js
@@ -2151,7 +2151,7 @@
     const allMsgs = msgs.concat(delayedMsgs);
     for (const msg of allMsgs) {
       if (msg.msgId) {
-        const text = Msgs.getMsg(msg.msgId);
+        const text = Msgs.getMsg(msg.msgId, msg.subs);
         this.append_(buff, text, {annotation: [msg.props]});
         ruleStr.write('hint_: ' + text + '\n');
       } else if (msg.text) {
@@ -2229,6 +2229,7 @@
    * @param {EventType|OutputEventType} type
    * @return {!Array<{text: (string|undefined),
    *           msgId: (string|undefined),
+   *           subs: (Array<string>|undefined),
    *           outputFormat: (string|undefined)}>} Note that the above caller
    * expects one and only one key be set.
    * @private
@@ -2247,7 +2248,14 @@
       const isWithinVirtualKeyboard = AutomationUtil.getAncestors(node).find(
           n => n.role === RoleType.KEYBOARD);
       if (AutomationPredicate.clickable(node) && !isWithinVirtualKeyboard) {
-        ret.push({msgId: 'hint_double_tap'});
+        if (node.doDefaultLabel) {
+          ret.push({
+            msgId: 'hint_double_tap_with_label',
+            subs: [node.doDefaultLabel],
+          });
+        } else {
+          ret.push({msgId: 'hint_double_tap'});
+        }
       }
 
       const enteredVirtualKeyboard =
@@ -2292,7 +2300,12 @@
     if (AutomationPredicate.checkable(node)) {
       ret.push({msgId: 'hint_checkable'});
     } else if (AutomationPredicate.clickable(node)) {
-      ret.push({msgId: 'hint_clickable'});
+      if (node.doDefaultLabel) {
+        ret.push(
+            {msgId: 'hint_clickable_with_label', subs: [node.doDefaultLabel]});
+      } else {
+        ret.push({msgId: 'hint_clickable'});
+      }
     }
 
     if (node.autoComplete === 'list' || node.autoComplete === 'both' ||
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js
index d9395e9e..423ff35 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js
@@ -1368,6 +1368,29 @@
       o.speechOutputForTest);
 });
 
+AX_TEST_F(
+    'ChromeVoxOutputE2ETest', 'DelayHintWithActionLabel', async function() {
+      const site = `<button>OK</button>`;
+      const root = await this.runWithLoadedTree(site);
+      const button = root.children[0];
+      const range = CursorRange.fromNode(button);
+
+      let o = new Output().withSpeech(range, null, 'navigate');
+
+      // Force a few properties to be set so that hints are triggered.
+      Object.defineProperty(button, 'clickable', {get: () => true});
+
+      Object.defineProperty(
+          button, 'doDefaultLabel', {get: () => 'click label'});
+      o = new Output().withSpeech(range, null, 'navigate');
+      assertEqualsJSON(
+          {
+            string_: 'OK|Press Search+Space to click label',
+            spans_: [{value: {delay: true}, start: 3, end: 36}],
+          },
+          o.speechOutputForTest);
+    });
+
 AX_TEST_F('ChromeVoxOutputE2ETest', 'WithoutFocusRing', async function() {
   const site = `<button></button>`;
   const root = await this.runWithLoadedTree(site);
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp b/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp
index c7a634c..cea0351e 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp
+++ b/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp
@@ -2330,6 +2330,12 @@
   <message desc="A hint to the user that the current control is clickable." name="IDS_CHROMEVOX_HINT_CLICKABLE">
     Press Search+Space to activate
   </message>
+  <message desc="A hint to the user that the current control is clickable. 'label' will explain what will happen when the user clicks." name="IDS_CHROMEVOX_HINT_CLICKABLE_WITH_LABEL" is_accessibility_with_no_ui="true">
+    Press Search+Space to <ph name="label">$1<ex>switch</ex></ph>
+  </message>
+  <message desc="A hint to the user that the current control can be double tapped. 'label' will explain what will happen when the user double taps." name="IDS_CHROMEVOX_HINT_DOUBLE_TAP_WITH_LABEL" is_accessibility_with_no_ui="true">
+    Double tap to <ph name="label">$1<ex>switch</ex></ph>
+  </message>
   <message desc="A hint to the user that the current control has a list of auto completions." name="IDS_CHROMEVOX_HINT_AUTOCOMPLETE_LIST">
     Press up or down arrow for auto completions
   </message>
diff --git a/chrome/browser/resources/chromeos/arc_support/OWNERS b/chrome/browser/resources/chromeos/arc_support/OWNERS
index ae82551..c7f559e 100644
--- a/chrome/browser/resources/chromeos/arc_support/OWNERS
+++ b/chrome/browser/resources/chromeos/arc_support/OWNERS
@@ -2,4 +2,4 @@
 mhasank@chromium.org
 
 per-file recommend_app_list_view.*=rrsilva@google.com
-per-file recommend_app_list_view.*=rsorokin@chromium.org
+per-file recommend_app_list_view.*=rsorokin@google.com
diff --git a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
index 1d14181..eee10c17 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
+++ b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
@@ -307,8 +307,9 @@
     ":events",
     ":types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_type_check("closure_compile") {
diff --git a/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn b/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn
index 9280ac6c..e857d75 100644
--- a/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn
+++ b/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn
@@ -52,8 +52,9 @@
   deps = [
     "//chrome/browser/resources/gaia_auth_host:authenticator.m",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 html_to_js("web_components") {
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn b/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
index 28b38d5..f1b99af0 100644
--- a/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
+++ b/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
@@ -70,7 +70,6 @@
     "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_config.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
@@ -80,6 +79,7 @@
     "$externs_path/chrome_extensions.js",
     "$externs_path/chrome_send.js",
     "$externs_path/networking_private.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
   ]
   extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
 }
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js
index a2734e9..f2d9700 100644
--- a/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js
+++ b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js
@@ -6,11 +6,11 @@
 import 'chrome://resources/cr_components/chromeos/network/network_icon.m.js';
 import 'chrome://resources/cr_components/chromeos/network/network_shared_css.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_page_host_style.css.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './strings.m.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index 8b5eff2..3c32d16 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -271,8 +271,6 @@
     "screens/common/wrong_hwid.m.js",
     "screens/login/active_directory_password_change.m.js",
     "screens/login/gaia_password_changed.m.js",
-    "screens/login/lacros_data_migration.m.js",
-    "screens/login/management_transition.m.js",
     "screens/login/offline_login.m.js",
     "screens/login/checking_downloading_update.m.js",
     "screens/login/update_required_card.m.js",
@@ -309,6 +307,8 @@
     "screens/common/pin_setup.js",
     "screens/common/saml_confirm_password.js",
     "screens/login/encryption_migration.js",
+    "screens/login/lacros_data_migration.js",
+    "screens/login/management_transition.js",
     "screens/oobe/auto_enrollment_check.js",
   ]
 }
diff --git a/chrome/browser/resources/chromeos/login/components/BUILD.gn b/chrome/browser/resources/chromeos/login/components/BUILD.gn
index 1a145c2..0751730 100644
--- a/chrome/browser/resources/chromeos/login/components/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/components/BUILD.gn
@@ -92,8 +92,9 @@
   sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/components/gaia_button.m.js" ]
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
   extra_deps = [ ":gaia_button_module" ]
 }
 
diff --git a/chrome/browser/resources/chromeos/login/components/dialogs/BUILD.gn b/chrome/browser/resources/chromeos/login/components/dialogs/BUILD.gn
index 371e72f..6eaff7f 100644
--- a/chrome/browser/resources/chromeos/login/components/dialogs/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/components/dialogs/BUILD.gn
@@ -66,9 +66,10 @@
     "../behaviors:oobe_i18n_behavior.m",
     "../buttons:oobe_text_button.m",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:cr.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
   extra_deps = [ ":oobe_modal_dialog_module" ]
 }
 
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html
index 42bece7..6f26088 100644
--- a/chrome/browser/resources/chromeos/login/oobe.html
+++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -15,6 +15,10 @@
   <script type="module" src="oobe.js"></script>
 </head>
 
+<custom-style>
+  <style include="oobe-flex-layout-styles"></style>
+</custom-style>
+
 <body class="oobe-display chromeos" style="font-family:$i18n{fontfamily}">
   <div id="api-keys-notice-container" hidden>
     <div id="api-keys-notice"></div>
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js
index c146caf3..a9c31a2f 100644
--- a/chrome/browser/resources/chromeos/login/oobe.js
+++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -13,6 +13,7 @@
 import 'chrome://oobe/test_api/test_api.m.js';
 import {commonScreensList, loginScreensList, oobeScreensList} from 'chrome://oobe/screens.js';
 import {MultiTapDetector} from './multi_tap_detector.m.js';
+import './components/common_styles/oobe_flex_layout_styles.m.js';
 // clang-format on
 
 /**
diff --git a/chrome/browser/resources/chromeos/login/screens.js b/chrome/browser/resources/chromeos/login/screens.js
index d6fca34b..454f395 100644
--- a/chrome/browser/resources/chromeos/login/screens.js
+++ b/chrome/browser/resources/chromeos/login/screens.js
@@ -45,8 +45,8 @@
 import './screens/login/active_directory_password_change.m.js';
 import './screens/login/encryption_migration.js';
 import './screens/login/gaia_password_changed.m.js';
-import './screens/login/lacros_data_migration.m.js';
-import './screens/login/management_transition.m.js';
+import './screens/login/lacros_data_migration.js';
+import './screens/login/management_transition.js';
 import './screens/login/offline_login.m.js';
 import './screens/login/update_required_card.m.js';
 // SCREENS USED DURING THE OOBE FLOW
diff --git a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
index 090b884..c865883 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
@@ -688,7 +688,9 @@
   onAcceptClick_() {
     this.RecordUMAHistogramForUserActions_(
         ConsolidatedConsentUserAction.ACCEPT_BUTTON);
-    chrome.send('ToSAccept', [
+
+    this.userActed([
+      'tos-accept',
       this.usageChecked,
       this.backupChecked,
       this.locationChecked,
diff --git a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.html b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.html
index c4bc3ad..3f66545 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.html
@@ -30,8 +30,8 @@
       }
     </style>
     <oobe-adaptive-dialog id="setupFingerprint" role="dialog" for-step="start"
-        footer-shrinkable
-        aria-label$="[[i18nDynamic(locale, 'setupFingerprintScreenAriaLabel')]]">
+        footer-shrinkable aria-label$="[[getAriaLabel_(locale, hasAriaLabel_,
+                                                       isChildAccount_)]]">
       <h1 slot="title" hidden="[[isChildAccount_]]">
         [[i18nDynamic(locale, 'setupFingerprintScreenTitle')]]
       </h1>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js
index df9f134e..5e45926 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js
@@ -52,6 +52,9 @@
  */
 FingerprintSetupBase.$;
 
+/**
+ * @polymer
+ */
 class FingerprintSetup extends FingerprintSetupBase {
   static get is() {
     return 'fingerprint-setup-element';
@@ -68,6 +71,7 @@
        */
       percentComplete_: {
         type: Number,
+        value: 0,
         observer: 'onProgressChanged_',
       },
 
@@ -76,6 +80,7 @@
        */
       complete_: {
         type: Boolean,
+        value: false,
         computed: 'enrollIsComplete_(percentComplete_)',
       },
 
@@ -84,6 +89,7 @@
        */
       canAddFinger: {
         type: Boolean,
+        value: true,
       },
 
       /**
@@ -92,6 +98,7 @@
        */
       scanResult_: {
         type: Number,
+        value: FingerprintResultType.SUCCESS,
       },
 
       /**
@@ -99,18 +106,21 @@
        */
       isChildAccount_: {
         type: Boolean,
+        value: false,
+      },
+      /**
+       * Indicates whether the fingerprint sensor location has a specific
+       * aria-label.
+       */
+      hasAriaLabel_: {
+        type: Boolean,
+        value: false,
       },
     };
   }
 
   constructor() {
     super();
-    this.UI_STEPS = FingerprintUIState;
-    this.percentComplete_ = 0;
-    this.complete_ = false;
-    this.canAddFinger = true;
-    this.scanResult_ = FingerprintResultType.SUCCESS;
-    this.isChildAccount_ = false;
   }
 
   /** @override */
@@ -118,6 +128,10 @@
     return ['onEnrollScanDone', 'enableAddAnotherFinger'];
   }
 
+  get UI_STEPS() {
+    return FingerprintUIState;
+  }
+
   /** @override */
   ready() {
     super.ready();
@@ -136,6 +150,7 @@
 
   onBeforeShow(data) {
     this.isChildAccount_ = data['isChildAccount'];
+    this.hasAriaLabel_ = data['hasAriaLabel'];
     this.setAnimationState_(true);
   }
 
@@ -259,6 +274,24 @@
 
     this.$.arc.setProgress(oldValue, newValue, newValue === 100);
   }
+
+  /**
+   * Returns the aria-label for the dialog.
+   * New fingerprint positions do not require aria-labels since the exact
+   * fingerprint sensor location is included in the subtitle, for these
+   * locations use the screen title as the aria-label for the dialog.
+   * @private
+   */
+  getAriaLabel_(locale, hasAriaLabel, isChildAccount) {
+    if (hasAriaLabel) {
+      return this.i18n('setupFingerprintScreenAriaLabel');
+    }
+
+    if (isChildAccount) {
+      return this.i18n('setupFingerprintScreenTitleForChild');
+    }
+    return this.i18n('setupFingerprintScreenTitle');
+  }
 }
 
 customElements.define(FingerprintSetup.is, FingerprintSetup);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
index 4e55a3ed..261f1a6 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
@@ -140,7 +140,8 @@
    */
   onSettingsSaveAndContinue_(e, opted_in) {
     assert(e.composedPath());
-    chrome.send('login.SyncConsentScreen.continue', [
+    this.userActed([
+      'continue',
       opted_in,
       this.$.reviewSettingsBox.checked,
       this.getConsentDescription_(),
diff --git a/chrome/browser/resources/chromeos/login/screens/login/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/login/BUILD.gn
index fbc878b..11bf7844 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/screens/login/BUILD.gn
@@ -13,8 +13,6 @@
     ":active_directory_password_change_module",
     ":checking_downloading_update_module",
     ":gaia_password_changed_module",
-    ":lacros_data_migration_module",
-    ":management_transition_module",
     ":offline_login_module",
     ":update_required_card_module",
   ]
@@ -28,8 +26,8 @@
     ":checking_downloading_update.m",
     ":encryption_migration",
     ":gaia_password_changed.m",
-    ":lacros_data_migration.m",
-    ":management_transition.m",
+    ":lacros_data_migration",
+    ":management_transition",
     ":offline_login.m",
     ":update_required_card.m",
   ]
@@ -83,19 +81,19 @@
   extra_deps = [ ":gaia_password_changed_module" ]
 }
 
-js_library("lacros_data_migration.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.m.js" ]
+js_library("lacros_data_migration") {
+  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js" ]
   deps = [
     "../../components:oobe_slide.m",
     "../../components/behaviors:login_screen_behavior.m",
     "../../components/behaviors:oobe_dialog_host_behavior.m",
     "../../components/dialogs:oobe_loading_dialog.m",
   ]
-  extra_deps = [ ":lacros_data_migration_module" ]
+  extra_deps = [ ":web_components" ]
 }
 
-js_library("management_transition.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/login/management_transition.m.js" ]
+js_library("management_transition") {
+  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/login/management_transition.js" ]
   deps = [
     "../../components/behaviors:login_screen_behavior.m",
     "../../components/behaviors:multi_step_behavior.m",
@@ -104,7 +102,7 @@
     "../../components/buttons:oobe_text_button.m",
     "../../components/dialogs:oobe_modal_dialog.m",
   ]
-  extra_deps = [ ":management_transition_module" ]
+  extra_deps = [ ":web_components" ]
 }
 
 js_library("offline_login.m") {
@@ -116,8 +114,9 @@
     "../../components/buttons:oobe_next_button.m",
     "../../components/buttons:oobe_text_button.m",
     "../../components/dialogs:oobe_modal_dialog.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
   extra_deps = [ ":offline_login_module" ]
 }
 
@@ -169,27 +168,11 @@
   namespace_rewrites = oobe_namespace_rewrites
 }
 
-polymer_modulizer("lacros_data_migration") {
-  js_file = "lacros_data_migration.js"
-  html_file = "lacros_data_migration.html"
-  html_type = "dom-module"
-  auto_imports = oobe_auto_imports
-  namespace_rewrites = oobe_namespace_rewrites
-}
-
-polymer_modulizer("management_transition") {
-  js_file = "management_transition.js"
-  html_file = "management_transition.html"
-  html_type = "dom-module"
-  auto_imports = oobe_auto_imports
-  namespace_rewrites = oobe_namespace_rewrites
-}
-
 polymer_modulizer("offline_login") {
   js_file = "offline_login.js"
   html_file = "offline_login.html"
   html_type = "dom-module"
-  auto_imports = oobe_auto_imports + [ "ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html|CrDialogElement" ]
+  auto_imports = oobe_auto_imports
   migrated_imports = oobe_migrated_imports
   namespace_rewrites = oobe_namespace_rewrites
 }
@@ -211,5 +194,9 @@
 }
 
 html_to_js("web_components") {
-  js_files = [ "encryption_migration.js" ]
+  js_files = [
+    "encryption_migration.js",
+    "lacros_data_migration.js",
+    "management_transition.js",
+  ]
 }
diff --git a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html
index 21150b4e..fc18d82 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html
+++ b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html
@@ -2,120 +2,98 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="oobe-dialog-host-styles">
+  <!-- TODO(crbug.com/1296174): merge following with other copies. -->
+  .update-illustration {
+      height: 264px;
+      width: 264px;
+  }
 
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
+  .slide-view {
+      border: 1px solid var(--google-grey-200);
+      border-radius: 16px;
+      height: 380px;
+      margin: auto;
+      overflow: hidden;
+      width: 380px;
+  }
+</style>
+<oobe-adaptive-dialog id="progressDialog" for-step="progress" id="dialog"
+                      role="dialog">
+  <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon>
+  <h1 slot="title">[[i18nDynamic(locale, 'lacrosDataMigrationTitle')]]</h1>
+  <paper-progress slot="progress" min="0" max="100"
+      value="[[progressValue_]]">
+  </paper-progress>
+  <div slot="subtitle">
+    <p role="status" aria-live="polite">
+      [[i18nDynamic(locale, 'lacrosDataMigrationSubtitle', progressValue_)]]
+    </p>
+    <p hidden="[[!canSkip_]]">
+      [[i18nDynamic(locale, 'lacrosDataMigrationSkipSuggestion')]]
+    </p>
+  </div>
+  <div slot="content" class="flex layout vertical center center-justified"
+       hidden="[[lowBatteryStatus_]]" id="updating">
+    <img src="/images/update_boot.svg"
+        class="oobe-illustration" aria-hidden="true">
+  </div>
+  <div hidden="[[!lowBatteryStatus_]]" class="slide-view"
+       slot="content", id="lowBattery">
+    <oobe-slide is-warning>
+      <img slot="slide-img" class="update-illustration oobe-illustration"
+           srcset="images/update-charge.svg" aria-hidden="true">
+      <div slot="title">
+        [[i18nDynamic(locale, 'batteryWarningTitle')]]
+      </div>
+      <div slot="text">
+        [[i18nDynamic(locale, 'batteryWarningText')]]
+      </div>
+    </oobe-slide>
+  </div>
 
-<link rel="import" href="../../components/behaviors/login_screen_behavior.html">
-<link rel="import" href="../../components/behaviors/multi_step_behavior.html">
-<link rel="import" href="../../components/behaviors/oobe_dialog_host_behavior.html">
-<link rel="import" href="../../components/behaviors/oobe_i18n_behavior.html">
-<link rel="import" href="../../components/common_styles/oobe_dialog_host_styles.html">
-<link rel="import" href="../../components/dialogs/oobe_loading_dialog.html">
-<link rel="import" href="../../components/oobe_icons.html">
-<link rel="import" href="../../components/oobe_slide.html">
+  <!-- Skip button -->
+  <div slot="bottom-buttons" class="flex layout horizontal end-justified">
+    <oobe-text-button id="skipButton"  hidden="[[!canSkip_]]"
+        on-click="onSkipButtonClicked_"
+        text-key="lacrosDataMigrationSkipButton">
+    </oobe-text-button>
+  </div>
+</oobe-adaptive-dialog>
+<oobe-adaptive-dialog id="errorDialog" for-step="error" role="dialog"
+                      footer-shrinkable>
+  <iron-icon slot="icon" icon="oobe-32:warning"></iron-icon>
+  <h1 slot="title">
+    [[i18nDynamic(locale, 'lacrosDataMigrationErrorTitle')]]
+  </h1>
+  <div slot="subtitle" id="lowDiskSpaceError"
+       hidden="[[!requiredSizeStr_]]">
+    <p>
+      [[i18nDynamic(locale, 'lacrosDataMigrationErrorLowDiskSpace',
+                    requiredSizeStr_)]]
+    </p>
+  </div>
+  <div slot="subtitle" id="genericError" hidden="[[requiredSizeStr_]]">
+    <p>
+      [[i18nDynamic(locale, 'lacrosDataMigrationErrorSubtitle')]]
+    </p>
+  </div>
+  <div slot="content" class="flex layout vertical center center-justified">
+    <img src="/images/error.svg"
+         class="oobe-illustration" aria-hidden="true">
+  </div>
 
-<dom-module id="lacros-data-migration-element">
-  <template>
-    <style include="oobe-dialog-host-styles">
-      <!-- TODO(crbug.com/1296174): merge following with other copies. -->
-      .update-illustration {
-          height: 264px;
-          width: 264px;
-      }
-
-      .slide-view {
-          border: 1px solid var(--google-grey-200);
-          border-radius: 16px;
-          height: 380px;
-          margin: auto;
-          overflow: hidden;
-          width: 380px;
-      }
-    </style>
-    <oobe-adaptive-dialog id="progressDialog" for-step="progress" id="dialog"
-                          role="dialog">
-      <iron-icon slot="icon" icon="oobe-32:googleg"></iron-icon>
-      <h1 slot="title">[[i18nDynamic(locale, 'lacrosDataMigrationTitle')]]</h1>
-      <paper-progress slot="progress" min="0" max="100"
-          value="[[progressValue_]]">
-      </paper-progress>
-      <div slot="subtitle">
-        <p role="status" aria-live="polite">
-          [[i18nDynamic(locale, 'lacrosDataMigrationSubtitle', progressValue_)]]
-        </p>
-        <p hidden="[[!canSkip_]]">
-          [[i18nDynamic(locale, 'lacrosDataMigrationSkipSuggestion')]]
-        </p>
-      </div>
-      <div slot="content" class="flex layout vertical center center-justified"
-           hidden="[[lowBatteryStatus_]]" id="updating">
-        <img src="/images/update_boot.svg"
-            class="oobe-illustration" aria-hidden="true">
-      </div>
-      <div hidden="[[!lowBatteryStatus_]]" class="slide-view"
-           slot="content", id="lowBattery">
-        <oobe-slide is-warning>
-          <img slot="slide-img" class="update-illustration oobe-illustration"
-               srcset="images/update-charge.svg" aria-hidden="true">
-          <div slot="title">
-            [[i18nDynamic(locale, 'batteryWarningTitle')]]
-          </div>
-          <div slot="text">
-            [[i18nDynamic(locale, 'batteryWarningText')]]
-          </div>
-        </oobe-slide>
-      </div>
-
-      <!-- Skip button -->
-      <div slot="bottom-buttons" class="flex layout horizontal end-justified">
-        <oobe-text-button id="skipButton"  hidden="[[!canSkip_]]"
-            on-click="onSkipButtonClicked_"
-            text-key="lacrosDataMigrationSkipButton">
-        </oobe-text-button>
-      </div>
-    </oobe-adaptive-dialog>
-
-    <oobe-adaptive-dialog id="errorDialog" for-step="error" role="dialog"
-                          footer-shrinkable>
-      <iron-icon slot="icon" icon="oobe-32:warning"></iron-icon>
-      <h1 slot="title">
-        [[i18nDynamic(locale, 'lacrosDataMigrationErrorTitle')]]
-      </h1>
-      <div slot="subtitle" id="lowDiskSpaceError"
-           hidden="[[!requiredSizeStr_]]">
-        <p>
-          [[i18nDynamic(locale, 'lacrosDataMigrationErrorLowDiskSpace',
-                        requiredSizeStr_)]]
-        </p>
-      </div>
-      <div slot="subtitle" id="genericError" hidden="[[requiredSizeStr_]]">
-        <p>
-          [[i18nDynamic(locale, 'lacrosDataMigrationErrorSubtitle')]]
-        </p>
-      </div>
-      <div slot="content" class="flex layout vertical center center-justified">
-        <img src="/images/error.svg"
-             class="oobe-illustration" aria-hidden="true">
-      </div>
-
-      <!-- Cancel button -->
-      <div slot="bottom-buttons" class="layout horizontal end-justified">
-        <oobe-text-button id="cancelButton"
-                          on-click="onCancelButtonClicked_"
-                          text-key="lacrosDataMigrationErrorCancelButton">
-        </oobe-text-button>
-        <oobe-text-button id="gotoFilesButton"
-                          on-click="onGotoFilesButtonClicked_"
-                          text-key="lacrosDataMigrationErrorGotoFilesButton"
-                          hidden="[[!showGotoFiles_]]"
-                          inverse>
-        </oobe-text-button>
-      </div>
-    </oobe-adaptive-dialog>
-  </template>
-  <script src="lacros_data_migration.js"></script>
-</dom-module>
+  <!-- Cancel button -->
+  <div slot="bottom-buttons" class="layout horizontal end-justified">
+    <oobe-text-button id="cancelButton"
+                      on-click="onCancelButtonClicked_"
+                      text-key="lacrosDataMigrationErrorCancelButton">
+    </oobe-text-button>
+    <oobe-text-button id="gotoFilesButton"
+                      on-click="onGotoFilesButtonClicked_"
+                      text-key="lacrosDataMigrationErrorGotoFilesButton"
+                      hidden="[[!showGotoFiles_]]"
+                      inverse>
+    </oobe-text-button>
+  </div>
+</oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js
index 9f27d8d..1ffc8b9 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js
+++ b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js
@@ -6,29 +6,47 @@
  * @fileoverview Polymer element for lacros data migration screen.
  */
 
-/* #js_imports_placeholder */
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '//resources/polymer/v3_0/paper-progress/paper-progress.js';
+import '//resources/polymer/v3_0/paper-styles/color.js';
+import '../../components/common_styles/oobe_dialog_host_styles.m.js';
+import '../../components/dialogs/oobe_loading_dialog.m.js';
+import '../../components/oobe_icons.m.js';
+import '../../components/oobe_slide.m.js';
+
+import {assert} from '//resources/js/assert.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.m.js';
+import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.m.js';
+import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.m.js';
+import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.m.js';
+
 
 /**
  * @constructor
  * @extends {PolymerElement}
  * @implements {LoginScreenBehaviorInterface}
+ * @implements {OobeI18nBehaviorInterface}
  * @implements {MultiStepBehaviorInterface}
  */
-const LacrosDataMigrationScreenElementBase = Polymer.mixinBehaviors(
+const LacrosDataMigrationScreenElementBase = mixinBehaviors(
     [
       OobeDialogHostBehavior,
       OobeI18nBehavior,
       LoginScreenBehavior,
       MultiStepBehavior,
     ],
-    Polymer.Element);
+    PolymerElement);
 
 class LacrosDataMigrationScreen extends LacrosDataMigrationScreenElementBase {
   static get is() {
     return 'lacros-data-migration-element';
   }
 
-  /* #html_template_placeholder */
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
   constructor() {
     super();
diff --git a/chrome/browser/resources/chromeos/login/screens/login/management_transition.html b/chrome/browser/resources/chromeos/login/screens/login/management_transition.html
index 8c2319b5..875c4cfc 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/management_transition.html
+++ b/chrome/browser/resources/chromeos/login/screens/login/management_transition.html
@@ -2,79 +2,60 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="oobe-dialog-host-styles">
+  paper-progress {
+    --paper-progress-active-color: var(--cros-slider-color-active);
+    --paper-progress-container-color: var(--cros-slider-track-color-active);
+    --paper-progress-secondary-color: var(--cros-slider-color-active);
+    height: 3px;
+    width: 100%;
+  }
+</style>
+<oobe-adaptive-dialog id="managementTransitionDialog" role="dialog"
+    aria-label$="[[getDialogTitle_(locale, arcTransition_, managementEntity_)]]"
+    for-step="progress">
+  <iron-icon slot="icon" icon="oobe-32:enterprise" aria-hidden="true"
+    hidden="[[isChildTransition_(arcTransition_)]]">
+  </iron-icon>
+  <iron-icon slot="icon" src="chrome://oobe/supervision_icon.png"
+    aria-hidden="true" hidden="[[!isChildTransition_(arcTransition_)]]">
+  </iron-icon>
+  <h1 slot="title">
+    [[getDialogTitle_(locale, arcTransition_, managementEntity_)]]
+  </h1>
+  <div slot="subtitle">
+    [[i18nDynamic(locale, 'managementTransitionIntroMessage')]]
+  </div>
+  <div slot="content" class="flex layout vertical center-justified"
+      aria-live="off">
+    <paper-progress class="slow" aria-hidden="true" indeterminate>
+    </paper-progress>
+  </div>
+</oobe-adaptive-dialog>
+<oobe-adaptive-dialog id="managementTransitionErrorDialog" role="dialog"
+    aria-label$="[[i18nDynamic(locale,'managementTransitionErrorTitle')]]"
+    for-step="error">
+  <iron-icon slot="icon" icon="oobe-32:enterprise" aria-hidden="true"
+    hidden="[[isChildTransition_(arcTransition_)]]">
+  </iron-icon>
+  <iron-icon slot="icon" src="chrome://oobe/supervision_icon.png"
+    aria-hidden="true" hidden="[[!isChildTransition_(arcTransition_)]]">
+  </iron-icon>
+  <h1 slot="title">
+    [[i18nDynamic(locale, 'managementTransitionErrorTitle')]]
+  </h1>
+  <div slot="subtitle">
+    [[i18nDynamic(locale, 'managementTransitionErrorMessage')]]
+  </div>
+  <div slot="content" class="flex layout vertical center center-justified">
+    <img src="../../images/error.svg"
+        class="oobe-illustration" aria-hidden="true">
+  </div>
+  <div slot="bottom-buttons">
+    <oobe-text-button id="accept-button" on-click="onAcceptAndContinue_"
+        text-key="managementTransitionErrorButton" class="focus-on-show"
+        inverse>
+    </oobe-text-button>
+  </div>
+</oobe-adaptive-dialog>
 
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
-
-<link rel="import" href="../../components/behaviors/login_screen_behavior.html">
-<link rel="import" href="../../components/behaviors/multi_step_behavior.html">
-<link rel="import" href="../../components/behaviors/oobe_i18n_behavior.html">
-<link rel="import" href="../../components/buttons/oobe_text_button.html">
-<link rel="import" href="../../components/common_styles/common_styles.html">
-<link rel="import" href="../../components/common_styles/oobe_dialog_host_styles.html">
-<link rel="import" href="../../components/dialogs/oobe_adaptive_dialog.html">
-
-<dom-module id="management-transition-element">
-  <template>
-    <style include="oobe-dialog-host-styles">
-      paper-progress {
-        --paper-progress-active-color: rgb(66, 133, 244); /*#4285F4*/
-        --paper-progress-container-color: rgb(206, 224, 252); /*#CEE0FC*/
-        --paper-progress-secondary-color: rgb(66, 133, 244); /*#4285F4*/
-        height: 3px;
-        width: 100%;
-      }
-    </style>
-    <oobe-adaptive-dialog id="managementTransitionDialog" role="dialog"
-        aria-label$="[[getDialogTitle_(locale, arcTransition_, managementEntity_)]]"
-        for-step="progress">
-      <iron-icon slot="icon" icon="oobe-32:enterprise" aria-hidden="true"
-        hidden="[[isChildTransition_(arcTransition_)]]">
-      </iron-icon>
-      <iron-icon slot="icon" src="chrome://oobe/supervision_icon.png"
-        aria-hidden="true" hidden="[[!isChildTransition_(arcTransition_)]]">
-      </iron-icon>
-      <h1 slot="title">
-        [[getDialogTitle_(locale, arcTransition_, managementEntity_)]]
-      </h1>
-      <div slot="subtitle">
-        [[i18nDynamic(locale, 'managementTransitionIntroMessage')]]
-      </div>
-      <div slot="content" class="flex layout vertical center-justified"
-          aria-live="off">
-        <paper-progress class="slow" aria-hidden="true" indeterminate>
-        </paper-progress>
-      </div>
-    </oobe-adaptive-dialog>
-    <oobe-adaptive-dialog id="managementTransitionErrorDialog" role="dialog"
-        aria-label$="[[i18nDynamic(locale,'managementTransitionErrorTitle')]]"
-        for-step="error">
-      <iron-icon slot="icon" icon="oobe-32:enterprise" aria-hidden="true"
-        hidden="[[isChildTransition_(arcTransition_)]]">
-      </iron-icon>
-      <iron-icon slot="icon" src="chrome://oobe/supervision_icon.png"
-        aria-hidden="true" hidden="[[!isChildTransition_(arcTransition_)]]">
-      </iron-icon>
-      <h1 slot="title">
-        [[i18nDynamic(locale, 'managementTransitionErrorTitle')]]
-      </h1>
-      <div slot="subtitle">
-        [[i18nDynamic(locale, 'managementTransitionErrorMessage')]]
-      </div>
-      <div slot="content" class="flex layout vertical center center-justified">
-        <img src="../../images/error.svg"
-            class="oobe-illustration" aria-hidden="true">
-      </div>
-      <div slot="bottom-buttons">
-        <oobe-text-button id="accept-button" on-click="onAcceptAndContinue_"
-            text-key="managementTransitionErrorButton" class="focus-on-show"
-            inverse>
-        </oobe-text-button>
-      </div>
-    </oobe-adaptive-dialog>
-  </template>
-  <script src="management_transition.js"></script>
-</dom-module>
diff --git a/chrome/browser/resources/chromeos/login/screens/login/management_transition.js b/chrome/browser/resources/chromeos/login/screens/login/management_transition.js
index 0a70b5c2e..9502825 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/management_transition.js
+++ b/chrome/browser/resources/chromeos/login/screens/login/management_transition.js
@@ -7,7 +7,20 @@
  * transition screen.
  */
 
-/* #js_imports_placeholder */
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '//resources/polymer/v3_0/paper-progress/paper-progress.js';
+import '../../components/buttons/oobe_text_button.m.js';
+import '../../components/common_styles/common_styles.m.js';
+import '../../components/common_styles/oobe_dialog_host_styles.m.js';
+import '../../components/dialogs/oobe_adaptive_dialog.m.js';
+
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.m.js';
+import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.m.js';
+import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.m.js';
+
 
 const ManagementTransitionUIState = {
   PROGRESS: 'progress',
@@ -33,16 +46,17 @@
  * @implements {OobeI18nBehaviorInterface}
  * @implements {MultiStepBehaviorInterface}
  */
-const ManagementTransitionScreenBase = Polymer.mixinBehaviors(
-    [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior],
-    Polymer.Element);
+const ManagementTransitionScreenBase = mixinBehaviors(
+    [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior], PolymerElement);
 
 class ManagementTransitionScreen extends ManagementTransitionScreenBase {
   static get is() {
     return 'management-transition-element';
   }
 
-  /* #html_template_placeholder */
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
   static get properties() {
     return {
diff --git a/chrome/browser/resources/chromeos/login/test_api/test_api.js b/chrome/browser/resources/chromeos/login/test_api/test_api.js
index 2d52ca9e..843bb8c 100644
--- a/chrome/browser/resources/chromeos/login/test_api/test_api.js
+++ b/chrome/browser/resources/chromeos/login/test_api/test_api.js
@@ -325,6 +325,58 @@
 class ThemeSelectionScreenTester extends ScreenElementApi {
   constructor() {
     super('theme-selection');
+    this.themeRadioButton = new PolymerElementApi(this, '#theme');
+    this.lightThemeButton = new PolymerElementApi(this, '#lightThemeButton');
+    this.darkThemeButton = new PolymerElementApi(this, '#darkThemeButton');
+    this.autoThemeButton = new PolymerElementApi(this, '#autoThemeButton');
+    this.textHeader = new PolymerElementApi(this, '#theme-selection-title');
+  }
+
+  /**
+   * Returns if the Theme Selection Screen is ready for test interaction.
+   * @return {boolean}
+   */
+  isReadyForTesting() {
+    return this.isVisible() && this.lightThemeButton.isVisible() &&
+        this.darkThemeButton.isVisible() && this.autoThemeButton.isVisible();
+  }
+
+  /**
+   * Presses light theme button to select it.
+   */
+  selectLightTheme() {
+    this.lightThemeButton.click();
+  }
+
+  /**
+   * Presses dark theme button to select it.
+   */
+  selectDarkTheme() {
+    this.darkThemeButton.click();
+  }
+
+  /**
+   * Presses auto theme button to select it.
+   */
+  selectAutoTheme() {
+    this.autoThemeButton.click();
+  }
+
+  /**
+   * Finds which theme is selected.
+   * @returns {string}
+   */
+  getNameOfSelectedTheme() {
+    return this.themeRadioButton.element().selected;
+  }
+
+  /**
+   * Retrieves computed color of the screen header. This value will be used to
+   * determine screen's color mode.
+   * @returns {string}
+   */
+  getHeaderTextColor() {
+    return window.getComputedStyle(this.textHeader.element()).color;
   }
 }
 
diff --git a/chrome/browser/resources/chromeos/parent_access/BUILD.gn b/chrome/browser/resources/chromeos/parent_access/BUILD.gn
index 3cd36cd0..dd085833 100644
--- a/chrome/browser/resources/chromeos/parent_access/BUILD.gn
+++ b/chrome/browser/resources/chromeos/parent_access/BUILD.gn
@@ -26,8 +26,9 @@
   deps = [
     "flows:local_web_approvals_after",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("parent_access_app") {
diff --git a/chrome/browser/resources/chromeos/password_change/BUILD.gn b/chrome/browser/resources/chromeos/password_change/BUILD.gn
index 984d48d..91a47d5 100644
--- a/chrome/browser/resources/chromeos/password_change/BUILD.gn
+++ b/chrome/browser/resources/chromeos/password_change/BUILD.gn
@@ -21,9 +21,11 @@
   deps = [
     "//ui/webui/resources/cr_components/chromeos/network:network_select.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
diff --git a/chrome/browser/resources/chromeos/password_change/OWNERS b/chrome/browser/resources/chromeos/password_change/OWNERS
index a8183f4..1f6c549 100644
--- a/chrome/browser/resources/chromeos/password_change/OWNERS
+++ b/chrome/browser/resources/chromeos/password_change/OWNERS
@@ -1 +1 @@
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_dark.json b/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_dark.json
new file mode 100644
index 0000000..b575ecb
--- /dev/null
+++ b/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_dark.json
@@ -0,0 +1 @@
+{"v":"5.9.3","fr":60,"ip":0,"op":282,"w":499,"h":246,"nm":"Fingerprint_motion_DM+3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"index","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[129.86,39.816,0],"ix":2,"l":2},"a":{"a":0,"k":[129.86,39.816,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[1.246,1.561],[2.398,-0.003],[0.641,-1.511],[-1.415,-1.095],[-3.176,1.641]],"o":[[-1.007,-1.263],[-2.419,0.003],[-0.641,1.511],[2.023,1.565],[2.962,-1.531]],"v":[[119.239,-3.284],[114.233,-5.8],[108.806,-2.871],[110.154,1.399],[117.606,1.94]],"c":true}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":9.6,"s":[{"i":[[1.297,2.726],[2.42,0.323],[0.609,-2.386],[-1.456,-1.986],[-3.163,2.253]],"o":[[-1.049,-2.205],[-2.441,-0.326],[-0.609,2.386],[2.082,2.838],[2.95,-2.1]],"v":[[119.578,-1.895],[114.461,-6.697],[109.059,-2.646],[110.757,4.298],[119.598,6.692]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":34,"s":[{"i":[[0.689,3.011],[2.135,0.808],[0.977,-2.289],[-0.965,-2.295],[-3.267,1.646]],"o":[[-0.557,-2.435],[-2.153,-0.815],[-0.977,2.289],[1.38,3.28],[3.047,-1.535]],"v":[[131.004,-0.144],[127.343,-4.578],[121.727,-1.561],[121.909,4.357],[128.998,7.45]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62.4,"s":[{"i":[[1.003,2.848],[2.373,0.577],[0.857,-2.309],[-1.239,-2.128],[-3.383,1.907]],"o":[[-0.811,-2.303],[-2.393,-0.582],[-0.857,2.309],[1.771,3.042],[3.155,-1.778]],"v":[[124.457,-3.222],[119.875,-8.537],[114.076,-5.078],[115.032,2.007],[123.572,5.32]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":171.4,"s":[{"i":[[1.003,2.848],[2.373,0.577],[0.857,-2.309],[-1.239,-2.128],[-3.383,1.907]],"o":[[-0.811,-2.303],[-2.393,-0.582],[-0.857,2.309],[1.771,3.042],[3.155,-1.778]],"v":[[124.457,-3.222],[119.875,-8.537],[114.076,-5.078],[115.032,2.007],[123.572,5.32]],"c":true}]},{"i":{"x":0.34,"y":1},"o":{"x":0.333,"y":0},"t":188.4,"s":[{"i":[[0.594,2.96],[2.269,0.903],[1.171,-2.166],[-0.929,-2.281],[-3.617,1.414]],"o":[[-0.481,-2.394],[-2.288,-0.911],[-1.171,2.166],[1.328,3.26],[3.372,-1.319]],"v":[[128.941,-3.578],[125.147,-9.481],[118.922,-6.867],[118.877,0.281],[126.869,4.756]],"c":true}]},{"t":211.400390625,"s":[{"i":[[1.246,1.561],[2.398,-0.003],[0.641,-1.511],[-1.415,-1.095],[-3.176,1.641]],"o":[[-1.007,-1.263],[-2.419,0.003],[-0.641,1.511],[2.023,1.565],[2.962,-1.531]],"v":[[119.239,-3.284],[114.233,-5.8],[108.806,-2.871],[110.154,1.399],[117.606,1.94]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.298039227724,0.352941185236,0.439215689898,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[7.59,21.375],[3.972,7.334],[-8.09,4.149],[-2.192,-3.381],[-7.696,-18.956],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-6.574,-18.516],[-2.158,-3.984],[5.602,-2.873],[4.248,6.551],[3.152,7.765],[0,0]],"v":[[139.769,93.433],[122.799,40.684],[107.77,8.822],[108.51,-8.936],[121.924,-4.305],[140.953,29.671],[150.819,55.192]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":9.6,"s":[{"i":[[0,0],[8.666,20.582],[2.823,7.226],[-8.257,3.806],[-2.049,-3.47],[-4.093,-8.34],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-4.272,-10.147],[-1.649,-4.22],[5.718,-2.636],[3.97,6.724],[3.692,7.523],[0,0]],"v":[[139.769,93.433],[117.463,34.894],[106.385,8.104],[109.059,-10.945],[122.266,-5.755],[136.296,22.867],[150.819,55.192]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":34,"s":[{"i":[[0,0],[5.925,20.819],[1.415,7.858],[-9.095,2.202],[-1.379,-3.911],[-2.405,-8.974],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-2.921,-10.264],[-0.826,-4.59],[6.298,-1.525],[2.672,7.579],[2.17,8.094],[0,0]],"v":[[139.769,93.433],[122.412,35.169],[115.574,7.33],[122.061,-11.374],[134.367,-3.508],[141.316,23.288],[150.819,55.192]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62,"s":[{"i":[[0,0],[7.498,21.405],[2.044,7.484],[-8.613,2.913],[-1.671,-3.667],[-3.19,-8.726],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.696,-10.553],[-1.194,-4.371],[5.965,-2.017],[3.238,7.106],[2.877,7.871],[0,0]],"v":[[139.769,93.433],[119.327,33.178],[110.294,5.334],[114.965,-13.326],[127.551,-6.771],[138.477,23.165],[150.819,55.192]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":171.4,"s":[{"i":[[0,0],[7.501,21.407],[2.046,7.483],[-8.612,2.914],[-1.672,-3.666],[-3.191,-8.725],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.698,-10.554],[-1.195,-4.371],[5.964,-2.018],[3.239,7.105],[2.879,7.87],[0,0]],"v":[[139.769,93.433],[119.32,33.174],[110.283,5.33],[114.95,-13.33],[127.537,-6.777],[138.471,23.164],[150.819,55.192]],"c":false}]},{"i":{"x":0.34,"y":1},"o":{"x":0.333,"y":0},"t":188.4,"s":[{"i":[[0,0],[6.472,22.127],[0.979,7.696],[-8.935,1.68],[-1.142,-3.864],[-1.939,-9.086],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.191,-10.909],[-0.572,-4.495],[6.188,-1.164],[2.213,7.488],[1.749,8.196],[0,0]],"v":[[139.769,93.433],[120.437,31.656],[113.71,2.907],[120.942,-14.917],[132.488,-6.667],[140.768,24.22],[150.819,55.192]],"c":false}]},{"t":211.400390625,"s":[{"i":[[0,0],[7.59,21.375],[3.972,7.334],[-8.09,4.149],[-2.192,-3.381],[-7.696,-18.956],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-6.574,-18.516],[-2.158,-3.984],[5.602,-2.873],[4.248,6.551],[3.152,7.765],[0,0]],"v":[[139.769,93.433],[122.799,40.684],[107.77,8.822],[108.51,-8.936],[121.924,-4.305],[140.953,29.671],[150.819,55.192]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":384,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"hand","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.335],"y":[1.035]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.639],"y":[0.105]},"t":28.801,"s":[19]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":67.199,"s":[6]},{"i":{"x":[0.499],"y":[0.989]},"o":{"x":[0.673],"y":[0]},"t":171,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.33],"y":[0.225]},"t":195,"s":[-3]},{"t":219,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[390.184,203.069,0],"to":[0,-2.833,0],"ti":[3.825,1.133,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[390.184,186.069,0],"to":[-3.825,-1.133,0],"ti":[3.825,-1.7,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.4,"y":0.4},"t":57.6,"s":[367.234,196.269,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":180.6,"s":[367.234,196.269,0],"to":[0,0,0],"ti":[0,0,0]},{"t":217.400390625,"s":[390.184,203.069,0]}],"ix":2,"l":2},"a":{"a":0,"k":[191.157,126.552,0],"ix":1,"l":2},"s":{"a":0,"k":[73,73,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-4.174,-1.462],[-1.952,-3.536],[-3.434,-11.376],[-3.791,-15.178]],"o":[[4.191,-0.821],[3.949,1.383],[5.758,10.432],[4.066,13.469],[0,0]],"v":[[186.674,42.882],[199.898,42.533],[208.723,51.149],[221.968,85.1],[232.244,126.272]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-3.749,-1.166],[-1.981,-3.388],[-3.9,-11.099],[-5.532,-17.305]],"o":[[3.581,-1.112],[3.547,1.103],[5.846,9.996],[4.617,13.141],[0,0]],"v":[[182.957,41.992],[193.49,41.044],[201.859,49.015],[216.105,81.93],[232.244,126.272]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-4.174,-1.462],[-1.952,-3.536],[-3.434,-11.376],[-3.791,-15.178]],"o":[[4.191,-0.821],[3.949,1.383],[5.758,10.432],[4.066,13.469],[0,0]],"v":[[186.674,42.882],[199.898,42.533],[208.723,51.149],[221.968,85.1],[232.244,126.272]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[118.855,95.287],[147.071,139.722]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":29,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[119.967,95.829],[147.071,139.722]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[118.855,95.287],[147.071,139.722]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-3.222,-0.408],[-1.982,-3.927],[-2.471,-5.634]],"o":[[3.208,-0.504],[4.364,0.553],[1.982,3.927],[0,0]],"v":[[166.538,35.782],[176.109,34.265],[185.72,42.518],[191.393,57.674]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-4.459,-0.224],[-2.04,-3.776],[-2.601,-5.443]],"o":[[2.751,-0.727],[3.845,0.193],[2.04,3.776],[0,0]],"v":[[162.853,36.62],[172.127,34.467],[182.097,41.696],[188.248,56.406]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-3.222,-0.408],[-1.982,-3.927],[-2.471,-5.634]],"o":[[3.208,-0.504],[4.364,0.553],[1.982,3.927],[0,0]],"v":[[166.538,35.782],[176.109,34.265],[185.72,42.518],[191.393,57.674]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-5.326,-3.612],[-3.037,-9.057]],"o":[[6.302,-1.303],[7.28,4.937],[0,0]],"v":[[141.077,29.65],[159.804,30.799],[174.626,55.866]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-4.924,-3.228],[-3.368,-8.816]],"o":[[6.302,-1.303],[6.731,4.412],[0,0]],"v":[[141.077,29.65],[157.661,32.153],[171.936,56.187]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-5.326,-3.612],[-3.037,-9.057]],"o":[[6.302,-1.303],[7.28,4.937],[0,0]],"v":[[141.077,29.65],[159.804,30.799],[174.626,55.866]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.902,-1.673],[11.202,-12.826],[-24.735,-1.137],[0,0],[5.392,6.96]],"o":[[-4.902,1.673],[-7.666,8.777],[24.735,1.137],[0,0],[-5.392,-6.96]],"v":[[135.507,32.114],[126.633,71.854],[157.251,131.713],[175.345,58.741],[163.456,35.552]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":384,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"blue_nut","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":51,"s":[246.337]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":71,"s":[246.337]},{"i":{"x":[0.673],"y":[1.783]},"o":{"x":[0.532],"y":[0.574]},"t":117,"s":[277.337]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.118]},"t":193,"s":[271.837]},{"t":231,"s":[246.337]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":51,"s":[76.34]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":71,"s":[76.34]},{"i":{"x":[0.673],"y":[1.651]},"o":{"x":[0.532],"y":[0.478]},"t":117,"s":[60.84]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.152]},"t":193,"s":[64.34]},{"t":231,"s":[76.34]}],"ix":4}},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.367,-9.449],[-0.357,-9.449]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.261,0],[1.225,-0.536],[0.883,-0.947],[0.364,-0.638],[0.023,-0.031],[0,0],[2.521,-0.608],[0.696,-0.12],[1.376,-1.673],[-0.779,-2.082],[-0.047,-0.107],[-1.785,-0.539],[-1.605,1.033],[-0.727,0.601],[-0.282,0.224],[-2.573,-0.282],[0,0],[-0.038,-0.009],[-0.736,-0.005],[-1.421,0.786],[1.589,4.342],[2.435,1.039]],"o":[[-1.29,0],[-1.192,0.522],[-0.501,0.536],[-0.019,0.034],[0,0],[-1.39,1.889],[-0.719,0.174],[-2.204,0.382],[-1.415,1.72],[0.041,0.107],[0.745,1.701],[1.826,0.549],[0.741,-0.477],[0.28,-0.231],[2.023,-1.617],[0,0],[0.038,0.004],[0.715,0.165],[1.603,-0.009],[4.038,-2.234],[-0.915,-2.499],[-1.203,-0.514]],"v":[[7.294,-11.784],[3.491,-10.979],[0.364,-8.766],[-0.939,-6.998],[-1.002,-6.9],[-2.546,-4.803],[-8.44,-1.041],[-10.576,-0.622],[-16.058,1.762],[-17.105,8.02],[-16.973,8.343],[-13.051,11.815],[-7.655,11.055],[-5.501,9.409],[-4.661,8.723],[2.47,6.658],[5.062,6.947],[5.176,6.966],[7.363,7.208],[11.92,6.009],[16.215,-5.526],[11.021,-11.013]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[1.614,0],[0.806,0.243],[0.968,2.211],[0.054,0.144],[-1.89,2.296],[-2.379,0.413],[-0.656,0.158],[-1.101,1.495],[0,0],[-1.023,1.389],[-0.593,0.636],[-1.443,0.632],[-2.905,-1.239],[-1.106,-3.023],[4.892,-2.707],[1.913,-0.011],[0.848,0.191],[0,0],[1.607,-1.284],[0.271,-0.223],[0.841,-0.541]],"o":[[-0.822,0],[-2.321,-0.701],[-0.061,-0.139],[-1.041,-2.783],[1.847,-2.246],[0.664,-0.115],[2.05,-0.496],[0,0],[0.133,-0.188],[0.434,-0.753],[1.069,-1.145],[2.891,-1.268],[2.947,1.258],[1.925,5.258],[-1.693,0.938],[-0.895,0.003],[0,0],[-2.045,-0.23],[-0.273,0.218],[-0.74,0.613],[-1.39,0.894]],"v":[[-11.174,14.092],[-13.629,13.73],[-18.804,9.148],[-18.977,8.723],[-17.602,0.49],[-10.917,-2.593],[-8.909,-2.984],[-4.159,-5.985],[-4.156,-5.983],[-2.646,-8.04],[-1.098,-10.132],[2.688,-12.811],[11.807,-12.853],[18.093,-6.214],[12.888,7.759],[7.375,9.208],[4.784,8.928],[2.249,8.647],[-3.413,10.285],[-4.226,10.95],[-6.573,12.737]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":71,"s":[0.372549027205,0.388235300779,0.407843142748,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":115,"s":[0.40000000596,0.615686297417,0.964705884457,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":127,"s":[0.40000000596,0.615686297417,0.964705884457,1]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":191,"s":[0.40000000596,0.615686297417,0.964705884457,1]},{"t":229,"s":[0.372549027205,0.388235300779,0.407843142748,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[421.294,105.593],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"red_semi_sphere","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":49,"s":[246.337]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":69,"s":[246.337]},{"i":{"x":[0.673],"y":[1.783]},"o":{"x":[0.532],"y":[0.574]},"t":115,"s":[277.337]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.118]},"t":191,"s":[271.837]},{"t":229,"s":[246.337]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":49,"s":[76.34]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":69,"s":[76.34]},{"i":{"x":[0.673],"y":[1.651]},"o":{"x":[0.532],"y":[0.478]},"t":115,"s":[60.84]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.152]},"t":191,"s":[64.34]},{"t":229,"s":[76.34]}],"ix":4}},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.699,0.676],[-8.25,-7.2],[6.322,-8.669],[0.75,0.655]],"o":[[-0.733,-0.64],[7.731,-7.475],[8.236,7.188],[-0.586,0.804],[0,0]],"v":[[-18.449,-7.751],[-18.534,-10.206],[9.749,-10.911],[12.911,17.163],[10.433,17.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":69,"s":[0.372549027205,0.388235300779,0.407843142748,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":115,"s":[0.917647063732,0.262745112181,0.207843139768,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":191,"s":[0.917647063732,0.262745112181,0.207843139768,1]},{"t":229,"s":[0.372549027205,0.388235300779,0.407843142748,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[396.815,116.057],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"triangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":58,"s":[0]},{"i":{"x":[0.518],"y":[0.81]},"o":{"x":[0.467],"y":[-0.124]},"t":117.26,"s":[-30]},{"i":{"x":[0.845],"y":[1.216]},"o":{"x":[0.456],"y":[0.151]},"t":191,"s":[-5.42]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.118]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[160.673]},{"i":{"x":[0.69],"y":[1.538]},"o":{"x":[0.459],"y":[0.578]},"t":120.6,"s":[137.673]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.108]},"t":191,"s":[142.673]},{"t":229,"s":[160.673]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.136]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[58.089]},{"i":{"x":[0.69],"y":[1.528]},"o":{"x":[0.459],"y":[0.568]},"t":120.6,"s":[43.589]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.13]},"t":191,"s":[47.214]},{"t":229,"s":[58.089]}],"ix":4}},"a":{"a":0,"k":[174.5,43.5,0],"ix":1,"l":2},"s":{"a":0,"k":[79,79,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.065,0],[0.057,-0.044],[-0.044,-0.295],[0,0],[-0.09,-0.037],[-0.233,0.175],[0,0],[0.014,0.1],[0.281,0.111],[18.926,7.542],[0,0]],"o":[[-0.17,0],[-0.077,0.062],[0,0],[0.044,0.29],[0.091,0.039],[0,0],[0.241,-0.182],[-0.013,-0.1],[-15.136,-5.993],[0,0],[-0.076,-0.03]],"v":[[-17.831,-18.954],[-18.184,-18.828],[-18.394,-18.296],[-12.861,18.624],[-12.512,19.068],[-11.952,18.996],[18.179,-3.753],[18.401,-4.286],[18.045,-4.74],[-17.616,-18.911],[-17.617,-18.911]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.547,0],[0.319,0.13],[0.135,0.906],[0,0],[-0.731,0.579],[-0.865,-0.346],[-15.133,-5.993],[-0.127,-0.933],[0.752,-0.568],[0,0]],"o":[[-0.329,0],[-0.847,-0.347],[0,0],[-0.138,-0.922],[0.73,-0.58],[18.924,7.54],[0.876,0.347],[0.127,0.934],[0,0],[-0.457,0.345]],"v":[[-12.29,21.114],[-13.269,20.92],[-14.838,18.92],[-20.372,-17.999],[-19.425,-20.395],[-16.876,-20.768],[18.781,-6.6],[20.383,-4.556],[19.385,-2.157],[-10.747,20.592]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.158,44.447],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"green_circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":0,"s":[0]},{"i":{"x":[0.518],"y":[0.838]},"o":{"x":[0.467],"y":[-0.106]},"t":59.26,"s":[-30]},{"i":{"x":[0.845],"y":[0.946]},"o":{"x":[0.456],"y":[-0.038]},"t":191,"s":[21.58]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.105]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[165.673]},{"i":{"x":[0.69],"y":[1.614]},"o":{"x":[0.459],"y":[0.661]},"t":120.6,"s":[139.798]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.09]},"t":191,"s":[144.173]},{"t":229,"s":[165.673]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.103]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[63.089]},{"i":{"x":[0.69],"y":[1.511]},"o":{"x":[0.459],"y":[0.549]},"t":120.6,"s":[43.964]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.092]},"t":191,"s":[47.714]},{"t":229,"s":[63.089]}],"ix":4}},"a":{"a":0,"k":[174.5,43.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.663,-7.228],[7.227,6.663],[-6.663,7.227],[-7.228,-6.663]],"o":[[-6.663,7.228],[-7.228,-6.662],[6.662,-7.228],[7.227,6.662]],"v":[[13.087,12.064],[-12.063,13.087],[-13.087,-12.064],[12.064,-13.087]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[0.372549027205,0.388235300779,0.407843142748,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":121,"s":[0.35686275363,0.72549021244,0.454901963472,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":191,"s":[0.35686275363,0.72549021244,0.454901963472,1]},{"t":229,"s":[0.372549027205,0.388235300779,0.407843142748,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.947,41.742],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape 02 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[360]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[93.709]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":118,"s":[72.209]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[72.209]},{"t":229,"s":[93.709]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[89.32]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":118,"s":[84.32]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[84.32]},{"t":229,"s":[89.32]}],"ix":4}},"a":{"a":0,"k":[98.5,60.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.24,-1.422],[0,0],[1.422,1.239],[0,0],[-1.24,1.422],[0,0],[-1.422,-1.239],[0,0]],"o":[[0,0],[-1.239,1.422],[0,0],[-1.422,-1.24],[0,0],[1.24,-1.422],[0,0],[1.422,1.24]],"v":[[13.06,1.587],[3.356,12.721],[-1.463,13.052],[-12.73,3.233],[-13.06,-1.587],[-3.357,-12.721],[1.463,-13.052],[12.729,-3.233]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":63,"s":[0.372549027205,0.388235300779,0.407843142748,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":117,"s":[0.988235294819,0.78823530674,0.203921571374,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":193,"s":[0.988235294819,0.78823530674,0.203921571374,1]},{"t":229,"s":[0.372549027205,0.388235300779,0.407843142748,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[98.529,60.42],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape 01 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":0,"s":[0]},{"i":{"x":[0.518],"y":[0.767]},"o":{"x":[0.467],"y":[-0.152]},"t":46.059,"s":[-30]},{"i":{"x":[0.845],"y":[0.934]},"o":{"x":[0.456],"y":[-0.046]},"t":193,"s":[21.58]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":20,"s":[104.271]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.47],"y":[0]},"t":62,"s":[104.271]},{"i":{"x":[0.833],"y":[0.986]},"o":{"x":[0.333],"y":[0]},"t":116,"s":[65.271]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[-0.017]},"t":154,"s":[68.271]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[65.771]},{"t":229,"s":[104.271]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":20,"s":[107.431]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.47],"y":[0]},"t":62,"s":[107.431]},{"i":{"x":[0.833],"y":[0.835]},"o":{"x":[0.333],"y":[0]},"t":116,"s":[114.431]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.169]},"t":154,"s":[113.931]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[113.431]},{"t":229,"s":[107.431]}],"ix":4}},"a":{"a":0,"k":[93.25,102.562,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.582,-1.16],[1.16,1.582],[-1.581,1.159],[-1.16,-1.581]],"o":[[-1.582,1.16],[-1.159,-1.581],[1.582,-1.16],[1.16,1.582]],"v":[[2.1,2.863],[-2.865,2.099],[-2.1,-2.864],[2.864,-2.101]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":62,"s":[0.372549027205,0.388235300779,0.407843142748,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":117,"s":[0.972549021244,0.509803950787,1,1]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":193,"s":[0.972549021244,0.509803950787,1,1]},{"t":238,"s":[0.372549027205,0.388235300779,0.407843142748,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[93.273,102.435],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Zoom in Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":9,"s":[276.5,117,0],"to":[-4.083,1,0],"ti":[4.083,-1,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":29,"s":[252,123,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":193,"s":[252,123,0],"to":[4.083,-1,0],"ti":[-4.083,1,0]},{"t":229,"s":[276.5,117,0]}],"ix":2,"l":2},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.2,0.2,0.2],"y":[0,0,0]},"t":9,"s":[59,59,100]},{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":29,"s":[100,100,100]},{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.2,0.2,0.2],"y":[0,0,0]},"t":193,"s":[100,100,100]},{"t":229,"s":[59,59,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.068,0],[0.013,0.003],[0.351,0.344],[0,0.637],[-0.547,0],[0,-0.522],[-0.37,0],[0,0.344],[1.287,0],[0.377,-0.789],[0,-0.335],[-0.193,-0.515],[0.083,-0.029],[0.029,0.08],[0,0.434],[-0.145,0.306],[-1.039,0],[0,-1.39],[0.547,0],[0,0.521],[0.37,0],[0,-0.344],[-0.39,-0.386],[-0.454,-0.125],[0.023,-0.084]],"o":[[-0.013,0],[-0.511,-0.142],[-0.45,-0.447],[0,-0.522],[0.547,0],[0,0.344],[0.37,0],[0,-1.213],[-0.914,0],[-0.125,0.26],[0,0.25],[0.032,0.084],[-0.084,0.032],[-0.158,-0.422],[0,-0.387],[0.428,-0.898],[1.464,0],[0,0.521],[-0.547,0],[0,-0.344],[-0.37,0],[0,0.55],[0.305,0.303],[0.086,0.023],[-0.016,0.074]],"v":[[0.938,3.217],[0.896,3.212],[-0.302,2.535],[-1,0.857],[-0.009,-0.09],[0.983,0.857],[1.651,1.48],[2.32,0.857],[-0.012,-1.342],[-2.138,-0.044],[-2.328,0.857],[-2.112,2.018],[-2.206,2.223],[-2.411,2.13],[-2.647,0.857],[-2.427,-0.187],[-0.012,-1.667],[2.642,0.852],[1.651,1.798],[0.66,0.852],[-0.009,0.229],[-0.677,0.852],[-0.076,2.303],[0.977,2.898],[1.089,3.096]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.045,0],[0.277,0.19],[0,0.559],[-0.09,0],[0,-0.091],[-0.392,-0.264],[-0.322,0],[-0.128,0.023],[-0.016,-0.09],[0.09,-0.016]],"o":[[-0.383,0],[-0.479,-0.325],[0,-0.091],[0.091,0],[0,0.453],[0.229,0.154],[0.077,0],[0.087,-0.016],[0.016,0.087],[-0.183,0.035]],"v":[[1.585,2.555],[0.586,2.268],[-0.178,0.857],[-0.018,0.695],[0.142,0.857],[0.767,2.001],[1.585,2.229],[1.918,2.197],[2.105,2.329],[1.974,2.516]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0.042,0],[0.029,0.032],[0.215,0.389],[0,0.517],[-1.004,0],[0,-0.956],[0.09,0],[0,0.09],[0.827,0],[0,-0.779],[-0.197,-0.347],[-0.248,-0.251],[0.061,-0.064]],"o":[[-0.042,0],[-0.28,-0.28],[-0.222,-0.396],[0,-0.956],[1.004,0],[0,0.09],[-0.09,0],[0,-0.779],[-0.827,0],[0,0.463],[0.206,0.37],[0.061,0.064],[-0.035,0.032]],"v":[[-0.723,3.15],[-0.836,3.102],[-1.482,2.253],[-1.819,0.857],[0.001,-0.878],[1.823,0.857],[1.661,1.016],[1.5,0.857],[0.001,-0.557],[-1.497,0.857],[-1.198,2.094],[-0.603,2.874],[-0.603,3.102]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.052,0],[0.029,0.02],[-0.051,0.074],[-0.483,0.248],[-1.014,-0.521],[-0.318,-0.447],[0.074,-0.052],[0.052,0.074],[0.434,0.222],[0.921,-0.476],[0.289,-0.406]],"o":[[-0.032,0],[-0.074,-0.051],[0.319,-0.45],[1.01,-0.521],[0.482,0.247],[0.052,0.071],[-0.074,0.051],[-0.289,-0.405],[-0.924,-0.473],[-0.437,0.226],[-0.026,0.045]],"v":[[-2.733,-0.734],[-2.827,-0.762],[-2.866,-0.988],[-1.659,-2.04],[1.659,-2.042],[2.865,-0.997],[2.827,-0.771],[2.6,-0.811],[1.51,-1.757],[-1.514,-1.753],[-2.608,-0.801]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0.058,0],[0.023,0.013],[0.64,0],[0.55,-0.303],[0.045,0.078],[-0.078,0.042],[-0.692,0],[-0.656,-0.337],[0.041,-0.077]],"o":[[-0.026,0],[-0.618,-0.319],[-0.637,0],[-0.077,0.042],[-0.042,-0.077],[0.598,-0.325],[0.685,0],[0.08,0.042],[-0.029,0.058]],"v":[[1.871,-2.423],[1.797,-2.441],[0.004,-2.896],[-1.788,-2.441],[-2.007,-2.507],[-1.941,-2.725],[0.004,-3.217],[1.944,-2.729],[2.013,-2.512]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[322.25,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":7,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[23.292,0],[0,-23.291],[-23.292,0],[0,23.292]],"o":[[-23.292,0],[0,23.292],[23.292,0],[0,-23.291]],"v":[[0,-42.241],[-42.241,-0.001],[0,42.241],[42.241,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[24.67,0],[0,24.67],[-24.67,0],[0,-24.67]],"o":[[-24.67,0],[0,-24.67],[24.67,0],[0,24.67]],"v":[[0,44.741],[-44.741,-0.001],[0,-44.741],[44.741,-0.001]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.156862750649,0.301960796118,0.490196079016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[326.377,92.814],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[344.795,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[322.249,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[299.704,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.325],[0,0],[0.325,0],[0,0],[0,-1.282],[-0.292,-2.036],[0,0]],"o":[[0,0],[0,-0.325],[0,0],[-0.109,1.253],[0,2.117],[0,0],[0.325,0]],"v":[[1.928,4.427],[1.928,-4.427],[1.339,-5.016],[-1.752,-5.016],[-1.927,-1.216],[-1.476,5.016],[1.339,5.016]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.814,94.031],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.667,0],[0,0],[0,-0.667],[0,0],[-0.667,0],[0,0],[0,0.667],[0,0]],"o":[[0,0],[-0.667,0],[0,0],[0,0.667],[0,0],[0.667,0],[0,0],[0,-0.667]],"v":[[17.872,-10.596],[-17.873,-10.596],[-19.08,-9.389],[-19.08,9.39],[-17.873,10.597],[17.872,10.597],[19.08,9.39],[19.08,-9.389]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[335.298,114.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.497],[0,0],[0.497,0],[0,0],[0,-0.497],[0,0],[-2.508,-2.23],[0,0]],"o":[[0,0],[0,-0.497],[0,0],[-0.498,0],[0,0],[1.936,2.75],[0,0],[0.497,0]],"v":[[10.596,9.697],[10.596,-9.697],[9.697,-10.596],[-9.697,-10.596],[-10.596,-9.697],[-10.596,3.101],[-3.909,10.597],[9.697,10.597]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[301.402,114.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.497,0],[0,0],[-1.227,-2.494],[0,0]],"o":[[0,0],[0.735,2.736],[0,0],[0,-0.497]],"v":[[0.578,-3.93],[-1.477,-3.93],[1.478,3.93],[1.478,-3.03]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[285.858,108.054],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.552],[0,0],[-6.016,3.601],[0,0]],"o":[[0,0],[7.443,-0.317],[0,0],[-0.552,0]],"v":[[-10.208,-2.053],[-10.208,3.052],[10.208,-3.052],[-9.209,-3.052]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[338.469,133.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.497,0],[0,0],[0.023,-0.002],[-7.42,-0.322],[0,0]],"o":[[0,0],[-0.023,0],[6.001,3.587],[0,0],[0,-0.497]],"v":[[9.279,-3.051],[-10.114,-3.051],[-10.179,-3.038],[10.179,3.051],[10.179,-2.151]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[314.278,133.204],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.325,0],[0,0],[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325],[0,0],[-0.325,0],[0,0]],"v":[[-35.71,-14.43],[-35.121,-15.019],[-17.133,-15.019],[-16.544,-14.43],[-16.544,-5.576],[-17.133,-4.987],[-35.121,-4.987],[-35.71,-5.576]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.325,0],[0,0],[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325],[0,0],[-0.325,0],[0,0]],"v":[[-13.165,-14.43],[-12.576,-15.019],[5.412,-15.019],[6.001,-14.43],[6.001,-5.576],[5.412,-4.987],[-12.576,-4.987],[-13.165,-5.576]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-0.326,0],[0,0],[0,-0.325],[0,0],[0.326,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.326,0],[0,0],[0,0.325],[0,0],[-0.326,0],[0,0]],"v":[[9.381,-14.43],[9.97,-15.019],[27.957,-15.019],[28.546,-14.43],[28.546,-5.576],[27.957,-4.987],[9.97,-4.987],[9.381,-5.576]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0.667,0],[0,0],[0,0.667],[0,0],[-0.667,0],[0,0],[0,-0.667]],"o":[[0,0.667],[0,0],[-0.667,0],[0,0],[0,-0.667],[0,0],[0.667,0],[0,0]],"v":[[28.546,20.077],[27.339,21.285],[-8.406,21.285],[-9.614,20.077],[-9.614,1.299],[-8.406,0.091],[27.339,0.091],[28.546,1.299]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0,-0.325],[0,0],[0.326,0],[0,0],[-0.445,-1.656],[0,0],[0,-0.497],[0,0],[-1.3,-1.847],[0,0],[-0.497,0],[0,0],[0,-0.497],[0,0],[0.497,0],[0,0],[-2.356,-1.408],[-0.023,0],[0,0],[0,-0.497],[0,0],[-0.643,0],[-0.626,0.026],[0,0],[-0.552,0],[0,0],[-2.807,11.407],[0,0],[7.451,0],[0,0],[0.539,-6.218]],"o":[[0.326,0],[0,0],[0,0.325],[0,0],[0.248,1.728],[0,0],[0.498,0],[0,0],[1.005,2.043],[0,0],[0,-0.497],[0,0],[0.497,0],[0,0],[0,0.497],[0,0],[2.039,1.814],[0.022,-0.001],[0,0],[0.498,0],[0,0],[0.637,0.027],[0.632,0],[0,0],[0,-0.551],[0,0],[9.816,-5.875],[0,0],[0,-7.451],[0,0],[-2.878,5.192],[0,0]],"v":[[-39.679,-15.019],[-39.09,-14.43],[-39.09,-5.576],[-39.679,-4.987],[-42.494,-4.987],[-41.451,0.091],[-39.396,0.091],[-38.496,0.992],[-38.496,7.951],[-35.026,13.789],[-35.026,0.992],[-34.126,0.091],[-14.732,0.091],[-13.832,0.992],[-13.832,20.384],[-14.732,21.285],[-28.337,21.285],[-21.732,26.132],[-21.668,26.119],[-2.275,26.119],[-1.374,27.02],[-1.374,32.223],[0.545,32.271],[2.43,32.224],[2.43,27.118],[3.429,26.119],[22.846,26.119],[42.77,-0.797],[42.77,-18.781],[29.279,-32.271],[-37.511,-32.271],[-42.77,-15.019]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039227724,0.352941185236,0.439215689898,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.831,104.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":7,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Keyboard Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.5,123,0],"ix":2,"l":2},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.063,0],[0.012,0.003],[0.328,0.323],[0,0.597],[-0.512,0],[0,-0.488],[-0.347,0],[0,0.323],[1.205,0],[0.352,-0.738],[0,-0.313],[-0.181,-0.482],[0.079,-0.027],[0.028,0.075],[0,0.407],[-0.135,0.286],[-0.973,0],[0,-1.301],[0.512,0],[0,0.489],[0.347,0],[0,-0.322],[-0.365,-0.361],[-0.425,-0.118],[0.021,-0.078]],"o":[[-0.012,0],[-0.479,-0.133],[-0.422,-0.419],[0,-0.488],[0.512,0],[0,0.323],[0.346,0],[0,-1.135],[-0.856,0],[-0.118,0.244],[0,0.235],[0.03,0.078],[-0.078,0.03],[-0.147,-0.395],[0,-0.361],[0.401,-0.84],[1.371,0],[0,0.489],[-0.512,0],[0,-0.322],[-0.346,0],[0,0.516],[0.286,0.284],[0.081,0.021],[-0.015,0.07]],"v":[[0.878,3.013],[0.839,3.007],[-0.282,2.374],[-0.936,0.801],[-0.008,-0.084],[0.92,0.801],[1.547,1.386],[2.174,0.801],[-0.011,-1.256],[-2.002,-0.042],[-2.18,0.801],[-1.978,1.889],[-2.066,2.082],[-2.259,1.995],[-2.478,0.801],[-2.274,-0.175],[-0.011,-1.561],[2.475,0.798],[1.547,1.684],[0.619,0.798],[-0.008,0.214],[-0.635,0.798],[-0.071,2.157],[0.914,2.715],[1.02,2.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.042,0],[0.259,0.178],[0,0.525],[-0.084,0],[0,-0.084],[-0.367,-0.247],[-0.302,0],[-0.121,0.021],[-0.015,-0.084],[0.085,-0.015]],"o":[[-0.359,0],[-0.449,-0.304],[0,-0.084],[0.084,0],[0,0.425],[0.214,0.145],[0.072,0],[0.081,-0.015],[0.015,0.082],[-0.172,0.033]],"v":[[1.484,2.392],[0.55,2.124],[-0.168,0.801],[-0.017,0.651],[0.134,0.801],[0.718,1.874],[1.484,2.088],[1.797,2.058],[1.972,2.181],[1.848,2.356]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0.039,0],[0.027,0.03],[0.202,0.365],[0,0.486],[-0.94,0],[0,-0.894],[0.084,0],[0,0.085],[0.775,0],[0,-0.729],[-0.183,-0.325],[-0.232,-0.235],[0.057,-0.061]],"o":[[-0.039,0],[-0.262,-0.263],[-0.208,-0.371],[0,-0.894],[0.94,0],[0,0.085],[-0.084,0],[0,-0.729],[-0.774,0],[0,0.434],[0.193,0.347],[0.057,0.06],[-0.033,0.03]],"v":[[-0.677,2.95],[-0.782,2.905],[-1.388,2.109],[-1.704,0.801],[0.001,-0.823],[1.707,0.801],[1.556,0.952],[1.405,0.801],[0.001,-0.521],[-1.403,0.801],[-1.123,1.961],[-0.565,2.691],[-0.565,2.905]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.048,0],[0.027,0.018],[-0.049,0.069],[-0.452,0.232],[-0.949,-0.488],[-0.298,-0.419],[0.069,-0.048],[0.048,0.069],[0.407,0.208],[0.862,-0.446],[0.271,-0.38]],"o":[[-0.03,0],[-0.07,-0.048],[0.298,-0.422],[0.946,-0.488],[0.452,0.232],[0.048,0.066],[-0.07,0.048],[-0.271,-0.38],[-0.864,-0.443],[-0.41,0.211],[-0.024,0.042]],"v":[[-2.56,-0.687],[-2.647,-0.714],[-2.683,-0.925],[-1.553,-1.91],[1.553,-1.913],[2.683,-0.934],[2.647,-0.723],[2.436,-0.759],[1.414,-1.645],[-1.418,-1.642],[-2.442,-0.75]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0.054,0],[0.022,0.012],[0.6,0],[0.515,-0.283],[0.042,0.072],[-0.072,0.039],[-0.648,0],[-0.615,-0.316],[0.04,-0.072]],"o":[[-0.024,0],[-0.578,-0.298],[-0.596,0],[-0.072,0.039],[-0.039,-0.072],[0.561,-0.304],[0.642,0],[0.075,0.039],[-0.027,0.054]],"v":[[1.752,-2.269],[1.682,-2.287],[0.004,-2.712],[-1.674,-2.287],[-1.879,-2.347],[-1.819,-2.552],[0.004,-3.013],[1.821,-2.555],[1.884,-2.353]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.835,96.568],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":7,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[333.18,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.71,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.24,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.771,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[279.301,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.831,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[252.361,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[238.891,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.421,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[211.952,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.482,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[185.012,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[171.542,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.072,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"bm":0,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[144.603,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"bm":0,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.133,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"bm":0,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.398,0],[0,0],[0,0.399],[0,0],[-0.398,0],[0,0],[0,-0.398],[0,0]],"o":[[0,0],[-0.398,0],[0,0],[0,-0.398],[0,0],[0.398,0],[0,0],[0,0.399]],"v":[[10.678,6.331],[-10.678,6.331],[-11.399,5.609],[-11.399,-5.61],[-10.678,-6.331],[10.678,-6.331],[11.4,-5.61],[11.4,5.609]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[327.506,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"bm":0,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[307.255,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":2,"cix":2,"bm":0,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.52,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"bm":0,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.785,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":2,"cix":2,"bm":0,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.572,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":2,"cix":2,"bm":0,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[247.837,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"bm":0,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[233.101,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":2,"cix":2,"bm":0,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[218.366,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":2,"cix":2,"bm":0,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[203.153,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"bm":0,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.418,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":2,"cix":2,"bm":0,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.443,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"bm":0,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.708,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"bm":0,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[143.973,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":2,"cix":2,"bm":0,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.265,0],[0,0],[0,0.265],[0,0],[-0.264,0],[0,0],[0,-0.265],[0,0]],"o":[[0,0],[-0.264,0],[0,0],[0,-0.265],[0,0],[0.265,0],[0,0],[0,0.265]],"v":[[4.546,6.331],[-4.546,6.331],[-5.025,5.852],[-5.025,-5.852],[-4.546,-6.331],[4.546,-6.331],[5.025,-5.852],[5.025,5.852]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[130.432,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"bm":0,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.33,0],[0,0],[0,0.33],[0,0],[-0.33,0],[0,0],[0,-0.33],[0,0]],"o":[[0,0],[-0.33,0],[0,0],[0,-0.33],[0,0],[0.33,0],[0,0],[0,0.33]],"v":[[7.205,6.331],[-7.204,6.331],[-7.801,5.734],[-7.801,-5.734],[-7.204,-6.331],[7.205,-6.331],[7.802,-5.734],[7.802,5.734]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[331.104,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":2,"cix":2,"bm":0,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[314.698,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"bm":0,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[299.91,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"bm":0,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[285.026,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":2,"cix":2,"bm":0,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.121,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":2,"cix":2,"bm":0,"ix":36,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.186,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 37","np":2,"cix":2,"bm":0,"ix":37,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[240.305,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 38","np":2,"cix":2,"bm":0,"ix":38,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.661,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 39","np":2,"cix":2,"bm":0,"ix":39,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.538,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 40","np":2,"cix":2,"bm":0,"ix":40,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.926,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 41","np":2,"cix":2,"bm":0,"ix":41,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.991,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 42","np":2,"cix":2,"bm":0,"ix":42,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[166.056,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 43","np":2,"cix":2,"bm":0,"ix":43,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[151.26,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 44","np":2,"cix":2,"bm":0,"ix":44,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.346,0],[0,0],[0,0.346],[0,0],[-0.346,0],[0,0],[0,-0.346],[0,0]],"o":[[0,0],[-0.346,0],[0,0],[0,-0.346],[0,0],[0.346,0],[0,0],[0,0.346]],"v":[[7.984,6.331],[-7.984,6.331],[-8.611,5.704],[-8.611,-5.704],[-7.984,-6.331],[7.984,-6.331],[8.611,-5.704],[8.611,5.704]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[134.018,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 45","np":2,"cix":2,"bm":0,"ix":45,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.432,0],[0,0],[0,0.432],[0,0],[-0.432,0],[0,0],[0,-0.433],[0,0]],"o":[[0,0],[-0.432,0],[0,0],[0,-0.433],[0,0],[0.432,0],[0,0],[0,0.432]],"v":[[12.642,6.331],[-12.641,6.331],[-13.424,5.548],[-13.424,-5.548],[-12.641,-6.331],[12.642,-6.331],[13.424,-5.548],[13.424,5.548]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.481,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 46","np":2,"cix":2,"bm":0,"ix":46,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[303.631,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 47","np":2,"cix":2,"bm":0,"ix":47,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.48,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 48","np":2,"cix":2,"bm":0,"ix":48,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.607,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 49","np":2,"cix":2,"bm":0,"ix":49,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[258.804,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 50","np":2,"cix":2,"bm":0,"ix":50,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[243.958,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 51","np":2,"cix":2,"bm":0,"ix":51,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[229.156,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 52","np":2,"cix":2,"bm":0,"ix":52,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[214.601,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 53","np":2,"cix":2,"bm":0,"ix":53,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[199.566,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 54","np":2,"cix":2,"bm":0,"ix":54,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[184.534,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 55","np":2,"cix":2,"bm":0,"ix":55,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[169.951,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 56","np":2,"cix":2,"bm":0,"ix":56,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[154.872,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 57","np":2,"cix":2,"bm":0,"ix":57,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.383,0],[0,0],[0,0.383],[0,0],[-0.383,0],[0,0],[0,-0.383],[0,0]],"o":[[0,0],[-0.383,0],[0,0],[0,-0.383],[0,0],[0.383,0],[0,0],[0,0.383]],"v":[[9.839,6.331],[-9.839,6.331],[-10.533,5.637],[-10.533,-5.638],[-9.839,-6.331],[9.839,-6.331],[10.533,-5.638],[10.533,5.637]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.94,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 58","np":2,"cix":2,"bm":0,"ix":58,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.488,0],[0,0],[0,0.488],[0,0],[-0.488,0],[0,0],[0,-0.488],[0,0]],"o":[[0,0],[-0.488,0],[0,0],[0,-0.488],[0,0],[0.488,0],[0,0],[0,0.488]],"v":[[16.185,6.331],[-16.185,6.331],[-17.068,5.448],[-17.068,-5.448],[-16.185,-6.331],[16.185,-6.331],[17.068,-5.448],[17.068,5.448]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[321.837,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 59","np":2,"cix":2,"bm":0,"ix":59,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[296.344,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 60","np":2,"cix":2,"bm":0,"ix":60,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.431,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 61","np":2,"cix":2,"bm":0,"ix":61,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.32,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 62","np":2,"cix":2,"bm":0,"ix":62,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[251.405,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 63","np":2,"cix":2,"bm":0,"ix":63,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236.91,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 64","np":2,"cix":2,"bm":0,"ix":64,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[221.869,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 65","np":2,"cix":2,"bm":0,"ix":65,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[207.064,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 66","np":2,"cix":2,"bm":0,"ix":66,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.04,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 67","np":2,"cix":2,"bm":0,"ix":67,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[177.268,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 68","np":2,"cix":2,"bm":0,"ix":68,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[162.394,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 69","np":2,"cix":2,"bm":0,"ix":69,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.447,0],[0,0],[0,0.447],[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0]],"o":[[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0],[0.447,0],[0,0],[0,0.447]],"v":[[13.533,6.331],[-13.533,6.331],[-14.342,5.522],[-14.342,-5.522],[-13.533,-6.331],[13.533,-6.331],[14.342,-5.522],[14.342,5.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[139.75,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 70","np":2,"cix":2,"bm":0,"ix":70,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.192,0],[0,0],[0,0.192],[0,0],[-0.193,0],[0,0],[0,-0.192],[0,0]],"o":[[0,0],[-0.193,0],[0,0],[0,-0.192],[0,0],[0.192,0],[0,0],[0,0.192]],"v":[[5.983,2.658],[-5.982,2.658],[-6.331,2.31],[-6.331,-2.309],[-5.982,-2.658],[5.983,-2.658],[6.331,-2.309],[6.331,2.31]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[317.448,178.429],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 71","np":2,"cix":2,"bm":0,"ix":71,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.192,0],[0,0],[0,0.192],[0,0],[-0.193,0],[0,0],[0,-0.193],[0,0]],"o":[[0,0],[-0.193,0],[0,0],[0,-0.193],[0,0],[0.192,0],[0,0],[0,0.192]],"v":[[5.983,2.658],[-5.982,2.658],[-6.331,2.309],[-6.331,-2.309],[-5.982,-2.658],[5.983,-2.658],[6.331,-2.309],[6.331,2.309]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[317.448,171.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 72","np":2,"cix":2,"bm":0,"ix":72,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[332.574,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 73","np":2,"cix":2,"bm":0,"ix":73,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[302.675,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 74","np":2,"cix":2,"bm":0,"ix":74,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.763,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 75","np":2,"cix":2,"bm":0,"ix":75,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.651,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 76","np":2,"cix":2,"bm":0,"ix":76,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.744,0],[0,0],[0,0.744],[0,0],[-0.744,0],[0,0],[0,-0.744],[0,0]],"o":[[0,0],[-0.744,0],[0,0],[0,-0.744],[0,0],[0.744,0],[0,0],[0,0.744]],"v":[[38.366,6.331],[-38.366,6.331],[-39.713,4.984],[-39.713,-4.984],[-38.366,-6.331],[38.366,-6.331],[39.713,-4.984],[39.713,4.984]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.422,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 77","np":2,"cix":2,"bm":0,"ix":77,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.438,0],[0,0],[0,0.438],[0,0],[-0.438,0],[0,0],[0,-0.438],[0,0]],"o":[[0,0],[-0.438,0],[0,0],[0,-0.438],[0,0],[0.438,0],[0,0],[0,0.438]],"v":[[12.975,6.331],[-12.975,6.331],[-13.768,5.538],[-13.768,-5.538],[-12.975,-6.331],[12.975,-6.331],[13.768,-5.538],[13.768,5.538]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[169.831,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 78","np":2,"cix":2,"bm":0,"ix":78,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.447,0],[0,0],[0,0.447],[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0]],"o":[[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0],[0.447,0],[0,0],[0,0.447]],"v":[[13.533,6.331],[-13.533,6.331],[-14.342,5.522],[-14.342,-5.522],[-13.533,-6.331],[13.533,-6.331],[14.342,-5.522],[14.342,5.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.196078434587,0.20000000298,0.211764708161,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[139.75,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 79","np":2,"cix":2,"bm":0,"ix":79,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.452,0],[0,0],[0,4.451],[0,0],[-4.451,0],[0,0],[0,-4.452],[0,0]],"o":[[0,0],[-4.451,0],[0,0],[0,-4.452],[0,0],[4.452,0],[0,0],[0,4.451]],"v":[[106.472,52.254],[-106.472,52.254],[-114.532,44.194],[-114.532,-44.194],[-106.472,-52.254],[106.472,-52.254],[114.532,-44.194],[114.532,44.194]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039227724,0.352941185236,0.439215689898,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[232.871,139.14],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 80","np":2,"cix":2,"bm":0,"ix":80,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_light.json b/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_light.json
new file mode 100644
index 0000000..111f75c
--- /dev/null
+++ b/chrome/browser/resources/chromeos/quick_unlock/fingerprint_left_of_power_button_top_right_light.json
@@ -0,0 +1 @@
+{"v":"5.9.3","fr":60,"ip":0,"op":282,"w":499,"h":246,"nm":"Fingerprint_motion_Light","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"index","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[129.86,39.816,0],"ix":2,"l":2},"a":{"a":0,"k":[129.86,39.816,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[1.246,1.561],[2.398,-0.003],[0.641,-1.511],[-1.415,-1.095],[-3.176,1.641]],"o":[[-1.007,-1.263],[-2.419,0.003],[-0.641,1.511],[2.023,1.565],[2.962,-1.531]],"v":[[119.239,-3.284],[114.233,-5.8],[108.806,-2.871],[110.154,1.399],[117.606,1.94]],"c":true}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":9.6,"s":[{"i":[[1.297,2.726],[2.42,0.323],[0.609,-2.386],[-1.456,-1.986],[-3.163,2.253]],"o":[[-1.049,-2.205],[-2.441,-0.326],[-0.609,2.386],[2.082,2.838],[2.95,-2.1]],"v":[[119.578,-1.895],[114.461,-6.697],[109.059,-2.646],[110.757,4.298],[119.598,6.692]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":34,"s":[{"i":[[0.689,3.011],[2.135,0.808],[0.977,-2.289],[-0.965,-2.295],[-3.267,1.646]],"o":[[-0.557,-2.435],[-2.153,-0.815],[-0.977,2.289],[1.38,3.28],[3.047,-1.535]],"v":[[131.004,-0.144],[127.343,-4.578],[121.727,-1.561],[121.909,4.357],[128.998,7.45]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62.4,"s":[{"i":[[1.003,2.848],[2.373,0.577],[0.857,-2.309],[-1.239,-2.128],[-3.383,1.907]],"o":[[-0.811,-2.303],[-2.393,-0.582],[-0.857,2.309],[1.771,3.042],[3.155,-1.778]],"v":[[124.457,-3.222],[119.875,-8.537],[114.076,-5.078],[115.032,2.007],[123.572,5.32]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":171.4,"s":[{"i":[[1.003,2.848],[2.373,0.577],[0.857,-2.309],[-1.239,-2.128],[-3.383,1.907]],"o":[[-0.811,-2.303],[-2.393,-0.582],[-0.857,2.309],[1.771,3.042],[3.155,-1.778]],"v":[[124.457,-3.222],[119.875,-8.537],[114.076,-5.078],[115.032,2.007],[123.572,5.32]],"c":true}]},{"i":{"x":0.34,"y":1},"o":{"x":0.333,"y":0},"t":188.4,"s":[{"i":[[0.594,2.96],[2.269,0.903],[1.171,-2.166],[-0.929,-2.281],[-3.617,1.414]],"o":[[-0.481,-2.394],[-2.288,-0.911],[-1.171,2.166],[1.328,3.26],[3.372,-1.319]],"v":[[128.941,-3.578],[125.147,-9.481],[118.922,-6.867],[118.877,0.281],[126.869,4.756]],"c":true}]},{"t":211.400390625,"s":[{"i":[[1.246,1.561],[2.398,-0.003],[0.641,-1.511],[-1.415,-1.095],[-3.176,1.641]],"o":[[-1.007,-1.263],[-2.419,0.003],[-0.641,1.511],[2.023,1.565],[2.962,-1.531]],"v":[[119.239,-3.284],[114.233,-5.8],[108.806,-2.871],[110.154,1.399],[117.606,1.94]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.823529422283,0.890196084976,0.988235294819,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[7.59,21.375],[3.972,7.334],[-8.09,4.149],[-2.192,-3.381],[-7.696,-18.956],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-6.574,-18.516],[-2.158,-3.984],[5.602,-2.873],[4.248,6.551],[3.152,7.765],[0,0]],"v":[[139.769,93.433],[122.799,40.684],[107.77,8.822],[108.51,-8.936],[121.924,-4.305],[140.953,29.671],[150.819,55.192]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":9.6,"s":[{"i":[[0,0],[8.666,20.582],[2.823,7.226],[-8.257,3.806],[-2.049,-3.47],[-4.093,-8.34],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-4.272,-10.147],[-1.649,-4.22],[5.718,-2.636],[3.97,6.724],[3.692,7.523],[0,0]],"v":[[139.769,93.433],[117.463,34.894],[106.385,8.104],[109.059,-10.945],[122.266,-5.755],[136.296,22.867],[150.819,55.192]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":34,"s":[{"i":[[0,0],[5.925,20.819],[1.415,7.858],[-9.095,2.202],[-1.379,-3.911],[-2.405,-8.974],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-2.921,-10.264],[-0.826,-4.59],[6.298,-1.525],[2.672,7.579],[2.17,8.094],[0,0]],"v":[[139.769,93.433],[122.412,35.169],[115.574,7.33],[122.061,-11.374],[134.367,-3.508],[141.316,23.288],[150.819,55.192]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62,"s":[{"i":[[0,0],[7.498,21.405],[2.044,7.484],[-8.613,2.913],[-1.671,-3.667],[-3.19,-8.726],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.696,-10.553],[-1.194,-4.371],[5.965,-2.017],[3.238,7.106],[2.877,7.871],[0,0]],"v":[[139.769,93.433],[119.327,33.178],[110.294,5.334],[114.965,-13.326],[127.551,-6.771],[138.477,23.165],[150.819,55.192]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":171.4,"s":[{"i":[[0,0],[7.501,21.407],[2.046,7.483],[-8.612,2.914],[-1.672,-3.666],[-3.191,-8.725],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.698,-10.554],[-1.195,-4.371],[5.964,-2.018],[3.239,7.105],[2.879,7.87],[0,0]],"v":[[139.769,93.433],[119.32,33.174],[110.283,5.33],[114.95,-13.33],[127.537,-6.777],[138.471,23.164],[150.819,55.192]],"c":false}]},{"i":{"x":0.34,"y":1},"o":{"x":0.333,"y":0},"t":188.4,"s":[{"i":[[0,0],[6.472,22.127],[0.979,7.696],[-8.935,1.68],[-1.142,-3.864],[-1.939,-9.086],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-3.191,-10.909],[-0.572,-4.495],[6.188,-1.164],[2.213,7.488],[1.749,8.196],[0,0]],"v":[[139.769,93.433],[120.437,31.656],[113.71,2.907],[120.942,-14.917],[132.488,-6.667],[140.768,24.22],[150.819,55.192]],"c":false}]},{"t":211.400390625,"s":[{"i":[[0,0],[7.59,21.375],[3.972,7.334],[-8.09,4.149],[-2.192,-3.381],[-7.696,-18.956],[-3.08,-7.793]],"o":[[-3.785,-14.375],[-6.574,-18.516],[-2.158,-3.984],[5.602,-2.873],[4.248,6.551],[3.152,7.765],[0,0]],"v":[[139.769,93.433],[122.799,40.684],[107.77,8.822],[108.51,-8.936],[121.924,-4.305],[140.953,29.671],[150.819,55.192]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":384,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"hand","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.335],"y":[1.035]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.639],"y":[0.105]},"t":28.801,"s":[19]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":67.199,"s":[6]},{"i":{"x":[0.499],"y":[0.989]},"o":{"x":[0.673],"y":[0]},"t":171,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.33],"y":[0.225]},"t":195,"s":[-3]},{"t":219,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[390.184,203.069,0],"to":[0,-2.833,0],"ti":[3.825,1.133,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[390.184,186.069,0],"to":[-3.825,-1.133,0],"ti":[3.825,-1.7,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.4,"y":0.4},"t":57.6,"s":[367.234,196.269,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":180.6,"s":[367.234,196.269,0],"to":[0,0,0],"ti":[0,0,0]},{"t":217.400390625,"s":[390.184,203.069,0]}],"ix":2,"l":2},"a":{"a":0,"k":[191.157,126.552,0],"ix":1,"l":2},"s":{"a":0,"k":[73,73,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-4.174,-1.462],[-1.952,-3.536],[-3.434,-11.376],[-3.791,-15.178]],"o":[[4.191,-0.821],[3.949,1.383],[5.758,10.432],[4.066,13.469],[0,0]],"v":[[186.674,42.882],[199.898,42.533],[208.723,51.149],[221.968,85.1],[232.244,126.272]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-3.749,-1.166],[-1.981,-3.388],[-3.9,-11.099],[-5.532,-17.305]],"o":[[3.581,-1.112],[3.547,1.103],[5.846,9.996],[4.617,13.141],[0,0]],"v":[[182.957,41.992],[193.49,41.044],[201.859,49.015],[216.105,81.93],[232.244,126.272]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-4.174,-1.462],[-1.952,-3.536],[-3.434,-11.376],[-3.791,-15.178]],"o":[[4.191,-0.821],[3.949,1.383],[5.758,10.432],[4.066,13.469],[0,0]],"v":[[186.674,42.882],[199.898,42.533],[208.723,51.149],[221.968,85.1],[232.244,126.272]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[118.855,95.287],[147.071,139.722]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":29,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[119.967,95.829],[147.071,139.722]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-3.327,-13.145],[-16.389,-16.681]],"o":[[-5.473,11.383],[4.992,19.724],[0,0]],"v":[[128.993,60.476],[118.855,95.287],[147.071,139.722]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-3.222,-0.408],[-1.982,-3.927],[-2.471,-5.634]],"o":[[3.208,-0.504],[4.364,0.553],[1.982,3.927],[0,0]],"v":[[166.538,35.782],[176.109,34.265],[185.72,42.518],[191.393,57.674]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-4.459,-0.224],[-2.04,-3.776],[-2.601,-5.443]],"o":[[2.751,-0.727],[3.845,0.193],[2.04,3.776],[0,0]],"v":[[162.853,36.62],[172.127,34.467],[182.097,41.696],[188.248,56.406]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-3.222,-0.408],[-1.982,-3.927],[-2.471,-5.634]],"o":[[3.208,-0.504],[4.364,0.553],[1.982,3.927],[0,0]],"v":[[166.538,35.782],[176.109,34.265],[185.72,42.518],[191.393,57.674]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[-5.326,-3.612],[-3.037,-9.057]],"o":[[6.302,-1.303],[7.28,4.937],[0,0]],"v":[[141.077,29.65],[159.804,30.799],[174.626,55.866]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":28.801,"s":[{"i":[[0,0],[-4.924,-3.228],[-3.368,-8.816]],"o":[[6.302,-1.303],[6.731,4.412],[0,0]],"v":[[141.077,29.65],[157.661,32.153],[171.936,56.187]],"c":false}]},{"t":57.599609375,"s":[{"i":[[0,0],[-5.326,-3.612],[-3.037,-9.057]],"o":[[6.302,-1.303],[7.28,4.937],[0,0]],"v":[[141.077,29.65],[159.804,30.799],[174.626,55.866]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.902,-1.673],[11.202,-12.826],[-24.735,-1.137],[0,0],[5.392,6.96]],"o":[[-4.902,1.673],[-7.666,8.777],[24.735,1.137],[0,0],[-5.392,-6.96]],"v":[[135.507,32.114],[126.633,71.854],[157.251,131.713],[175.345,58.741],[163.456,35.552]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":384,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"blue_nut","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":51,"s":[246.337]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":71,"s":[246.337]},{"i":{"x":[0.673],"y":[1.783]},"o":{"x":[0.532],"y":[0.574]},"t":117,"s":[277.337]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.118]},"t":193,"s":[271.837]},{"t":231,"s":[246.337]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":51,"s":[76.34]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":71,"s":[76.34]},{"i":{"x":[0.673],"y":[1.651]},"o":{"x":[0.532],"y":[0.478]},"t":117,"s":[60.84]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.152]},"t":193,"s":[64.34]},{"t":231,"s":[76.34]}],"ix":4}},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.367,-9.449],[-0.357,-9.449]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.261,0],[1.225,-0.536],[0.883,-0.947],[0.364,-0.638],[0.023,-0.031],[0,0],[2.521,-0.608],[0.696,-0.12],[1.376,-1.673],[-0.779,-2.082],[-0.047,-0.107],[-1.785,-0.539],[-1.605,1.033],[-0.727,0.601],[-0.282,0.224],[-2.573,-0.282],[0,0],[-0.038,-0.009],[-0.736,-0.005],[-1.421,0.786],[1.589,4.342],[2.435,1.039]],"o":[[-1.29,0],[-1.192,0.522],[-0.501,0.536],[-0.019,0.034],[0,0],[-1.39,1.889],[-0.719,0.174],[-2.204,0.382],[-1.415,1.72],[0.041,0.107],[0.745,1.701],[1.826,0.549],[0.741,-0.477],[0.28,-0.231],[2.023,-1.617],[0,0],[0.038,0.004],[0.715,0.165],[1.603,-0.009],[4.038,-2.234],[-0.915,-2.499],[-1.203,-0.514]],"v":[[7.294,-11.784],[3.491,-10.979],[0.364,-8.766],[-0.939,-6.998],[-1.002,-6.9],[-2.546,-4.803],[-8.44,-1.041],[-10.576,-0.622],[-16.058,1.762],[-17.105,8.02],[-16.973,8.343],[-13.051,11.815],[-7.655,11.055],[-5.501,9.409],[-4.661,8.723],[2.47,6.658],[5.062,6.947],[5.176,6.966],[7.363,7.208],[11.92,6.009],[16.215,-5.526],[11.021,-11.013]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[1.614,0],[0.806,0.243],[0.968,2.211],[0.054,0.144],[-1.89,2.296],[-2.379,0.413],[-0.656,0.158],[-1.101,1.495],[0,0],[-1.023,1.389],[-0.593,0.636],[-1.443,0.632],[-2.905,-1.239],[-1.106,-3.023],[4.892,-2.707],[1.913,-0.011],[0.848,0.191],[0,0],[1.607,-1.284],[0.271,-0.223],[0.841,-0.541]],"o":[[-0.822,0],[-2.321,-0.701],[-0.061,-0.139],[-1.041,-2.783],[1.847,-2.246],[0.664,-0.115],[2.05,-0.496],[0,0],[0.133,-0.188],[0.434,-0.753],[1.069,-1.145],[2.891,-1.268],[2.947,1.258],[1.925,5.258],[-1.693,0.938],[-0.895,0.003],[0,0],[-2.045,-0.23],[-0.273,0.218],[-0.74,0.613],[-1.39,0.894]],"v":[[-11.174,14.092],[-13.629,13.73],[-18.804,9.148],[-18.977,8.723],[-17.602,0.49],[-10.917,-2.593],[-8.909,-2.984],[-4.159,-5.985],[-4.156,-5.983],[-2.646,-8.04],[-1.098,-10.132],[2.688,-12.811],[11.807,-12.853],[18.093,-6.214],[12.888,7.759],[7.375,9.208],[4.784,8.928],[2.249,8.647],[-3.413,10.285],[-4.226,10.95],[-6.573,12.737]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[0.909803926945,0.917647063732,0.929411768913,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":115,"s":[0.258823529412,0.521568627451,0.956862804936,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":191,"s":[0.258823529412,0.521568627451,0.956862804936,1]},{"t":229,"s":[0.909803926945,0.917647063732,0.929411768913,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[421.294,105.593],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"red_semi_sphere","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":49,"s":[246.337]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":69,"s":[246.337]},{"i":{"x":[0.673],"y":[1.783]},"o":{"x":[0.532],"y":[0.574]},"t":115,"s":[277.337]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.118]},"t":191,"s":[271.837]},{"t":229,"s":[246.337]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.66],"y":[0]},"t":49,"s":[76.34]},{"i":{"x":[0.412],"y":[1.072]},"o":{"x":[0.363],"y":[0]},"t":69,"s":[76.34]},{"i":{"x":[0.673],"y":[1.651]},"o":{"x":[0.532],"y":[0.478]},"t":115,"s":[60.84]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.524],"y":[-0.152]},"t":191,"s":[64.34]},{"t":229,"s":[76.34]}],"ix":4}},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.699,0.676],[-8.25,-7.2],[6.322,-8.669],[0.75,0.655]],"o":[[-0.733,-0.64],[7.731,-7.475],[8.236,7.188],[-0.586,0.804],[0,0]],"v":[[-18.449,-7.751],[-18.534,-10.206],[9.749,-10.911],[12.911,17.163],[10.433,17.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":69,"s":[0.909803926945,0.917647063732,0.929411768913,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":115,"s":[0.854902020623,0.317647058824,0.247058838489,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":191,"s":[0.854902020623,0.317647058824,0.247058838489,1]},{"t":229,"s":[0.909803926945,0.917647063732,0.929411768913,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[396.815,116.057],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"triangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":58,"s":[0]},{"i":{"x":[0.518],"y":[0.81]},"o":{"x":[0.467],"y":[-0.124]},"t":117.26,"s":[-30]},{"i":{"x":[0.845],"y":[1.216]},"o":{"x":[0.456],"y":[0.151]},"t":191,"s":[-5.42]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.118]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[160.673]},{"i":{"x":[0.69],"y":[1.538]},"o":{"x":[0.459],"y":[0.578]},"t":120.6,"s":[137.673]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.108]},"t":191,"s":[142.673]},{"t":229,"s":[160.673]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.136]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[58.089]},{"i":{"x":[0.69],"y":[1.528]},"o":{"x":[0.459],"y":[0.568]},"t":120.6,"s":[43.589]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.13]},"t":191,"s":[47.214]},{"t":229,"s":[58.089]}],"ix":4}},"a":{"a":0,"k":[174.5,43.5,0],"ix":1,"l":2},"s":{"a":0,"k":[79,79,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.065,0],[0.057,-0.044],[-0.044,-0.295],[0,0],[-0.09,-0.037],[-0.233,0.175],[0,0],[0.014,0.1],[0.281,0.111],[18.926,7.542],[0,0]],"o":[[-0.17,0],[-0.077,0.062],[0,0],[0.044,0.29],[0.091,0.039],[0,0],[0.241,-0.182],[-0.013,-0.1],[-15.136,-5.993],[0,0],[-0.076,-0.03]],"v":[[-17.831,-18.954],[-18.184,-18.828],[-18.394,-18.296],[-12.861,18.624],[-12.512,19.068],[-11.952,18.996],[18.179,-3.753],[18.401,-4.286],[18.045,-4.74],[-17.616,-18.911],[-17.617,-18.911]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.547,0],[0.319,0.13],[0.135,0.906],[0,0],[-0.731,0.579],[-0.865,-0.346],[-15.133,-5.993],[-0.127,-0.933],[0.752,-0.568],[0,0]],"o":[[-0.329,0],[-0.847,-0.347],[0,0],[-0.138,-0.922],[0.73,-0.58],[18.924,7.54],[0.876,0.347],[0.127,0.934],[0,0],[-0.457,0.345]],"v":[[-12.29,21.114],[-13.269,20.92],[-14.838,18.92],[-20.372,-17.999],[-19.425,-20.395],[-16.876,-20.768],[18.781,-6.6],[20.383,-4.556],[19.385,-2.157],[-10.747,20.592]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.909803981407,0.917647118662,0.929411824544,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.158,44.447],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"green_circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":0,"s":[0]},{"i":{"x":[0.518],"y":[0.838]},"o":{"x":[0.467],"y":[-0.106]},"t":59.26,"s":[-30]},{"i":{"x":[0.845],"y":[0.946]},"o":{"x":[0.456],"y":[-0.038]},"t":191,"s":[21.58]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.105]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[165.673]},{"i":{"x":[0.69],"y":[1.614]},"o":{"x":[0.459],"y":[0.661]},"t":120.6,"s":[139.798]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.09]},"t":191,"s":[144.173]},{"t":229,"s":[165.673]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.49],"y":[1.103]},"o":{"x":[0.333],"y":[0]},"t":65,"s":[63.089]},{"i":{"x":[0.69],"y":[1.511]},"o":{"x":[0.459],"y":[0.549]},"t":120.6,"s":[43.964]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.538],"y":[-0.092]},"t":191,"s":[47.714]},{"t":229,"s":[63.089]}],"ix":4}},"a":{"a":0,"k":[174.5,43.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.663,-7.228],[7.227,6.663],[-6.663,7.227],[-7.228,-6.663]],"o":[[-6.663,7.228],[-7.228,-6.662],[6.662,-7.228],[7.227,6.662]],"v":[[13.087,12.064],[-12.063,13.087],[-13.087,-12.064],[12.064,-13.087]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":65,"s":[0.909803926945,0.917647063732,0.929411768913,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":121,"s":[0.203921583587,0.658823529412,0.325490196078,1]},{"i":{"x":[0.67],"y":[0.942]},"o":{"x":[0.35],"y":[0.104]},"t":191,"s":[0.203921583587,0.658823529412,0.325490196078,1]},{"t":229,"s":[0.909803926945,0.917647063732,0.929411768913,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.947,41.742],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape 02 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[360]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[93.709]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":118,"s":[72.209]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[72.209]},{"t":229,"s":[93.709]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[89.32]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":118,"s":[84.32]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[84.32]},{"t":229,"s":[89.32]}],"ix":4}},"a":{"a":0,"k":[98.5,60.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.24,-1.422],[0,0],[1.422,1.239],[0,0],[-1.24,1.422],[0,0],[-1.422,-1.239],[0,0]],"o":[[0,0],[-1.239,1.422],[0,0],[-1.422,-1.24],[0,0],[1.24,-1.422],[0,0],[1.422,1.24]],"v":[[13.06,1.587],[3.356,12.721],[-1.463,13.052],[-12.73,3.233],[-13.06,-1.587],[-3.357,-12.721],[1.463,-13.052],[12.729,-3.233]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":63,"s":[0.909803926945,0.917647063732,0.929411768913,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":117,"s":[0.984313785329,0.737254901961,0.01568627451,1]},{"i":{"x":[0.49],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":193,"s":[0.984313785329,0.737254901961,0.01568627451,1]},{"t":229,"s":[0.909803926945,0.917647063732,0.929411768913,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[98.529,60.42],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape 01 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.515],"y":[0.924]},"o":{"x":[0.174],"y":[0.295]},"t":0,"s":[0]},{"i":{"x":[0.518],"y":[0.767]},"o":{"x":[0.467],"y":[-0.152]},"t":46.059,"s":[-30]},{"i":{"x":[0.845],"y":[0.934]},"o":{"x":[0.456],"y":[-0.046]},"t":193,"s":[21.58]},{"t":229,"s":[0]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":20,"s":[104.271]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.47],"y":[0]},"t":62,"s":[104.271]},{"i":{"x":[0.833],"y":[0.986]},"o":{"x":[0.333],"y":[0]},"t":116,"s":[65.271]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[-0.017]},"t":154,"s":[68.271]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[65.771]},{"t":229,"s":[104.271]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.999],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":20,"s":[107.431]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.47],"y":[0]},"t":62,"s":[107.431]},{"i":{"x":[0.833],"y":[0.835]},"o":{"x":[0.333],"y":[0]},"t":116,"s":[114.431]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.169]},"t":154,"s":[113.931]},{"i":{"x":[0.34],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":193,"s":[113.431]},{"t":229,"s":[107.431]}],"ix":4}},"a":{"a":0,"k":[93.25,102.562,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.582,-1.16],[1.16,1.582],[-1.581,1.159],[-1.16,-1.581]],"o":[[-1.582,1.16],[-1.159,-1.581],[1.582,-1.16],[1.16,1.582]],"v":[[2.1,2.863],[-2.865,2.099],[-2.1,-2.864],[2.864,-2.101]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":62,"s":[0.909803926945,0.917647063732,0.929411768913,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":117,"s":[0.933333393172,0.372549019608,0.980392216701,1]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":193,"s":[0.933333393172,0.372549019608,0.980392216701,1]},{"t":238,"s":[0.909803926945,0.917647063732,0.929411768913,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[93.273,102.435],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Zoom in Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":9,"s":[276.5,117,0],"to":[-4.083,1,0],"ti":[4.083,-1,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":29,"s":[252,123,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":193,"s":[252,123,0],"to":[4.083,-1,0],"ti":[-4.083,1,0]},{"t":229,"s":[276.5,117,0]}],"ix":2,"l":2},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.2,0.2,0.2],"y":[0,0,0]},"t":9,"s":[59,59,100]},{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":29,"s":[100,100,100]},{"i":{"x":[0,0,0],"y":[1,1,1]},"o":{"x":[0.2,0.2,0.2],"y":[0,0,0]},"t":193,"s":[100,100,100]},{"t":229,"s":[59,59,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.068,0],[0.013,0.003],[0.351,0.344],[0,0.637],[-0.547,0],[0,-0.522],[-0.37,0],[0,0.344],[1.287,0],[0.377,-0.789],[0,-0.335],[-0.193,-0.515],[0.083,-0.029],[0.029,0.08],[0,0.434],[-0.145,0.306],[-1.039,0],[0,-1.39],[0.547,0],[0,0.521],[0.37,0],[0,-0.344],[-0.39,-0.386],[-0.454,-0.125],[0.023,-0.084]],"o":[[-0.013,0],[-0.511,-0.142],[-0.45,-0.447],[0,-0.522],[0.547,0],[0,0.344],[0.37,0],[0,-1.213],[-0.914,0],[-0.125,0.26],[0,0.25],[0.032,0.084],[-0.084,0.032],[-0.158,-0.422],[0,-0.387],[0.428,-0.898],[1.464,0],[0,0.521],[-0.547,0],[0,-0.344],[-0.37,0],[0,0.55],[0.305,0.303],[0.086,0.023],[-0.016,0.074]],"v":[[0.938,3.217],[0.896,3.212],[-0.302,2.535],[-1,0.857],[-0.009,-0.09],[0.983,0.857],[1.651,1.48],[2.32,0.857],[-0.012,-1.342],[-2.138,-0.044],[-2.328,0.857],[-2.112,2.018],[-2.206,2.223],[-2.411,2.13],[-2.647,0.857],[-2.427,-0.187],[-0.012,-1.667],[2.642,0.852],[1.651,1.798],[0.66,0.852],[-0.009,0.229],[-0.677,0.852],[-0.076,2.303],[0.977,2.898],[1.089,3.096]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.045,0],[0.277,0.19],[0,0.559],[-0.09,0],[0,-0.091],[-0.392,-0.264],[-0.322,0],[-0.128,0.023],[-0.016,-0.09],[0.09,-0.016]],"o":[[-0.383,0],[-0.479,-0.325],[0,-0.091],[0.091,0],[0,0.453],[0.229,0.154],[0.077,0],[0.087,-0.016],[0.016,0.087],[-0.183,0.035]],"v":[[1.585,2.555],[0.586,2.268],[-0.178,0.857],[-0.018,0.695],[0.142,0.857],[0.767,2.001],[1.585,2.229],[1.918,2.197],[2.105,2.329],[1.974,2.516]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0.042,0],[0.029,0.032],[0.215,0.389],[0,0.517],[-1.004,0],[0,-0.956],[0.09,0],[0,0.09],[0.827,0],[0,-0.779],[-0.197,-0.347],[-0.248,-0.251],[0.061,-0.064]],"o":[[-0.042,0],[-0.28,-0.28],[-0.222,-0.396],[0,-0.956],[1.004,0],[0,0.09],[-0.09,0],[0,-0.779],[-0.827,0],[0,0.463],[0.206,0.37],[0.061,0.064],[-0.035,0.032]],"v":[[-0.723,3.15],[-0.836,3.102],[-1.482,2.253],[-1.819,0.857],[0.001,-0.878],[1.823,0.857],[1.661,1.016],[1.5,0.857],[0.001,-0.557],[-1.497,0.857],[-1.198,2.094],[-0.603,2.874],[-0.603,3.102]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.052,0],[0.029,0.02],[-0.051,0.074],[-0.483,0.248],[-1.014,-0.521],[-0.318,-0.447],[0.074,-0.052],[0.052,0.074],[0.434,0.222],[0.921,-0.476],[0.289,-0.406]],"o":[[-0.032,0],[-0.074,-0.051],[0.319,-0.45],[1.01,-0.521],[0.482,0.247],[0.052,0.071],[-0.074,0.051],[-0.289,-0.405],[-0.924,-0.473],[-0.437,0.226],[-0.026,0.045]],"v":[[-2.733,-0.734],[-2.827,-0.762],[-2.866,-0.988],[-1.659,-2.04],[1.659,-2.042],[2.865,-0.997],[2.827,-0.771],[2.6,-0.811],[1.51,-1.757],[-1.514,-1.753],[-2.608,-0.801]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0.058,0],[0.023,0.013],[0.64,0],[0.55,-0.303],[0.045,0.078],[-0.078,0.042],[-0.692,0],[-0.656,-0.337],[0.041,-0.077]],"o":[[-0.026,0],[-0.618,-0.319],[-0.637,0],[-0.077,0.042],[-0.042,-0.077],[0.598,-0.325],[0.685,0],[0.08,0.042],[-0.029,0.058]],"v":[[1.871,-2.423],[1.797,-2.441],[0.004,-2.896],[-1.788,-2.441],[-2.007,-2.507],[-1.941,-2.725],[0.004,-3.217],[1.944,-2.729],[2.013,-2.512]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[322.25,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":7,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[23.292,0],[0,-23.291],[-23.292,0],[0,23.292]],"o":[[-23.292,0],[0,23.292],[23.292,0],[0,-23.291]],"v":[[0,-42.241],[-42.241,-0.001],[0,42.241],[42.241,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[24.67,0],[0,24.67],[-24.67,0],[0,-24.67]],"o":[[-24.67,0],[0,-24.67],[24.67,0],[0,24.67]],"v":[[0,44.741],[-44.741,-0.001],[0,-44.741],[44.741,-0.001]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541176470588,0.705882352941,0.972549079446,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[326.377,92.814],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[344.795,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[322.249,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.325,0],[0,0],[0,0.325],[0,0],[0.325,0],[0,0],[0,-0.325],[0,0]],"o":[[0,0],[0.325,0],[0,0],[0,-0.325],[0,0],[-0.325,0],[0,0],[0,0.325]],"v":[[-8.994,5.016],[8.994,5.016],[9.583,4.427],[9.583,-4.427],[8.994,-5.016],[-8.994,-5.016],[-9.583,-4.427],[-9.583,4.427]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[299.704,94.03],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.325],[0,0],[0.325,0],[0,0],[0,-1.282],[-0.292,-2.036],[0,0]],"o":[[0,0],[0,-0.325],[0,0],[-0.109,1.253],[0,2.117],[0,0],[0.325,0]],"v":[[1.928,4.427],[1.928,-4.427],[1.339,-5.016],[-1.752,-5.016],[-1.927,-1.216],[-1.476,5.016],[1.339,5.016]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.814,94.031],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.667,0],[0,0],[0,-0.667],[0,0],[-0.667,0],[0,0],[0,0.667],[0,0]],"o":[[0,0],[-0.667,0],[0,0],[0,0.667],[0,0],[0.667,0],[0,0],[0,-0.667]],"v":[[17.872,-10.596],[-17.873,-10.596],[-19.08,-9.389],[-19.08,9.39],[-17.873,10.597],[17.872,10.597],[19.08,9.39],[19.08,-9.389]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[335.298,114.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.497],[0,0],[0.497,0],[0,0],[0,-0.497],[0,0],[-2.508,-2.23],[0,0]],"o":[[0,0],[0,-0.497],[0,0],[-0.498,0],[0,0],[1.936,2.75],[0,0],[0.497,0]],"v":[[10.596,9.697],[10.596,-9.697],[9.697,-10.596],[-9.697,-10.596],[-10.596,-9.697],[-10.596,3.101],[-3.909,10.597],[9.697,10.597]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[301.402,114.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.497,0],[0,0],[-1.227,-2.494],[0,0]],"o":[[0,0],[0.735,2.736],[0,0],[0,-0.497]],"v":[[0.578,-3.93],[-1.477,-3.93],[1.478,3.93],[1.478,-3.03]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[285.858,108.054],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.552],[0,0],[-6.016,3.601],[0,0]],"o":[[0,0],[7.443,-0.317],[0,0],[-0.552,0]],"v":[[-10.208,-2.053],[-10.208,3.052],[10.208,-3.052],[-9.209,-3.052]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[338.469,133.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.497,0],[0,0],[0.023,-0.002],[-7.42,-0.322],[0,0]],"o":[[0,0],[-0.023,0],[6.001,3.587],[0,0],[0,-0.497]],"v":[[9.279,-3.051],[-10.114,-3.051],[-10.179,-3.038],[10.179,3.051],[10.179,-2.151]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[314.278,133.204],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.325,0],[0,0],[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325],[0,0],[-0.325,0],[0,0]],"v":[[-35.71,-14.43],[-35.121,-15.019],[-17.133,-15.019],[-16.544,-14.43],[-16.544,-5.576],[-17.133,-4.987],[-35.121,-4.987],[-35.71,-5.576]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.325,0],[0,0],[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.325,0],[0,0],[0,0.325],[0,0],[-0.325,0],[0,0]],"v":[[-13.165,-14.43],[-12.576,-15.019],[5.412,-15.019],[6.001,-14.43],[6.001,-5.576],[5.412,-4.987],[-12.576,-4.987],[-13.165,-5.576]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-0.326,0],[0,0],[0,-0.325],[0,0],[0.326,0],[0,0],[0,0.325]],"o":[[0,-0.325],[0,0],[0.326,0],[0,0],[0,0.325],[0,0],[-0.326,0],[0,0]],"v":[[9.381,-14.43],[9.97,-15.019],[27.957,-15.019],[28.546,-14.43],[28.546,-5.576],[27.957,-4.987],[9.97,-4.987],[9.381,-5.576]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0.667,0],[0,0],[0,0.667],[0,0],[-0.667,0],[0,0],[0,-0.667]],"o":[[0,0.667],[0,0],[-0.667,0],[0,0],[0,-0.667],[0,0],[0.667,0],[0,0]],"v":[[28.546,20.077],[27.339,21.285],[-8.406,21.285],[-9.614,20.077],[-9.614,1.299],[-8.406,0.091],[27.339,0.091],[28.546,1.299]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0,-0.325],[0,0],[0.326,0],[0,0],[-0.445,-1.656],[0,0],[0,-0.497],[0,0],[-1.3,-1.847],[0,0],[-0.497,0],[0,0],[0,-0.497],[0,0],[0.497,0],[0,0],[-2.356,-1.408],[-0.023,0],[0,0],[0,-0.497],[0,0],[-0.643,0],[-0.626,0.026],[0,0],[-0.552,0],[0,0],[-2.807,11.407],[0,0],[7.451,0],[0,0],[0.539,-6.218]],"o":[[0.326,0],[0,0],[0,0.325],[0,0],[0.248,1.728],[0,0],[0.498,0],[0,0],[1.005,2.043],[0,0],[0,-0.497],[0,0],[0.497,0],[0,0],[0,0.497],[0,0],[2.039,1.814],[0.022,-0.001],[0,0],[0.498,0],[0,0],[0.637,0.027],[0.632,0],[0,0],[0,-0.551],[0,0],[9.816,-5.875],[0,0],[0,-7.451],[0,0],[-2.878,5.192],[0,0]],"v":[[-39.679,-15.019],[-39.09,-14.43],[-39.09,-5.576],[-39.679,-4.987],[-42.494,-4.987],[-41.451,0.091],[-39.396,0.091],[-38.496,0.992],[-38.496,7.951],[-35.026,13.789],[-35.026,0.992],[-34.126,0.091],[-14.732,0.091],[-13.832,0.992],[-13.832,20.384],[-14.732,21.285],[-28.337,21.285],[-21.732,26.132],[-21.668,26.119],[-2.275,26.119],[-1.374,27.02],[-1.374,32.223],[0.545,32.271],[2.43,32.224],[2.43,27.118],[3.429,26.119],[22.846,26.119],[42.77,-0.797],[42.77,-18.781],[29.279,-32.271],[-37.511,-32.271],[-42.77,-15.019]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.831,104.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":7,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Keyboard Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.5,123,0],"ix":2,"l":2},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.063,0],[0.012,0.003],[0.328,0.323],[0,0.597],[-0.512,0],[0,-0.488],[-0.347,0],[0,0.323],[1.205,0],[0.352,-0.738],[0,-0.313],[-0.181,-0.482],[0.079,-0.027],[0.028,0.075],[0,0.407],[-0.135,0.286],[-0.973,0],[0,-1.301],[0.512,0],[0,0.489],[0.347,0],[0,-0.322],[-0.365,-0.361],[-0.425,-0.118],[0.021,-0.078]],"o":[[-0.012,0],[-0.479,-0.133],[-0.422,-0.419],[0,-0.488],[0.512,0],[0,0.323],[0.346,0],[0,-1.135],[-0.856,0],[-0.118,0.244],[0,0.235],[0.03,0.078],[-0.078,0.03],[-0.147,-0.395],[0,-0.361],[0.401,-0.84],[1.371,0],[0,0.489],[-0.512,0],[0,-0.322],[-0.346,0],[0,0.516],[0.286,0.284],[0.081,0.021],[-0.015,0.07]],"v":[[0.878,3.013],[0.839,3.007],[-0.282,2.374],[-0.936,0.801],[-0.008,-0.084],[0.92,0.801],[1.547,1.386],[2.174,0.801],[-0.011,-1.256],[-2.002,-0.042],[-2.18,0.801],[-1.978,1.889],[-2.066,2.082],[-2.259,1.995],[-2.478,0.801],[-2.274,-0.175],[-0.011,-1.561],[2.475,0.798],[1.547,1.684],[0.619,0.798],[-0.008,0.214],[-0.635,0.798],[-0.071,2.157],[0.914,2.715],[1.02,2.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.042,0],[0.259,0.178],[0,0.525],[-0.084,0],[0,-0.084],[-0.367,-0.247],[-0.302,0],[-0.121,0.021],[-0.015,-0.084],[0.085,-0.015]],"o":[[-0.359,0],[-0.449,-0.304],[0,-0.084],[0.084,0],[0,0.425],[0.214,0.145],[0.072,0],[0.081,-0.015],[0.015,0.082],[-0.172,0.033]],"v":[[1.484,2.392],[0.55,2.124],[-0.168,0.801],[-0.017,0.651],[0.134,0.801],[0.718,1.874],[1.484,2.088],[1.797,2.058],[1.972,2.181],[1.848,2.356]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0.039,0],[0.027,0.03],[0.202,0.365],[0,0.486],[-0.94,0],[0,-0.894],[0.084,0],[0,0.085],[0.775,0],[0,-0.729],[-0.183,-0.325],[-0.232,-0.235],[0.057,-0.061]],"o":[[-0.039,0],[-0.262,-0.263],[-0.208,-0.371],[0,-0.894],[0.94,0],[0,0.085],[-0.084,0],[0,-0.729],[-0.774,0],[0,0.434],[0.193,0.347],[0.057,0.06],[-0.033,0.03]],"v":[[-0.677,2.95],[-0.782,2.905],[-1.388,2.109],[-1.704,0.801],[0.001,-0.823],[1.707,0.801],[1.556,0.952],[1.405,0.801],[0.001,-0.521],[-1.403,0.801],[-1.123,1.961],[-0.565,2.691],[-0.565,2.905]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.048,0],[0.027,0.018],[-0.049,0.069],[-0.452,0.232],[-0.949,-0.488],[-0.298,-0.419],[0.069,-0.048],[0.048,0.069],[0.407,0.208],[0.862,-0.446],[0.271,-0.38]],"o":[[-0.03,0],[-0.07,-0.048],[0.298,-0.422],[0.946,-0.488],[0.452,0.232],[0.048,0.066],[-0.07,0.048],[-0.271,-0.38],[-0.864,-0.443],[-0.41,0.211],[-0.024,0.042]],"v":[[-2.56,-0.687],[-2.647,-0.714],[-2.683,-0.925],[-1.553,-1.91],[1.553,-1.913],[2.683,-0.934],[2.647,-0.723],[2.436,-0.759],[1.414,-1.645],[-1.418,-1.642],[-2.442,-0.75]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0.054,0],[0.022,0.012],[0.6,0],[0.515,-0.283],[0.042,0.072],[-0.072,0.039],[-0.648,0],[-0.615,-0.316],[0.04,-0.072]],"o":[[-0.024,0],[-0.578,-0.298],[-0.596,0],[-0.072,0.039],[-0.039,-0.072],[0.561,-0.304],[0.642,0],[0.075,0.039],[-0.027,0.054]],"v":[[1.752,-2.269],[1.682,-2.287],[0.004,-2.712],[-1.674,-2.287],[-1.879,-2.347],[-1.819,-2.552],[0.004,-3.013],[1.821,-2.555],[1.884,-2.353]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.90588241278,0.913725550034,0.925490255917,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.835,96.568],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":7,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[333.18,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317647058824,0.521568627451,0.925490255917,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.71,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.24,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.771,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[279.301,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.831,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[252.361,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[238.891,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.421,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[211.952,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.482,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[185.012,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[171.542,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.373,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.373,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.072,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"bm":0,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.373,2.997],[-5.374,2.997],[-5.726,2.645],[-5.726,-2.646],[-5.374,-2.997],[5.373,-2.997],[5.725,-2.646],[5.725,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[144.603,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"bm":0,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.194,0],[0,0],[0,0.194],[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0]],"o":[[0,0],[-0.194,0],[0,0],[0,-0.194],[0,0],[0.194,0],[0,0],[0,0.194]],"v":[[5.374,2.997],[-5.374,2.997],[-5.725,2.645],[-5.725,-2.646],[-5.374,-2.997],[5.374,-2.997],[5.726,-2.646],[5.726,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.133,100.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"bm":0,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.398,0],[0,0],[0,0.399],[0,0],[-0.398,0],[0,0],[0,-0.398],[0,0]],"o":[[0,0],[-0.398,0],[0,0],[0,-0.398],[0,0],[0.398,0],[0,0],[0,0.399]],"v":[[10.678,6.331],[-10.678,6.331],[-11.399,5.609],[-11.399,-5.61],[-10.678,-6.331],[10.678,-6.331],[11.4,-5.61],[11.4,5.609]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[327.506,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"bm":0,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[307.255,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":2,"cix":2,"bm":0,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.52,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"bm":0,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.785,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":2,"cix":2,"bm":0,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.572,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":2,"cix":2,"bm":0,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[247.837,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"bm":0,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[233.101,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":2,"cix":2,"bm":0,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[218.366,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":2,"cix":2,"bm":0,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[203.153,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"bm":0,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.418,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":2,"cix":2,"bm":0,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.443,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"bm":0,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.708,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"bm":0,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[143.973,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":2,"cix":2,"bm":0,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.265,0],[0,0],[0,0.265],[0,0],[-0.264,0],[0,0],[0,-0.265],[0,0]],"o":[[0,0],[-0.264,0],[0,0],[0,-0.265],[0,0],[0.265,0],[0,0],[0,0.265]],"v":[[4.546,6.331],[-4.546,6.331],[-5.025,5.852],[-5.025,-5.852],[-4.546,-6.331],[4.546,-6.331],[5.025,-5.852],[5.025,5.852]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[130.432,112.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"bm":0,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.33,0],[0,0],[0,0.33],[0,0],[-0.33,0],[0,0],[0,-0.33],[0,0]],"o":[[0,0],[-0.33,0],[0,0],[0,-0.33],[0,0],[0.33,0],[0,0],[0,0.33]],"v":[[7.205,6.331],[-7.204,6.331],[-7.801,5.734],[-7.801,-5.734],[-7.204,-6.331],[7.205,-6.331],[7.802,-5.734],[7.802,5.734]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[331.104,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":2,"cix":2,"bm":0,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[314.698,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"bm":0,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[299.91,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"bm":0,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[285.026,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":2,"cix":2,"bm":0,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.121,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":2,"cix":2,"bm":0,"ix":36,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.186,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 37","np":2,"cix":2,"bm":0,"ix":37,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[240.305,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 38","np":2,"cix":2,"bm":0,"ix":38,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.661,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 39","np":2,"cix":2,"bm":0,"ix":39,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.538,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 40","np":2,"cix":2,"bm":0,"ix":40,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.926,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 41","np":2,"cix":2,"bm":0,"ix":41,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.991,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 42","np":2,"cix":2,"bm":0,"ix":42,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[166.056,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 43","np":2,"cix":2,"bm":0,"ix":43,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[151.26,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 44","np":2,"cix":2,"bm":0,"ix":44,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.346,0],[0,0],[0,0.346],[0,0],[-0.346,0],[0,0],[0,-0.346],[0,0]],"o":[[0,0],[-0.346,0],[0,0],[0,-0.346],[0,0],[0.346,0],[0,0],[0,0.346]],"v":[[7.984,6.331],[-7.984,6.331],[-8.611,5.704],[-8.611,-5.704],[-7.984,-6.331],[7.984,-6.331],[8.611,-5.704],[8.611,5.704]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[134.018,128.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 45","np":2,"cix":2,"bm":0,"ix":45,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.432,0],[0,0],[0,0.432],[0,0],[-0.432,0],[0,0],[0,-0.433],[0,0]],"o":[[0,0],[-0.432,0],[0,0],[0,-0.433],[0,0],[0.432,0],[0,0],[0,0.432]],"v":[[12.642,6.331],[-12.641,6.331],[-13.424,5.548],[-13.424,-5.548],[-12.641,-6.331],[12.642,-6.331],[13.424,-5.548],[13.424,5.548]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.481,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 46","np":2,"cix":2,"bm":0,"ix":46,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[303.631,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 47","np":2,"cix":2,"bm":0,"ix":47,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.48,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 48","np":2,"cix":2,"bm":0,"ix":48,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.607,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 49","np":2,"cix":2,"bm":0,"ix":49,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[258.804,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 50","np":2,"cix":2,"bm":0,"ix":50,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[243.958,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 51","np":2,"cix":2,"bm":0,"ix":51,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[229.156,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 52","np":2,"cix":2,"bm":0,"ix":52,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[214.601,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 53","np":2,"cix":2,"bm":0,"ix":53,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[199.566,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 54","np":2,"cix":2,"bm":0,"ix":54,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[184.534,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 55","np":2,"cix":2,"bm":0,"ix":55,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[169.951,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 56","np":2,"cix":2,"bm":0,"ix":56,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[154.872,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 57","np":2,"cix":2,"bm":0,"ix":57,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.383,0],[0,0],[0,0.383],[0,0],[-0.383,0],[0,0],[0,-0.383],[0,0]],"o":[[0,0],[-0.383,0],[0,0],[0,-0.383],[0,0],[0.383,0],[0,0],[0,0.383]],"v":[[9.839,6.331],[-9.839,6.331],[-10.533,5.637],[-10.533,-5.638],[-9.839,-6.331],[9.839,-6.331],[10.533,-5.638],[10.533,5.637]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317647058824,0.521568627451,0.925490255917,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.94,143.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 58","np":2,"cix":2,"bm":0,"ix":58,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.488,0],[0,0],[0,0.488],[0,0],[-0.488,0],[0,0],[0,-0.488],[0,0]],"o":[[0,0],[-0.488,0],[0,0],[0,-0.488],[0,0],[0.488,0],[0,0],[0,0.488]],"v":[[16.185,6.331],[-16.185,6.331],[-17.068,5.448],[-17.068,-5.448],[-16.185,-6.331],[16.185,-6.331],[17.068,-5.448],[17.068,5.448]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[321.837,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 59","np":2,"cix":2,"bm":0,"ix":59,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[296.344,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 60","np":2,"cix":2,"bm":0,"ix":60,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.431,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 61","np":2,"cix":2,"bm":0,"ix":61,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.32,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 62","np":2,"cix":2,"bm":0,"ix":62,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[251.405,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 63","np":2,"cix":2,"bm":0,"ix":63,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236.91,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 64","np":2,"cix":2,"bm":0,"ix":64,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[221.869,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 65","np":2,"cix":2,"bm":0,"ix":65,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[207.064,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 66","np":2,"cix":2,"bm":0,"ix":66,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.04,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 67","np":2,"cix":2,"bm":0,"ix":67,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[177.268,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 68","np":2,"cix":2,"bm":0,"ix":68,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[162.394,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 69","np":2,"cix":2,"bm":0,"ix":69,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.447,0],[0,0],[0,0.447],[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0]],"o":[[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0],[0.447,0],[0,0],[0,0.447]],"v":[[13.533,6.331],[-13.533,6.331],[-14.342,5.522],[-14.342,-5.522],[-13.533,-6.331],[13.533,-6.331],[14.342,-5.522],[14.342,5.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[139.75,159.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 70","np":2,"cix":2,"bm":0,"ix":70,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.192,0],[0,0],[0,0.192],[0,0],[-0.193,0],[0,0],[0,-0.192],[0,0]],"o":[[0,0],[-0.193,0],[0,0],[0,-0.192],[0,0],[0.192,0],[0,0],[0,0.192]],"v":[[5.983,2.658],[-5.982,2.658],[-6.331,2.31],[-6.331,-2.309],[-5.982,-2.658],[5.983,-2.658],[6.331,-2.309],[6.331,2.31]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[317.448,178.429],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 71","np":2,"cix":2,"bm":0,"ix":71,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.192,0],[0,0],[0,0.192],[0,0],[-0.193,0],[0,0],[0,-0.193],[0,0]],"o":[[0,0],[-0.193,0],[0,0],[0,-0.193],[0,0],[0.192,0],[0,0],[0,0.192]],"v":[[5.983,2.658],[-5.982,2.658],[-6.331,2.309],[-6.331,-2.309],[-5.982,-2.658],[5.983,-2.658],[6.331,-2.309],[6.331,2.309]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[317.448,171.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 72","np":2,"cix":2,"bm":0,"ix":72,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[332.574,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 73","np":2,"cix":2,"bm":0,"ix":73,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[302.675,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 74","np":2,"cix":2,"bm":0,"ix":74,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.763,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 75","np":2,"cix":2,"bm":0,"ix":75,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.297,0],[0,0],[0,0.297],[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0]],"o":[[0,0],[-0.297,0],[0,0],[0,-0.297],[0,0],[0.297,0],[0,0],[0,0.297]],"v":[[5.793,6.331],[-5.794,6.331],[-6.331,5.793],[-6.331,-5.793],[-5.794,-6.331],[5.793,-6.331],[6.331,-5.793],[6.331,5.793]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.651,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 76","np":2,"cix":2,"bm":0,"ix":76,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.744,0],[0,0],[0,0.744],[0,0],[-0.744,0],[0,0],[0,-0.744],[0,0]],"o":[[0,0],[-0.744,0],[0,0],[0,-0.744],[0,0],[0.744,0],[0,0],[0,0.744]],"v":[[38.366,6.331],[-38.366,6.331],[-39.713,4.984],[-39.713,-4.984],[-38.366,-6.331],[38.366,-6.331],[39.713,-4.984],[39.713,4.984]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.422,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 77","np":2,"cix":2,"bm":0,"ix":77,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.438,0],[0,0],[0,0.438],[0,0],[-0.438,0],[0,0],[0,-0.438],[0,0]],"o":[[0,0],[-0.438,0],[0,0],[0,-0.438],[0,0],[0.438,0],[0,0],[0,0.438]],"v":[[12.975,6.331],[-12.975,6.331],[-13.768,5.538],[-13.768,-5.538],[-12.975,-6.331],[12.975,-6.331],[13.768,-5.538],[13.768,5.538]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[169.831,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 78","np":2,"cix":2,"bm":0,"ix":78,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.447,0],[0,0],[0,0.447],[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0]],"o":[[0,0],[-0.447,0],[0,0],[0,-0.447],[0,0],[0.447,0],[0,0],[0,0.447]],"v":[[13.533,6.331],[-13.533,6.331],[-14.342,5.522],[-14.342,-5.522],[-13.533,-6.331],[13.533,-6.331],[14.342,-5.522],[14.342,5.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[139.75,174.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 79","np":2,"cix":2,"bm":0,"ix":79,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.452,0],[0,0],[0,4.451],[0,0],[-4.451,0],[0,0],[0,-4.452],[0,0]],"o":[[0,0],[-4.451,0],[0,0],[0,-4.452],[0,0],[4.452,0],[0,0],[0,4.451]],"v":[[106.472,52.254],[-106.472,52.254],[-114.532,44.194],[-114.532,-44.194],[-106.472,-52.254],[106.472,-52.254],[114.532,-44.194],[114.532,44.194]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[232.871,139.14],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 80","np":2,"cix":2,"bm":0,"ix":80,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":919,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":1,"nm":"White Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.5,123,0],"ix":2,"l":2},"a":{"a":0,"k":[249.5,123,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"sw":499,"sh":246,"sc":"#ffffff","ip":0,"op":919,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn b/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
index 33e241a..ed8966e 100644
--- a/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
+++ b/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
@@ -16,12 +16,14 @@
 js_library("set_time_dialog") {
   deps = [
     ":set_time_browser_proxy",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("set_time_browser_proxy") {
diff --git a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js
index 6ee703e..4b39ca2 100644
--- a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js
+++ b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js
@@ -13,12 +13,12 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_page_host_style.css.js';
 import 'chrome://resources/cr_elements/md_select.css.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './strings.m.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
diff --git a/chrome/browser/resources/chromeos/smb_shares/BUILD.gn b/chrome/browser/resources/chromeos/smb_shares/BUILD.gn
index 9afa1e7..49a9cb8 100644
--- a/chrome/browser/resources/chromeos/smb_shares/BUILD.gn
+++ b/chrome/browser/resources/chromeos/smb_shares/BUILD.gn
@@ -15,6 +15,7 @@
 
 js_library("smb_share_dialog") {
   deps = [
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/smb_shares:add_smb_share_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
@@ -22,15 +23,17 @@
 
 js_library("smb_credentials_dialog") {
   deps = [
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 html_to_js("web_components") {
diff --git a/chrome/browser/resources/extensions/shared_style.css b/chrome/browser/resources/extensions/shared_style.css
index 1bbd2fcc4..083a9f3 100644
--- a/chrome/browser/resources/extensions/shared_style.css
+++ b/chrome/browser/resources/extensions/shared_style.css
@@ -12,7 +12,6 @@
 
 a[href] {
   color: var(--cr-link-color);
-  text-decoration: none;
 }
 
 .activity-message {
diff --git a/chrome/browser/resources/gaia_auth_host/OWNERS b/chrome/browser/resources/gaia_auth_host/OWNERS
index ddff231d..7417bb1 100644
--- a/chrome/browser/resources/gaia_auth_host/OWNERS
+++ b/chrome/browser/resources/gaia_auth_host/OWNERS
@@ -3,4 +3,4 @@
 xiyuan@chromium.org
 
 # (in CET)
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/chrome/browser/resources/history/shared_style.css b/chrome/browser/resources/history/shared_style.css
index 3cabafa..9b07ee4 100644
--- a/chrome/browser/resources/history/shared_style.css
+++ b/chrome/browser/resources/history/shared_style.css
@@ -12,7 +12,6 @@
 
 a {
   color: var(--cr-link-color);
-  text-decoration: none;
 }
 
 .history-cards {
diff --git a/chrome/browser/resources/management/management_ui.html b/chrome/browser/resources/management/management_ui.html
index c868241e..73e9c2b 100644
--- a/chrome/browser/resources/management/management_ui.html
+++ b/chrome/browser/resources/management/management_ui.html
@@ -10,7 +10,6 @@
 
       a {
         color: var(--cr-link-color);
-        text-decoration: none;
       }
 
       cr-toolbar {
diff --git a/chrome/browser/resources/nearby_share/BUILD.gn b/chrome/browser/resources/nearby_share/BUILD.gn
index f3a9079..36efb47c1 100644
--- a/chrome/browser/resources/nearby_share/BUILD.gn
+++ b/chrome/browser/resources/nearby_share/BUILD.gn
@@ -180,9 +180,10 @@
     "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile",
     "//chrome/browser/ui/webui/nearby_share:share_type_js_library_for_compile",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("nearby_discovery_page") {
@@ -194,8 +195,9 @@
     "//chrome/browser/ui/webui/nearby_share:share_type_js_library_for_compile",
     "//third_party/polymer/v3_0/components-chromium/iron-list",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/cr_elements/cr_lottie:cr_lottie",
     "//ui/webui/resources/js:assert.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
diff --git a/chrome/browser/resources/new_tab_page/middle_slot_promo.html b/chrome/browser/resources/new_tab_page/middle_slot_promo.html
index d032a1e..f1d5f17 100644
--- a/chrome/browser/resources/new_tab_page/middle_slot_promo.html
+++ b/chrome/browser/resources/new_tab_page/middle_slot_promo.html
@@ -33,7 +33,7 @@
   a {
     color: var(--cr-link-color);
     cursor: pointer;
-    text-decoration: none;
+    text-decoration: underline;
   }
 
   a:focus {
@@ -66,7 +66,7 @@
   #dismissPromoButton {
     --cr-icon-button-icon-size: 14px;
     --cr-icon-button-size: 20px;
-    margin-inline-start: 4px; 
+    margin-inline-start: 4px;
   }
 
   #promoContainer > :last-child {
diff --git a/chrome/browser/resources/new_tab_page/modules/drive/module.html b/chrome/browser/resources/new_tab_page/modules/drive/module.html
index 2edacb7..cf8313f 100644
--- a/chrome/browser/resources/new_tab_page/modules/drive/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/drive/module.html
@@ -66,18 +66,6 @@
     color: var(--color-new-tab-page-secondary-foreground);
     font-size: 12px;
   }
-
-  ntp-info-dialog a {
-    color: var(--cr-link-color);
-    cursor: pointer;
-    text-decoration: none;
-  }
-
-  ntp-info-dialog a:focus {
-    border-radius: 2px;
-    box-shadow: var(--ntp-focus-shadow);
-    outline: none;
-  }
 </style>
 <ntp-module-header
     dismiss-text="[[i18nRecursive('',
diff --git a/chrome/browser/resources/new_tab_page/modules/photos/module.html b/chrome/browser/resources/new_tab_page/modules/photos/module.html
index 8458221..cd9f31de 100644
--- a/chrome/browser/resources/new_tab_page/modules/photos/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/photos/module.html
@@ -411,7 +411,6 @@
   ntp-info-dialog a {
     color: var(--cr-link-color);
     cursor: pointer;
-    text-decoration: none;
   }
 
   ntp-info-dialog a:focus {
diff --git a/chrome/browser/resources/new_tab_page/modules/recipes/module.html b/chrome/browser/resources/new_tab_page/modules/recipes/module.html
index 99b1a0aa8..49686282 100644
--- a/chrome/browser/resources/new_tab_page/modules/recipes/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/recipes/module.html
@@ -165,18 +165,6 @@
     margin-inline-end: 12px;
     margin-inline-start: 8px;
   }
-
-  ntp-info-dialog a {
-    color: var(--cr-link-color);
-    cursor: pointer;
-    text-decoration: none;
-  }
-
-  ntp-info-dialog a:focus {
-    border-radius: 2px;
-    box-shadow: var(--ntp-focus-shadow);
-    outline: none;
-  }
 </style>
 <ntp-module-header
     dismiss-text="[[i18n('modulesDismissButtonText', dismissName_)]]"
diff --git a/chrome/browser/resources/new_tab_page/voice_search_overlay.html b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
index d04f243..077080e 100644
--- a/chrome/browser/resources/new_tab_page/voice_search_overlay.html
+++ b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
@@ -109,7 +109,6 @@
     font-size: 18px;
     font-weight: 500;
     margin-inline-start: 0.25em;
-    text-decoration: none;
   }
 
   #micContainer {
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn
index 4852d393..b05ba1f 100644
--- a/chrome/browser/resources/password_manager/BUILD.gn
+++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -12,7 +12,10 @@
     "side_bar.ts",
     "toolbar.ts",
   ]
-  non_web_component_files = [ "password_manager.ts" ]
+  non_web_component_files = [
+    "password_manager.ts",
+    "router.ts",
+  ]
 
   # Files that are passed as input to css_to_wrapper().
   css_files = [
diff --git a/chrome/browser/resources/password_manager/COMMON_METADATA b/chrome/browser/resources/password_manager/COMMON_METADATA
new file mode 100644
index 0000000..43d76b8
--- /dev/null
+++ b/chrome/browser/resources/password_manager/COMMON_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "UI>Browser>Passwords"
+}
diff --git a/chrome/browser/resources/password_manager/OWNERS b/chrome/browser/resources/password_manager/OWNERS
new file mode 100644
index 0000000..dcc0544
--- /dev/null
+++ b/chrome/browser/resources/password_manager/OWNERS
@@ -0,0 +1,2 @@
+mamir@chromium.org
+vsemeniuk@google.com
diff --git a/chrome/browser/resources/password_manager/password_manager.ts b/chrome/browser/resources/password_manager/password_manager.ts
index d4ce26b..b0c4ef05 100644
--- a/chrome/browser/resources/password_manager/password_manager.ts
+++ b/chrome/browser/resources/password_manager/password_manager.ts
@@ -5,5 +5,6 @@
 import './password_manager_app.js';
 
 export {PasswordManagerAppElement} from './password_manager_app.js';
+export {Page, RouteObserverMixin, RouteObserverMixinInterface, Router} from './router.js';
 export {PasswordManagerSideBarElement} from './side_bar.js';
 export {PasswordManagerToolbarElement} from './toolbar.js';
diff --git a/chrome/browser/resources/password_manager/router.ts b/chrome/browser/resources/password_manager/router.ts
new file mode 100644
index 0000000..1160055
--- /dev/null
+++ b/chrome/browser/resources/password_manager/router.ts
@@ -0,0 +1,127 @@
+// 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 {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {dedupingMixin, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+/**
+ * The different pages that can be shown at a time.
+ */
+export enum Page {
+  PASSWORDS = 'passwords',
+  CHECKUP = 'checkup',
+  SETTINGS = 'settings',
+}
+
+/**
+ * A helper object to manage in-page navigations. Since the Password Manager
+ * page needs to support different urls for different subpages (like the checkup
+ * page), we use this object to manage the history and url conversions.
+ */
+export class Router {
+  static getInstance(): Router {
+    return routerInstance || (routerInstance = new Router());
+  }
+
+  private currentPage_: Page = Page.PASSWORDS;
+  private routeObservers_: Set<RouteObserverMixinInterface> = new Set();
+
+  constructor() {
+    this.processRoute_();
+
+    window.addEventListener('popstate', () => {
+      this.processRoute_();
+    });
+  }
+
+  addObserver(observer: RouteObserverMixinInterface) {
+    assert(!this.routeObservers_.has(observer));
+    this.routeObservers_.add(observer);
+  }
+
+  removeObserver(observer: RouteObserverMixinInterface) {
+    assert(this.routeObservers_.delete(observer));
+  }
+
+  get currentPage(): Page {
+    return this.currentPage_;
+  }
+
+  /**
+   * Navigates to a page and pushes a new history entry.
+   */
+  navigateTo(page: Page) {
+    if (page === this.currentPage_) {
+      return;
+    }
+
+    this.currentPage_ = page;
+    const path = '/' + page;
+    const state = {url: path};
+    history.pushState(state, '', path);
+    this.notifyObservers_();
+  }
+
+  private notifyObservers_() {
+    this.routeObservers_.forEach((observer) => {
+      observer.currentRouteChanged(this.currentPage_);
+    });
+  }
+
+  /**
+   * Helper function to set the current page and notify all observers.
+   */
+  private processRoute_() {
+    const section = location.pathname.substring(1).split('/')[0] || '';
+
+    switch (section) {
+      case Page.PASSWORDS:
+        this.currentPage_ = Page.PASSWORDS;
+        break;
+      case Page.CHECKUP:
+        this.currentPage_ = Page.CHECKUP;
+        break;
+      case Page.SETTINGS:
+        this.currentPage_ = Page.SETTINGS;
+        break;
+      default:
+        history.replaceState({}, '', this.currentPage_);
+    }
+    this.notifyObservers_();
+  }
+}
+
+let routerInstance: Router|null = null;
+
+type Constructor<T> = new (...args: any[]) => T;
+
+export const RouteObserverMixin = dedupingMixin(
+    <T extends Constructor<PolymerElement>>(superClass: T): T&
+    Constructor<RouteObserverMixinInterface> => {
+      class RouteObserverMixin extends superClass {
+        override connectedCallback() {
+          super.connectedCallback();
+
+          Router.getInstance().addObserver(this);
+
+          this.currentRouteChanged(Router.getInstance().currentPage);
+        }
+
+        override disconnectedCallback() {
+          super.disconnectedCallback();
+
+          Router.getInstance().removeObserver(this);
+        }
+
+        currentRouteChanged(_: Page): void {
+          assertNotReached();
+        }
+      }
+
+      return RouteObserverMixin;
+    });
+
+export interface RouteObserverMixinInterface {
+  currentRouteChanged(page: Page): void;
+}
diff --git a/chrome/browser/resources/password_manager/side_bar.html b/chrome/browser/resources/password_manager/side_bar.html
index bc2b930..5a7aed8 100644
--- a/chrome/browser/resources/password_manager/side_bar.html
+++ b/chrome/browser/resources/password_manager/side_bar.html
@@ -11,7 +11,8 @@
 </style>
 <cr-menu-selector>
   <iron-selector id="menu" selectable=".page-item" attr-for-selected="path"
-      selected-attribute="selected" selected="passwords">
+      selected-attribute="selected" selected="[[selectedPage_]]"
+      on-iron-activate="onSelectorActivate_">
     <a id="passwords" role="menuitem" class="page-item cr-nav-menu-item"
         path="passwords">
       <iron-icon icon="passwords-icon:password"></iron-icon>
diff --git a/chrome/browser/resources/password_manager/side_bar.ts b/chrome/browser/resources/password_manager/side_bar.ts
index 2f415de..7866007 100644
--- a/chrome/browser/resources/password_manager/side_bar.ts
+++ b/chrome/browser/resources/password_manager/side_bar.ts
@@ -12,6 +12,7 @@
 import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {Page, RouteObserverMixin, Router} from './router.js';
 import {getTemplate} from './side_bar.html.js';
 
 export interface PasswordManagerSideBarElement {
@@ -20,7 +21,8 @@
   };
 }
 
-export class PasswordManagerSideBarElement extends PolymerElement {
+export class PasswordManagerSideBarElement extends RouteObserverMixin
+(PolymerElement) {
   static get is() {
     return 'password-manager-side-bar';
   }
@@ -28,6 +30,23 @@
   static get template() {
     return getTemplate();
   }
+
+  static get properties() {
+    return {
+      // The id of the currently selected page.
+      selectedPage_: String,
+    };
+  }
+
+  private selectedPage_: Page;
+
+  override currentRouteChanged(page: Page): void {
+    this.selectedPage_ = page;
+  }
+
+  private onSelectorActivate_(event: CustomEvent<{selected: Page}>) {
+    Router.getInstance().navigateTo(event.detail.selected);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index 8f5dc2b..473a49b 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -470,7 +470,6 @@
     "os_privacy_page:closure_compile_module",
     "os_reset_page:closure_compile_module",
     "os_search_page:closure_compile_module",
-    "os_settings_page:closure_compile_module",
     "settings_scheduler_slider:closure_compile_module",
   ]
 }
@@ -484,6 +483,7 @@
     ":deep_linking_behavior",
     ":global_scroll_target_behavior",
     ":lazy_load",
+    ":main_page_behavior",
     ":metrics_recorder",
     ":os_icons",
     ":os_page_visibility",
@@ -523,6 +523,15 @@
   ]
 }
 
+js_library("main_page_behavior") {
+  deps = [
+    "..:router",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/js:assert.m",
+    "//ui/webui/resources/js:util.m",
+  ]
+}
+
 js_library("metrics_recorder") {
   deps = [
     "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_webui_js",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
index 160e7dd..8c9ef96 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
@@ -37,23 +37,26 @@
     "..:os_route",
     "..:route_observer_behavior",
     "../..:router",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("crostini_arc_adb_confirmation_dialog") {
   deps = [
     ":crostini_browser_proxy",
     "..:metrics_recorder",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("crostini_browser_proxy") {
@@ -78,23 +81,26 @@
   deps = [
     ":crostini_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js",
+  ]
 }
 
 js_library("crostini_disk_resize_confirmation_dialog") {
   deps = [
     ":crostini_browser_proxy",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("crostini_export_import") {
@@ -107,20 +113,23 @@
     "../..:router",
     "../guest_os:guest_os_browser_proxy",
     "../guest_os:guest_os_container_select",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("crostini_import_confirmation_dialog") {
   deps = [
     ":crostini_browser_proxy",
     "../guest_os:guest_os_browser_proxy",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("crostini_page") {
@@ -140,11 +149,12 @@
     "../..:router",
     "../guest_os:guest_os_shared_paths",
     "../guest_os:guest_os_shared_usb_devices",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("crostini_port_forwarding") {
@@ -173,14 +183,15 @@
     "..:metrics_recorder",
     "../guest_os:guest_os_browser_proxy",
     "../guest_os:guest_os_container_select",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("crostini_extra_containers") {
@@ -227,12 +238,14 @@
     "..:route_observer_behavior",
     "..:route_origin_behavior",
     "../..:router",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list = [ "../settings_controls_types.js" ]
+  externs_list = [
+    "../settings_controls_types.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("crostini_shared_usb_devices") {
@@ -252,12 +265,14 @@
     "..:route_observer_behavior",
     "..:route_origin_behavior",
     "../..:router",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list = [ "../settings_controls_types.js" ]
+  externs_list = [
+    "../settings_controls_types.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 html_to_js("web_components") {
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_disk_resize_confirmation_dialog.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_disk_resize_confirmation_dialog.js
index ecc91f78..7d18d0e 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_disk_resize_confirmation_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_disk_resize_confirmation_dialog.js
@@ -8,9 +8,9 @@
  * By clicking 'Reserve size', the user agrees to start the operation.
  */
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import '../../settings_shared.css.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 /** @polymer */
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
index caabdde1..59600b0 100644
--- a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
@@ -51,12 +51,14 @@
     ":guest_os_browser_proxy",
     ":guest_os_container_select",
     "..:metrics_recorder",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("guest_os_shared_paths") {
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index 260e6628..dd74237 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -40,9 +40,10 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_setup.m",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_setup_delegate.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("internet_config") {
@@ -55,11 +56,13 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/network:network_config.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:util.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("internet_detail_menu") {
@@ -113,7 +116,6 @@
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/network_health:network_health_container",
     "//ui/webui/resources/cr_components/chromeos/traffic_counters:traffic_counters",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
@@ -121,6 +123,7 @@
   ]
   externs_list = [
     "../settings_controls_types.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
     "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js",
   ]
 }
@@ -241,11 +244,13 @@
     "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_indicator_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_proxy.m",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list = [ "../settings_controls_types.js" ]
+  externs_list = [
+    "../settings_controls_types.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("network_summary") {
@@ -285,10 +290,12 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/network:network_icon.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("cellular_networks_list") {
@@ -333,21 +340,23 @@
   deps = [
     "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("esim_rename_dialog") {
   deps = [
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("esim_remove_profile_dialog") {
@@ -357,11 +366,12 @@
     "//chrome/browser/resources/settings/chromeos:route_observer_behavior",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("settings_traffic_counters") {
@@ -373,9 +383,10 @@
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/traffic_counters:traffic_counters",
     "//ui/webui/resources/cr_components/chromeos/traffic_counters:traffic_counters_adapter",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 html_to_js("web_components") {
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
index 0dec09c6..595e60e 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
@@ -8,11 +8,11 @@
  */
 import 'chrome://resources/cr_components/chromeos/network/network_config.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import './internet_shared_css.js';
 
 import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {HTMLEscape} from 'chrome://resources/js/util.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
index 2fe1167..0894e533 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
@@ -4,6 +4,7 @@
 
 import 'chrome://resources/cr_components/chromeos/network/network_icon.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
@@ -12,7 +13,6 @@
 import '../../settings_shared.css.js';
 
 import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {HTMLEscape} from 'chrome://resources/js/util.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/kerberos_page/BUILD.gn
index 1c77878..cfbeb689 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/BUILD.gn
@@ -50,14 +50,15 @@
     ":kerberos_accounts_browser_proxy",
     "..:metrics_recorder",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("kerberos_page") {
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.js b/chrome/browser/resources/settings/chromeos/main_page_behavior.js
similarity index 96%
rename from chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.js
rename to chrome/browser/resources/settings/chromeos/main_page_behavior.js
index 19d7c24..9bd0d94 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.js
+++ b/chrome/browser/resources/settings/chromeos/main_page_behavior.js
@@ -5,8 +5,9 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {beforeNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import { MinimumRoutes,Route, Router} from '../../router.js';
-import {ensureLazyLoaded} from '../ensure_lazy_loaded.js';
+import {MinimumRoutes, Route, Router} from '../router.js';
+
+import {ensureLazyLoaded} from './ensure_lazy_loaded.js';
 
 /**
  * @enum {string}
@@ -49,12 +50,12 @@
   return RouteState.SECTION;
 }
 
-  /**
-   * Responds to route changes by expanding, collapsing, or scrolling to
-   * sections on the page. Expanded sections take up the full height of the
-   * container. At most one section should be expanded at any given time.
-   * @polymerBehavior
-   */
+/**
+ * Responds to route changes by expanding, collapsing, or scrolling to
+ * sections on the page. Expanded sections take up the full height of the
+ * container. At most one section should be expanded at any given time.
+ * @polymerBehavior
+ */
 export const MainPageBehavior = {
   /** @type {?HTMLElement} */
   scroller: null,
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
index 36c1531..79a890c 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
@@ -113,7 +113,6 @@
 
 js_library("multidevice_radio_button") {
   deps = [
-    "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
     "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
   ]
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js
index 9f4f5dd..69cc487 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js
@@ -25,6 +25,8 @@
 import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {LockStateBehavior, LockStateBehaviorInterface} from '../os_people_page/lock_state_behavior.js';
+
 import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js';
 import {MultiDeviceFeature, PhoneHubPermissionsSetupAction, PhoneHubPermissionsSetupFlowScreens} from './multidevice_constants.js';
 
@@ -86,11 +88,13 @@
  * @extends {PolymerElement}
  * @implements {I18nBehaviorInterface}
  * @implements {WebUIListenerBehaviorInterface}
+ * @implements {LockStateBehaviorInterface}
  */
 const SettingsMultidevicePermissionsSetupDialogElementBase = mixinBehaviors(
     [
       I18nBehavior,
       WebUIListenerBehavior,
+      LockStateBehavior,
     ],
     PolymerElement);
 
@@ -271,7 +275,7 @@
       },
 
       /** @private */
-      isSetPinDone_: {
+      isPinSet_: {
         type: Boolean,
         value: false,
       },
@@ -639,7 +643,7 @@
         if (!this.isScreenLockEnabled_) {
           return;
         }
-        if (this.isPinNumberSelected_ && !this.isSetPinDone_) {
+        if (this.isPinNumberSelected_ && !this.isPinSet_ && !this.hasPin) {
           // When users select pin number and click next button, popup set pin
           // dialog.
           this.showSetupPinDialog_ = true;
@@ -723,7 +727,7 @@
   onSetPinDone_() {
     // Once users confirm pin number, take them to the 'finish setup on the
     // phone' step directly.
-    this.isSetPinDone_ = true;
+    this.isPinSet_ = true;
     this.nextPage_();
   }
 
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js
index 71f61f8..621f73d 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js
@@ -4,7 +4,6 @@
 
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style.css.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.js';
-import 'chrome://resources/polymer/v3_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
 import '../../settings_shared.css.js';
 
 import {CrRadioButtonMixin} from 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button_mixin.js';
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn
index 194f0b09..ea1dff72 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/BUILD.gn
@@ -40,8 +40,10 @@
   deps = [
     "//chrome/browser/resources/nearby_share/shared:nearby_contact_visibility",
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+  ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
   ]
 }
 
@@ -50,22 +52,25 @@
     ":types",
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings",
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_externs.js",
+  ]
 }
 
 js_library("nearby_share_device_name_dialog") {
   deps = [
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("nearby_share_high_visibility_page") {
@@ -85,14 +90,15 @@
     "//chrome/browser/resources/nearby_share/shared:nearby_onboarding_page",
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior",
     "//chrome/browser/resources/nearby_share/shared:nearby_visibility_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data",
   ]
-
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager_externs.js",
+  ]
 }
 
 js_library("nearby_share_receive_manager") {
@@ -101,10 +107,12 @@
     ":nearby_share_high_visibility_page",
     "//chrome/browser/resources/nearby_share/shared:nearby_share_settings_behavior",
     "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("nearby_share_subpage") {
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.js
index 7e5b3aae0..be13ac1 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.js
@@ -9,10 +9,10 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import '../../shared/nearby_onboarding_page.js';
 import '../../shared/nearby_visibility_page.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.js
index e18fa8aa..36cbe25 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.js
@@ -9,10 +9,10 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_device_name_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_device_name_dialog.js
index 3edfdac7..614b671 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_device_name_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_device_name_dialog.js
@@ -9,9 +9,9 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
index 2c26c64..8239820 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
@@ -26,9 +26,9 @@
 import '../../shared/nearby_visibility_page.js';
 import './nearby_share_confirm_page.js';
 import './nearby_share_high_visibility_page.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
 
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
index 522de81..0564c8a 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
@@ -46,13 +46,15 @@
     "//chrome/browser/resources/settings/chromeos:prefs_behavior",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements:cr_scrollable_behavior",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_search_field/cr_search_field_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_search_field/cr_search_field_externs.js",
+  ]
 }
 
 js_library("manage_a11y_page") {
@@ -187,24 +189,28 @@
     ":switch_access_constants",
     "//chrome/browser/resources/settings/chromeos:prefs_behavior",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("switch_access_action_assignment_pane") {
   deps = [
     ":switch_access_constants",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("switch_access_constants") {
@@ -218,23 +224,26 @@
     ":switch_access_constants",
     "//chrome/browser/resources/settings/chromeos:prefs_behavior",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js",
+  ]
 }
 
 js_library("switch_access_setup_guide_warning_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("switch_access_subpage") {
@@ -268,11 +277,11 @@
     "//chrome/browser/resources/settings/chromeos:route_observer_behavior",
     "//chrome/browser/resources/settings/chromeos/os_languages_page:languages_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
   externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
     "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
     "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js",
   ]
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts
index 72b5208..ebb694c 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts
@@ -37,9 +37,9 @@
 import {Setting} from '../../mojom-webui/setting.mojom-webui.js';
 import {Route, Router} from '../../router.js';
 import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
+import {MainPageBehavior, MainPageBehaviorInterface} from '../main_page_behavior.js';
 import {recordSettingChange} from '../metrics_recorder.js';
 import {routes} from '../os_route.js';
-import {MainPageBehavior, MainPageBehaviorInterface} from '../os_settings_page/main_page_behavior.js';
 import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
 import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, AboutPageUpdateInfo, BrowserChannel, browserChannelToI18nId, RegulatoryInfo, TPMFirmwareUpdateStatusChangedEvent, UpdateStatus, UpdateStatusChangedEvent} from './about_page_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
index bf4117f..599b0857 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -227,11 +227,13 @@
 js_library("supported_links_overlapping_apps_dialog") {
   deps = [
     ":store_client",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list = [ "./types.js" ]
+  externs_list = [
+    "./types.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("supported_links_dialog") {
@@ -239,8 +241,9 @@
     ":browser_proxy",
     ":store_client",
     "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("supported_links_item") {
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn
index 62993b0..3758308 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn
@@ -162,22 +162,25 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/bluetooth:bluetooth_metrics_utils",
     "//ui/webui/resources/cr_components/chromeos/bluetooth:bluetooth_pairing_ui",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("os_remove_saved_device_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("os_bluetooth_forget_device_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("settings_fast_pair_constants") {
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog.html
index 63ee179..d2a8af5 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog.html
@@ -1,6 +1,6 @@
 <style>
   #dialog {
-    --cr-dialog-top-container-min-height: 0px;
+    --cr-dialog-top-container-min-height: 0;
   }
 </style>
 <cr-dialog id="dialog" show-on-attach>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
index b4056bb..6c0f0ed 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -88,10 +88,12 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements:cr_scrollable_behavior",
     "//ui/webui/resources/cr_elements:find_shortcut_behavior",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_search_field/cr_search_field_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_search_field/cr_search_field_externs.js",
+  ]
 }
 
 js_library("add_spellcheck_languages_dialog") {
@@ -188,10 +190,11 @@
     "..:os_route",
     "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("os_languages_page_v2") {
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
index 08ad4a20..8498916 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
@@ -212,13 +212,13 @@
 js_library("users_add_user_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
   externs_list = [
     "$externs_path/users_private.js",
     "//ui/webui/resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html b/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html
index d1209015..8e72a15 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.html
@@ -11,10 +11,6 @@
     padding: 10px 0;
   }
 
-  #messageDiv {
-    height: 20px;
-  }
-
   /* Use this instead of hidden so that the dialog does not resize when the
      message appears or disappears. */
   #messageDiv[invisible] {
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
index 83939dd1..95f397e 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
@@ -12,7 +12,7 @@
 
   .peripheral-data-access-protection {
     /* Remove the unecessary spacing infront of the learn-more link. */
-    --cr-subsequent-anchors-of-span-margin: 0px;
+    --cr-subsequent-anchors-of-span-margin: 0;
   }
 </style>
 <settings-animated-pages id="pages" section="osPrivacy"
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.html b/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.html
index e36a2c6..0c9e2f6 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.html
@@ -13,3 +13,9 @@
     sub-label="[[microphoneHardwareToggleActiveSubLabel_]]"
     disabled="[[microphoneHardwareToggleActive_]]">
 </settings-toggle-button>
+<settings-toggle-button
+    pref="{{prefs.ash.user.geolocation_allowed}}"
+    id="geolocationToggle"
+    label="$i18n{geolocationToggleTitle}"
+    deep-link-focus-id$="[[Setting.kGeolocationOnOff]]">
+</settings-toggle-button>
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.js b/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.js
index 898c4a6..e89b126 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/privacy_hub_page.js
@@ -95,6 +95,7 @@
         value: () => new Set([
           Setting.kCameraOnOff,
           Setting.kMicrophoneOnOff,
+          Setting.kGeolocationOnOff,
         ]),
       },
 
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn
index 40f011a58..9d2ac500 100644
--- a/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn
@@ -39,12 +39,14 @@
   deps = [
     "//chrome/browser/resources/settings/chromeos/os_search_page:search_engines_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("search_subpage") {
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index 8db1182..155238f 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -29,8 +29,8 @@
   "chromeos/os_languages_page/smart_inputs_page.js",
   "chromeos/os_settings_main/os_settings_main.ts",
   "chromeos/os_settings_menu/os_settings_menu.ts",
-  "chromeos/os_settings_page/os_settings_page.js",
-  "chromeos/os_settings_page/settings_idle_load.js",
+  "chromeos/os_settings_page/os_settings_page.ts",
+  "chromeos/os_settings_page/settings_idle_load.ts",
   "chromeos/os_settings_search_box/os_search_result_row.ts",
   "chromeos/os_settings_search_box/os_settings_search_box.ts",
   "chromeos/os_settings_ui/os_settings_ui.ts",
@@ -87,6 +87,7 @@
   "chromeos/internet_page/internet_page_browser_proxy.js",
   "chromeos/kerberos_page/kerberos_accounts_browser_proxy.js",
   "chromeos/lazy_load.js",
+  "chromeos/main_page_behavior.js",
   "chromeos/metrics_recorder.js",
   "chromeos/multidevice_page/multidevice_browser_proxy.js",
   "chromeos/multidevice_page/multidevice_constants.js",
@@ -145,7 +146,6 @@
   "chromeos/os_route.js",
   "chromeos/os_search_page/search_engines_browser_proxy.js",
   "chromeos/os_settings.js",
-  "chromeos/os_settings_page/main_page_behavior.js",
   "chromeos/os_settings_routes.js",
   "chromeos/parental_controls_page/parental_controls_browser_proxy.ts",
   "chromeos/personalization_page/personalization_hub_browser_proxy.ts",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn
deleted file mode 100644
index 9d93bb4..0000000
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/closure_compiler/compile_js.gni")
-import("../os_settings.gni")
-
-js_type_check("closure_compile_module") {
-  closure_flags = os_settings_closure_flags
-  is_polymer3 = true
-  deps = [
-    ":main_page_behavior",
-    ":os_settings_page",
-    ":settings_idle_load",
-  ]
-}
-
-js_library("os_settings_page") {
-  deps = [
-    ":main_page_behavior",
-    ":settings_idle_load",
-    "..:os_page_visibility",
-    "..:os_route",
-    "..:route_observer_behavior",
-    "../..:router",
-    "../bluetooth_page:bluetooth_page",
-    "../crostini_page:crostini_page",
-    "../device_page:device_page",
-    "../kerberos_page:kerberos_page",
-    "../multidevice_page:multidevice_page",
-    "../os_a11y_page:os_a11y_page",
-    "../os_apps_page:android_apps_browser_proxy",
-    "../os_apps_page:os_apps_page",
-    "../os_apps_page/app_notifications_page:app_notifications_subpage",
-    "../os_bluetooth_page:os_bluetooth_page",
-    "../os_people_page:os_people_page",
-    "../os_printing_page:os_printing_page",
-    "../os_privacy_page:os_privacy_page",
-    "../os_search_page:os_search_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/js:assert.m",
-    "//ui/webui/resources/js:load_time_data.m",
-    "//ui/webui/resources/js:web_ui_listener_behavior.m",
-  ]
-}
-
-js_library("main_page_behavior") {
-  deps = [
-    "../..:router",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js:assert.m",
-    "//ui/webui/resources/js:util.m",
-  ]
-}
-
-js_library("settings_idle_load") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js:assert.m",
-  ]
-}
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
similarity index 70%
rename from chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js
rename to chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
index 6be760ba..f4e9868 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
@@ -29,32 +29,28 @@
 import '../os_bluetooth_page/os_bluetooth_page.js';
 import '../os_icons.js';
 
-import {assert} from 'chrome://resources/js/assert.m.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {WebUIListenerMixin, WebUIListenerMixinInterface} from 'chrome://resources/js/web_ui_listener_mixin.js';
 import {beforeNextRender, microTask, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Route, Router} from '../../router.js';
+import {MainPageBehavior, MainPageBehaviorInterface} from '../main_page_behavior.js';
 import {AndroidAppsBrowserProxyImpl, AndroidAppsInfo} from '../os_apps_page/android_apps_browser_proxy.js';
 import {OSPageVisibility} from '../os_page_visibility.js';
 import {routes} from '../os_route.js';
 import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-import {MainPageBehavior, MainPageBehaviorInterface} from './main_page_behavior.js';
 import {getTemplate} from './os_settings_page.html.js';
+import {SettingsIdleLoadElement} from './settings_idle_load.js';
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {MainPageBehaviorInterface}
- * @implements {RouteObserverBehaviorInterface}
- * @implements {WebUIListenerBehaviorInterface}
- */
 const OsSettingsPageElementBase = mixinBehaviors(
-    [MainPageBehavior, RouteObserverBehavior, WebUIListenerBehavior],
-    PolymerElement);
+                                      [MainPageBehavior, RouteObserverBehavior],
+                                      WebUIListenerMixin(PolymerElement)) as {
+  new (): PolymerElement & WebUIListenerMixinInterface &
+      MainPageBehaviorInterface & RouteObserverBehaviorInterface,
+};
 
-/** @polymer */
 class OsSettingsPageElement extends OsSettingsPageElementBase {
   static get is() {
     return 'os-settings-page';
@@ -90,12 +86,10 @@
 
       havePlayStoreApp: Boolean,
 
-      /** @type {!AndroidAppsInfo|undefined} */
       androidAppsInfo: Object,
 
       /**
        * Whether the user is in guest mode.
-       * @private {boolean}
        */
       isGuestMode_: {
         type: Boolean,
@@ -104,7 +98,6 @@
 
       /**
        * Whether Accessibility OS Settings visibility improvements are enabled.
-       * @private{boolean}
        */
       isAccessibilityOSSettingsVisibilityEnabled_: {
         type: Boolean,
@@ -117,7 +110,6 @@
 
       /**
        * Dictionary defining page visibility.
-       * @type {!OSPageVisibility}
        */
       pageVisibility: {
         type: Object,
@@ -136,7 +128,6 @@
       /**
        * True if a section is fully expanded to hide other sections beneath it.
        * False otherwise (even while animating a section open/closed).
-       * @private {boolean}
        */
       hasExpandedSection_: {
         type: Boolean,
@@ -146,7 +137,6 @@
       /**
        * Whether the user is a secondary user. Computed so that it is calculated
        * correctly after loadTimeData is available.
-       * @private
        */
       showSecondaryUserBanner_: {
         type: Boolean,
@@ -157,17 +147,14 @@
        * Whether to show banner indicating the user to return this device as an
        * update is required as per policy but the device has reached end of
        * life.
-       * @private
        */
       showUpdateRequiredEolBanner_: {
         type: Boolean,
         value: !!loadTimeData.getString('updateRequiredEolBannerText'),
       },
 
-      /** @private {!Route|undefined} */
       currentRoute_: Object,
 
-      /** @private */
       isBluetoothRevampEnabled_: {
         type: Boolean,
         value() {
@@ -177,26 +164,33 @@
     };
   }
 
+  androidAppsInfo?: AndroidAppsInfo;
+  pageVisibility: OSPageVisibility;
+  advancedToggleExpanded: boolean;
+  private allowCrostini_: boolean;
+  private hasExpandedSection_: boolean;
+  private showSecondaryUserBanner_: boolean;
+  private showUpdateRequiredEolBanner_: boolean;
+  private currentRoute_?: Route;
+  private isBluetoothRevampEnabled_: boolean;
+  /**
+   * Used to avoid handling a new toggle while currently toggling.
+   */
+  private advancedTogglingInProgress_: boolean;
+
   constructor() {
     super();
-
-    /**
-     * Used to avoid handling a new toggle while currently toggling.
-     * @private {boolean}
-     */
     this.advancedTogglingInProgress_ = false;
   }
 
-  ready() {
+  override ready() {
     super.ready();
 
     this.setAttribute('role', 'main');
-
     this.addEventListener('subpage-expand', this.onSubpageExpanded_);
   }
 
-  /** @override */
-  connectedCallback() {
+  override connectedCallback() {
     super.connectedCallback();
 
     this.currentRoute_ = Router.getInstance().getCurrentRoute();
@@ -209,11 +203,7 @@
     AndroidAppsBrowserProxyImpl.getInstance().requestAndroidAppsInfo();
   }
 
-  /**
-   * @param {!Route} newRoute
-   * @param {!Route=} oldRoute
-   */
-  currentRouteChanged(newRoute, oldRoute) {
+  override currentRouteChanged(newRoute: Route, oldRoute?: Route) {
     this.currentRoute_ = newRoute;
 
     if (routes.ADVANCED && routes.ADVANCED.contains(newRoute)) {
@@ -233,68 +223,53 @@
     MainPageBehavior.currentRouteChanged.call(this, newRoute, oldRoute);
   }
 
-  // Override MainPageBehavior method.
-  containsRoute(route) {
+  override containsRoute(route: Route) {
     return !route || routes.BASIC.contains(route) ||
         routes.ADVANCED.contains(route);
   }
 
-  /**
-   * @param {boolean|undefined} visibility
-   * @return {boolean}
-   * @private
-   */
-  showPage_(visibility) {
+  private showPage_(visibility?: boolean): boolean {
     return visibility !== false;
   }
 
-  /**
-   * @return {boolean}
-   * @private
-   */
-  computeShowSecondaryUserBanner_() {
+  private computeShowSecondaryUserBanner_(): boolean {
     return !this.hasExpandedSection_ &&
         loadTimeData.getBoolean('isSecondaryUser');
   }
 
-  /**
-   * @return {boolean}
-   * @private
-   */
-  computeShowUpdateRequiredEolBanner_() {
+  private computeShowUpdateRequiredEolBanner_(): boolean {
     return !this.hasExpandedSection_ && this.showUpdateRequiredEolBanner_;
   }
 
-  /**
-   * @param {!AndroidAppsInfo} info
-   * @private
-   */
-  androidAppsInfoUpdate_(info) {
+  private androidAppsInfoUpdate_(info: AndroidAppsInfo) {
     this.androidAppsInfo = info;
   }
 
   /**
    * Hides the update required EOL banner. It is shown again when Settings is
    * re-opened.
-   * @private
    */
-  onCloseEolBannerClicked_() {
+  private onCloseEolBannerClicked_() {
     this.showUpdateRequiredEolBanner_ = false;
   }
 
   /**
    * Hides everything but the newly expanded subpage.
-   * @private
    */
-  onSubpageExpanded_() {
+  private onSubpageExpanded_() {
     this.hasExpandedSection_ = true;
   }
 
+  private getAdvancedPageTemplate_(): SettingsIdleLoadElement {
+    const el = this.shadowRoot!.getElementById('advancedPageTemplate');
+    assert(el);
+    return el as SettingsIdleLoadElement;
+  }
+
   /**
    * Render the advanced page now (don't wait for idle).
-   * @private
    */
-  advancedToggleExpandedChanged_() {
+  private advancedToggleExpandedChanged_() {
     if (!this.advancedToggleExpanded) {
       return;
     }
@@ -302,35 +277,35 @@
     // In Polymer2, async() does not wait long enough for layout to complete.
     // beforeNextRender() must be used instead.
     beforeNextRender(this, () => {
-      this.shadowRoot.querySelector('#advancedPageTemplate').get();
+      this.getAdvancedPageTemplate_().get();
     });
   }
 
-  advancedToggleClicked_() {
+  private advancedToggleClicked_() {
     if (this.advancedTogglingInProgress_) {
       return;
     }
 
     this.advancedTogglingInProgress_ = true;
-    const toggle = this.shadowRoot.querySelector('#toggleContainer');
+    const toggle = this.shadowRoot!.getElementById('toggleContainer');
+    assert(toggle);
+
     if (!this.advancedToggleExpanded) {
       this.advancedToggleExpanded = true;
       microTask.run(() => {
-        this.shadowRoot.querySelector('#advancedPageTemplate')
-            .get()
-            .then(() => {
-              const event = new CustomEvent('scroll-to-top', {
-                bubbles: true,
-                composed: true,
-                detail: {
-                  top: toggle.offsetTop,
-                  callback: () => {
-                    this.advancedTogglingInProgress_ = false;
-                  },
-                },
-              });
-              this.dispatchEvent(event);
-            });
+        this.getAdvancedPageTemplate_().get().then(() => {
+          const event = new CustomEvent('scroll-to-top', {
+            bubbles: true,
+            composed: true,
+            detail: {
+              top: toggle.offsetTop,
+              callback: () => {
+                this.advancedTogglingInProgress_ = false;
+              },
+            },
+          });
+          this.dispatchEvent(event);
+        });
       });
     } else {
       const event = new CustomEvent('scroll-to-bottom', {
@@ -349,56 +324,47 @@
   }
 
   /**
-   * @param {!Route} currentRoute
-   * @param {boolean} hasExpandedSection
-   * @return {boolean} Whether to show the basic page, taking into account
+   * @return Whether to show the basic page, taking into account
    *     both routing and search state.
-   * @private
    */
-  showBasicPage_(currentRoute, hasExpandedSection) {
+  private showBasicPage_(currentRoute: Route, hasExpandedSection: boolean):
+      boolean {
     return !hasExpandedSection || routes.BASIC.contains(currentRoute);
   }
 
   /**
-   * @param {!Route} currentRoute
-   * @param {boolean} hasExpandedSection
-   * @param {boolean} advancedToggleExpanded
-   * @return {boolean} Whether to show the advanced page, taking into account
+   * @return Whether to show the advanced page, taking into account
    *     both routing and search state.
-   * @private
    */
-  showAdvancedPage_(currentRoute, hasExpandedSection, advancedToggleExpanded) {
+  private showAdvancedPage_(
+      currentRoute: Route, hasExpandedSection: boolean,
+      advancedToggleExpanded: boolean): boolean {
     return hasExpandedSection ?
         (routes.ADVANCED && routes.ADVANCED.contains(currentRoute)) :
         advancedToggleExpanded;
   }
 
-  /**
-   * @param {(boolean|undefined)} visibility
-   * @return {boolean} True unless visibility is false.
-   * @private
-   */
-  showAdvancedSettings_(visibility) {
+  private showAdvancedSettings_(visibility?: boolean): boolean {
     return visibility !== false;
   }
 
   /**
-   * @param {boolean} opened Whether the menu is expanded.
-   * @return {string} Icon name.
-   * @private
+   * @param opened Whether the menu is expanded.
+   * @return Icon name.
    */
-  getArrowIcon_(opened) {
+  private getArrowIcon_(opened: boolean): string {
     return opened ? 'cr:arrow-drop-up' : 'cr:arrow-drop-down';
   }
 
-  /**
-   * @param {boolean} bool
-   * @return {string}
-   * @private
-   */
-  boolToString_(bool) {
+  private boolToString_(bool: boolean): string {
     return bool.toString();
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'os-settings-page': OsSettingsPageElement;
+  }
+}
+
 customElements.define(OsSettingsPageElement.is, OsSettingsPageElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.js b/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.js
deleted file mode 100644
index 585a277..0000000
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview
- * settings-idle-load is a simple variant of dom-if designed for lazy
- * loading and rendering of elements that are accessed imperatively. A URL is
- * given that holds the elements to be loaded lazily.
- */
-
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {PolymerElement, TemplateInstanceBase, templatize} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {ensureLazyLoaded} from '../ensure_lazy_loaded.js';
-
-import {getTemplate} from './settings_idle_load.html.js';
-
-/** @polymer */
-class SettingsIdleLoadElement extends PolymerElement {
-  static get is() {
-    return 'settings-idle-load';
-  }
-
-  static get template() {
-    return getTemplate();
-  }
-
-  static get properties() {
-    return {
-      /**
-       * If specified, it will be loaded via an HTML import before stamping the
-       * template.
-       */
-      url: String,
-    };
-  }
-
-  constructor() {
-    super();
-
-    /** @private {?Element} */
-    this.child_ = null;
-
-    /** @private {?Element|?TemplateInstanceBase} */
-    this.instance_ = null;
-
-    /** @private {?Promise<Element>} */
-    this.loading_ = null;
-
-    /** @private {number} */
-    this.idleCallback_ = 0;
-  }
-
-  /** @override */
-  connectedCallback() {
-    super.connectedCallback();
-
-    this.idleCallback_ = requestIdleCallback(() => {
-      this.get();
-    });
-  }
-
-  /** @override */
-  disconnectedCallback() {
-    super.disconnectedCallback();
-
-    // No-op if callback already fired.
-    cancelIdleCallback(this.idleCallback_);
-  }
-
-  /**
-   * @param {!function():!Promise} requestFn Requests the lazy module.
-   * @return {!Promise<!Element>} Resolves with the stamped child element after
-   *     the lazy module has been loaded.
-   */
-  requestLazyModule_(requestFn) {
-    return new Promise((resolve, reject) => {
-      requestFn().then(() => {
-        const template =
-            /** @type {!HTMLTemplateElement} */ (
-                this.shadowRoot.querySelector('slot')
-                    .assignedNodes({flatten: true})
-                    .filter(n => n.nodeType === Node.ELEMENT_NODE)[0]);
-        const TemplateClass = templatize(template, this, {
-          mutableData: false,
-          forwardHostProp: this._forwardHostPropV2,
-        });
-
-        this.instance_ = new TemplateClass();
-
-        assert(!this.child_);
-        this.child_ = this.instance_.root.firstElementChild;
-
-        this.parentNode.insertBefore(this.instance_.root, this);
-        resolve(this.child_);
-
-        const event =
-            new CustomEvent('lazy-loaded', {bubbles: true, composed: true});
-        this.dispatchEvent(event);
-      }, reject);
-    });
-  }
-
-  /**
-   * @return {!Promise<Element>} Child element which has been stamped into the
-   *     DOM tree.
-   */
-  get() {
-    if (this.loading_) {
-      return this.loading_;
-    }
-
-    const requestLazyModuleFn = ensureLazyLoaded;
-
-    this.loading_ = this.requestLazyModule_(requestLazyModuleFn);
-    return this.loading_;
-  }
-
-  /**
-   * @param {string} prop
-   * @param {Object} value
-   */
-  _forwardHostPropV2(prop, value) {
-    if (this.instance_) {
-      this.instance_.forwardHostProp(prop, value);
-    }
-  }
-}
-
-customElements.define(SettingsIdleLoadElement.is, SettingsIdleLoadElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.ts b/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.ts
new file mode 100644
index 0000000..3af236b
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.ts
@@ -0,0 +1,130 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * settings-idle-load is a simple variant of dom-if designed for lazy
+ * loading and rendering of elements that are accessed imperatively. A URL is
+ * given that holds the elements to be loaded lazily.
+ */
+
+import {assert} from 'chrome://resources/js/assert_ts.js';
+import {PolymerElement, TemplateInstanceBase, templatize} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {ensureLazyLoaded} from '../ensure_lazy_loaded.js';
+
+import {getTemplate} from './settings_idle_load.html.js';
+
+export class SettingsIdleLoadElement extends PolymerElement {
+  static get is() {
+    return 'settings-idle-load';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      /**
+       * If specified, it will be loaded via an HTML import before stamping the
+       * template.
+       */
+      url: String,
+    };
+  }
+
+  private child_: Element|null;
+  private instance_: TemplateInstanceBase|null;
+  private loading_: Promise<Element>|null;
+  private idleCallback_: number;
+
+  constructor() {
+    super();
+
+    this.child_ = null;
+    this.instance_ = null;
+    this.loading_ = null;
+    this.idleCallback_ = 0;
+  }
+
+
+  override connectedCallback() {
+    super.connectedCallback();
+
+    this.idleCallback_ = window.requestIdleCallback(() => {
+      this.get();
+    });
+  }
+
+  override disconnectedCallback() {
+    super.disconnectedCallback();
+
+    // No-op if callback already fired.
+    window.cancelIdleCallback(this.idleCallback_);
+  }
+
+  /**
+   * @param requestFn Requests the lazy module.
+   * @return Resolves with the stamped child element after the lazy module has
+   *    been loaded.
+   */
+  private requestLazyModule_(): Promise<Element> {
+    return new Promise((resolve, reject) => {
+      ensureLazyLoaded().then(() => {
+        const slot = this.shadowRoot!.querySelector('slot');
+        assert(slot);
+        const template =
+            slot.assignedNodes({flatten: true})
+                .filter(n => n.nodeType === Node.ELEMENT_NODE)[0] as
+            HTMLTemplateElement;
+
+        const TemplateClass = templatize(template, this, {
+          mutableData: false,
+          forwardHostProp: this._forwardHostPropV2,
+        });
+
+        this.instance_ = new TemplateClass();
+
+        assert(!this.child_);
+        this.child_ = this.instance_.root.firstElementChild;
+        assert(this.child_);
+
+        this.parentNode!.insertBefore(this.instance_.root, this);
+        resolve(this.child_);
+
+        const event =
+            new CustomEvent('lazy-loaded', {bubbles: true, composed: true});
+        this.dispatchEvent(event);
+      }, reject);
+    });
+  }
+
+  /**
+   * @return Child element which has been stamped into the DOM tree.
+   */
+  override get(): Promise<Element> {
+    if (this.loading_) {
+      return this.loading_;
+    }
+
+    this.loading_ = this.requestLazyModule_();
+    return this.loading_;
+  }
+
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
+  private _forwardHostPropV2(prop: string, value: any) {
+    if (this.instance_) {
+      this.instance_.forwardHostProp(prop, value);
+    }
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'settings-idle-load': SettingsIdleLoadElement;
+  }
+}
+
+customElements.define(SettingsIdleLoadElement.is, SettingsIdleLoadElement);
diff --git a/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.ts b/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.ts
index a0bce0db..dcf3dc02 100644
--- a/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.ts
+++ b/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.ts
@@ -11,6 +11,7 @@
 import '../../settings_page/settings_animated_pages.js';
 import '../../settings_page/settings_subpage.js';
 import '../../settings_shared.css.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
@@ -75,9 +76,10 @@
    * Returns the setup parental controls CrButtonElement.
    */
   getSetupButton(): CrButtonElement {
-    const setupButton = this.shadowRoot!.querySelector('#setupButton');
+    const setupButton =
+        this.shadowRoot!.querySelector<CrButtonElement>('#setupButton');
     assert(setupButton);
-    return setupButton as CrButtonElement;
+    return setupButton;
   }
 
   /**
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.ts b/chrome/browser/resources/settings/controls/controlled_radio_button.ts
index 7810afa5..716cd940 100644
--- a/chrome/browser/resources/settings/controls/controlled_radio_button.ts
+++ b/chrome/browser/resources/settings/controls/controlled_radio_button.ts
@@ -4,7 +4,6 @@
 
 import '//resources/cr_elements/cr_radio_button/cr_radio_button_style.css.js';
 import '//resources/cr_elements/policy/cr_policy_pref_indicator.js';
-import '//resources/polymer/v3_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
 import '../settings_shared.css.js';
 
 import {CrRadioButtonMixin, CrRadioButtonMixinInterface} from '//resources/cr_elements/cr_radio_button/cr_radio_button_mixin.js';
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chrome/browser/resources/settings/settings_page/settings_subpage.html
index 6c9acda..df8c1f0 100644
--- a/chrome/browser/resources/settings/settings_page/settings_subpage.html
+++ b/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -4,7 +4,7 @@
         display: block;
         left: 0;
         min-height: calc(100vh - var(--cr-toolbar-height) -
-            var(--cr-toolbar-padding-top, 0px));
+            var(--cr-toolbar-padding-top, 0));
         padding-bottom: 60px;
         position: absolute;
         right: 0;
diff --git a/chrome/browser/resources/settings/settings_shared.css b/chrome/browser/resources/settings/settings_shared.css
index 084ffccc..4315a768 100644
--- a/chrome/browser/resources/settings/settings_shared.css
+++ b/chrome/browser/resources/settings/settings_shared.css
@@ -84,7 +84,6 @@
 
 a[href] {
   color: var(--cr-link-color);
-  text-decoration: none;
 }
 
 /* For elements that are simple out-links but don't look like anchors. */
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index ef14089..e9e95a3 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -95,6 +95,9 @@
             $i18n{siteSettingsDelete}
           </cr-button>
         </div>
+        <div id="fpsMembership" hidden$="[[!fpsMembership_]]">
+          [[fpsMembership_]]
+        </div>
       </div>
     </div>
 
diff --git a/chrome/browser/resources/settings/site_settings/site_details.ts b/chrome/browser/resources/settings/site_settings/site_details.ts
index ea353a8..3494a7b 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.ts
+++ b/chrome/browser/resources/settings/site_settings/site_details.ts
@@ -45,6 +45,7 @@
   $: {
     confirmClearStorage: CrDialogElement,
     confirmResetSettings: CrDialogElement,
+    fpsMembership: HTMLElement,
     noStorage: HTMLElement,
     storage: HTMLElement,
     usage: HTMLElement,
@@ -105,6 +106,14 @@
         value: '',
       },
 
+      /**
+       * The first party set info for a site including owner and members count.
+       */
+      fpsMembership_: {
+        type: String,
+        value: '',
+      },
+
       enableExperimentalWebPlatformFeatures_: {
         type: Boolean,
         value() {
@@ -131,6 +140,7 @@
   private origin_: string;
   private storedData_: string;
   private numCookies_: string;
+  private fpsMembership_: string;
   private enableExperimentalWebPlatformFeatures_: boolean;
   private enableWebBluetoothNewPermissionsBackend_: boolean;
 
@@ -143,8 +153,8 @@
 
     this.addWebUIListener(
         'usage-total-changed',
-        (host: string, data: string, cookies: string) => {
-          this.onUsageTotalChanged_(host, data, cookies);
+        (host: string, data: string, cookies: string, fps: string) => {
+          this.onUsageTotalChanged_(host, data, cookies, fps);
         });
 
     this.addWebUIListener(
@@ -205,11 +215,14 @@
    * @param host The host that the usage was fetched for.
    * @param usage The string showing how much data the given host is using.
    * @param cookies The string showing how many cookies the given host is using.
+   * @param fpsMembership The string showing first party set membership details.
    */
-  private onUsageTotalChanged_(host: string, usage: string, cookies: string) {
+  private onUsageTotalChanged_(
+      host: string, usage: string, cookies: string, fpsMembership: string) {
     if (this.fetchingForHost_ === host) {
       this.storedData_ = usage;
       this.numCookies_ = cookies;
+      this.fpsMembership_ = fpsMembership;
     }
   }
 
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts
index 5f87a65..2b02d997 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.ts
+++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -69,12 +69,17 @@
   }
 
   private buildNode_(nodeId: number): Node|null {
-    const htmlTag = chrome.readAnything.getHtmlTag(nodeId);
+    let htmlTag = chrome.readAnything.getHtmlTag(nodeId);
     // Text nodes do not have an html tag.
     if (!htmlTag.length) {
       const textContent = chrome.readAnything.getTextContent(nodeId);
       return document.createTextNode(textContent);
     }
+    // getHtmlTag might return '#document' which is not a valid to pass to
+    // createElement.
+    if (htmlTag === '#document') {
+      htmlTag = 'div';
+    }
 
     const element = document.createElement(htmlTag);
     const url = chrome.readAnything.getUrl(nodeId);
@@ -117,7 +122,7 @@
     // would create a shadow node element representing each AXNode, because
     // experimentation found the shadow node creation to be ~8-10x slower than
     // constructing and appending nodes directly to the container element.
-    for (const nodeId of chrome.readAnything.contentNodeIds) {
+    for (const nodeId of chrome.readAnything.displayNodeIds) {
       const node = this.buildNode_(nodeId);
       if (node) {
         container.appendChild(node);
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
index 7b197e3f..f0e72b1 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
@@ -10,9 +10,8 @@
     // Implemented in read_anything_app_controller.cc and consumed by ts.
     /////////////////////////////////////////////////////////////////////
 
-    // A list of AXNodeIDs corresponding to the content node IDs identified by
-    // the AXTree distillation process.
-    let contentNodeIds: number[];
+    // A list of AXNodeIDs whose subtree should be displayed.
+    let displayNodeIds: number[];
 
     // Items in the ReadAnythingTheme struct, see read_anything.mojom for info.
     let fontName: string;
@@ -21,7 +20,9 @@
     let backgroundColor: number;
 
     // Returns a list of AXNodeIDs corresponding to the unignored children of
-    // the AXNode for the provided AXNodeID.
+    // the AXNode for the provided AXNodeID. If there is a selection contained
+    // in this node, only returns children which are partially or entirely
+    // contained within the selection.
     function getChildren(nodeId: number): number[];
 
     // Returns the HTML tag of the AXNode for the provided AXNodeID.
@@ -30,7 +31,9 @@
     // Returns the language of the AXNode for the provided AXNodeID.
     function getLanguage(nodeId: number): string;
 
-    // Returns the text content of the AXNode for the provided AXNodeID.
+    // Returns the text content of the AXNode for the provided AXNodeID. If a
+    // selection begins or ends in this node, truncates the text to only return
+    // the selected text.
     function getTextContent(nodeId: number): string;
 
     // Returns the url of the AXNode for the provided AXNodeID.
diff --git a/chrome/browser/resources/welcome/shared/action_link_style.css b/chrome/browser/resources/welcome/shared/action_link_style.css
index 0fb9ce83..47d7daae7 100644
--- a/chrome/browser/resources/welcome/shared/action_link_style.css
+++ b/chrome/browser/resources/welcome/shared/action_link_style.css
@@ -16,7 +16,7 @@
   cursor: pointer;
   display: inline-block;
   font-family: inherit;
-  text-decoration: none;
+  text-decoration: underline;
 }
 
 button.action-link[disabled] {
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
index 654bffb1..b239c26 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
@@ -313,8 +313,8 @@
   head->headers = new net::HttpResponseHeaders(
       "HTTP/1.1 200 OK\nContent-type: text/html\n\n");
   head->mime_type = "text/html";
-  client_remote->OnReceiveResponse(std::move(head),
-                                   mojo::ScopedDataPipeConsumerHandle());
+  client_remote->OnReceiveResponse(
+      std::move(head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
   client_remote->OnComplete(network::URLLoaderCompletionStatus());
 }
 
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index e7bd30e..26624fe 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -63,6 +63,10 @@
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chrome/browser/lacros/browser_launcher.h"
+#endif
+
 #if BUILDFLAG(IS_MAC)
 #include "chrome/browser/app_controller_mac.h"
 #endif
@@ -180,9 +184,14 @@
   }
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Restore should trigger for lacros-chrome if handling a restart.
+  // Restore should trigger for lacros-chrome if handling a restart or if
+  // currently processing a full restore.
+  auto* primary_user_profile =
+      g_browser_process->profile_manager()->GetProfileByPath(
+          ProfileManager::GetPrimaryUserProfilePath());
   if (StartupBrowserCreator::WasRestarted() ||
-      StartupBrowserCreator::IsLaunchingBrowserForLastProfiles()) {
+      BrowserLauncher::GetForProfile(primary_user_profile)
+          ->is_launching_for_full_restore()) {
     return true;
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
index 48dc4533..49a1cf8 100644
--- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
+++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
@@ -151,8 +151,10 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
     target_client_->OnReceiveEarlyHints(std::move(early_hints));
   }
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
 
@@ -163,10 +165,6 @@
                                      std::move(callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    target_client_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     target_client_->OnTransferSizeUpdated(transfer_size_diff);
   }
@@ -394,12 +392,14 @@
 
 void ProxyingURLLoaderFactory::InProgressRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // Even though |head| is const we can get a non-const pointer to the headers
   // and modifications we made are passed to the target client.
   ProxyResponseAdapter adapter(this, head->headers.get());
   factory_->delegate_->ProcessResponse(&adapter, GURL() /* redirect_url */);
-  target_client_->OnReceiveResponse(std::move(head), std::move(body));
+  target_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                    std::move(cached_metadata));
 }
 
 void ProxyingURLLoaderFactory::InProgressRequest::OnReceiveRedirect(
diff --git a/chrome/browser/speech/cros_speech_recognition_service.cc b/chrome/browser/speech/cros_speech_recognition_service.cc
index 48acbf9..cfc312d 100644
--- a/chrome/browser/speech/cros_speech_recognition_service.cc
+++ b/chrome/browser/speech/cros_speech_recognition_service.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/file_path.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "chrome/services/speech/audio_source_fetcher_impl.h"
 #include "chrome/services/speech/cros_speech_recognition_recognizer_impl.h"
 #include "components/soda/constants.h"
@@ -67,7 +68,7 @@
     media::mojom::SpeechRecognitionOptionsPtr options,
     BindRecognizerCallback callback) {
   base::FilePath binary_path, languagepack_path;
-  PopulateFilePaths(base::OptionalOrNullptr(options->language), binary_path,
+  PopulateFilePaths(base::OptionalToPtr(options->language), binary_path,
                     languagepack_path);
 
   CrosSpeechRecognitionRecognizerImpl::Create(
@@ -84,7 +85,7 @@
     media::mojom::SpeechRecognitionOptionsPtr options,
     BindRecognizerCallback callback) {
   base::FilePath binary_path, languagepack_path;
-  PopulateFilePaths(base::OptionalOrNullptr(options->language), binary_path,
+  PopulateFilePaths(base::OptionalToPtr(options->language), binary_path,
                     languagepack_path);
 
   // CrosSpeechRecognitionService runs on browser UI thread.
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
index 1decdf1..c86966a 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -1031,8 +1031,16 @@
 
 }  // namespace
 
+#if BUILDFLAG(IS_MAC)
+// TODO(crbug.com/1357773): Flaky on Mac.
+#define MAYBE_ExpectPerformanceHistogramsAreRecorded \
+  DISABLED_ExpectPerformanceHistogramsAreRecorded
+#else
+#define MAYBE_ExpectPerformanceHistogramsAreRecorded \
+  ExpectPerformanceHistogramsAreRecorded
+#endif
 IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest,
-                       ExpectPerformanceHistogramsAreRecorded) {
+                       MAYBE_ExpectPerformanceHistogramsAreRecorded) {
   ASSERT_NO_FATAL_FAILURE(
       SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
   ResetConfigurationToEnableOnPhishingSites(true /* measure_performance */);
diff --git a/chrome/browser/themes/custom_theme_supplier.cc b/chrome/browser/themes/custom_theme_supplier.cc
index 54e0a8bf..05ac854 100644
--- a/chrome/browser/themes/custom_theme_supplier.cc
+++ b/chrome/browser/themes/custom_theme_supplier.cc
@@ -7,8 +7,9 @@
 #include "base/memory/ref_counted_memory.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/image/image.h"
+#include "ui/native_theme/native_theme.h"
 
-CustomThemeSupplier::~CustomThemeSupplier() {}
+CustomThemeSupplier::~CustomThemeSupplier() = default;
 
 void CustomThemeSupplier::StartUsingTheme() {}
 
@@ -33,7 +34,7 @@
 base::RefCountedMemory* CustomThemeSupplier::GetRawData(
     int idr_id,
     ui::ResourceScaleFactor scale_factor) const {
-  return NULL;
+  return nullptr;
 }
 
 bool CustomThemeSupplier::HasCustomImage(int id) const {
@@ -43,3 +44,7 @@
 bool CustomThemeSupplier::CanUseIncognitoColors() const {
   return true;
 }
+
+ui::NativeTheme* CustomThemeSupplier::GetNativeTheme() const {
+  return ui::NativeTheme::GetInstanceForNativeUi();
+}
diff --git a/chrome/browser/themes/custom_theme_supplier.h b/chrome/browser/themes/custom_theme_supplier.h
index 6e7ff19..da34b2a 100644
--- a/chrome/browser/themes/custom_theme_supplier.h
+++ b/chrome/browser/themes/custom_theme_supplier.h
@@ -25,6 +25,7 @@
 
 namespace ui {
 class ColorProvider;
+class NativeTheme;
 }
 
 // A representation of a theme. All theme properties can be accessed through the
@@ -81,6 +82,8 @@
     // this.
   }
 
+  virtual ui::NativeTheme* GetNativeTheme() const;
+
  protected:
   ~CustomThemeSupplier() override;
 
diff --git a/chrome/browser/themes/theme_helper.cc b/chrome/browser/themes/theme_helper.cc
index b8e38e7..40d4e173 100644
--- a/chrome/browser/themes/theme_helper.cc
+++ b/chrome/browser/themes/theme_helper.cc
@@ -170,21 +170,7 @@
   if (IsCustomTheme(theme_supplier))
     return false;
 
-  ui::NativeTheme const* native_theme =
-      ui::NativeTheme::GetInstanceForNativeUi();
-#if BUILDFLAG(IS_LINUX)
-  if (const auto* linux_ui = ui::LinuxUi::instance()) {
-    // We rely on the fact that the system theme is in use iff `theme_supplier`
-    // is non-null, but this is cheating. In the future this might not hold
-    // after we fully migrate to the color provider and remove SystemThemeLinux.
-    native_theme = linux_ui->GetNativeTheme(
-        theme_supplier &&
-        theme_supplier->get_theme_type() ==
-            ui::ColorProviderManager::ThemeInitializerSupplier::ThemeType::
-                kNativeX11);
-  }
-#endif
-  return native_theme->ShouldUseDarkColors();
+  return theme_supplier->GetNativeTheme()->ShouldUseDarkColors();
 }
 
 gfx::Image ThemeHelper::GetImageNamed(
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index c6b9ad5..3b2b9ab 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -313,14 +313,6 @@
   return theme_supplier_.get();
 }
 
-bool ThemeService::ShouldUseSystemTheme() const {
-#if BUILDFLAG(IS_LINUX)
-  return profile_->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme);
-#else
-  return false;
-#endif
-}
-
 bool ThemeService::ShouldUseCustomFrame() const {
 #if BUILDFLAG(IS_LINUX)
   if (!ui::OzonePlatform::GetInstance()
@@ -535,12 +527,14 @@
         static_cast<void (ThemeService::*)(SkColor)>(
             &ThemeService::BuildAutogeneratedThemeFromColor),
         weak_ptr_factory_.GetWeakPtr(), GetAutogeneratedThemeColor());
-  } else if (UsingSystemTheme()) {
-    reinstall_callback = base::BindOnce(&ThemeService::UseSystemTheme,
-                                        weak_ptr_factory_.GetWeakPtr());
   } else {
-    reinstall_callback = base::BindOnce(&ThemeService::UseDefaultTheme,
-                                        weak_ptr_factory_.GetWeakPtr());
+    auto system_theme = ui::SystemTheme::kDefault;
+    if (auto* theme_supplier = GetThemeSupplier()) {
+      if (auto* native_theme = theme_supplier->GetNativeTheme())
+        system_theme = native_theme->system_theme();
+    }
+    reinstall_callback = base::BindOnce(
+        &ThemeService::UseTheme, weak_ptr_factory_.GetWeakPtr(), system_theme);
   }
 
   return std::make_unique<ThemeReinstaller>(profile_,
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h
index c6206f61..86cd2e23 100644
--- a/chrome/browser/themes/theme_service.h
+++ b/chrome/browser/themes/theme_service.h
@@ -44,7 +44,6 @@
 class BrowserThemeProviderDelegate {
  public:
   virtual CustomThemeSupplier* GetThemeSupplier() const = 0;
-  virtual bool ShouldUseSystemTheme() const = 0;
   virtual bool ShouldUseCustomFrame() const = 0;
 };
 
@@ -87,7 +86,6 @@
 
   // Overridden from BrowserThemeProviderDelegate:
   CustomThemeSupplier* GetThemeSupplier() const override;
-  bool ShouldUseSystemTheme() const override;
   bool ShouldUseCustomFrame() const override;
 
   // Set the current theme to the theme defined in |extension|.
@@ -116,8 +114,8 @@
   // Virtual for testing.
   virtual bool UsingDefaultTheme() const;
 
-  // Whether we are using the system theme. On GTK, the system theme is the GTK
-  // theme, not the "Classic" theme.
+  // Whether we are using the system theme. On Linux, the system theme is the
+  // GTK or QT themes, not the "Classic" theme.
   virtual bool UsingSystemTheme() const;
 
   // Forwards to ThemeProviderBase::IsExtensionTheme().
diff --git a/chrome/browser/themes/theme_service_aura_linux.cc b/chrome/browser/themes/theme_service_aura_linux.cc
index 5d8b8d1f..166c4ee 100644
--- a/chrome/browser/themes/theme_service_aura_linux.cc
+++ b/chrome/browser/themes/theme_service_aura_linux.cc
@@ -8,14 +8,13 @@
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/custom_theme_supplier.h"
+#include "chrome/browser/themes/theme_service.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
+#include "ui/color/system_theme.h"
 #include "ui/gfx/image/image.h"
-#include "ui/native_theme/native_theme_aura.h"
-
-#if BUILDFLAG(IS_LINUX)
 #include "ui/linux/linux_ui.h"
-#endif
+#include "ui/native_theme/native_theme_aura.h"
 
 namespace {
 
@@ -33,6 +32,7 @@
   bool GetDisplayProperty(int id, int* result) const override;
   gfx::Image GetImageNamed(int id) const override;
   bool HasCustomImage(int id) const override;
+  ui::NativeTheme* GetNativeTheme() const override;
 
  private:
   ~SystemThemeLinux() override;
@@ -53,27 +53,21 @@
 void SystemThemeLinux::StopUsingTheme() {
   pref_service_->SetBoolean(prefs::kUsesSystemTheme, false);
   // Have the former theme notify its observers of change.
-#if BUILDFLAG(IS_LINUX)
   if (auto* linux_ui = ui::LinuxUi::instance())
     linux_ui->GetNativeTheme(nullptr)->NotifyOnNativeThemeUpdated();
-#endif
 }
 
 bool SystemThemeLinux::GetColor(int id, SkColor* color) const {
-#if BUILDFLAG(IS_LINUX)
   if (auto* linux_ui = ui::LinuxUi::instance()) {
     return linux_ui->GetColor(
         id, color, pref_service_->GetBoolean(prefs::kUseCustomChromeFrame));
   }
-#endif
   return false;
 }
 
 bool SystemThemeLinux::GetDisplayProperty(int id, int* result) const {
-#if BUILDFLAG(IS_LINUX)
   if (auto* linux_ui = ui::LinuxUi::instance())
     return linux_ui->GetDisplayProperty(id, result);
-#endif
   return false;
 }
 
@@ -85,6 +79,14 @@
   return false;
 }
 
+ui::NativeTheme* SystemThemeLinux::GetNativeTheme() const {
+  if (auto* linux_ui = ui::LinuxUi::instance()) {
+    if (auto* native_theme = linux_ui->GetNativeTheme(nullptr))
+      return native_theme;
+  }
+  return CustomThemeSupplier::GetNativeTheme();
+}
+
 SystemThemeLinux::~SystemThemeLinux() = default;
 
 }  // namespace
@@ -92,12 +94,9 @@
 ThemeServiceAuraLinux::~ThemeServiceAuraLinux() = default;
 
 ui::SystemTheme ThemeServiceAuraLinux::GetDefaultSystemTheme() const {
-#if defined(IS_LINUX)
   // TODO(https://crbug.com/1317782): Add QT theme preference.
   return ShouldUseSystemThemeForProfile(profile()) ? ui::SystemTheme::kGtk
                                                    : ui::SystemTheme::kDefault;
-#endif
-  return ui::SystemTheme::kDefault;
 }
 
 void ThemeServiceAuraLinux::UseTheme(ui::SystemTheme system_theme) {
@@ -105,17 +104,20 @@
     UseDefaultTheme();
     return;
   }
-#if BUILDFLAG(IS_LINUX)
-  if (ui::LinuxUi::instance()) {
+  if (ui::LinuxUi::instance())
     SetCustomDefaultTheme(new SystemThemeLinux(profile()->GetPrefs()));
-  }
-#else
-  UseDefaultTheme();
-#endif
 }
 
 void ThemeServiceAuraLinux::UseSystemTheme() {
-  SetCustomDefaultTheme(new SystemThemeLinux(profile()->GetPrefs()));
+  if (UsingSystemTheme())
+    return;
+  if (auto* linux_ui = ui::LinuxUi::instance()) {
+    if (auto* native_theme = linux_ui->GetNativeTheme(nullptr)) {
+      UseTheme(native_theme->system_theme());
+      return;
+    }
+  }
+  ThemeService::UseSystemTheme();
 }
 
 bool ThemeServiceAuraLinux::IsSystemThemeDistinctFromDefaultTheme() const {
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc
index a4aad78..b89866b 100644
--- a/chrome/browser/themes/theme_service_factory.cc
+++ b/chrome/browser/themes/theme_service_factory.cc
@@ -81,9 +81,7 @@
 
 KeyedService* ThemeServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* profile) const {
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX)
   using ThemeService = ThemeServiceAuraLinux;
 #endif
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index ccb2d70..ce33b8d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3120,6 +3120,7 @@
       "//chrome/browser/chromeos",
       "//chrome/browser/chromeos/extensions/vpn_provider",
       "//chrome/browser/chromeos/launcher_search:search_util",
+      "//chrome/browser/enterprise/connectors/device_trust:prefs",
       "//chrome/browser/media/router/discovery/access_code:access_code_cast_feature",
       "//chrome/browser/media/router/discovery/access_code:discovery_resources_proto",
       "//chrome/browser/nearby_sharing:share_target",
diff --git a/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn b/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
index 1c3b9cd5..bd03b04 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
+++ b/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
@@ -14,8 +14,9 @@
     "java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediator.java",
     "java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutProperties.java",
     "java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutSheetContent.java",
-    "java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutToolbar.java",
-    "java/src/org/chromium/chrome/browser/ui/fast_checkout/autofill_profile_screen/AutofillProfileItemProperties.java",
+    "java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemProperties.java",
+    "java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenCoordinator.java",
+    "java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenViewBinder.java",
     "java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenCoordinator.java",
     "java/src/org/chromium/chrome/browser/ui/fast_checkout/home_screen/HomeScreenViewBinder.java",
   ]
@@ -53,6 +54,7 @@
     "java/res/drawable/fast_checkout_item_background_bottom.xml",
     "java/res/drawable/fast_checkout_item_background_top.xml",
     "java/res/layout/fast_checkout_bottom_sheet.xml",
+    "java/res/layout/fast_checkout_detail_screen_sheet.xml",
     "java/res/layout/fast_checkout_home_screen_sheet.xml",
     "java/res/menu/fast_checkout_toolbar_menu.xml",
     "java/res/values/dimens.xml",
@@ -73,15 +75,25 @@
 robolectric_library("junit") {
   testonly = true
 
-  sources = [ "junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java" ]
+  sources = [
+    "junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java",
+    "junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java",
+  ]
   deps = [
     ":java",
+    "//base:base_java_test_support",
     "//base:base_junit_test_support",
+    "//chrome/android:chrome_java",
+    "//chrome/browser/flags:java",
     "//chrome/browser/ui/android/fast_checkout:java",
     "//components/autofill/android:main_autofill_java",
     "//components/autofill_assistant/android:public_java",
     "//components/browser_ui/bottomsheet/android:java",
+    "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
+    "//third_party/androidx:androidx_test_core_java",
+    "//third_party/androidx:androidx_test_ext_junit_java",
+    "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_bottom_sheet.xml b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_bottom_sheet.xml
index 7013e089..9888260 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_bottom_sheet.xml
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_bottom_sheet.xml
@@ -16,5 +16,7 @@
     <include
         android:id="@+id/fast_checkout_home_screen_sheet"
         layout="@layout/fast_checkout_home_screen_sheet" />
-    <!-- TODO(crbug.com/1334642): Create views for the remaining 2 screens. -->
+    <include
+        android:id="@+id/fast_checkout_detail_screen_sheet"
+        layout="@layout/fast_checkout_detail_screen_sheet" />
 </ViewFlipper>
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_detail_screen_sheet.xml b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_detail_screen_sheet.xml
new file mode 100644
index 0000000..ca862700
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/res/layout/fast_checkout_detail_screen_sheet.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="vertical">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/action_bar"
+        android:layout_width="match_parent"
+        android:layout_height="?attr/actionBarSize"
+        android:titleTextAppearance="@style/TextAppearance.Headline"
+        style="@style/ModernToolbar" />
+
+    <!-- TODO(crbug.com/1355310): Add RecyclerView for item list. -->
+
+</LinearLayout>
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutCoordinator.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutCoordinator.java
index 523d12c..871b0ef 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutCoordinator.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutCoordinator.java
@@ -9,8 +9,10 @@
 import android.view.View;
 import android.widget.ViewFlipper;
 
+import org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.ScreenType;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.DetailScreenCoordinator;
 import org.chromium.chrome.browser.ui.fast_checkout.home_screen.HomeScreenCoordinator;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -32,11 +34,17 @@
         View homeScreenView = rootView.findViewById(R.id.fast_checkout_home_screen_sheet);
         HomeScreenCoordinator homeScreenCoordinator =
                 new HomeScreenCoordinator(context, homeScreenView, mModel, delegate);
-        // TODO(crbug.com/1334642): Create remaining 2 screens.
+
+        // The detail screen can display the Autofill profile or the credit
+        // card selection.
+        View detailScreenView = rootView.findViewById(R.id.fast_checkout_detail_screen_sheet);
+        DetailScreenCoordinator detailScreenCoordinator =
+                new DetailScreenCoordinator(context, detailScreenView, mModel);
 
         mModel.addObserver((source, propertyKey) -> {
             if (FastCheckoutProperties.CURRENT_SCREEN == propertyKey) {
-                rootView.setDisplayedChild(mModel.get(FastCheckoutProperties.CURRENT_SCREEN));
+                rootView.setDisplayedChild(getScreenIndexForScreenType(
+                        mModel.get(FastCheckoutProperties.CURRENT_SCREEN)));
             } else if (FastCheckoutProperties.VISIBLE == propertyKey) {
                 // Dismiss the sheet if it can't be immediately shown.
                 boolean visibilityChangeSuccessful =
@@ -48,6 +56,24 @@
         });
     }
 
+    /**
+     * Acts as a helper function to convert a {@link FastCheckoutProperties.ScreenType}
+     * the index of the screen in the ViewFlipper.
+     */
+    private static int getScreenIndexForScreenType(@ScreenType int screenType) {
+        switch (screenType) {
+            case ScreenType.HOME_SCREEN:
+                return 0;
+            // Both the Autofill profile selection and the credit card selection
+            // are displayed on the detail screen.
+            case ScreenType.AUTOFILL_PROFILE_SCREEN:
+            case ScreenType.CREDIT_CARD_SCREEN:
+                return 1;
+        }
+        assert false : "Undefined ScreenType: " + screenType;
+        return 0;
+    }
+
     @Override
     public void showOptions(
             FastCheckoutAutofillProfile[] profiles, FastCheckoutCreditCard[] creditCards) {
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediator.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediator.java
index 2caf311..605ec45 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediator.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediator.java
@@ -4,14 +4,17 @@
 
 package org.chromium.chrome.browser.ui.fast_checkout;
 
+import android.view.MenuItem;
 import android.view.View;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar.OnMenuItemClickListener;
 
-import org.chromium.chrome.browser.ui.fast_checkout.autofill_profile_screen.AutofillProfileItemProperties;
+import org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.ScreenType;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.AutofillProfileItemProperties;
 import org.chromium.chrome.browser.ui.fast_checkout.home_screen.HomeScreenCoordinator;
 import org.chromium.components.autofill_assistant.AutofillAssistantPublicTags;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
@@ -59,41 +62,47 @@
             }
         };
 
-        mModel.set(
-                FastCheckoutProperties.HOME_SCREEN_DELEGATE, new HomeScreenCoordinator.Delegate() {
-                    @Override
-                    public void onOptionsAccepted() {
-                        if (!mModel.get(FastCheckoutProperties.VISIBLE)) {
-                            return; // Dismiss only if not dismissed yet.
-                        }
-                        FastCheckoutAutofillProfile profile =
-                                mModel.get(FastCheckoutProperties.SELECTED_PROFILE);
-                        FastCheckoutCreditCard creditCard =
-                                mModel.get(FastCheckoutProperties.SELECTED_CREDIT_CARD);
-                        assert profile != null && creditCard != null;
-                        mModel.set(FastCheckoutProperties.VISIBLE, false);
-                        mDelegate.onOptionsSelected(profile, creditCard);
-                    };
+        mModel.set(FastCheckoutProperties.HOME_SCREEN_DELEGATE, createHomeScreenDelegate());
+        mModel.set(FastCheckoutProperties.DETAIL_SCREEN_BACK_CLICK_HANDLER,
+                () -> setCurrentScreen(FastCheckoutProperties.ScreenType.HOME_SCREEN));
+    }
 
-                    @Override
-                    public void onDismiss() {
-                        if (!mModel.get(FastCheckoutProperties.VISIBLE)) {
-                            return; // Dismiss only if not dismissed yet.
-                        }
-                        mModel.set(FastCheckoutProperties.VISIBLE, false);
-                        mDelegate.onDismissed();
-                    }
+    /** Returns an implementation the {@link HomeScreenCoordinator.Delegate} interface. */
+    private HomeScreenCoordinator.Delegate createHomeScreenDelegate() {
+        return new HomeScreenCoordinator.Delegate() {
+            @Override
+            public void onOptionsAccepted() {
+                if (!mModel.get(FastCheckoutProperties.VISIBLE)) {
+                    return; // Dismiss only if not dismissed yet.
+                }
+                FastCheckoutAutofillProfile profile =
+                        mModel.get(FastCheckoutProperties.SELECTED_PROFILE);
+                FastCheckoutCreditCard creditCard =
+                        mModel.get(FastCheckoutProperties.SELECTED_CREDIT_CARD);
+                assert profile != null && creditCard != null;
+                mModel.set(FastCheckoutProperties.VISIBLE, false);
+                mDelegate.onOptionsSelected(profile, creditCard);
+            };
 
-                    @Override
-                    public void onShowAddressesList() {
-                        // TODO(crbug.com/1334642): Show addresses list screen.
-                    }
+            @Override
+            public void onDismiss() {
+                if (!mModel.get(FastCheckoutProperties.VISIBLE)) {
+                    return; // Dismiss only if not dismissed yet.
+                }
+                mModel.set(FastCheckoutProperties.VISIBLE, false);
+                mDelegate.onDismissed();
+            }
 
-                    @Override
-                    public void onShowCreditCardList() {
-                        // TODO(crbug.com/1334642): Show credit cards list screen.
-                    }
-                });
+            @Override
+            public void onShowAddressesList() {
+                setCurrentScreen(FastCheckoutProperties.ScreenType.AUTOFILL_PROFILE_SCREEN);
+            }
+
+            @Override
+            public void onShowCreditCardList() {
+                // TODO(crbug.com/1334642): Show credit cards list screen.
+            }
+        };
     }
 
     public void showOptions(
@@ -222,10 +231,45 @@
      *         shown.
      */
     public void setCurrentScreen(int screenType) {
+        if (screenType == FastCheckoutProperties.ScreenType.AUTOFILL_PROFILE_SCREEN) {
+            mModel.set(FastCheckoutProperties.DETAIL_SCREEN_TITLE,
+                    R.string.fast_checkout_autofill_profile_sheet_title);
+            mModel.set(FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_MENU_TITLE,
+                    R.string.fast_checkout_autofill_profile_settings_button_description);
+            // TODO(crbug.com/1355310): Implement handler for opening Autofill profile settings.
+            mModel.set(FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_CLICK_HANDLER,
+                    createSettingsOnClickListener(() -> {}));
+            mModel.set(FastCheckoutProperties.DETAIL_SCREEN_MODEL_LIST,
+                    mModel.get(FastCheckoutProperties.PROFILE_MODEL_LIST));
+        } else if (screenType == ScreenType.CREDIT_CARD_SCREEN) {
+            // TODO(crbug.com/1355310): Implement handler for opening credit card settings.
+            mModel.set(FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_CLICK_HANDLER,
+                    createSettingsOnClickListener(() -> {}));
+            // TODO(crbug.com/1355310): Switch to credit card model, set title, etc.
+        }
+
         mModel.set(FastCheckoutProperties.CURRENT_SCREEN, screenType);
     }
 
     /**
+     * Creates and returns an {@link Toolbar.OnMenuItemClickListener} that
+     * executes a Runnable if and only if the Settings MenuItem was clicked.
+     * @param runnable The Runnable to execute.
+     */
+    static OnMenuItemClickListener createSettingsOnClickListener(Runnable runnable) {
+        return new OnMenuItemClickListener() {
+            @Override
+            public boolean onMenuItemClick(MenuItem item) {
+                if (item.getItemId() == R.id.settings_menu_id) {
+                    runnable.run();
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
+    /**
      * Releases the resources used by FastCheckoutMediator.
      */
     @MainThread
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutProperties.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutProperties.java
index 372b3bd..711e0b0 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutProperties.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutProperties.java
@@ -5,12 +5,13 @@
 package org.chromium.chrome.browser.ui.fast_checkout;
 
 import androidx.annotation.IntDef;
+import androidx.appcompat.widget.Toolbar.OnMenuItemClickListener;
 
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
 import org.chromium.chrome.browser.ui.fast_checkout.home_screen.HomeScreenCoordinator;
 import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.modelutil.MVCListAdapter;
+import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey;
@@ -28,34 +29,19 @@
     /**
      * The different screens that can be shown on the sheet.
      */
-    @IntDef({ScreenType.HOME_SCREEN, ScreenType.AUTOFILL_PROFILES_SCREEN,
-            ScreenType.CREDIT_CARDS_SCREEN})
+    @IntDef({ScreenType.HOME_SCREEN, ScreenType.AUTOFILL_PROFILE_SCREEN,
+            ScreenType.CREDIT_CARD_SCREEN})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ScreenType {
         int HOME_SCREEN = 0;
-        int AUTOFILL_PROFILES_SCREEN = 1;
-        int CREDIT_CARDS_SCREEN = 2;
+        int AUTOFILL_PROFILE_SCREEN = 1;
+        int CREDIT_CARD_SCREEN = 2;
     }
 
     /** Property that indicates the bottom sheet visibility. */
     public static final WritableBooleanPropertyKey VISIBLE =
             new WritableBooleanPropertyKey("visible");
 
-    /** The chosen autofill profile option. */
-    public static final WritableObjectPropertyKey<FastCheckoutAutofillProfile> SELECTED_PROFILE =
-            new WritableObjectPropertyKey<>("selected_profile");
-
-    /** The models corresponding to all autofill profile options. */
-    public static final ReadableObjectPropertyKey<ListModel<MVCListAdapter.ListItem>>
-            PROFILE_MODEL_LIST = new ReadableObjectPropertyKey("profile_model_list");
-
-    /** The chosen credit card option. */
-    public static final WritableObjectPropertyKey<FastCheckoutCreditCard> SELECTED_CREDIT_CARD =
-            new WritableObjectPropertyKey<>("selected_credit_card");
-
-    public static final WritableObjectPropertyKey<HomeScreenCoordinator.Delegate>
-            HOME_SCREEN_DELEGATE = new WritableObjectPropertyKey<>("home_screen_delegate");
-
     /**
      * Property that indicates which screen (i.e ScreenType) is currently displayed on the bottom
      * sheet.
@@ -63,7 +49,47 @@
     public static final WritableIntPropertyKey CURRENT_SCREEN =
             new WritableIntPropertyKey("current_screen");
 
-    static PropertyModel createDefaultModel() {
+    /** The chosen autofill profile option. */
+    public static final WritableObjectPropertyKey<FastCheckoutAutofillProfile> SELECTED_PROFILE =
+            new WritableObjectPropertyKey<>("selected_profile");
+
+    /** The models corresponding to all autofill profile options. */
+    public static final ReadableObjectPropertyKey<ListModel<ListItem>> PROFILE_MODEL_LIST =
+            new ReadableObjectPropertyKey("profile_model_list");
+
+    /** The chosen credit card option. */
+    public static final WritableObjectPropertyKey<FastCheckoutCreditCard> SELECTED_CREDIT_CARD =
+            new WritableObjectPropertyKey<>("selected_credit_card");
+
+    /** The delegate that handles actions on the home screen. */
+    public static final WritableObjectPropertyKey<HomeScreenCoordinator.Delegate>
+            HOME_SCREEN_DELEGATE = new WritableObjectPropertyKey<>("home_screen_delegate");
+
+    /** The string id of the title shown on the detail screen. */
+    public static final WritableIntPropertyKey DETAIL_SCREEN_TITLE =
+            new WritableIntPropertyKey("detail_screen_title");
+
+    /** The string id of the title shown on the settings icon. */
+    public static final WritableIntPropertyKey DETAIL_SCREEN_SETTINGS_MENU_TITLE =
+            new WritableIntPropertyKey("detail_screen_settings_menu_title");
+
+    /** The handler for the back icon on the detail screens (autofill profiles, credit cards). */
+    public static final WritableObjectPropertyKey<Runnable> DETAIL_SCREEN_BACK_CLICK_HANDLER =
+            new WritableObjectPropertyKey<>("detail_screen_back_click_handler");
+
+    /** The handler for the settings icon on the autofill profile screen. */
+    public static final WritableObjectPropertyKey<OnMenuItemClickListener>
+            DETAIL_SCREEN_SETTINGS_CLICK_HANDLER =
+                    new WritableObjectPropertyKey<>("detail_screen_settings_click_handler");
+
+    /**
+     * The models that are displayed on the detail screen. This will either point to
+     * PROFILE_MODEL_LIST or CREDIT_CARD_MODEL_LIST.
+     */
+    public static final WritableObjectPropertyKey<ListModel<ListItem>> DETAIL_SCREEN_MODEL_LIST =
+            new WritableObjectPropertyKey<>("detail_screen_model_list");
+
+    public static PropertyModel createDefaultModel() {
         return new PropertyModel.Builder(ALL_KEYS)
                 .with(VISIBLE, false)
                 .with(CURRENT_SCREEN, ScreenType.HOME_SCREEN)
@@ -72,6 +98,9 @@
     }
 
     /** All keys used for the fast checkout bottom sheet. */
-    static final PropertyKey[] ALL_KEYS = new PropertyKey[] {CURRENT_SCREEN, VISIBLE,
-            SELECTED_PROFILE, PROFILE_MODEL_LIST, SELECTED_CREDIT_CARD, HOME_SCREEN_DELEGATE};
+    static final PropertyKey[] ALL_KEYS =
+            new PropertyKey[] {VISIBLE, CURRENT_SCREEN, SELECTED_PROFILE, PROFILE_MODEL_LIST,
+                    SELECTED_CREDIT_CARD, HOME_SCREEN_DELEGATE, DETAIL_SCREEN_TITLE,
+                    DETAIL_SCREEN_SETTINGS_MENU_TITLE, DETAIL_SCREEN_BACK_CLICK_HANDLER,
+                    DETAIL_SCREEN_SETTINGS_CLICK_HANDLER, DETAIL_SCREEN_MODEL_LIST};
 }
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutToolbar.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutToolbar.java
deleted file mode 100644
index 0c17a3bc..0000000
--- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutToolbar.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.ui.fast_checkout;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.MenuItem;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
-
-import org.chromium.components.browser_ui.styles.SemanticColorUtils;
-import org.chromium.components.browser_ui.widget.TintedDrawable;
-
-/**
- * A toolbar for the selection screens in the FastCheckout bottom sheet. It
- * contains an additional Menu with a settings gear icon.
- */
-public class FastCheckoutToolbar extends Toolbar {
-    /** The delegate of the class that processes clicks on menu items. */
-    public interface Delegate {
-        /**
-         * The user clicked on the gear to open settings to edit an Autofill profile
-         * or a credit card profile.
-         */
-        public void onOpenSettingsClick();
-
-        /** The user clicked the back icon in the toolbar to return to the home screen. */
-        public void onBackIconClick();
-    }
-
-    public FastCheckoutToolbar(Context context) {
-        this(context, null);
-    }
-
-    public FastCheckoutToolbar(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public FastCheckoutToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        inflateMenu(R.menu.fast_checkout_toolbar_menu);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        setBackgroundColor(SemanticColorUtils.getDefaultBgColor(getContext()));
-        setTitleTextAppearance(getContext(), R.style.TextAppearance_Headline);
-        Drawable tintedBackIcon = TintedDrawable.constructTintedDrawable(getContext(),
-                R.drawable.ic_arrow_back_white_24dp, R.color.default_icon_color_tint_list);
-        setNavigationIcon(tintedBackIcon);
-    }
-
-    /** Binds the items to the Delegate. The delegate must be non-null. */
-    public void setDelegate(@NonNull Delegate delegate) {
-        assert delegate != null;
-
-        setNavigationOnClickListener((v) -> delegate.onBackIconClick());
-        setOnMenuItemClickListener(new OnMenuItemClickListener() {
-            @Override
-            public boolean onMenuItemClick(MenuItem item) {
-                if (item.getItemId() == R.id.settings_menu_id) {
-                    delegate.onOpenSettingsClick();
-                    return true;
-                }
-                return false;
-            }
-        });
-    }
-
-    /** Sets the title of the MenuItem for opening settings. */
-    public void setSettingsMenuTitle(int resId) {
-        MenuItem settingsMenuItem = getMenu().findItem(R.id.settings_menu_id);
-        assert settingsMenuItem != null;
-        settingsMenuItem.setTitle(resId);
-    }
-}
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/autofill_profile_screen/AutofillProfileItemProperties.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemProperties.java
similarity index 94%
rename from chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/autofill_profile_screen/AutofillProfileItemProperties.java
rename to chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemProperties.java
index 9659eb6..5bda528f 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/autofill_profile_screen/AutofillProfileItemProperties.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/AutofillProfileItemProperties.java
@@ -2,7 +2,7 @@
 // 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.ui.fast_checkout.autofill_profile_screen;
+package org.chromium.chrome.browser.ui.fast_checkout.detail_screen;
 
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.ui.modelutil.PropertyKey;
@@ -11,7 +11,7 @@
 import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
 
 /**
- * Model for an {@link FastCheckoutAutofillProfile} entry in the autofill Profile screen sheet.
+ * Model for an {@link FastCheckoutAutofillProfile} entry in the Autofill profile screen sheet.
  */
 public class AutofillProfileItemProperties {
     public static final int DEFAULT_ITEM_TYPE = 0;
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenCoordinator.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenCoordinator.java
new file mode 100644
index 0000000..b1a0c05
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenCoordinator.java
@@ -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.
+
+package org.chromium.chrome.browser.ui.fast_checkout.detail_screen;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.appcompat.widget.Toolbar;
+
+import org.chromium.chrome.browser.ui.fast_checkout.R;
+import org.chromium.components.browser_ui.widget.TintedDrawable;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+
+/**
+ * Coordinator for the detail screens (Autofill profile selection, credit card selection)
+ * of the Fast Checkout bottom sheet.
+ */
+public class DetailScreenCoordinator {
+    /**
+     * Sets up the view of the detail screen, puts it into a {@link
+     * DetailScreenViewBinder.ViewHolder} and connects it to the PropertyModel by setting up a model
+     * change processor.
+     */
+    public DetailScreenCoordinator(Context context, View view, PropertyModel model) {
+        Toolbar toolbar = (Toolbar) view.findViewById(R.id.action_bar);
+        assert toolbar != null;
+        toolbar.inflateMenu(R.menu.fast_checkout_toolbar_menu);
+        Drawable tintedBackIcon = TintedDrawable.constructTintedDrawable(toolbar.getContext(),
+                R.drawable.ic_arrow_back_white_24dp, R.color.default_icon_color_tint_list);
+        toolbar.setNavigationIcon(tintedBackIcon);
+        toolbar.setNavigationContentDescription(
+                R.string.fast_checkout_back_to_home_screen_icon_description);
+
+        DetailScreenViewBinder.ViewHolder viewHolder =
+                new DetailScreenViewBinder.ViewHolder(context, view);
+
+        PropertyModelChangeProcessor.create(model, viewHolder, DetailScreenViewBinder::bind);
+    }
+}
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenViewBinder.java b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenViewBinder.java
new file mode 100644
index 0000000..71289083
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/src/org/chromium/chrome/browser/ui/fast_checkout/detail_screen/DetailScreenViewBinder.java
@@ -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.
+
+package org.chromium.chrome.browser.ui.fast_checkout.detail_screen;
+
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_BACK_CLICK_HANDLER;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_CLICK_HANDLER;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_MENU_TITLE;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_TITLE;
+
+import android.content.Context;
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.appcompat.widget.Toolbar;
+
+import org.chromium.chrome.browser.ui.fast_checkout.R;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * A ViewHolder and a static bind method for FastCheckout's Autofill profile screen.
+ */
+public class DetailScreenViewBinder {
+    /** A ViewHolder that inflates the toolbar and provides easy item look-up. */
+    static class ViewHolder {
+        final Toolbar mToolbar;
+        final MenuItem mSettingsMenuItem;
+
+        ViewHolder(Context context, View contentView) {
+            mToolbar = contentView.findViewById(R.id.action_bar);
+            mSettingsMenuItem = mToolbar.getMenu().findItem(R.id.settings_menu_id);
+        }
+    }
+
+    /**
+     * Binds the {@link ViewHolder} to a {@link PropertyModel} with properties defined in
+     * {@link FastCheckoutProperties} and prefix DETAIL_SCREEN.
+     */
+    public static void bind(PropertyModel model, ViewHolder view, PropertyKey propertyKey) {
+        if (propertyKey == DETAIL_SCREEN_BACK_CLICK_HANDLER) {
+            view.mToolbar.setNavigationOnClickListener(
+                    (v) -> model.get(DETAIL_SCREEN_BACK_CLICK_HANDLER).run());
+        } else if (propertyKey == DETAIL_SCREEN_SETTINGS_CLICK_HANDLER) {
+            view.mToolbar.setOnMenuItemClickListener(
+                    model.get(DETAIL_SCREEN_SETTINGS_CLICK_HANDLER));
+        } else if (propertyKey == DETAIL_SCREEN_TITLE) {
+            view.mToolbar.setTitle(model.get(DETAIL_SCREEN_TITLE));
+        } else if (propertyKey == DETAIL_SCREEN_SETTINGS_MENU_TITLE) {
+            view.mSettingsMenuItem.setTitle(model.get(DETAIL_SCREEN_SETTINGS_MENU_TITLE));
+        }
+    }
+}
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings.grd b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings.grd
index 19793ed..1c436158 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings.grd
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings.grd
@@ -200,6 +200,15 @@
       <message name="IDS_FAST_CHECKOUT_SHEET_CLOSED" desc="Accessibility string read when the Fast Checkout bottom sheet showing a list of the user stored addresses and payment options is closed.">
         List of addresses and payment options to be filled during checkout flows is closed.
       </message>
+      <message name="IDS_FAST_CHECKOUT_BACK_TO_HOME_SCREEN_ICON_DESCRIPTION" desc="Acessibility string describing the back icon on the autofill profile and credit card detail sheets.">
+        Go back
+      </message>
+      <message name="IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SHEET_TITLE" desc="Header of the autofill profile selection sheet.">
+        Shipping address
+      </message>
+      <message name="IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SETTINGS_BUTTON_DESCRIPTION" desc="Accessibility string describing the icon to open Autofill profile settings.">
+        Open Autofill profile settings
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SETTINGS_BUTTON_DESCRIPTION.png.sha1 b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SETTINGS_BUTTON_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..c4f5fa7
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SETTINGS_BUTTON_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+4a022162e4583fbe53d4ce4e06ed67ac09a6c384
\ No newline at end of file
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SHEET_TITLE.png.sha1 b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SHEET_TITLE.png.sha1
new file mode 100644
index 0000000..f7e69033
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_AUTOFILL_PROFILE_SHEET_TITLE.png.sha1
@@ -0,0 +1 @@
+5d4a8cd717a21a817d4b1944ac989a4d18d564db
\ No newline at end of file
diff --git a/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_BACK_TO_HOME_SCREEN_ICON_DESCRIPTION.png.sha1 b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_BACK_TO_HOME_SCREEN_ICON_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..a9aa804
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/java/strings/android_fast_checkout_strings_grd/IDS_FAST_CHECKOUT_BACK_TO_HOME_SCREEN_ICON_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+53b6a1e26830f6bf1ca0d0cbc9e51f45189f46eb
\ No newline at end of file
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
new file mode 100644
index 0000000..d502ad3
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
@@ -0,0 +1,121 @@
+// 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.ui.fast_checkout;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_BACK_CLICK_HANDLER;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_CLICK_HANDLER;
+
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.appcompat.widget.Toolbar;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.SmallTest;
+
+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.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.ScalableTimeout;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.DetailScreenCoordinator;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * Simple unit tests for the detail screen view.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+@CommandLineFlags.
+Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeSwitches.DISABLE_NATIVE_INITIALIZATION})
+public class FastCheckoutDetailScreenViewTest {
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule();
+    @Rule
+    public ActivityScenarioRule<ChromeTabbedActivity> mActivityScenarioRule =
+            new ActivityScenarioRule<>(ChromeTabbedActivity.class);
+
+    @Mock
+    private Runnable mBackClickHandler;
+    @Mock
+    private Runnable mSettingsClickHandler;
+
+    private PropertyModel mModel;
+    private View mView;
+
+    @Before
+    public void setUp() {
+        mActivityScenarioRule.getScenario().onActivity(activity -> {
+            mModel = FastCheckoutProperties.createDefaultModel();
+            mModel.set(DETAIL_SCREEN_SETTINGS_CLICK_HANDLER,
+                    FastCheckoutMediator.createSettingsOnClickListener(mSettingsClickHandler));
+            mModel.set(DETAIL_SCREEN_BACK_CLICK_HANDLER, mBackClickHandler);
+
+            // Create the view.
+            mView = LayoutInflater.from(activity).inflate(
+                    R.layout.fast_checkout_detail_screen_sheet, null);
+
+            // Let the coordinator connect model and view.
+            new DetailScreenCoordinator(activity, mView, mModel);
+        });
+    }
+
+    public static <T> T waitForEvent(T mock) {
+        return verify(mock,
+                timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
+    }
+
+    @Test
+    @SmallTest
+    public void testBackArrowClickCallsHandler() {
+        assertNotNull(mView);
+        Toolbar toolbar = mView.findViewById(R.id.action_bar);
+        assertNotNull(toolbar);
+
+        // Find the navigation button. Toolbar does not expose a method to get
+        // the navigation button and Espresso does not work in this setup.
+        // TODO(crbug.com/1355310): Move to integration test once that exists.
+        View backButton = null;
+        for (int index = 0; index < toolbar.getChildCount(); ++index) {
+            View candidateView = toolbar.getChildAt(index);
+            if (candidateView.getContentDescription() != null
+                    && candidateView.getContentDescription().equals(
+                            toolbar.getNavigationContentDescription())) {
+                backButton = candidateView;
+            }
+        }
+        assertNotNull(backButton);
+        backButton.performClick();
+        waitForEvent(mBackClickHandler).run();
+    }
+
+    @Test
+    @SmallTest
+    public void testOpenSettingsClickCallsHandler() {
+        assertNotNull(mView);
+
+        // Click on the settings element.
+        View settingsMenuElement = mView.findViewById(R.id.settings_menu_id);
+        assertNotNull(settingsMenuElement);
+        settingsMenuElement.performClick();
+        waitForEvent(mSettingsClickHandler).run();
+    }
+}
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java
index 2ec3cc2..01aba95 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutMediatorTest.java
@@ -6,6 +6,7 @@
 
 import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -15,10 +16,17 @@
 import static org.mockito.Mockito.when;
 
 import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.CURRENT_SCREEN;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_BACK_CLICK_HANDLER;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_MODEL_LIST;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_CLICK_HANDLER;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_SETTINGS_MENU_TITLE;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.DETAIL_SCREEN_TITLE;
+import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.HOME_SCREEN_DELEGATE;
 import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.PROFILE_MODEL_LIST;
 import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.SELECTED_PROFILE;
 import static org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.VISIBLE;
 
+import androidx.appcompat.widget.Toolbar.OnMenuItemClickListener;
 import androidx.recyclerview.widget.RecyclerView;
 
 import org.junit.Before;
@@ -30,9 +38,10 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.ui.fast_checkout.FastCheckoutProperties.ScreenType;
-import org.chromium.chrome.browser.ui.fast_checkout.autofill_profile_screen.AutofillProfileItemProperties;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.AutofillProfileItemProperties;
+import org.chromium.chrome.browser.ui.fast_checkout.home_screen.HomeScreenCoordinator;
 import org.chromium.components.autofill.VirtualCardEnrollmentState;
 import org.chromium.components.autofill_assistant.AutofillAssistantPublicTags;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
@@ -80,6 +89,41 @@
         assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.HOME_SCREEN));
         assertThat(mModel.get(PROFILE_MODEL_LIST), instanceOf(ListModel.class));
         assertThat(mModel.get(PROFILE_MODEL_LIST).size(), is(0));
+
+        // On top of that, the initialize method of the Mediator sets up delegates.
+        assertNotNull(mModel.get(HOME_SCREEN_DELEGATE));
+        assertThat(
+                mModel.get(HOME_SCREEN_DELEGATE), instanceOf(HomeScreenCoordinator.Delegate.class));
+
+        assertNotNull(mModel.get(DETAIL_SCREEN_BACK_CLICK_HANDLER));
+        assertThat(mModel.get(DETAIL_SCREEN_BACK_CLICK_HANDLER), instanceOf(Runnable.class));
+    }
+
+    @Test
+    public void testSetCurrentScreenUpdatesModel() {
+        mMediator.setCurrentScreen(ScreenType.AUTOFILL_PROFILE_SCREEN);
+
+        // Test that all relevant model entries got updated.
+        assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.AUTOFILL_PROFILE_SCREEN));
+        assertThat(mModel.get(DETAIL_SCREEN_TITLE),
+                is(R.string.fast_checkout_autofill_profile_sheet_title));
+        assertThat(mModel.get(DETAIL_SCREEN_SETTINGS_MENU_TITLE),
+                is(R.string.fast_checkout_autofill_profile_settings_button_description));
+        assertThat(mModel.get(DETAIL_SCREEN_MODEL_LIST), is(mModel.get(PROFILE_MODEL_LIST)));
+
+        assertNotNull(mModel.get(DETAIL_SCREEN_SETTINGS_CLICK_HANDLER));
+        assertThat(mModel.get(DETAIL_SCREEN_SETTINGS_CLICK_HANDLER),
+                instanceOf(OnMenuItemClickListener.class));
+        // TODO(crbug.com/1355310): Test opening Autofill settings.
+    }
+
+    @Test
+    public void testNavigateBackWorksFromAutofillProfileScreen() {
+        mMediator.setCurrentScreen(ScreenType.AUTOFILL_PROFILE_SCREEN);
+        assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.AUTOFILL_PROFILE_SCREEN));
+
+        mModel.get(DETAIL_SCREEN_BACK_CLICK_HANDLER).run();
+        assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.HOME_SCREEN));
     }
 
     @Test
@@ -105,15 +149,6 @@
     }
 
     @Test
-    public void testSetCurrentScreenUpdatesModel() {
-        mMediator.setCurrentScreen(ScreenType.AUTOFILL_PROFILES_SCREEN);
-        assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.AUTOFILL_PROFILES_SCREEN));
-
-        mMediator.setCurrentScreen(ScreenType.HOME_SCREEN);
-        assertThat(mModel.get(CURRENT_SCREEN), is(ScreenType.HOME_SCREEN));
-    }
-
-    @Test
     public void testSetAutofillProfilesCreatesModels() {
         mMediator.setAutofillProfileItems(DUMMY_PROFILES);
 
@@ -153,7 +188,7 @@
     public void testAutofillProfileItemOnClickListenerUpdatesSelectedProfile() {
         mMediator.setAutofillProfileItems(DUMMY_PROFILES);
         mMediator.setSelectedAutofillProfile(DUMMY_PROFILES[0]);
-        mMediator.setCurrentScreen(ScreenType.AUTOFILL_PROFILES_SCREEN);
+        mMediator.setCurrentScreen(ScreenType.AUTOFILL_PROFILE_SCREEN);
 
         ListModel<MVCListAdapter.ListItem> models = mModel.get(PROFILE_MODEL_LIST);
         assertThat(models.size(), is(DUMMY_PROFILES.length));
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn
index 1063f68..15a856ad 100644
--- a/chrome/browser/ui/android/omnibox/BUILD.gn
+++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -404,6 +404,7 @@
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilderUnitTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManagerUnitTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/FaviconFetcherUnitTest.java",
+    "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownUnitTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextNewLayoutUnitTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorUnitTest.java",
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/colors.xml b/chrome/browser/ui/android/omnibox/java/res/values/colors.xml
index 08bf05d5..efe86b78 100644
--- a/chrome/browser/ui/android/omnibox/java/res/values/colors.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/values/colors.xml
@@ -41,4 +41,6 @@
 
     <color name="text_highlight_color_incognito">@color/baseline_primary_200_alpha_20</color>
 
+    <color name="omnibox_dropdown_bg_incognito">@color/default_bg_color_dark_elev_1_baseline</color>
+
 </resources>
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
index e90e24af..305ac48 100644
--- a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
@@ -76,11 +76,13 @@
     <dimen name="omnibox_suggestion_refine_view_modern_end_padding">4dp</dimen>
     <dimen name="omnibox_suggestion_carousel_spacing_maximum">8dp</dimen>
 
-    <dimen name="omnibox_suggestion_bg_elevation">@dimen/default_elevation_1</dimen>
+    <dimen name="omnibox_suggestion_bg_elevation">@dimen/default_elevation_0</dimen>
     <dimen name="omnibox_suggestion_bg_round_corner_radius">16dp</dimen>
     <dimen name="omnibox_suggestion_bg_rectangle_corner_radius">0dp</dimen>
     <dimen name="omnibox_suggestion_vertical_spacing">2dp</dimen>
 
+    <dimen name="omnibox_suggestion_dropdown_bg_elevation">@dimen/default_elevation_1</dimen>
+
     <!-- Adding search engine logo to the omnibox. -->
     <!-- Max size which will fit completely in the composed/rounded bg. -->
     <dimen name="omnibox_search_engine_logo_favicon_size">17dp</dimen>
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
index 48dedc4..f138b42 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
@@ -170,6 +170,8 @@
         mTextOffsetAdjustedScale = mTextOffsetThreshold == 1 ? 1 : (1 - mTextOffsetThreshold);
 
         mIsTablet = isTablet;
+        mShowStatusIconWhenUrlFocused = mIsTablet;
+
         mPermissionDialogController = permissionDialogController;
         mPermissionDialogController.addObserver(this);
 
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java
index 6c610dd..0a03b3c 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java
@@ -180,7 +180,20 @@
         doReturn(true).when(mNewTabPageDelegate).isCurrentlyVisible();
 
         mMediator.setUrlHasFocus(false);
-        mMediator.setShowIconsWhenUrlFocused(true);
+        Assert.assertTrue(mModel.get(StatusProperties.SHOW_STATUS_ICON));
+        Assert.assertFalse(mMediator.shouldDisplaySearchEngineIcon());
+    }
+
+    @Test
+    @SmallTest
+    public void searchEngineLogoTablet() {
+        setupStatusMediator(/* isTablet= */ true);
+        mMediator.setUrlHasFocus(true);
+
+        Assert.assertTrue(mModel.get(StatusProperties.SHOW_STATUS_ICON));
+        Assert.assertTrue(mMediator.shouldDisplaySearchEngineIcon());
+
+        doReturn(true).when(mLocationBarDataProvider).isIncognito();
         Assert.assertTrue(mModel.get(StatusProperties.SHOW_STATUS_ICON));
         Assert.assertFalse(mMediator.shouldDisplaySearchEngineIcon());
     }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java
index d3e78128..f67b407 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java
@@ -129,8 +129,7 @@
                 ? SuggestionCommonProperties.FormFactor.TABLET
                 : SuggestionCommonProperties.FormFactor.PHONE;
         DropdownItemViewInfo prevSuggestionWithBackground = null;
-        // Note: we consider the Omnibox as part of the background rounding group.
-        boolean inDropdownItemBackgroundRoundingGroup = true;
+        boolean inDropdownItemBackgroundRoundingGroup = false;
         for (int i = 0; i < mSourceViewInfoList.size(); i++) {
             final DropdownItemViewInfo item = mSourceViewInfoList.get(i);
             final PropertyModel model = item.model;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManagerUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManagerUnitTest.java
index 6b4a3fb..43cde40 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManagerUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManagerUnitTest.java
@@ -374,4 +374,56 @@
         verifyModelEquals(list);
         verifyPropertyValues(View.LAYOUT_DIRECTION_RTL, BrandedColorScheme.INCOGNITO);
     }
+
+    @Test
+    @SmallTest
+    public void suggestionsListRoundedCorners() {
+        final int groupId = 1;
+        when(mHeaderProcessor.allowBackgroundRounding()).thenReturn(false);
+        when(mBasicSuggestionProcessor.allowBackgroundRounding()).thenReturn(true);
+
+        List<DropdownItemViewInfo> list = Arrays.asList(
+                new DropdownItemViewInfo(mBasicSuggestionProcessor,
+                        new PropertyModel(SuggestionCommonProperties.ALL_KEYS), groupId),
+                new DropdownItemViewInfo(mHeaderProcessor,
+                        new PropertyModel(SuggestionCommonProperties.ALL_KEYS), groupId),
+                new DropdownItemViewInfo(mBasicSuggestionProcessor,
+                        new PropertyModel(SuggestionCommonProperties.ALL_KEYS), groupId),
+                new DropdownItemViewInfo(mBasicSuggestionProcessor,
+                        new PropertyModel(SuggestionCommonProperties.ALL_KEYS), groupId));
+
+        mManager.setSourceViewInfoList(list, new SparseArray<GroupDetails>());
+        verifyModelEquals(list);
+
+        //
+        // ******************** <--- rounded corner
+        // * basic suggestion *
+        // ******************** <--- rounded corner
+        //                      <--- no corner
+        //  header suggestion
+        //                      <--- no corner
+        // ******************** <--- rounded corner
+        // * basic suggestion *
+        // ******************** <--- sharped corner
+        // ******************** <--- sharped corner
+        // * basic suggestion *
+        // ******************** <--- rounded corner
+        //
+        Assert.assertTrue(
+                mSuggestionModels.get(0).model.get(DropdownCommonProperties.BG_TOP_CORNER_ROUNDED));
+        Assert.assertTrue(mSuggestionModels.get(0).model.get(
+                DropdownCommonProperties.BG_BOTTOM_CORNER_ROUNDED));
+        Assert.assertFalse(
+                mSuggestionModels.get(1).model.get(DropdownCommonProperties.BG_TOP_CORNER_ROUNDED));
+        Assert.assertFalse(mSuggestionModels.get(1).model.get(
+                DropdownCommonProperties.BG_BOTTOM_CORNER_ROUNDED));
+        Assert.assertTrue(
+                mSuggestionModels.get(2).model.get(DropdownCommonProperties.BG_TOP_CORNER_ROUNDED));
+        Assert.assertFalse(mSuggestionModels.get(2).model.get(
+                DropdownCommonProperties.BG_BOTTOM_CORNER_ROUNDED));
+        Assert.assertFalse(
+                mSuggestionModels.get(3).model.get(DropdownCommonProperties.BG_TOP_CORNER_ROUNDED));
+        Assert.assertTrue(mSuggestionModels.get(3).model.get(
+                DropdownCommonProperties.BG_BOTTOM_CORNER_ROUNDED));
+    }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
index 84c5f75..4a2cd84 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
@@ -23,6 +23,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Px;
+import androidx.annotation.VisibleForTesting;
 import androidx.core.view.ViewCompat;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
@@ -193,16 +194,23 @@
             }
         });
 
+        boolean shouldShowModernizeVisualUpdate =
+                OmniboxFeatures.shouldShowModernizeVisualUpdate(context);
         final Resources resources = context.getResources();
-        int paddingSide = OmniboxFeatures.shouldShowModernizeVisualUpdate(context)
+        int paddingSide = shouldShowModernizeVisualUpdate
                 ? resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_side)
                 : 0;
         int paddingBottom =
                 resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_bottom);
         ViewCompat.setPaddingRelative(this, paddingSide, 0, paddingSide, paddingBottom);
 
-        mStandardBgColor = ChromeColors.getDefaultThemeColor(context, false);
-        mIncognitoBgColor = ChromeColors.getDefaultThemeColor(context, true);
+        mStandardBgColor = shouldShowModernizeVisualUpdate
+                ? ChromeColors.getSurfaceColor(
+                        context, R.dimen.omnibox_suggestion_dropdown_bg_elevation)
+                : ChromeColors.getDefaultThemeColor(context, false);
+        mIncognitoBgColor = shouldShowModernizeVisualUpdate
+                ? context.getColor(R.color.omnibox_dropdown_bg_incognito)
+                : ChromeColors.getDefaultThemeColor(context, true);
     }
 
     /** Get the Android View implementing suggestion list. */
@@ -546,4 +554,14 @@
                 mAnchorView.getWidth() - mAlignmentView.getWidth() - mTempPosition[0],
                 getPaddingBottom());
     }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public int getStandardBgColor() {
+        return mStandardBgColor;
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public int getIncognitoBgColor() {
+        return mIncognitoBgColor;
+    }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownUnitTest.java
new file mode 100644
index 0000000..8fc8524
--- /dev/null
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownUnitTest.java
@@ -0,0 +1,79 @@
+// 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.omnibox.suggestions;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.content.Context;
+import android.view.ContextThemeWrapper;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.omnibox.test.R;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
+import org.chromium.components.browser_ui.styles.ChromeColors;
+
+/**
+ * Unit tests for {@link OmniboxSuggestionsDropdown}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+public class OmniboxSuggestionsDropdownUnitTest {
+    @Rule
+    public TestRule mProcessor = new Features.JUnitProcessor();
+
+    private Context mContext;
+
+    private OmniboxSuggestionsDropdown mDropdown;
+
+    @Before
+    public void setUp() {
+        mContext = new ContextThemeWrapper(
+                ApplicationProvider.getApplicationContext(), R.style.Theme_BrowserUI_DayNight);
+    }
+
+    @Test
+    @SmallTest
+    @Feature("Omnibox")
+    @EnableFeatures({ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE})
+    @CommandLineFlags.
+    Add({"enable-features=" + ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE + "<Study",
+            "force-fieldtrials=Study/Group",
+            "force-fieldtrial-params=Study.Group:enable_modernize_visual_update_on_tablet/true"})
+    public void
+    testBackgroundColor_withOmniboxModernizeVisualUpdateFlags() {
+        mDropdown = new OmniboxSuggestionsDropdown(mContext);
+
+        assertEquals(mDropdown.getStandardBgColor(),
+                ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_1));
+        assertEquals(mDropdown.getIncognitoBgColor(),
+                mContext.getColor(R.color.default_bg_color_dark_elev_1_baseline));
+    }
+
+    @Test
+    @SmallTest
+    @Feature("Omnibox")
+    @DisableFeatures({ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE})
+    public void testBackgroundColor_withoutOmniboxModernizeVisualUpdateFlags() {
+        mDropdown = new OmniboxSuggestionsDropdown(mContext);
+
+        assertEquals(
+                mDropdown.getStandardBgColor(), ChromeColors.getDefaultThemeColor(mContext, false));
+        assertEquals(
+                mDropdown.getIncognitoBgColor(), ChromeColors.getDefaultThemeColor(mContext, true));
+    }
+}
\ No newline at end of file
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java
index 8259d423..99397baf 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java
@@ -29,7 +29,7 @@
      * Callback for the switch in the dialog.
      */
     public interface Listener {
-        void onAllowCrashUploadChecked(boolean isChecked);
+        void onAllowMetricsAndCrashUploadingChecked(boolean allowMetricsAndCrashUploading);
     }
 
     private final ModalDialogManager mDialogManager;
@@ -41,7 +41,7 @@
      */
     @MainThread
     public FreUMADialogCoordinator(Context context, ModalDialogManager modalDialogManager,
-            Listener listener, boolean allowCrashUpload) {
+            Listener listener, boolean allowMetricsAndCrashUploading) {
         mView = LayoutInflater.from(context).inflate(R.layout.fre_uma_dialog, null);
         mDialogManager = modalDialogManager;
         mModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
@@ -54,9 +54,10 @@
             mDialogManager.dismissDialog(mModel, DialogDismissalCause.ACTION_ON_CONTENT);
         });
         final Switch umaSwitch = mView.findViewById(R.id.fre_uma_dialog_switch);
-        umaSwitch.setChecked(allowCrashUpload);
+        umaSwitch.setChecked(allowMetricsAndCrashUploading);
         umaSwitch.setOnCheckedChangeListener(
-                (compoundButton, isChecked) -> listener.onAllowCrashUploadChecked(isChecked));
+                (compoundButton,
+                        isChecked) -> listener.onAllowMetricsAndCrashUploadingChecked(isChecked));
 
         mDialogManager.showDialog(mModel, ModalDialogType.APP);
     }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogTest.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogTest.java
index e736d83..219772b 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogTest.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogTest.java
@@ -111,7 +111,7 @@
     @Test
     @MediumTest
     public void testTurningOnAllowCrashUploadWhenCrashUploadByNotAllowedDefault() {
-        showFreUMADialog(/*allowCrashUpload=*/false);
+        showFreUMADialog(/*allowMetricsAndCrashUploading=*/false);
 
         onView(withId(R.id.fre_uma_dialog_switch))
                 .inRoot(isDialog())
@@ -120,31 +120,31 @@
         onView(withText(org.chromium.chrome.R.string.done)).inRoot(isDialog()).perform(click());
 
         onView(withText(R.string.signin_fre_uma_dialog_title)).check(doesNotExist());
-        verify(mListenerMock).onAllowCrashUploadChecked(true);
+        verify(mListenerMock).onAllowMetricsAndCrashUploadingChecked(true);
     }
 
     @Test
     @MediumTest
     public void testTurningOffAllowCrashUploadWhenCrashUploadAllowedByDefault() {
-        showFreUMADialog(/*allowCrashUpload=*/true);
+        showFreUMADialog(/*allowMetricsAndCrashUploading=*/true);
 
         onView(withId(R.id.fre_uma_dialog_switch)).perform(click());
 
         onView(withText(org.chromium.chrome.R.string.done)).perform(click());
         onView(withText(R.string.signin_fre_uma_dialog_title)).check(doesNotExist());
-        verify(mListenerMock).onAllowCrashUploadChecked(false);
+        verify(mListenerMock).onAllowMetricsAndCrashUploadingChecked(false);
     }
 
     @Test
     @MediumTest
     public void testLeavingAllowCrashUploadOn() {
-        showFreUMADialog(/*allowCrashUpload=*/true);
+        showFreUMADialog(/*allowMetricsAndCrashUploading=*/true);
         onView(withId(R.id.fre_uma_dialog_switch)).check(matches(isChecked()));
 
         onView(withText(org.chromium.chrome.R.string.done)).perform(click());
 
         onView(withText(R.string.signin_fre_uma_dialog_title)).check(doesNotExist());
-        verify(mListenerMock, never()).onAllowCrashUploadChecked(anyBoolean());
+        verify(mListenerMock, never()).onAllowMetricsAndCrashUploadingChecked(anyBoolean());
     }
 
     @Test
@@ -152,7 +152,7 @@
     @Feature("RenderTest")
     @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class)
     public void testFreUMADialogView(boolean nightModeEnabled) throws IOException {
-        showFreUMADialog(/*allowCrashUpload=*/true);
+        showFreUMADialog(/*allowMetricsAndCrashUploading=*/true);
 
         CriteriaHelper.pollUiThread(() -> {
             return mCoordinator.getDialogViewForTesting()
@@ -162,12 +162,12 @@
         mRenderTestRule.render(mCoordinator.getDialogViewForTesting(), "fre_uma_dialog");
     }
 
-    private void showFreUMADialog(boolean allowCrashUpload) {
+    private void showFreUMADialog(boolean allowMetricsAndCrashUploading) {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             final Activity activity = activityTestRule.getActivity();
             mCoordinator = new FreUMADialogCoordinator(activity,
                     new ModalDialogManager(new AppModalPresenter(activity), ModalDialogType.APP),
-                    mListenerMock, allowCrashUpload);
+                    mListenerMock, allowMetricsAndCrashUploading);
         });
     }
 }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java
index a1e47062..f8c9f38 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java
@@ -31,9 +31,10 @@
 
         /**
          * Notifies when the user accepts the terms of service.
-         * @param allowCrashUpload Whether the user has opted into uploading crash reports and UMA.
+         * @param allowMetricsAndCrashUploading Whether the user has opted into uploading crash
+         *         reports and UMA.
          * */
-        void acceptTermsOfService(boolean allowCrashUpload);
+        void acceptTermsOfService(boolean allowMetricsAndCrashUploading);
 
         /** Called when the interaction with the page is over and the next page should be shown. */
         void advanceToNextPage();
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
index bbf54e40..8fb6694f 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
@@ -82,7 +82,7 @@
     private AccountPickerDialogCoordinator mDialogCoordinator;
     private @Nullable String mSelectedAccountName;
     private @Nullable String mDefaultAccountName;
-    private boolean mAllowCrashUpload;
+    private boolean mAllowMetricsAndCrashUploading;
 
     SigninFirstRunMediator(Context context, ModalDialogManager modalDialogManager,
             Delegate delegate, PrivacyPreferencesManager privacyPreferencesManager) {
@@ -202,7 +202,7 @@
         mModel.set(SigninFirstRunProperties.IS_SIGNIN_SUPPORTED,
                 ExternalAuthUtils.getInstance().canUseGooglePlayServices()
                         && !isSigninDisabledByPolicy);
-        mAllowCrashUpload = !isMetricsReportingDisabledByPolicy;
+        mAllowMetricsAndCrashUploading = !isMetricsReportingDisabledByPolicy;
 
         mModel.set(SigninFirstRunProperties.FOOTER_STRING,
                 getFooterString(isMetricsReportingDisabledByPolicy));
@@ -233,12 +233,13 @@
 
     /** Implements {@link FreUMADialogCoordinator.Listener} */
     @Override
-    public void onAllowCrashUploadChecked(boolean allowCrashUpload) {
-        mAllowCrashUpload = allowCrashUpload;
+    public void onAllowMetricsAndCrashUploadingChecked(boolean allowMetricsAndCrashUploading) {
+        mAllowMetricsAndCrashUploading = allowMetricsAndCrashUploading;
     }
 
     private void openUmaDialog() {
-        new FreUMADialogCoordinator(mContext, mModalDialogManager, this, mAllowCrashUpload);
+        new FreUMADialogCoordinator(
+                mContext, mModalDialogManager, this, mAllowMetricsAndCrashUploading);
     }
 
     /**
@@ -260,14 +261,14 @@
 
         if (!mModel.get(SigninFirstRunProperties.IS_SIGNIN_SUPPORTED)) {
             if (mDelegate.getNativeInitializationPromise().isFulfilled()) {
-                mDelegate.acceptTermsOfService(mAllowCrashUpload);
+                mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading);
                 mDelegate.advanceToNextPage();
             } else {
                 // Show the progress spinner while the native finishes loading.
                 mModel.set(SigninFirstRunProperties.SHOW_SIGNIN_PROGRESS_SPINNER, true);
                 mDelegate.getNativeInitializationPromise().then(ignored -> {
                     // When the native is loaded - mark ToS as accepted and move to the next page.
-                    mDelegate.acceptTermsOfService(mAllowCrashUpload);
+                    mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading);
                     mDelegate.advanceToNextPage();
                 });
             }
@@ -290,7 +291,7 @@
         assert mDelegate.getNativeInitializationPromise().isFulfilled();
 
         // This is needed to get metrics/crash reports from the sign-in flow itself.
-        mDelegate.acceptTermsOfService(mAllowCrashUpload);
+        mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading);
         if (mModel.get(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED)) {
             // Don't perform the sign-in here, as it will be handled by SigninChecker.
             mDelegate.advanceToNextPage();
@@ -354,7 +355,7 @@
         assert mDelegate.getNativeInitializationPromise().isFulfilled();
 
         mDelegate.recordFreProgressHistogram(MobileFreProgress.WELCOME_DISMISS);
-        mDelegate.acceptTermsOfService(mAllowCrashUpload);
+        mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading);
         SigninPreferencesManager.getInstance().temporarilySuppressNewTabPagePromos();
         if (IdentityServicesProvider.get()
                         .getIdentityManager(Profile.getLastUsedRegularProfile())
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
index b744931..4c7e416 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Jy sal binnekort stories van <ph name="SITE_NAME" /> af sien wanneer jy 'n nuwe oortjie oopmaak. Werwe wat jy volg, word in jou Google-rekening gestoor. Jy kan hulle bestuur in Ontdek-instellings.</translation>
 <translation id="5091249083535528968">Uitgebreide datagebruik</translation>
 <translation id="509429900233858213">'n Fout het voorgekom.</translation>
+<translation id="5099845111805573968">As jy een keer rekenaarwerf gekies het, sal die instelling elke keer wanneer jy besoek aflê op die werf toegepas word</translation>
 <translation id="5102401324271069229">As 'n werf probeer om jou wagwoord te steel, of wanneer jy 'n skadelike lêer aflaai, sal Chrome dalk URL'e, insluitend stukkies bladsyinhoud, na Veiligblaai toe stuur</translation>
 <translation id="510275257476243843">1 uur oor</translation>
 <translation id="5115811374190515607">na <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Kry jou lêers en bladsye in Aflaaie</translation>
 <translation id="5962718611393537961">Tik om in te vou</translation>
 <translation id="5964869237734432770">Stop prentbeskrywings</translation>
+<translation id="5966233851250124270">Chrome sal jou keuse onthou</translation>
 <translation id="5979084224081478209">Gaan wagwoorde na</translation>
 <translation id="5995726099713306770">Laai bladsy weer af?</translation>
 <translation id="6000066717592683814">Hou Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
index 536ea59..7f8881d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
@@ -749,6 +749,7 @@
 <translation id="5091199029769593641">‏قريبًا، ستظهر لك قصص من <ph name="SITE_NAME" /> عند فتح علامة تبويب جديدة. تم حفظ المواقع الإلكترونية التي تتابعها في حسابك على Google. ويمكنك إدارة هذه المواقع الإلكترونية من خلال إعدادات "اقتراحات".</translation>
 <translation id="5091249083535528968">بيانات الاستخدام الموسَّعة</translation>
 <translation id="509429900233858213">حدث خطأ.</translation>
+<translation id="5099845111805573968">عند اختيار موقع إلكتروني متوافق مع أجهزة الكمبيوتر المكتبي مرة واحدة، يتم تطبيق الإعداد على هذا الموقع الإلكتروني في كل مرة تنتقل فيها إليه.</translation>
 <translation id="5102401324271069229">‏وإذا حاول موقع إلكتروني سرقة كلمة المرور أو إذا نزّلت ملفًا ضارًا، قد يرسل متصفّح Chrome أيضًا عناوين URL تتضمّن أجزاء من محتوى الصفحة إلى "التصفّح الآمن".</translation>
 <translation id="510275257476243843">يتبقى ساعة واحدة</translation>
 <translation id="5115811374190515607">إلى "<ph name="PRODUCT_NAME" />"</translation>
@@ -908,6 +909,7 @@
 <translation id="5958275228015807058">العثور على الملفات والصفحات في مجلد "المحتوى الذي تم تنزيله"</translation>
 <translation id="5962718611393537961">النقر للتصغير</translation>
 <translation id="5964869237734432770">إيقاف عرض أوصاف الصور</translation>
+<translation id="5966233851250124270">‏سيتذكر متصفِّح Chrome خياراتك</translation>
 <translation id="5979084224081478209">التحقق من كلمات المرور</translation>
 <translation id="5995726099713306770">هل تريد تنزيل الصفحة مرة أخرى؟</translation>
 <translation id="6000066717592683814">‏الاستمرار في استخدام محرك Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
index 34ae195c..59ec2d1 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Tezliklə yeni tab açdığınız zaman <ph name="SITE_NAME" /> saytından hekayələri görəcəksiniz. İzlədiyiniz saytlar Google hesabınızda saxlanılır. Onları Təkliflər ayarlarında idarə edə bilərsiniz.</translation>
 <translation id="5091249083535528968">Artırılmış istifadə datası</translation>
 <translation id="509429900233858213">Xəta baş verdi.</translation>
+<translation id="5099845111805573968">Masaüstü saytını bir dəfə seçdiyiniz zaman ayar hər dəfə ziyarət etdiyinizdə sayta tətbiq edilir</translation>
 <translation id="5102401324271069229">Sayt parolunuzu oğurlamağa çalışdıqda və ya zərərli fayl endirdiyinizdə Chrome səhifə məzmunundan kiçik nümunələr də daxil olmaqla, URL'ləri Təhlükəsiz Baxışa göndərə bilər</translation>
 <translation id="510275257476243843">1 saat qaldı</translation>
 <translation id="5115811374190515607"><ph name="PRODUCT_NAME" /> məkanına</translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Fayl və səhifələri Endirilənlər bölməsində tapın</translation>
 <translation id="5962718611393537961">Yığcamlaşdırmaq üçün klikləyin</translation>
 <translation id="5964869237734432770">Şəkil təsvirini dayandırın</translation>
+<translation id="5966233851250124270">Chrome seçiminizi yadda saxlayacaq</translation>
 <translation id="5979084224081478209">Parolları yoxlayın</translation>
 <translation id="5995726099713306770">Səhifə yenidən endirilsin?</translation>
 <translation id="6000066717592683814">Google'u saxlayın</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cy.xtb
index 792e074..052acd9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cy.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cy.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Yn fuan, byddwch yn gweld straeon o <ph name="SITE_NAME" /> pan fyddwch yn agor tab newydd. Mae gwefannau rydych yn eu dilyn yn cael eu cadw yn eich cyfrif Google. Gallwch eu rheoli yn y gosodiadau Discover.</translation>
 <translation id="5091249083535528968">Data defnydd estynedig</translation>
 <translation id="509429900233858213">Bu gwall.</translation>
+<translation id="5099845111805573968">Pan fyddwch yn dewis gwefan bwrdd gwaith unwaith, mae'r gosodiad yn cael ei gymhwyso i'r wefan bob tro y byddwch yn ymweld</translation>
 <translation id="5102401324271069229">Os yw gwefan yn ceisio dwyn eich cyfrinair, neu pan fyddwch yn lawrlwytho ffeil niweidiol, gall Chrome anfon cyfeiriadau URL, gan gynnwys darnau o gynnwys tudalen, i Pori'n Ddiogel</translation>
 <translation id="510275257476243843">1 awr ar ôl</translation>
 <translation id="5115811374190515607">i <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Gallwch ddod o hyd i'ch ffeiliau a'ch tudalennau yn Lawrlwythiadau</translation>
 <translation id="5962718611393537961">Tapiwch i grebachu</translation>
 <translation id="5964869237734432770">Stopio disgrifio lluniau</translation>
+<translation id="5966233851250124270">Bydd Chrome yn cofio eich dewis</translation>
 <translation id="5979084224081478209">Gwirio cyfrineiriau</translation>
 <translation id="5995726099713306770">Lawrlwytho'r dudalen eto?</translation>
 <translation id="6000066717592683814">Cadw Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
index 34e9792..2e1642a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Pronto, cuando abras una nueva pestaña, verás historias de <ph name="SITE_NAME" />. Los sitios que sigues se guardan en tu Cuenta de Google. Puedes administrarlos en la configuración de Descubre.</translation>
 <translation id="5091249083535528968">Datos de uso extendidos</translation>
 <translation id="509429900233858213">Se ha producido un error.</translation>
+<translation id="5099845111805573968">Si seleccionas el sitio para computadoras una vez, la configuración se aplicará al sitio cada vez que lo visites.</translation>
 <translation id="5102401324271069229">Si un sitio intenta robar tu contraseña, o cuando descargas un archivo dañino, es posible que Chrome también envíe las URL con partes del contenido de la página a la Navegación segura.</translation>
 <translation id="510275257476243843">1 hora restante</translation>
 <translation id="5115811374190515607">a <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Encuentra tus archivos y páginas en Descargas</translation>
 <translation id="5962718611393537961">Presiona para contraer</translation>
 <translation id="5964869237734432770">Detener descripciones de imágenes</translation>
+<translation id="5966233851250124270">Chrome recordará tu elección</translation>
 <translation id="5979084224081478209">Revisar contraseñas</translation>
 <translation id="5995726099713306770">¿Quieres descargar la página de nuevo?</translation>
 <translation id="6000066717592683814">Seguir usando Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
index 2026422..83d1f55 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">‏به‌زودی وقتی برگه جدیدی باز می‌کنید، داستان‌هایی از <ph name="SITE_NAME" /> را خواهید دید. سایت‌هایی که دنبال می‌کنید در «حساب Google» شما ذخیره می‌شوند. می‌توانید در تنظیمات «یافته‌ها»، آن‌ها را مدیریت کنید.</translation>
 <translation id="5091249083535528968">داده‌های استفاده گسترده</translation>
 <translation id="509429900233858213">خطایی روی داد.</translation>
+<translation id="5099845111805573968">وقتی سایت ویژه رایانه را یک‌بار انتخاب کنید، هربار که از آن سایت بازدید کنید این تنظیم اعمال می‌شود</translation>
 <translation id="5102401324271069229">‏اگر سایتی تلاش کند گذرواژه شما را به‌سرقت ببرد، یا وقتی فایل مخربی بارگیری می‌کنید، Chrome ممکن است نشانی‌های وب را به‌همراه بخش‌های کوچکی از محتوای صفحه به «مرور ایمن» ارسال کند</translation>
 <translation id="510275257476243843">۱ ساعت باقی‌مانده است</translation>
 <translation id="5115811374190515607">به <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">فایل‌ها و صفحه‌هایتان را در «بارگیری‌ها» پیدا کنید</translation>
 <translation id="5962718611393537961">برای کوچک کردن ضربه بزنید</translation>
 <translation id="5964869237734432770">توقف توضیحات تصویر</translation>
+<translation id="5966233851250124270">‏Chrome انتخابتان را به‌خاطر می‌سپارد</translation>
 <translation id="5979084224081478209">بررسی گذرواژه‌ها</translation>
 <translation id="5995726099713306770">صفحه دوباره بارگیری شود؟</translation>
 <translation id="6000066717592683814">‏حفظ Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
index d055ca3..612408fa 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Sebentar lagi, Anda akan melihat cerita dari <ph name="SITE_NAME" /> saat membuka tab baru. Situs yang Anda ikuti akan disimpan di Akun Google Anda. Anda dapat mengelolanya di setelan Discover.</translation>
 <translation id="5091249083535528968">Data penggunaan yang diperluas</translation>
 <translation id="509429900233858213">Terjadi error.</translation>
+<translation id="5099845111805573968">Sekali Anda memilih situs desktop, setelan ini akan diterapkan setiap kali Anda membuka situs</translation>
 <translation id="5102401324271069229">Jika situs berusaha mencuri sandi Anda, atau jika Anda mendownload file berbahaya, Chrome dapat mengirimkan URL, termasuk bit konten halaman, ke Safe Browsing</translation>
 <translation id="510275257476243843">1 jam lagi</translation>
 <translation id="5115811374190515607">ke <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Temukan file dan halaman di Download</translation>
 <translation id="5962718611393537961">Ketuk untuk menciutkan</translation>
 <translation id="5964869237734432770">Hentikan deskripsi gambar</translation>
+<translation id="5966233851250124270">Chrome akan mengingat pilihan Anda</translation>
 <translation id="5979084224081478209">Periksa sandi</translation>
 <translation id="5995726099713306770">Download halaman lagi?</translation>
 <translation id="6000066717592683814">Tetap menggunakan Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
index 3a6fba7..7674df37 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">A breve vedrai storie di <ph name="SITE_NAME" /> quando aprirai una nuova scheda. I siti che segui vengono salvati nel tuo Account Google. Puoi gestirli nelle impostazioni di Discover.</translation>
 <translation id="5091249083535528968">Dati completi sull'utilizzo</translation>
 <translation id="509429900233858213">Si è verificato un errore.</translation>
+<translation id="5099845111805573968">Se selezioni il sito desktop una volta sola, l'impostazione viene applicata al sito ogni volta che lo visiti</translation>
 <translation id="5102401324271069229">Se un sito cerca di rubare la tua password o se scarichi un file dannoso, Chrome potrebbe inviare gli URL, inclusi frammenti dei contenuti delle pagine, a Navigazione sicura</translation>
 <translation id="510275257476243843">1 ora rimanente</translation>
 <translation id="5115811374190515607">in <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Puoi trovare i tuoi file e le tue pagine nella cartella Download</translation>
 <translation id="5962718611393537961">Tocca per comprimere</translation>
 <translation id="5964869237734432770">Interrompi descr. immagini</translation>
+<translation id="5966233851250124270">Chrome memorizzerà la tua scelta</translation>
 <translation id="5979084224081478209">Controlla password</translation>
 <translation id="5995726099713306770">Vuoi scaricare di nuovo la pagina?</translation>
 <translation id="6000066717592683814">Mantieni Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
index 38ec41f..97d080d7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">‏בקרוב יוצגו סטוריז מהאתר <ph name="SITE_NAME" /> בפתיחת כרטיסייה חדשה. אתרים שנמצאים במעקב נשמרים בחשבון Google שלך. יש לך אפשרות לנהל אותם בהגדרות של Discover.</translation>
 <translation id="5091249083535528968">נתונים נוספים על השימוש במכשיר</translation>
 <translation id="509429900233858213">אירעה שגיאה.</translation>
+<translation id="5099845111805573968">כשבוחרים אתר שמותאם למחשב בפעם הראשונה, ההגדרה חלה על האתר בכל פעם שמבקרים בו</translation>
 <translation id="5102401324271069229">‏אם באתר כלשהו מתבצע ניסיון לגנוב את הסיסמה שלך, או אם המערכת מזהה הורדה של קובץ מזיק, Chrome עשוי לשלוח כתובות URL לבדיקה באמצעות 'גלישה בטוחה'. הנתונים שנשלחים לבדיקה כוללים ביטים מתוכן של דפים</translation>
 <translation id="510275257476243843">נותרה שעה אחת</translation>
 <translation id="5115811374190515607">אל <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">הקבצים והדפים שלך נמצאים ב'הורדות'</translation>
 <translation id="5962718611393537961">יש להקיש כדי לכווץ</translation>
 <translation id="5964869237734432770">הפסקה של תיאורי התמונות</translation>
+<translation id="5966233851250124270">‏הבחירה שלך תישמר ב-Chrome</translation>
 <translation id="5979084224081478209">בדיקת הסיסמאות</translation>
 <translation id="5995726099713306770">להוריד שוב את הדף?</translation>
 <translation id="6000066717592683814">‏להמשיך להשתמש ב-Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
index 25666b26..40739f2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">곧 새 탭을 열 때 <ph name="SITE_NAME" /> 스토리가 표시됩니다. 내가 팔로우하는 사이트는 Google 계정에 저장되며 디스커버 설정에서 관리할 수 있습니다.</translation>
 <translation id="5091249083535528968">확장된 사용 데이터</translation>
 <translation id="509429900233858213">오류가 발생했습니다.</translation>
+<translation id="5099845111805573968">데스크톱 사이트를 선택하면 사이트에 방문할 때마다 이 설정이 적용됩니다.</translation>
 <translation id="5102401324271069229">사이트에서 사용자의 비밀번호를 도용하려고 하거나 사용자가 유해한 파일을 다운로드하는 경우, Chrome에서 페이지 콘텐츠 일부를 비롯한 URL을 세이프 브라우징 서비스에 보낼 수 있습니다.</translation>
 <translation id="510275257476243843">1시간 남음</translation>
 <translation id="5115811374190515607">이동 위치: <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">다운로드에서 파일 및 페이지를 찾아보세요.</translation>
 <translation id="5962718611393537961">탭하여 접기</translation>
 <translation id="5964869237734432770">이미지 설명 중지</translation>
+<translation id="5966233851250124270">선택사항이 Chrome에 저장됩니다</translation>
 <translation id="5979084224081478209">비밀번호 확인</translation>
 <translation id="5995726099713306770">페이지를 다시 다운로드하시겠습니까?</translation>
 <translation id="6000066717592683814">계속 Google 사용</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
index e187ab7..132642b 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">ໃນອີກບໍ່ດົນ, ທ່ານຈະເຫັນຂ່າວຈາກ <ph name="SITE_NAME" /> ເມື່ອທ່ານເປີດແຖບໃໝ່. ເວັບໄຊທີ່ທ່ານຕິດຕາມແມ່ນຖືກບັນທຶກໄວ້ໃນບັນຊີ Google ຂອງທ່ານ. ທ່ານສາມາດຈັດການພວກມັນໄດ້ໃນການຕັ້ງຄ່າ Discover.</translation>
 <translation id="5091249083535528968">ຂໍ້ມູນການນຳໃຊ້ເພີ່ມເຕີມ</translation>
 <translation id="509429900233858213">ເກີດຄວາມຜິດພາດຂຶ້ນ.</translation>
+<translation id="5099845111805573968">ເມື່ອທ່ານເລືອກເວັບໄຊເດັສທັອບເທື່ອໜຶ່ງ, ການຕັ້ງຄ່າຈະຖືກນຳໃຊ້ໄປໃສ່ເວັບໄຊໃນແຕ່ລະເທື່ອທີ່ທ່ານເຂົ້າ</translation>
 <translation id="5102401324271069229">ຖ້າເວັບໄຊພະຍາຍາມລັກເອົາລະຫັດຜ່ານຂອງທ່ານ ຫຼື ເມື່ອທ່ານດາວໂຫຼດໄຟລ໌ທີ່ເປັນອັນຕະລາຍ, Chrome ອາດສົ່ງ URL ຮວມທັງເນື້ອຫາບາງສ່ວນຂອງໜ້າໄປໃຫ້ Safe Browsing</translation>
 <translation id="510275257476243843">ຍັງເຫຼືອ 1 ຊົ່ວໂມງ</translation>
 <translation id="5115811374190515607">ຫາ <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">ຊອກຫາໄຟລ໌ ແລະ ໜ້າເວັບຂອງທ່ານໃນການດາວໂຫຼດ</translation>
 <translation id="5962718611393537961">ແຕະເພື່ອຫຍໍ້ລົງ</translation>
 <translation id="5964869237734432770">ຢຸດຄຳອະທິບາຍຮູບ</translation>
+<translation id="5966233851250124270">Chrome ຈະຈື່ຕົວເລືອກຂອງທ່ານ</translation>
 <translation id="5979084224081478209">ກວດເບິ່ງລະຫັດຜ່ານ</translation>
 <translation id="5995726099713306770">ດາວໂຫຼດໜ້າອີກເທື່ອໜຶ່ງບໍ່?</translation>
 <translation id="6000066717592683814">ດຳເນີນການໃຊ້ Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
index edc1fcfb..d38454ec 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Netrukus atidarę naują skirtuką matysite istorijas iš „<ph name="SITE_NAME" />“. Svetainės, kurias stebite, saugomos jūsų „Google“ paskyroje. Jas galite tvarkyti „Discover“ nustatymuose.</translation>
 <translation id="5091249083535528968">Išplėstiniai naudojimo duomenys</translation>
 <translation id="509429900233858213">Įvyko klaida.</translation>
+<translation id="5099845111805573968">Vienąkart pasirinkus svetainę kompiuteriams, nustatymas taikomas svetainei kaskart apsilankius</translation>
 <translation id="5102401324271069229">Jei svetainė bando pavogti slaptažodį ar atsisiuntėte žalingą failą, „Chrome“ gali siųsti URL, įskaitant puslapio turinio dalis, Saugaus naršymo funkcijai</translation>
 <translation id="510275257476243843">Liko 1 val.</translation>
 <translation id="5115811374190515607">į <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Suraskite failus ir puslapius „Atsisiuntimų“ skiltyje</translation>
 <translation id="5962718611393537961">Palieskite ir sutraukite</translation>
 <translation id="5964869237734432770">Stabdyti vaizdų aprašus</translation>
+<translation id="5966233851250124270">„Chrome“ prisimins jūsų pasirinkimą</translation>
 <translation id="5979084224081478209">Patikrinti slaptažodžius</translation>
 <translation id="5995726099713306770">Atsisiųsti puslapį dar kartą?</translation>
 <translation id="6000066717592683814">Palikti „Google“</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
index 4865a56..6fcf708 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Tidak lama lagi, anda akan melihat cerita daripada <ph name="SITE_NAME" /> apabila anda membuka tab baharu. Laman yang anda ikuti disimpan pada Google Account anda. Anda boleh mengurus laman tersebut dalam tetapan Discover.</translation>
 <translation id="5091249083535528968">Data penggunaan lanjutan</translation>
 <translation id="509429900233858213">Ralat telah berlaku.</translation>
+<translation id="5099845111805573968">Apabila anda memilih laman desktop sekali, tetapan itu akan digunakan pada laman setiap kali anda melawati laman itu</translation>
 <translation id="5102401324271069229">Jika laman cuba mencuri kata laluan anda atau apabila anda memuat turun fail yang berbahaya, Chrome mungkin menghantar URL termasuk sedikit kandungan halaman kepada Penyemakan Imbas Selamat</translation>
 <translation id="510275257476243843">1 jam lagi</translation>
 <translation id="5115811374190515607">ke <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Cari fail dan halaman anda dalam Muat Turun</translation>
 <translation id="5962718611393537961">Ketik untuk runtuhkan</translation>
 <translation id="5964869237734432770">Hentikan perihalan imej</translation>
+<translation id="5966233851250124270">Chrome akan mengingati pilihan anda</translation>
 <translation id="5979084224081478209">Semak kata laluan</translation>
 <translation id="5995726099713306770">Muat turun halaman sekali lagi?</translation>
 <translation id="6000066717592683814">Kekalkan Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
index e9ae493..43991d3 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">တဘ်အသစ်ဖွင့်သောအခါ <ph name="SITE_NAME" /> မှ သတင်းဆောင်းပါးများကို မကြာမီ ကြည့်နိုင်ပါမည်။ သင် လိုက်ကြည့်ထားသည့် ဝဘ်ဆိုက်များကို Google Account ထဲတွင် သိမ်းထားသည်။ ၎င်းတို့ကို ကြည့်ရှုစရာဆက်တင်များထဲတွင် စီမံနိုင်သည်။</translation>
 <translation id="5091249083535528968">နောက်ဆက်တွဲ သုံးစွဲမှုဒေတာ</translation>
 <translation id="509429900233858213">အမှား တစ်ခု ကြုံခဲ့ရသည်။</translation>
+<translation id="5099845111805573968">ဒက်စ်တော့ဝဘ်ဆိုက်ကို တစ်ကြိမ်ရွေးပြီးသည်နှင့် ဤဝဘ်ဆိုက်သို့ သင်ဝင်ကြည့်တိုင်း ၎င်းဆက်တင်ကို သတ်မှတ်သည်</translation>
 <translation id="5102401324271069229">ဝဘ်ဆိုက်တစ်ခုက သင့်စကားဝှက်ကို ခိုးယူရန်ကြိုးပမ်းပါက (သို့) အန္တရာယ်ဖိုင်ကို သင်ဒေါင်းလုဒ်မိလုပ်ပါက Chrome သည် ‘လုံခြုံစွာကြည့်ရှုခြင်း’ သို့ စာမျက်နှာပါ အကြောင်းအရာအချို့အပါအဝင် URL များကို ပေးပို့နိုင်သည်</translation>
 <translation id="510275257476243843">၁ နာရီ ကျန်သည်</translation>
 <translation id="5115811374190515607"><ph name="PRODUCT_NAME" /> သို့</translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">သင့်ဖိုင်များနှင့် စာမျက်နှာများကို ဒေါင်းလုဒ်များထဲတွင် ရှာဖွေပါ</translation>
 <translation id="5962718611393537961">လျှော့ပြရန် တို့ပါ</translation>
 <translation id="5964869237734432770">ပုံရှင်းလင်းချက်များ ရပ်ရန်</translation>
+<translation id="5966233851250124270">သင့်ရွေးချယ်မှုကို Chrome က မှတ်ထားပါမည်</translation>
 <translation id="5979084224081478209">စကားဝှက်များ စစ်ဆေးရန်</translation>
 <translation id="5995726099713306770">စာမျက်နှာကို ထပ်မံဒေါင်းလုဒ်လုပ်လိုပါသလား။</translation>
 <translation id="6000066717592683814">Google ကို ဆက်သုံးရန်</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
index f88d339..1767d3f4 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Binnenkort zie je artikelen van <ph name="SITE_NAME" /> als je een nieuw tabblad opent. Sites die je volgt, worden opgeslagen in je Google-account. Je kunt ze beheren in de instellingen van Discover.</translation>
 <translation id="5091249083535528968">Uitgebreide gebruiksgegevens</translation>
 <translation id="509429900233858213">Er is een fout opgetreden.</translation>
+<translation id="5099845111805573968">Als je één keer Desktopsite selecteert, wordt de instelling elke keer toegepast als je deze site bezoekt</translation>
 <translation id="5102401324271069229">Als een site je wachtwoord probeert te stelen of als je een schadelijk bestand downloadt, kan Chrome URL's, inclusief delen van de paginacontent, naar Safe Browsing sturen</translation>
 <translation id="510275257476243843">1 uur resterend</translation>
 <translation id="5115811374190515607">naar <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Vind je bestanden en pagina's in Downloads</translation>
 <translation id="5962718611393537961">Tik om samen te vouwen</translation>
 <translation id="5964869237734432770">Afbeeldingsbeschrijvingen stoppen</translation>
+<translation id="5966233851250124270">Chrome onthoudt je keuze</translation>
 <translation id="5979084224081478209">Wachtwoorden controleren</translation>
 <translation id="5995726099713306770">Pagina opnieuw downloaden?</translation>
 <translation id="6000066717592683814">Google blijven gebruiken</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
index 48291bf..a05ddf8 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">ଶୀଘ୍ର, ଆପଣ ଏକ ନୂଆ ଟାବ୍ ଖୋଲିଲେ <ph name="SITE_NAME" />ରୁ ଷ୍ଟୋରୀଗୁଡ଼ିକୁ ଦେଖିବେ। ଆପଣ ଅନୁସରଣ କରୁଥିବା ସାଇଟଗୁଡ଼ିକୁ ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟରେ ସେଭ୍ କରାଯାଏ। ଆପଣ ସେଗୁଡ଼ିକୁ ଡିସ୍କଭର ସେଟିଂସରେ ପରିଚାଳନା କରିପାରିବେ।</translation>
 <translation id="5091249083535528968">ବିସ୍ତାରିତ ବ୍ୟବହାର ଡାଟା</translation>
 <translation id="509429900233858213">ଏକ ତ୍ରୁଟି ଦେଖାଦେଲା।</translation>
+<translation id="5099845111805573968">ଆପଣ ଡେସ୍କଟପ ସାଇଟ ଚୟନ କରିବା ପରେ ପ୍ରତ୍ୟେକ ଥର ଆପଣ ସାଇଟ ଭିଜିଟ କରିବା ସମୟରେ ସେଟିଂ ଲାଗୁ ହୁଏ</translation>
 <translation id="5102401324271069229">ଯଦି କୌଣସି ସାଇଟ ଆପଣଙ୍କ ପାସୱାର୍ଡ ଚୋରି କରିବାକୁ ଚେଷ୍ଟା କରେ କିମ୍ବା ଆପଣ ଏକ କ୍ଷତିକାରକ ଫାଇଲ ଡାଉନଲୋଡ କଲେ, ପୃଷ୍ଠାର କିଛି ବିଷୟବସ୍ତୁ ସହିତ URLଗୁଡ଼ିକୁ Chrome ସେଫ ବ୍ରାଉଜିଂକୁ ପଠାଇପାରେ</translation>
 <translation id="510275257476243843">1 ଘଣ୍ଟା ବାକି ଅଛି</translation>
 <translation id="5115811374190515607"><ph name="PRODUCT_NAME" />କୁ</translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">ଡାଉନ୍‌ଲୋଡ୍‌ରେ ଆପଣଙ୍କର ଫାଇଲ୍‌ ଏବଂ ପୃଷ୍ଠାଗୁଡ଼ିକ ଖୋଜନ୍ତୁ</translation>
 <translation id="5962718611393537961">ସଙ୍କୁଚିତ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ</translation>
 <translation id="5964869237734432770">ଛବିର ବର୍ଣ୍ଣନା ବନ୍ଦ କରନ୍ତୁ</translation>
+<translation id="5966233851250124270">Chrome ଆପଣଙ୍କ ପସନ୍ଦକୁ ମନେ ରଖିବ</translation>
 <translation id="5979084224081478209">ପାସ୍‌ୱାର୍ଡଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ</translation>
 <translation id="5995726099713306770">ପୃଷ୍ଠାକୁ ପୁଣି ଡାଉନଲୋଡ୍ କରିବେ କି?</translation>
 <translation id="6000066717592683814">Googleକୁ ଡିଫଲ୍ଟ ଭାବେ ରଖନ୍ତୁ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
index 4b1bbca20..8272719 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Już niedługo po otwarciu nowej karty będziesz widzieć relacje ze strony <ph name="SITE_NAME" />. Strony, które obserwujesz, są zapisywane na Twoim koncie Google. Możesz nimi zarządzać w ustawieniach kart Discover.</translation>
 <translation id="5091249083535528968">Rozszerzone dane o korzystaniu</translation>
 <translation id="509429900233858213">Wystąpił błąd.</translation>
+<translation id="5099845111805573968">Jeśli raz wybierzesz stronę na komputery, to ustawienie będzie stosowane w jej przypadku przy każdej wizycie</translation>
 <translation id="5102401324271069229">Jeśli strona próbuje wykraść Twoje hasło lub pobierasz szkodliwy plik, Chrome może wysłać URL wraz z fragmentami zawartości strony do usługi Bezpieczne przeglądanie</translation>
 <translation id="510275257476243843">Pozostała godzina</translation>
 <translation id="5115811374190515607">do: <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Znajdź pliki i strony w Pobranych plikach</translation>
 <translation id="5962718611393537961">Kliknij, by zwinąć</translation>
 <translation id="5964869237734432770">Wstrzymaj opisy obrazów</translation>
+<translation id="5966233851250124270">Chrome zapamięta Twój wybór</translation>
 <translation id="5979084224081478209">Sprawdź hasła</translation>
 <translation id="5995726099713306770">Pobrać stronę ponownie?</translation>
 <translation id="6000066717592683814">Zachowaj Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
index f708e8a..42155e2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Скоро, открывая новую вкладку, вы будете видеть статьи с сайта "<ph name="SITE_NAME" />". Сайты, на которые вы подписаны, сохранены в вашем аккаунте Google. Управлять ими можно в настройках рекомендаций.</translation>
 <translation id="5091249083535528968">Расширенные данные</translation>
 <translation id="509429900233858213">Произошла ошибка.</translation>
+<translation id="5099845111805573968">Если выбрать полную версию сайта, она будет загружаться при каждом его посещении.</translation>
 <translation id="5102401324271069229">Если вы скачаете вредоносный файл или сайт попытается похитить ваш пароль, Chrome может отправить URL с образцами контента на проверку с помощью Безопасного просмотра.</translation>
 <translation id="510275257476243843">Остался 1 час</translation>
 <translation id="5115811374190515607">в <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Скачанные файлы и веб-страницы хранятся в одноименном разделе.</translation>
 <translation id="5962718611393537961">Нажмите, чтобы свернуть</translation>
 <translation id="5964869237734432770">Не генерировать описания</translation>
+<translation id="5966233851250124270">Chrome запомнит ваш выбор</translation>
 <translation id="5979084224081478209">Проверить пароли</translation>
 <translation id="5995726099713306770">Снова скачать страницу?</translation>
 <translation id="6000066717592683814">Использовать Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
index 14ff428..f9cd32d3 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">ළඟදීම, ඔබ නව ටැබයක් විවෘත කරන විට <ph name="SITE_NAME" /> වෙතින් නව කතන්දර දකිනු ඇත. ඔබ අනුගමනය කරන අඩවි ඔබගේ Google ගිණුමේ සුරැකේ. ඔබට ඒවා Discover සැකසීම් තුළ කළමනාකරණය කළ හැකිය.</translation>
 <translation id="5091249083535528968">දීර්ඝ කළ භාවිත දත්ත</translation>
 <translation id="509429900233858213">දෝශයක් ඇතිවිය.</translation>
+<translation id="5099845111805573968">ඔබ එක් වරක් ඩෙස්ක්ටොප් අඩවිය තේරූ විට, ඔබ පිවිසෙන සෑම අවස්ථාවකටම එම සැකසීම අදාළ වේ</translation>
 <translation id="5102401324271069229">අඩවියක් ඔබගේ මුරපදය සොරා ගැනීමට උත්සාහ කළහොත් හෝ ඔබ හානිකර ගොනුවක් බාගන්නා විට, Chrome පිටු අන්තර්ගතයේ කැබලි ඇතුළුව, URL සුරක්ෂිත බ්‍රවුස් කිරීම වෙත යැවීමට හැකිය</translation>
 <translation id="510275257476243843">පැය 1ක් ඉතිරියි</translation>
 <translation id="5115811374190515607"><ph name="PRODUCT_NAME" /> දක්වා</translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">බාගැනීම් තුළ ඔබේ ගොනු සහ පිටු සොයා ගන්න</translation>
 <translation id="5962718611393537961">හැකිළවීමට තට්ටු කරන්න</translation>
 <translation id="5964869237734432770">රූප විස්තර නවත්වන්න</translation>
+<translation id="5966233851250124270">Chrome ඔබේ තේරීම මතක තබා ගනී</translation>
 <translation id="5979084224081478209">මුරපද පරීක්‍ෂා කරන්න</translation>
 <translation id="5995726099713306770">නැවත පිටුව බාගන්නද?</translation>
 <translation id="6000066717592683814">Keep Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
index 0604574..cc1dbe0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">Keď otvoríte novú kartu, čoskoro sa vám budú zobrazovať príbehy z webu <ph name="SITE_NAME" />. Weby, ktoré sledujete, sa ukladajú do vášho účtu Google. Môžete ich spravovať v nastaveniach kanála Objaviť.</translation>
 <translation id="5091249083535528968">Rozšírené údaje o používaní</translation>
 <translation id="509429900233858213">Vyskytla sa chyba.</translation>
+<translation id="5099845111805573968">Keď raz vyberiete web pre počítače, toto nastavenie sa použije pri každej návšteve príslušného webu</translation>
 <translation id="5102401324271069229">Ak sa vám určitý web pokúsi ukradnúť heslo alebo stiahnete škodlivý súbor, Chrome môže odoslať Bezpečnému prehliadaniu webové adresy vrátane častí obsahu stránok</translation>
 <translation id="510275257476243843">Zostáva: 1 h</translation>
 <translation id="5115811374190515607">do služby <ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">Nájdite stiahnuté súbory a stránky</translation>
 <translation id="5962718611393537961">Klepnutím zbaliť</translation>
 <translation id="5964869237734432770">Zastaviť popisy obrázkov</translation>
+<translation id="5966233851250124270">Chrome si vašu voľbu zapamätá</translation>
 <translation id="5979084224081478209">Skontrolovať heslá</translation>
 <translation id="5995726099713306770">Chcete stránku znova stiahnuť?</translation>
 <translation id="6000066717592683814">Ponechať Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
index 12027b7..e3e76212c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">不久之后,当打开新标签页时,您将看到来自<ph name="SITE_NAME" />的故事。您关注的网站会保存在您的 Google 帐号中。您可在“探索”设置中管理它们。</translation>
 <translation id="5091249083535528968">扩展的使用情况数据</translation>
 <translation id="509429900233858213">出现错误。</translation>
+<translation id="5099845111805573968">只要选择了一次桌面版网站,每当您访问相应网站时,系统都会应用此设置</translation>
 <translation id="5102401324271069229">如果某个网站企图窃取您的密码,或者您下载了有害的文件,Chrome 可能会将相应网址连同少量网页内容发送给“安全浏览”功能</translation>
 <translation id="510275257476243843">还剩 1 小时</translation>
 <translation id="5115811374190515607">已移至<ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">在“下载内容”中查找您的文件和网页</translation>
 <translation id="5962718611393537961">点按即可收起</translation>
 <translation id="5964869237734432770">停止获取图片说明</translation>
+<translation id="5966233851250124270">Chrome 会记住您的选择</translation>
 <translation id="5979084224081478209">检查密码</translation>
 <translation id="5995726099713306770">再次下载此页面?</translation>
 <translation id="6000066717592683814">继续使用 Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
index c3eb6e8..f3db63df 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
@@ -748,6 +748,7 @@
 <translation id="5091199029769593641">不久後,您將會在開啟新分頁時看到 <ph name="SITE_NAME" /> 的內容。您追蹤的網站會儲存在 Google 帳戶中。您可在「探索」設定中管理已儲存的網站。</translation>
 <translation id="5091249083535528968">延伸使用情況資料</translation>
 <translation id="509429900233858213">發生錯誤。</translation>
+<translation id="5099845111805573968">只要選取一次電腦版網站,當你每次造訪時,網站都會套用這項設定</translation>
 <translation id="5102401324271069229">如果有網站試圖盜取您的密碼,或當您下載有害檔案時,Chrome 可能將網址 (包括部分網頁內容) 傳送至「安全瀏覽」功能</translation>
 <translation id="510275257476243843">尚餘 1 小時</translation>
 <translation id="5115811374190515607">移至<ph name="PRODUCT_NAME" /></translation>
@@ -907,6 +908,7 @@
 <translation id="5958275228015807058">在「下載」主畫面尋找您的檔案和網頁</translation>
 <translation id="5962718611393537961">輕按即可收合</translation>
 <translation id="5964869237734432770">停止取得圖片說明</translation>
+<translation id="5966233851250124270">Chrome 會記住你的選擇</translation>
 <translation id="5979084224081478209">檢查密碼</translation>
 <translation id="5995726099713306770">要再次下載頁面嗎?</translation>
 <translation id="6000066717592683814">繼續使用 Google</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
index 77f3d5f..17ea9074 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -747,6 +747,7 @@
 <translation id="5091199029769593641">不久後,你就會在開啟新分頁時看到「<ph name="SITE_NAME" />」的網路故事。你追蹤的網站會儲存在 Google 帳戶中,你可以在「探索」設定中管理這些網站。</translation>
 <translation id="5091249083535528968">延伸使用資料</translation>
 <translation id="509429900233858213">發生錯誤。</translation>
+<translation id="5099845111805573968">只要選取一次電腦版網站,當你每次造訪時,網站都會套用這項設定</translation>
 <translation id="5102401324271069229">如果有網站試圖竊取你的密碼,或當你下載有害檔案時,Chrome 可能會將網址 (包括部分網頁內容) 傳送至安全瀏覽功能</translation>
 <translation id="510275257476243843">還剩 1 小時</translation>
 <translation id="5115811374190515607">移至<ph name="PRODUCT_NAME" /></translation>
@@ -906,6 +907,7 @@
 <translation id="5958275228015807058">前往「下載」主畫面尋找你的檔案和網頁</translation>
 <translation id="5962718611393537961">輕觸即可收合</translation>
 <translation id="5964869237734432770">停止取得圖片說明</translation>
+<translation id="5966233851250124270">Chrome 會記住你的選擇</translation>
 <translation id="5979084224081478209">檢查密碼</translation>
 <translation id="5995726099713306770">要再次下載網頁嗎?</translation>
 <translation id="6000066717592683814">繼續使用 Google</translation>
diff --git a/chrome/browser/ui/android/webid/account_selection_view_android.cc b/chrome/browser/ui/android/webid/account_selection_view_android.cc
index 7614cf7..57928d5 100644
--- a/chrome/browser/ui/android/webid/account_selection_view_android.cc
+++ b/chrome/browser/ui/android/webid/account_selection_view_android.cc
@@ -66,7 +66,7 @@
 
 ScopedJavaLocalRef<jobjectArray> ConvertToJavaAccounts(
     JNIEnv* env,
-    base::span<const Account> accounts) {
+    const std::vector<Account>& accounts) {
   ScopedJavaLocalRef<jclass> account_clazz = base::android::GetClass(
       env, "org/chromium/chrome/browser/ui/android/webid/data/Account");
   ScopedJavaLocalRef<jobjectArray> array(
@@ -117,7 +117,7 @@
 void AccountSelectionViewAndroid::Show(
     const std::string& rp_for_display,
     const std::string& idp_for_display,
-    base::span<const Account> accounts,
+    const std::vector<Account>& accounts,
     const content::IdentityProviderMetadata& idp_metadata,
     const content::ClientIdData& client_data,
     Account::SignInMode sign_in_mode) {
diff --git a/chrome/browser/ui/android/webid/account_selection_view_android.h b/chrome/browser/ui/android/webid/account_selection_view_android.h
index f01b3c0..4f425ce2 100644
--- a/chrome/browser/ui/android/webid/account_selection_view_android.h
+++ b/chrome/browser/ui/android/webid/account_selection_view_android.h
@@ -22,7 +22,7 @@
   // AccountSelectionView:
   void Show(const std::string& rp_for_display,
             const std::string& idp_for_display,
-            base::span<const Account> accounts,
+            const std::vector<Account>& accounts,
             const content::IdentityProviderMetadata& idp_metadata,
             const content::ClientIdData& client_data,
             Account::SignInMode sign_in_mode) override;
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc
index b7edc27..1c4e7a7 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc
@@ -43,6 +43,7 @@
 #include "components/sync/model/string_ordinal.h"
 #include "components/sync/test/fake_sync_change_processor.h"
 #include "components/sync/test/sync_error_factory_mock.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/browser/extension_system.h"
 
@@ -77,10 +78,9 @@
     // from the test data directory to it.
     base::FilePath user_data_dir;
     base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
-    const std::string& email =
-        login_mixin_.users()[0].account_id.GetUserEmail();
     const std::string user_id_hash =
-        ash::ProfileHelper::GetUserIdHashByUserIdForTesting(email);
+        user_manager::FakeUserManager::GetFakeUsernameHash(
+            login_mixin_.users()[0].account_id);
     const base::FilePath user_profile_path = user_data_dir.Append(
         ash::ProfileHelper::GetUserProfileDir(user_id_hash));
     base::CreateDirectory(user_profile_path);
diff --git a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
index bf075e29..b0d1b0ce 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
@@ -20,6 +20,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/account_id/account_id.h"
 #include "components/session_manager/core/session_manager.h"
+#include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/known_user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
@@ -41,7 +42,7 @@
   known_user.SetProfileRequiresPolicy(
       account_id, user_manager::ProfileRequiresPolicy::kNoPolicyRequired);
   const std::string user_id_hash =
-      ProfileHelper::GetUserIdHashByUserIdForTesting(account_id.GetUserEmail());
+      user_manager::FakeUserManager::GetFakeUsernameHash(account_id);
   SessionManager::Get()->CreateSession(account_id, user_id_hash, false);
   profiles::testing::CreateProfileSync(
       g_browser_process->profile_manager(),
diff --git a/chrome/browser/ui/ash/desks/desks_client.cc b/chrome/browser/ui/ash/desks/desks_client.cc
index ea97c96..9b57a248 100644
--- a/chrome/browser/ui/ash/desks/desks_client.cc
+++ b/chrome/browser/ui/ash/desks/desks_client.cc
@@ -244,7 +244,7 @@
       /*root_window_to_show=*/nullptr);
 }
 
-void DesksClient::UpdateDeskTemplate(const std::string& template_uuid,
+void DesksClient::UpdateDeskTemplate(const base::GUID& template_uuid,
                                      const std::u16string& template_name,
                                      UpdateDeskTemplateCallback callback) {
   if (!active_profile_) {
@@ -298,7 +298,7 @@
                       : ""));
 }
 
-void DesksClient::GetTemplateJson(const std::string uuid,
+void DesksClient::GetTemplateJson(const base::GUID& uuid,
                                   Profile* profile,
                                   GetTemplateJsonCallback callback) {
   if (!active_profile_ || active_profile_ != profile) {
@@ -317,7 +317,7 @@
 }
 
 void DesksClient::LaunchDeskTemplate(
-    const std::string& template_uuid,
+    const base::GUID& template_uuid,
     LaunchDeskCallback callback,
     const std::u16string& customized_desk_name) {
   base::Time launch_started = base::Time::Now();
diff --git a/chrome/browser/ui/ash/desks/desks_client.h b/chrome/browser/ui/ash/desks/desks_client.h
index 6c96662a..acba9bb3 100644
--- a/chrome/browser/ui/ash/desks/desks_client.h
+++ b/chrome/browser/ui/ash/desks/desks_client.h
@@ -76,7 +76,7 @@
   // error as the |error|.
   // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
   // further uses of this method.
-  void UpdateDeskTemplate(const std::string& template_uuid,
+  void UpdateDeskTemplate(const base::GUID& template_uuid,
                           const std::u16string& template_name,
                           UpdateDeskTemplateCallback callback);
 
@@ -110,7 +110,7 @@
                               std::string error)>;
   // Takes in |uuid| and fetches the stringified json representation of a
   // desk template.
-  void GetTemplateJson(const std::string uuid,
+  void GetTemplateJson(const base::GUID& uuid,
                        Profile* profile,
                        GetTemplateJsonCallback callback);
 
@@ -127,7 +127,7 @@
   // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
   // further uses of this method.
   void LaunchDeskTemplate(
-      const std::string& template_uuid,
+      const base::GUID& template_uuid,
       LaunchDeskCallback callback,
       const std::u16string& customized_desk_name = std::u16string());
 
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
index b8eae77b..7b879f5 100644
--- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -211,7 +211,7 @@
   return false;
 }
 
-std::string GetTemplateJson(const std::string& uuid, Profile* profile) {
+std::string GetTemplateJson(const base::GUID& uuid, Profile* profile) {
   base::RunLoop run_loop;
   std::string template_json_result;
   DesksClient::Get()->GetTemplateJson(
@@ -226,7 +226,7 @@
   return template_json_result;
 }
 
-void DeleteDeskTemplate(const base::GUID uuid) {
+void DeleteDeskTemplate(const base::GUID& uuid) {
   base::RunLoop run_loop;
   DesksClient::Get()->DeleteDeskTemplate(
       uuid, base::BindLambdaForTesting(
@@ -416,8 +416,7 @@
   }
 
   void LaunchTemplate(const base::GUID& uuid) {
-    DesksClient::Get()->LaunchDeskTemplate(uuid.AsLowercaseString(),
-                                           base::DoNothing());
+    DesksClient::Get()->LaunchDeskTemplate(uuid, base::DoNothing());
   }
 
   void SetAndLaunchTemplate(std::unique_ptr<ash::DeskTemplate> desk_template) {
@@ -1287,8 +1286,8 @@
   std::unique_ptr<ash::DeskTemplate> desk_template =
       CaptureActiveDeskAndSaveTemplate();
 
-  std::string template_json = GetTemplateJson(
-      desk_template->uuid().AsLowercaseString(), browser()->profile());
+  std::string template_json =
+      GetTemplateJson(desk_template->uuid(), browser()->profile());
 
   // content of the conversion is tested in:
   // components/desks_storage/core/desk_template_conversion_unittests.cc in this
@@ -2303,13 +2302,13 @@
   base::GUID desk_id;
   // Launch one template, desk size should increase by 1.
   DesksClient::Get()->LaunchDeskTemplate(
-      "", base::BindLambdaForTesting(
-              [&](std::string error, const base::GUID& desk_uuid) {
-                EXPECT_TRUE(error.empty());
-                EXPECT_EQ(2, desks_controller->desks().size());
-                desk_id = desk_uuid;
-                loop.Quit();
-              }));
+      base::GUID(), base::BindLambdaForTesting(
+                        [&](std::string error, const base::GUID& desk_uuid) {
+                          EXPECT_TRUE(error.empty());
+                          EXPECT_EQ(2, desks_controller->desks().size());
+                          desk_id = desk_uuid;
+                          loop.Quit();
+                        }));
   loop.Run();
 
   DesksClient::Get()->RemoveDesk(
diff --git a/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.cc b/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.cc
index 9ce8098e..b559182 100644
--- a/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.cc
+++ b/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.cc
@@ -8,8 +8,10 @@
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/notreached.h"
+#include "chrome/browser/ash/app_restore/full_restore_service.h"
+#include "chrome/browser/ash/app_restore/full_restore_service_factory.h"
 #include "chrome/common/chrome_switches.h"
+#include "components/app_restore/full_restore_save_handler.h"
 
 namespace {
 ChromeGlanceablesDelegate* g_instance = nullptr;
@@ -34,15 +36,29 @@
   return g_instance;
 }
 
-void ChromeGlanceablesDelegate::OnPrimaryUserSessionStarted() {
+void ChromeGlanceablesDelegate::OnPrimaryUserSessionStarted(Profile* profile) {
+  primary_profile_ = profile;
   if (ShouldShowOnLogin())
     controller_->ShowOnLogin();
 }
 
 void ChromeGlanceablesDelegate::RestoreSession() {
-  // TODO(crbug.com/1353119): Use the FullRestoreService to trigger session
-  // restore.
-  NOTIMPLEMENTED();
+  if (!primary_profile_ || did_restore_)
+    return;
+  auto* full_restore_service =
+      ash::full_restore::FullRestoreService::GetForProfile(primary_profile_);
+  if (!full_restore_service)
+    return;
+  full_restore_service->Restore();
+  did_restore_ = true;
+}
+
+void ChromeGlanceablesDelegate::OnGlanceablesClosed() {
+  if (!did_restore_) {
+    // The user closed glanceables without triggering a session restore, so
+    // start the full restore state save timer.
+    ::full_restore::FullRestoreSaveHandler::GetInstance()->AllowSave();
+  }
 }
 
 bool ChromeGlanceablesDelegate::ShouldShowOnLogin() const {
@@ -52,7 +68,13 @@
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoFirstRun))
     return false;
 
-  // TODO(crbug.com/1353119): Use logic from FullRestoreService to decide
-  // whether or not to show.
+  // Don't show glanceables for session types that don't support full restore
+  // (e.g. demo mode, forced app mode).
+  // TODO(crbug.com/1353119): Refine triggering logic based on PM/UX feedback.
+  if (!ash::full_restore::FullRestoreServiceFactory::
+          IsFullRestoreAvailableForProfile(primary_profile_)) {
+    return false;
+  }
+
   return true;
 }
diff --git a/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.h b/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.h
index aa6e454..9a2d682 100644
--- a/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.h
+++ b/chrome/browser/ui/ash/glanceables/chrome_glanceables_delegate.h
@@ -7,6 +7,8 @@
 
 #include "ash/glanceables/glanceables_delegate.h"
 
+class Profile;
+
 namespace ash {
 class GlanceablesController;
 }  // namespace ash
@@ -25,16 +27,23 @@
 
   // Called when the primary user logs in, after various KeyedServices are
   // created.
-  void OnPrimaryUserSessionStarted();
+  void OnPrimaryUserSessionStarted(Profile* profile);
 
   // ash::GlanceablesDelegate:
   void RestoreSession() override;
+  void OnGlanceablesClosed() override;
 
  private:
   // Returns true if glanceables should be show for the current login.
   bool ShouldShowOnLogin() const;
 
   ash::GlanceablesController* const controller_;
+
+  // The profile for the primary user in the session.
+  Profile* primary_profile_ = nullptr;
+
+  // Whether the user triggered session restore on login.
+  bool did_restore_ = false;
 };
 
 #endif  // CHROME_BROWSER_UI_ASH_GLANCEABLES_CHROME_GLANCEABLES_DELEGATE_H_
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
index 1bef9ca..9475682a 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_util_chromeos_unittest.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
@@ -62,11 +61,10 @@
   CoreAccountId AddUserAndSignIn(const std::string& email) {
     AccountInfo account_info = identity_test_env()->MakePrimaryAccountAvailable(
         email, signin::ConsentLevel::kSync);
-    fake_user_manager_->AddUser(
+    auto* user = fake_user_manager_->AddUser(
         multi_user_util::GetAccountIdFromEmail(account_info.email));
     fake_user_manager_->UserLoggedIn(
-        multi_user_util::GetAccountIdFromEmail(account_info.email),
-        ProfileHelper::GetUserIdHashByUserIdForTesting(account_info.email),
+        user->GetAccountId(), user->username_hash(),
         false /* browser_restart */, false /* is_child */);
 
     return account_info.account_id;
diff --git a/chrome/browser/ui/ash/session_controller_client_impl_unittest.cc b/chrome/browser/ui/ash/session_controller_client_impl_unittest.cc
index d9e82a4..42bf5afa 100644
--- a/chrome/browser/ui/ash/session_controller_client_impl_unittest.cc
+++ b/chrome/browser/ui/ash/session_controller_client_impl_unittest.cc
@@ -150,11 +150,7 @@
     const user_manager::User* user =
         is_child ? user_manager()->AddChildUser(account_id)
                  : user_manager()->AddUser(account_id);
-    session_manager_.CreateSession(
-        account_id,
-        ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-            account_id.GetUserEmail()),
-        is_child);
+    session_manager_.CreateSession(account_id, user->username_hash(), is_child);
 
     // Simulate that user profile is loaded.
     CreateTestingProfile(user);
@@ -457,11 +453,7 @@
       AccountId::FromUserEmailGaiaId("user@test.com", "5555555555"));
   const user_manager::User* user = user_manager()->AddUser(account_id);
   CreateTestingProfile(user);
-  session_manager_.CreateSession(
-      account_id,
-      ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-          account_id.GetUserEmail()),
-      false);
+  session_manager_.CreateSession(account_id, user->username_hash(), false);
   session_manager_.SetSessionState(SessionState::ACTIVE);
 
   // User session was sent.
@@ -512,11 +504,7 @@
   const AccountId account_id(
       AccountId::FromUserEmailGaiaId("user@test.com", "5555555555"));
   const user_manager::User* user = user_manager()->AddUser(account_id);
-  session_manager_.CreateSession(
-      account_id,
-      ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-          account_id.GetUserEmail()),
-      false);
+  session_manager_.CreateSession(account_id, user->username_hash(), false);
 
   // Simulate the notification that the profile is ready.
   TestingProfile* const user_profile = CreateTestingProfile(user);
diff --git a/chrome/browser/ui/breadcrumb_manager_browser_agent_unittest.cc b/chrome/browser/ui/breadcrumb_manager_browser_agent_unittest.cc
index 1189ea70..d16ce82 100644
--- a/chrome/browser/ui/breadcrumb_manager_browser_agent_unittest.cc
+++ b/chrome/browser/ui/breadcrumb_manager_browser_agent_unittest.cc
@@ -39,7 +39,7 @@
   }
 
   std::list<std::string> GetEvents() const {
-    return breadcrumb_service_->GetEvents(/*event_count_limit=*/0);
+    return breadcrumb_service_->GetEvents();
   }
 
  private:
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 8932e8a8..59bc000 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -70,6 +70,8 @@
 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
@@ -1187,45 +1189,42 @@
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 }
 
-// Open with --app-id=<id>, and see that an application tab opens by default.
+// Open with --app-id=<id>, and see that an application window opens by default.
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(BrowserTest, AppIdSwitch) {
   base::HistogramTester tester;
   ASSERT_TRUE(embedded_test_server()->Start());
 
-  // There should be one tab to start with.
+  // There should be one browser and one tab to start with.
+  EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
-  ui_test_utils::TabAddedWaiter tab_waiter(browser());
-
   // Load an app.
-  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/")));
-  const Extension* extension_app = GetExtension();
-
+  web_app::AppId app_id = web_app::test::InstallDummyWebApp(
+      browser()->profile(), "testapp", GURL("https://testapp.com"));
   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
-  command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
+  command_line.AppendSwitchASCII(switches::kAppId, app_id);
 
   EXPECT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl(
       command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo,
       {browser()->profile(), StartupProfileMode::kBrowserWindow}, {}));
 
-  tab_waiter.Wait();
-
+  Browser* app_browser = ui_test_utils::WaitForBrowserToOpen();
+  EXPECT_TRUE(app_browser->is_type_app());
   {
     // From launch_mode_recorder.cc:
     constexpr char kLaunchModesHistogram[] = "Launch.Modes";
-    const base::HistogramBase::Sample LM_AS_WEBAPP_IN_TAB = 21;
+    const base::HistogramBase::Sample LM_AS_WEBAPP_IN_WINDOW_BY_APP_ID = 24;
 
-    tester.ExpectUniqueSample(kLaunchModesHistogram, LM_AS_WEBAPP_IN_TAB, 1);
+    tester.ExpectUniqueSample(kLaunchModesHistogram,
+                              LM_AS_WEBAPP_IN_WINDOW_BY_APP_ID, 1);
   }
 
   // Check that the number of browsers and tabs is correct.
-  const unsigned int expected_browsers = 1;
-  int expected_tabs = 1;
-  expected_tabs++;
-
-  EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile()));
-  EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count());
+  EXPECT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
+  EXPECT_EQ(1, browser()->tab_strip_model()->count());
 }
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Overscroll is only enabled on Aura platforms currently, and even then only
 // when a specific feature (OverscrollHistoryNavigation) is enabled.
diff --git a/chrome/browser/ui/extensions/extension_image_util_browsertest.cc b/chrome/browser/ui/extensions/extension_image_util_browsertest.cc
index af626e8..24259f9 100644
--- a/chrome/browser/ui/extensions/extension_image_util_browsertest.cc
+++ b/chrome/browser/ui/extensions/extension_image_util_browsertest.cc
@@ -12,7 +12,7 @@
 #include "ui/color/color_provider.h"
 #include "ui/native_theme/native_theme.h"
 
-#if BUILDFLAG(USE_GTK)
+#if BUILDFLAG(IS_LINUX)
 #include "ui/linux/linux_ui.h"
 #endif
 
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc
index 4595cc9..6de9c701 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -618,9 +618,6 @@
 // static
 bool StartupBrowserCreator::in_synchronous_profile_launch_ = false;
 
-// static
-bool StartupBrowserCreator::is_launching_browser_for_last_profiles_ = false;
-
 void StartupBrowserCreator::AddFirstRunTabs(const std::vector<GURL>& urls) {
   for (const auto& url : urls) {
     if (url.is_valid())
@@ -698,9 +695,6 @@
     StartupProfileInfo profile_info,
     const Profiles& last_opened_profiles) {
   DCHECK_NE(profile_info.mode, StartupProfileMode::kError);
-  DCHECK(!is_launching_browser_for_last_profiles_);
-  base::AutoReset<bool> resetter(&is_launching_browser_for_last_profiles_,
-                                 true);
 
   Profile* profile = profile_info.profile;
   // On Windows, when chrome is launched by notification activation where the
@@ -759,11 +753,6 @@
 }
 
 // static
-bool StartupBrowserCreator::IsLaunchingBrowserForLastProfiles() {
-  return is_launching_browser_for_last_profiles_;
-}
-
-// static
 bool StartupBrowserCreator::WasRestarted() {
   // Stores the value of the preference kWasRestarted had when it was read.
   static bool was_restarted = false;
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h
index 482ca95..3f0c1d4d 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.h
+++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -149,10 +149,6 @@
       StartupProfileInfo profile_info,
       const Profiles& last_opened_profiles);
 
-  // Returns true if we're in the process of restoring the session for the
-  // last opened profiles in `LaunchBrowserForLastProfiles()`.
-  static bool IsLaunchingBrowserForLastProfiles();
-
   // Returns true during browser process startup if the previous browser was
   // restarted. This only returns true before the first StartupBrowserCreator
   // destructs. WasRestarted() will update prefs::kWasRestarted to false, but
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index 80787330..08add98b 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -784,6 +784,7 @@
       case ChromeAppDeprecationFeatureValue::kEnabled:
         return false;
       case ChromeAppDeprecationFeatureValue::kDefault:
+        return !base::FeatureList::IsEnabled(features::kChromeAppsDeprecation);
       case ChromeAppDeprecationFeatureValue::kDisabled:
         return true;
     }
@@ -3186,9 +3187,14 @@
 #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \
     BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Set a policy that prevents the first-run dialog from being shown.
-  policy_map_.Set(policy::key::kMetricsReportingEnabled,
-                  policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-                  policy::POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
+  policy_map_.Set(
+#if BUILDFLAG(IS_CHROMEOS)
+      policy::key::kDeviceMetricsReportingEnabled,
+#else
+      policy::key::kMetricsReportingEnabled,
+#endif
+      policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+      policy::POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
   provider_.UpdateChromePolicy(policy_map_);
 #endif  // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) &&
         // BUILDFLAG(GOOGLE_CHROME_BRANDING)
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index ad6f8d11..eb8c0655 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -92,6 +92,8 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "chrome/browser/chromeos/arc/arc_web_contents_data.h"
+#include "chrome/browser/lacros/browser_launcher.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"
 #include "chromeos/startup/browser_params_proxy.h"
 #endif
@@ -100,9 +102,11 @@
 
 // Utility functions ----------------------------------------------------------
 
-// In ChromeOS, if the full restore feature is disabled, always restores apps
-// unconditionally. If the full restore feature is enabled, check the previous
-// apps launching history info to decide whether restore apps.
+// On ChromeOS Ash check the previous apps launching history info to decide
+// whether restore apps.
+//
+// On ChromeOS Lacros restore if the browser has automatically restarted or if
+// performing a full restore.
 //
 // In other platforms, restore apps only when the browser is automatically
 // restarted.
@@ -110,6 +114,15 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // In ChromeOS, restore apps only when there are apps launched before reboot.
   return full_restore::HasAppTypeBrowser(profile->GetPath());
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+  auto* primary_user_profile =
+      g_browser_process->profile_manager()->GetProfileByPath(
+          ProfileManager::GetPrimaryUserProfilePath());
+
+  return is_post_restart ||
+         (primary_user_profile &&
+          BrowserLauncher::GetForProfile(primary_user_profile)
+              ->is_launching_for_full_restore());
 #else
   return is_post_restart;
 #endif
diff --git a/chrome/browser/ui/views/extensions/extensions_dialogs_utils.cc b/chrome/browser/ui/views/extensions/extensions_dialogs_utils.cc
index 2cdef35ae..8fe2166 100644
--- a/chrome/browser/ui/views/extensions/extensions_dialogs_utils.cc
+++ b/chrome/browser/ui/views/extensions/extensions_dialogs_utils.cc
@@ -65,12 +65,9 @@
 // "action" action based on the web contents.
 ui::ImageModel GetIcon(ToolbarActionViewController* action,
                        content::WebContents* web_contents) {
-  return ui::ImageModel::FromImageSkia(
-      action
-          ->GetIcon(web_contents,
-                    gfx::Size(extension_misc::EXTENSION_ICON_SMALLISH,
-                              extension_misc::EXTENSION_ICON_SMALLISH))
-          .AsImageSkia());
+  return ui::ImageModel::FromImage(action->GetIcon(
+      web_contents, gfx::Size(extension_misc::EXTENSION_ICON_SMALLISH,
+                              extension_misc::EXTENSION_ICON_SMALLISH)));
 }
 
 std::u16string GetCurrentHost(content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/views/external_protocol_dialog.cc b/chrome/browser/ui/views/external_protocol_dialog.cc
index 30da67c..4a842425 100644
--- a/chrome/browser/ui/views/external_protocol_dialog.cc
+++ b/chrome/browser/ui/views/external_protocol_dialog.cc
@@ -8,6 +8,7 @@
 
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
@@ -122,7 +123,7 @@
       profile->GetPrefs()->GetBoolean(
           prefs::kExternalProtocolDialogShowAlwaysOpenCheckbox) &&
       ExternalProtocolHandler::MayRememberAllowDecisionsForThisOrigin(
-          base::OptionalOrNullptr(initiating_origin_));
+          base::OptionalToPtr(initiating_origin_));
 
   if (show_remember_selection_checkbox) {
     message_box_view_->SetCheckBoxLabel(l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc
index f3cc4af3..723d477 100644
--- a/chrome/browser/ui/views/frame/browser_frame.cc
+++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -47,22 +47,15 @@
 #include "components/user_manager/user_manager.h"
 #endif
 
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "ui/display/screen.h"
-#endif
-
 #if BUILDFLAG(IS_LINUX)
+#include "ui/display/screen.h"
 #include "ui/linux/linux_ui.h"
 #endif
 
 namespace {
 
-bool IsUsingGtkTheme(Profile* profile) {
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+bool IsUsingLinuxSystemTheme(Profile* profile) {
+#if BUILDFLAG(IS_LINUX)
   return ThemeServiceFactory::GetForProfile(profile)->UsingSystemTheme();
 #else
   return false;
@@ -244,11 +237,11 @@
 const ui::ThemeProvider* BrowserFrame::GetThemeProvider() const {
   Browser* browser = browser_view_->browser();
   auto* app_controller = browser->app_controller();
-  // Ignore GTK+ for web apps with window-controls-overlay as the
+  // Ignore the system theme for web apps with window-controls-overlay as the
   // display_override so the web contents can blend with the overlay by using
   // the developer-provided theme color for a better experience. Context:
   // https://crbug.com/1219073.
-  if (app_controller && (!IsUsingGtkTheme(browser->profile()) ||
+  if (app_controller && (!IsUsingLinuxSystemTheme(browser->profile()) ||
                          app_controller->AppUsesWindowControlsOverlay())) {
     return app_controller->GetThemeProvider();
   }
@@ -262,11 +255,11 @@
   if (browser->profile()->IsIncognitoProfile())
     return nullptr;
   auto* app_controller = browser->app_controller();
-  // Ignore GTK+ for web apps with window-controls-overlay as the
+  // Ignore the system theme for web apps with window-controls-overlay as the
   // display_override so the web contents can blend with the overlay by using
   // the developer-provided theme color for a better experience. Context:
   // https://crbug.com/1219073.
-  if (app_controller && (!IsUsingGtkTheme(browser->profile()) ||
+  if (app_controller && (!IsUsingLinuxSystemTheme(browser->profile()) ||
                          app_controller->AppUsesWindowControlsOverlay())) {
     return app_controller->GetThemeSupplier();
   }
@@ -277,9 +270,7 @@
   chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace());
   chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(),
                                            IsVisibleOnAllWorkspaces());
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX)
   // If the window was sent to a different workspace, prioritize it if
   // it was sent to the current workspace and deprioritize it
   // otherwise.  This is done by MoveBrowsersInWorkspaceToFront()
@@ -392,7 +383,7 @@
 }
 
 void BrowserFrame::SelectNativeTheme() {
-  // Select between regular, dark and GTK theme.
+  // Select between regular, dark and system theme.
   ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
 
   if (browser_view_->browser()->profile()->IsIncognitoProfile()) {
@@ -404,7 +395,7 @@
 
 #if BUILDFLAG(IS_LINUX)
   const ui::LinuxUi* linux_ui = ui::LinuxUi::instance();
-  // Ignore GTK+ for web apps with window-controls-overlay as the
+  // Ignore the system theme for web apps with window-controls-overlay as the
   // display_override so the web contents can blend with the overlay by using
   // the developer-provided theme color for a better experience. Context:
   // https://crbug.com/1219073.
@@ -419,10 +410,8 @@
 bool BrowserFrame::RegenerateFrameOnThemeChange(
     BrowserThemeChangeType theme_change_type) {
   bool need_regenerate = false;
-  // TODO(crbug.com/1052397): Revisit the macro expression once build flag
-  // switch of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  // GTK and user theme changes can both change frame buttons, so the frame
+#if BUILDFLAG(IS_LINUX)
+  // System and user theme changes can both change frame buttons, so the frame
   // always needs to be regenerated on Linux.
   need_regenerate = true;
 #endif
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
index b70cca0..b5223be 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -55,13 +55,7 @@
 
   static GURL GetAppURL() { return GURL("https://test.org"); }
 
-  void SetUpOnMainThread() override {
-    SetThemeMode(ThemeMode::kDefault);
-#if BUILDFLAG(IS_LINUX)
-    ui::LinuxUi::instance()->SetUseSystemThemeCallback(
-        base::BindRepeating([](aura::Window* window) { return false; }));
-#endif
-  }
+  void SetUpOnMainThread() override { SetThemeMode(ThemeMode::kDefault); }
 
   bool InstallAndLaunchWebApp(
       absl::optional<SkColor> theme_color = absl::nullopt) {
@@ -110,6 +104,13 @@
   };
 
   void SetThemeMode(ThemeMode theme_mode) {
+#if BUILDFLAG(IS_LINUX)
+    ui::LinuxUi::instance()->SetUseSystemThemeCallback(base::BindRepeating(
+        [&](bool use_system_theme, aura::Window* window) {
+          return use_system_theme;
+        },
+        theme_mode == ThemeMode::kSystem));
+#endif
     ThemeService* theme_service =
         ThemeServiceFactory::GetForProfile(browser()->profile());
     if (theme_mode == ThemeMode::kSystem)
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
index 04ba278..943ae36b 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -392,8 +392,21 @@
     return;
   }
 
-  live_caption_title_->SetText(l10n_util::GetStringUTF16(
-      IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR));
+  std::u16string error_message;
+  switch (error_code) {
+    case speech::SodaInstaller::ErrorCode::kUnspecifiedError: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR);
+      break;
+    }
+    case speech::SodaInstaller::ErrorCode::kNeedsReboot: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_GLOBAL_MEDIA_CONTROLS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED);
+      break;
+    }
+  }
+
+  live_caption_title_->SetText(error_message);
 }
 
 void MediaDialogView::OnSodaProgress(speech::LanguageCode language_code,
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
index 9d8a085..8a93b92 100644
--- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -83,6 +83,11 @@
         apps::features::kLinkCapturingUiUpdate);
   }
 
+  void SetUpOnMainThread() override {
+    web_app::WebAppNavigationBrowserTest::SetUpOnMainThread();
+    InstallTestWebApp();
+  }
+
   void TearDownOnMainThread() override {
     web_app::test::UninstallWebApp(profile(), test_web_app_id());
     if (!overlapping_app_id_.empty()) {
@@ -150,8 +155,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonBrowserTest,
                        NavigationToInScopeLinkShowsIntentChip) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), in_scope_url));
@@ -168,8 +171,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonBrowserTest,
                        NavigationToOutOfScopeLinkDoesNotShowsIntentChip) {
-  InstallTestWebApp();
-
   const GURL out_of_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), out_of_scope_url));
@@ -179,8 +180,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonBrowserTest,
                        IconVisibilityAfterTabSwitching) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   const GURL out_of_scope_url =
@@ -204,7 +203,6 @@
 // Using the Intent Chip for an app which is set as preferred should launch
 // directly into the app. Preferred apps are only available on ChromeOS.
 IN_PROC_BROWSER_TEST_F(IntentChipButtonBrowserTest, OpensAppForPreferredApp) {
-  InstallTestWebApp();
   SetSupportedLinksPreference();
 
   const GURL in_scope_url =
@@ -220,7 +218,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonBrowserTest,
                        ShowsIntentChipExpandedForPreferredApp) {
-  InstallTestWebApp();
   SetSupportedLinksPreference();
 
   const GURL in_scope_url =
@@ -256,8 +253,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonSkipIntentPickerBrowserTest,
                        ClickingChipOpensApp) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), in_scope_url));
@@ -279,7 +274,6 @@
 #endif
 IN_PROC_BROWSER_TEST_F(IntentChipButtonSkipIntentPickerBrowserTest,
                        MAYBE_ShowsIntentPickerWhenMultipleApps) {
-  InstallTestWebApp();
   InstallOverlappingApp();
 
   const GURL in_scope_url =
@@ -302,8 +296,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonSkipIntentPickerBrowserTest,
                        ShowsIntentChipCollapsed) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   const GURL out_of_scope_url =
@@ -384,8 +376,6 @@
 };
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonIPHBubbleBrowserTest, ShowAndCloseIPH) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
 
@@ -453,7 +443,6 @@
 };
 
 IN_PROC_BROWSER_TEST_F(IntentChipButtonAppIconBrowserTest, ShowsAppIconInChip) {
-  InstallTestWebApp();
   InstallOverlappingApp();
 
   const GURL root_url = https_server().GetURL(GetAppUrlHost(), "/");
@@ -509,8 +498,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipWithInfoBarBrowserTest,
                        ShowsInfoBarOnAppOpen) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), in_scope_url));
@@ -541,8 +528,6 @@
 
 IN_PROC_BROWSER_TEST_F(IntentChipWithAutoDisplayBrowserTest,
                        ShowsIntentPickerOnNavigation) {
-  InstallTestWebApp();
-
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
index 6450ec0c..953dd1b 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
@@ -211,7 +211,7 @@
     // be different. But when using the GTK theme on Linux, these colors will be
     // the same. Ensure we're not using the system (GTK) theme, which may be
     // conditionally enabled depending on the environment.
-#if BUILDFLAG(USE_GTK)
+#if BUILDFLAG(IS_LINUX)
     // Normally it would be sufficient to call ThemeService::UseDefaultTheme()
     // which sets the kUsesSystemTheme user pref on the browser's profile.
     // However BrowserThemeProvider::GetColorProviderColor() currently does not
@@ -230,7 +230,7 @@
       theme_service->UseDefaultTheme();
     }
     ASSERT_TRUE(theme_service->UsingDefaultTheme());
-#endif  // BUILDFLAG(USE_GTK)
+#endif  // BUILDFLAG(IS_LINUX)
   }
 };
 
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc
index f19dd3b..0aae831 100644
--- a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc
+++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc
@@ -172,8 +172,8 @@
   }
 
   void SetUserWithAffiliation() {
-    const AccountId account_id(AccountId::FromUserEmailGaiaId(
-        browser()->profile()->GetProfileUserName(), "id"));
+    const AccountId account_id(
+        AccountId::FromUserEmailGaiaId("test@test", "id"));
     auto user_manager = std::make_unique<ash::FakeChromeUserManager>();
     user_manager->AddUserWithAffiliation(account_id, true);
     user_manager->LoginUser(account_id);
diff --git a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
index 777de46..2ba4e23 100644
--- a/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/lens/lens_side_panel_coordinator_browsertest.cc
@@ -49,6 +49,8 @@
 namespace {
 
 constexpr char kCloseAction[] = "LensUnifiedSidePanel.HideSidePanel";
+constexpr char kExpectedSidePanelContentUrlRegex[] =
+    ".*ep=ccm&re=dcsp&s=csp&st=\\d+&p=somepayload";
 
 // Maintains image search test state. In particular, note that |menu_observer_|
 // must live until the right-click completes asynchronously.
@@ -170,15 +172,8 @@
   base::UserActionTester user_action_tester;
 };
 
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel \
-  DISABLED_ImageSearchWithValidImageOpensUnifiedSidePanel
-#else
-#define MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel \
-  ImageSearchWithValidImageOpensUnifiedSidePanel
-#endif
 IN_PROC_BROWSER_TEST_F(SearchImageWithUnifiedSidePanel,
-                       MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel) {
+                       ImageSearchWithValidImageOpensUnifiedSidePanel) {
   SetupUnifiedSidePanel();
   EXPECT_TRUE(GetRightAlignedSidePanel()->GetVisible());
 
@@ -194,7 +189,7 @@
   EXPECT_TRUE(GetLensSidePanelCoordinator()->IsLaunchButtonEnabledForTesting());
   // Match the query parameters, without the value of start_time.
   EXPECT_THAT(side_panel_content,
-              testing::MatchesRegex(".*ep=ccm&s=csp&st=\\d+&p=somepayload"));
+              testing::MatchesRegex(kExpectedSidePanelContentUrlRegex));
 }
 
 IN_PROC_BROWSER_TEST_F(SearchImageWithUnifiedSidePanel,
@@ -263,15 +258,8 @@
   }
 };
 
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel \
-  DISABLED_ImageSearchWithValidImageOpensUnifiedSidePanel
-#else
-#define MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel \
-  ImageSearchWithValidImageOpensUnifiedSidePanel
-#endif
 IN_PROC_BROWSER_TEST_F(SearchImageWithUnifiedSidePanelFooterDisabled,
-                       MAYBE_ImageSearchWithValidImageOpensUnifiedSidePanel) {
+                       ImageSearchWithValidImageOpensUnifiedSidePanel) {
   SetupUnifiedSidePanel();
   EXPECT_TRUE(GetRightAlignedSidePanel()->GetVisible());
 
@@ -288,7 +276,7 @@
       GetLensSidePanelCoordinator()->IsLaunchButtonEnabledForTesting());
   // Match the query parameters, without the value of start_time.
   EXPECT_THAT(side_panel_content,
-              testing::MatchesRegex(".*ep=ccm&s=csp&st=\\d+&p=somepayload"));
+              testing::MatchesRegex(kExpectedSidePanelContentUrlRegex));
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc
index 786c8b01..3faa65a 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc
@@ -8,6 +8,7 @@
 
 #include "base/containers/cxx20_erase.h"
 #include "base/strings/utf_string_conversions.h"
+#include "ui/base/models/combobox_model_observer.h"
 #include "ui/views/style/typography.h"
 
 SidePanelComboboxModel::Item::Item(SidePanelEntry::Key key,
@@ -32,11 +33,17 @@
   std::sort(entries_.begin(), entries_.end(), [](const auto& a, const auto& b) {
     return a.key.id() < b.key.id();
   });
+  for (auto& observer : observers()) {
+    observer.OnComboboxModelChanged(this);
+  }
 }
 
 void SidePanelComboboxModel::RemoveItem(const SidePanelEntry::Key& entry_key) {
   base::EraseIf(entries_,
                 [entry_key](Item entry) { return entry.key == entry_key; });
+  for (auto& observer : observers()) {
+    observer.OnComboboxModelChanged(this);
+  }
 }
 
 void SidePanelComboboxModel::AddItems(
@@ -46,6 +53,9 @@
   }
   std::sort(entries_.begin(), entries_.end(),
             [](const auto& a, const auto& b) { return a.key < b.key; });
+  for (auto& observer : observers()) {
+    observer.OnComboboxModelChanged(this);
+  }
 }
 
 void SidePanelComboboxModel::RemoveItems(
@@ -58,6 +68,9 @@
     if (position != entries_.end())
       entries_.erase(position);
   }
+  for (auto& observer : observers()) {
+    observer.OnComboboxModelChanged(this);
+  }
 }
 
 SidePanelEntry::Key SidePanelComboboxModel::GetKeyAt(int index) const {
diff --git a/chrome/browser/ui/views/side_search/unified_side_search_controller.cc b/chrome/browser/ui/views/side_search/unified_side_search_controller.cc
index 559ed01..793003a 100644
--- a/chrome/browser/ui/views/side_search/unified_side_search_controller.cc
+++ b/chrome/browser/ui/views/side_search/unified_side_search_controller.cc
@@ -41,17 +41,8 @@
       return;
 
     auto* tab_web_contents = side_contents_helper->GetTabWebContents();
-
-    // (crbug.com/1348296) Do not clear side panel contents if the current tab's
-    // contextual entry is still active. This prevents the uaf bug also does not
-    // cause the side search to reload when switching back to a tab that has
-    // side search previously open.
-    auto* registry = SidePanelRegistry::Get(tab_web_contents);
-    if (registry && registry->active_entry().has_value() &&
-        registry->active_entry().value()->key().id() ==
-            SidePanelEntry::Id::kSideSearch) {
+    if (!tab_web_contents)
       return;
-    }
 
     auto* helper =
         SideSearchTabContentsHelper::FromWebContents(tab_web_contents);
diff --git a/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc b/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc
index e7b6efe..13f7a94 100644
--- a/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc
@@ -546,6 +546,30 @@
   EXPECT_NE(nullptr, tab_contents_helper->side_panel_contents_for_testing());
 }
 
+#if BUILDFLAG(IS_MAC)
+// TODO(crbug.com/1340387): Test is flaky on Mac.
+#define MAYBE_CloseTabWithSideSearchOpenShouldNotCrash \
+  DISABLED_CloseTabWithSideSearchOpenShouldNotCrash
+#else
+#define MAYBE_CloseTabWithSideSearchOpenShouldNotCrash \
+  CloseTabWithSideSearchOpenShouldNotCrash
+#endif
+// Test added for crbug.com/1356966 .
+IN_PROC_BROWSER_TEST_F(SideSearchV2Test,
+                       MAYBE_CloseTabWithSideSearchOpenShouldNotCrash) {
+  auto* browser_view = BrowserViewFor(browser());
+  NavigateActiveTab(browser(), GetMatchingSearchUrl());
+  NavigateActiveTab(browser(), GetNonMatchingUrl());
+  EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible());
+  NotifyButtonClick(browser());
+  EXPECT_EQ(SidePanelEntry::Id::kSideSearch,
+            browser_view->side_panel_coordinator()
+                ->GetCurrentSidePanelEntryForTesting()
+                ->key()
+                .id());
+  browser()->tab_strip_model()->CloseAllTabs();
+}
+
 class SideSearchV2TestAutoTriggeringBrowserTest : public SideSearchBrowserTest {
  public:
   SideSearchV2TestAutoTriggeringBrowserTest() {
diff --git a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
index 705f66d..2ef0abc 100644
--- a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
@@ -439,7 +439,6 @@
     tabbed_pane_->GetTabAt(0)->SetTitleText(source_language_name);
     tabbed_pane_->GetTabAt(1)->SetTitleText(target_language_name);
     model_->Translate();
-    tabbed_pane_->SelectTabAt(1);
 
     // Update max width of text selection label to match width of bubble, which
     // changes with the lengths of the languages displayed in the tabbed pane.
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
index 34c777e4..75597d0 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
@@ -49,7 +49,7 @@
 void FedCmAccountSelectionView::Show(
     const std::string& rp_etld_plus_one,
     const std::string& idp_etld_plus_one,
-    base::span<const Account> accounts,
+    const std::vector<Account>& accounts,
     const content::IdentityProviderMetadata& idp_metadata,
     const content::ClientIdData& client_data,
     Account::SignInMode sign_in_mode) {
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
index d8df21e..fc13eeb 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
@@ -30,7 +30,7 @@
   // AccountSelectionView:
   void Show(const std::string& rp_etld_plus_one,
             const std::string& idp_etld_plus_one,
-            base::span<const Account> accounts,
+            const std::vector<Account>& accounts,
             const content::IdentityProviderMetadata& idp_metadata,
             const content::ClientIdData& client_data,
             Account::SignInMode sign_in_mode) override;
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
index 3c68728d..8a7bf6460 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
@@ -29,7 +29,7 @@
   }
 
   void ShowUi(const std::string& name) override {
-    std::vector<const content::IdentityRequestAccount> accounts = {
+    std::vector<content::IdentityRequestAccount> accounts = {
         {"id", "email", "name", "given_name", GURL::EmptyGURL()}};
     content::IdentityProviderMetadata idp_metadata;
     content::ClientIdData client_data(GURL::EmptyGURL(), GURL::EmptyGURL());
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc
index ce0385b..ddfd2dbc 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -427,14 +427,6 @@
   return theme_pack_.get();
 }
 
-bool AppBrowserController::ShouldUseSystemTheme() const {
-#if BUILDFLAG(IS_LINUX)
-  return browser_->profile()->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme);
-#else
-  return false;
-#endif
-}
-
 bool AppBrowserController::ShouldUseCustomFrame() const {
   return true;
 }
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h
index 562f1a5..14d6a1a 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -223,7 +223,6 @@
 
   // BrowserThemeProviderDelegate:
   CustomThemeSupplier* GetThemeSupplier() const override;
-  bool ShouldUseSystemTheme() const override;
   bool ShouldUseCustomFrame() const override;
 
   // ui::ColorProviderManager::InitializerSupplier
diff --git a/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc b/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
index bc21768d..64142a3 100644
--- a/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
+++ b/chrome/browser/ui/web_applications/sub_apps_service_impl_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/web_applications/sub_apps_service_impl.h"
 
 #include "base/containers/flat_set.h"
+#include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "chrome/browser/ui/browser.h"
@@ -17,12 +18,16 @@
 #include "chrome/browser/web_applications/commands/sub_app_install_command.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/browser/web_applications/web_app_install_finalizer.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_registry_update.h"
 #include "chrome/browser/web_applications/web_app_ui_manager.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/webapps/browser/install_result_code.h"
+#include "components/webapps/browser/uninstall_result_code.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
@@ -82,6 +87,18 @@
 
   void UninstallParentApp() { UninstallWebApp(parent_app_id_); }
 
+  void UninstallParentAppBySource(WebAppManagement::Type source) {
+    base::RunLoop run_loop;
+    provider().install_finalizer().UninstallExternalWebApp(
+        parent_app_id_, source,
+        webapps::WebappUninstallSource::kParentUninstall,
+        base::BindLambdaForTesting([&](webapps::UninstallResultCode code) {
+          EXPECT_EQ(code, webapps::UninstallResultCode::kSuccess);
+          run_loop.Quit();
+        }));
+    run_loop.Run();
+  }
+
   std::vector<AppId> GetAllSubAppIds(const AppId& parent_app_id) {
     return provider().registrar().GetAllSubAppIds(parent_app_id);
   }
@@ -601,6 +618,55 @@
       GenerateAppIdFromUnhashed(unhashed_sub_app_id_3)));
 }
 
+// Verify that uninstalling an app that has multiple sources just
+// removes a source and does not end up removing the sub_apps.
+IN_PROC_BROWSER_TEST_F(SubAppsServiceImplBrowserTest,
+                       RemovingSourceFromParentAppDoesNotRemoveSubApps) {
+  NavigateToParentApp();
+  InstallParentApp();
+  BindRemote();
+
+  // Add another source to mock installation from 2 sources.
+  {
+    ScopedRegistryUpdate update(&provider().sync_bridge());
+    WebApp* web_app = update->UpdateApp(parent_app_id_);
+    if (web_app)
+      web_app->AddSource(WebAppManagement::kDefault);
+  }
+
+  // Verify that 2 subapps are installed.
+  UnhashedAppId unhashed_sub_app_id_1 =
+      GenerateAppIdUnhashed(/*manifest_id=*/absl::nullopt, GetURL(kSubAppPath));
+  UnhashedAppId unhashed_sub_app_id_2 = GenerateAppIdUnhashed(
+      /*manifest_id=*/absl::nullopt, GetURL(kSubAppPath2));
+
+  EXPECT_EQ(
+      Result(blink::mojom::SubAppsServiceAddResultCode::kSuccessNewInstall,
+             unhashed_sub_app_id_1),
+      CallAdd({{unhashed_sub_app_id_1, GetURL(kSubAppPath)}}));
+  EXPECT_EQ(
+      Result(blink::mojom::SubAppsServiceAddResultCode::kSuccessNewInstall,
+             unhashed_sub_app_id_2),
+      CallAdd({{unhashed_sub_app_id_2, GetURL(kSubAppPath2)}}));
+
+  EXPECT_TRUE(provider().registrar().IsInstalled(
+      GenerateAppIdFromUnhashed(unhashed_sub_app_id_1)));
+  EXPECT_TRUE(provider().registrar().IsInstalled(
+      GenerateAppIdFromUnhashed(unhashed_sub_app_id_2)));
+
+  UninstallParentAppBySource(WebAppManagement::kDefault);
+  // Verify that parent app and sub_apps are still installed, only
+  // the default install source is removed from the parent app.
+  EXPECT_TRUE(provider().registrar().IsInstalled(parent_app_id_));
+  EXPECT_FALSE(
+      provider().registrar().GetAppById(parent_app_id_)->IsPreinstalledApp());
+
+  EXPECT_TRUE(provider().registrar().IsInstalled(
+      GenerateAppIdFromUnhashed(unhashed_sub_app_id_1)));
+  EXPECT_TRUE(provider().registrar().IsInstalled(
+      GenerateAppIdFromUnhashed(unhashed_sub_app_id_2)));
+}
+
 // Make sure the Add API can't force manifest update. Add sub-app, verify
 // display mode, then add the same one again with different display mode in the
 // manifest, and verify that it didn't change.
diff --git a/chrome/browser/ui/webid/account_selection_view.h b/chrome/browser/ui/webid/account_selection_view.h
index df893339..fe5559470 100644
--- a/chrome/browser/ui/webid/account_selection_view.h
+++ b/chrome/browser/ui/webid/account_selection_view.h
@@ -61,7 +61,7 @@
   // either OnAccountSelected() or OnDismiss() gets invoked.
   virtual void Show(const std::string& rp_for_display,
                     const std::string& idp_for_display,
-                    base::span<const Account> accounts,
+                    const std::vector<Account>& accounts,
                     const content::IdentityProviderMetadata& idp_metadata,
                     const content::ClientIdData& client_data,
                     Account::SignInMode sign_in_mode) = 0;
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.cc b/chrome/browser/ui/webid/identity_dialog_controller.cc
index bbc27f9..ba3ed4a 100644
--- a/chrome/browser/ui/webid/identity_dialog_controller.cc
+++ b/chrome/browser/ui/webid/identity_dialog_controller.cc
@@ -54,7 +54,7 @@
   // TODO(crbug.com/1348262): Temporarily support only the first IDP, extend to
   // support multiple IDPs.
   GURL idp_url = identity_provider_data[0].idp_config_url;
-  base::span<const content::IdentityRequestAccount> accounts =
+  std::vector<content::IdentityRequestAccount> accounts =
       identity_provider_data[0].accounts;
   content::IdentityProviderMetadata idp_metadata =
       identity_provider_data[0].idp_metadata;
diff --git a/chrome/browser/ui/webui/app_home/app_home_ui.cc b/chrome/browser/ui/webui/app_home/app_home_ui.cc
index 90cfc06..0010ab8 100644
--- a/chrome/browser/ui/webui/app_home/app_home_ui.cc
+++ b/chrome/browser/ui/webui/app_home/app_home_ui.cc
@@ -7,15 +7,19 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/app_home/app_home.mojom.h"
 #include "chrome/browser/ui/webui/app_home/app_home_page_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/app_home_resources.h"
+#include "chrome/grit/app_home_resources_map.h"
 #include "content/public/browser/web_ui_data_source.h"
-
 namespace webapps {
 
 AppHomeUI::AppHomeUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui) {
   content::WebUIDataSource* source =
       content::WebUIDataSource::Create(chrome::kChromeUIAppLauncherPageHost);
-
+  webui::SetupWebUIDataSource(
+      source, base::make_span(kAppHomeResources, kAppHomeResourcesSize),
+      IDR_APP_HOME_APP_HOME_HTML);
   Profile* profile = Profile::FromWebUI(web_ui);
   content::WebUIDataSource::Add(profile, source);
 }
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_handler.cc b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_handler.cc
index 139450e4..186fd3d 100644
--- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_handler.cc
@@ -145,7 +145,8 @@
   std::unique_ptr<file_manager::io_task::IOTask> task =
       std::make_unique<file_manager::io_task::CopyOrMoveIOTask>(
           file_manager::io_task::OperationType::kCopy, std::move(source_urls),
-          std::move(destination_folder_url), profile_, file_system_context);
+          std::move(destination_folder_url), profile_, file_system_context,
+          /*show_notifications=*/false);
 
   observed_task_id_ = io_task_controller_->Add(std::move(task));
 }
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/OWNERS b/chrome/browser/ui/webui/chromeos/in_session_password_change/OWNERS
index a8183f4..1f6c549 100644
--- a/chrome/browser/ui/webui/chromeos/in_session_password_change/OWNERS
+++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/OWNERS
@@ -1 +1 @@
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.cc
index a8562975..c1420061 100644
--- a/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.cc
@@ -6,6 +6,7 @@
 
 #include "ash/constants/ash_switches.h"
 #include "base/command_line.h"
+#include "base/values.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
 #include "chrome/browser/ash/login/screens/consolidated_consent_screen.h"
 #include "chrome/grit/chromium_strings.h"
@@ -18,18 +19,10 @@
 
 ConsolidatedConsentScreenView::ScreenConfig::~ScreenConfig() = default;
 
-constexpr StaticOobeScreenId ConsolidatedConsentScreenView::kScreenId;
-
 ConsolidatedConsentScreenHandler::ConsolidatedConsentScreenHandler()
-    : BaseScreenHandler(kScreenId) {
-  set_user_acted_method_path_deprecated(
-      "login.ConsolidatedConsentScreen.userActed");
-}
+    : BaseScreenHandler(kScreenId) {}
 
-ConsolidatedConsentScreenHandler::~ConsolidatedConsentScreenHandler() {
-  if (screen_)
-    screen_->OnViewDestroyed(this);
-}
+ConsolidatedConsentScreenHandler::~ConsolidatedConsentScreenHandler() = default;
 
 void ConsolidatedConsentScreenHandler::DeclareLocalizedValues(
     ::login::LocalizedValuesBuilder* builder) {
@@ -125,73 +118,26 @@
   }
 }
 
-void ConsolidatedConsentScreenHandler::InitializeDeprecated() {}
-
-void ConsolidatedConsentScreenHandler::Show(const ScreenConfig& config) {
-  base::Value::Dict data;
-  // If ARC is enabled, show the ARC ToS and the related opt-ins.
-  data.Set("isArcEnabled", config.is_arc_enabled);
-  // In demo mode, don't show any opt-ins related to ARC and allow showing the
-  // offline ARC ToS if the online version failed to load.
-  data.Set("isDemo", config.is_demo);
-  // Child accounts have alternative strings for the opt-ins.
-  data.Set("isChildAccount", config.is_child_account);
-  // If the user is affiliated with the device management domain, ToS should be
-  // hidden.
-  data.Set("isTosHidden", config.is_tos_hidden);
-  // Country code is needed to load the ARC ToS.
-  data.Set("countryCode", config.country_code);
-  // URL for EULA, the URL should include the locale.
-  data.Set("googleEulaUrl", config.google_eula_url);
-  // URL for Chrome and ChromeOS additional terms of service, the URL should
-  // include the locale.
-  data.Set("crosEulaUrl", config.cros_eula_url);
+void ConsolidatedConsentScreenHandler::Show(base::Value::Dict data) {
   ShowInWebUI(std::move(data));
 }
 
-void ConsolidatedConsentScreenHandler::Bind(ConsolidatedConsentScreen* screen) {
-  screen_ = screen;
-  BaseScreenHandler::SetBaseScreenDeprecated(screen_);
-}
-
-void ConsolidatedConsentScreenHandler::Unbind() {
-  screen_ = nullptr;
-  BaseScreenHandler::SetBaseScreenDeprecated(nullptr);
-}
-
-void ConsolidatedConsentScreenHandler::RegisterMessages() {
-  BaseScreenHandler::RegisterMessages();
-
-  AddCallback("ToSAccept", &ConsolidatedConsentScreenHandler::HandleAccept);
-}
-
-void ConsolidatedConsentScreenHandler::HandleAccept(
-    bool enable_stats_usage,
-    bool enable_backup_restore,
-    bool enable_location_services,
-    const std::string& tos_content) {
-  if (screen_) {
-    screen_->OnAccept(enable_stats_usage, enable_backup_restore,
-                      enable_location_services, tos_content);
-  }
-}
-
 void ConsolidatedConsentScreenHandler::SetUsageMode(bool enabled,
                                                     bool managed) {
-  CallJS("login.ConsolidatedConsentScreen.setUsageMode", enabled, managed);
+  CallExternalAPI("setUsageMode", enabled, managed);
 }
 
 void ConsolidatedConsentScreenHandler::SetBackupMode(bool enabled,
                                                      bool managed) {
-  CallJS("login.ConsolidatedConsentScreen.setBackupMode", enabled, managed);
+  CallExternalAPI("setBackupMode", enabled, managed);
 }
 
 void ConsolidatedConsentScreenHandler::SetLocationMode(bool enabled,
                                                        bool managed) {
-  CallJS("login.ConsolidatedConsentScreen.setLocationMode", enabled, managed);
+  CallExternalAPI("setLocationMode", enabled, managed);
 }
 
 void ConsolidatedConsentScreenHandler::SetUsageOptinOptinHidden(bool hidden) {
-  CallJS("login.ConsolidatedConsentScreen.setUsageOptinHidden", hidden);
+  CallExternalAPI("setUsageOptinHidden", hidden);
 }
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.h
index a785c2555..f89eb9c 100644
--- a/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/consolidated_consent_screen_handler.h
@@ -7,6 +7,8 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_CONSOLIDATED_CONSENT_SCREEN_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_CONSOLIDATED_CONSENT_SCREEN_HANDLER_H_
 
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
 namespace ash {
@@ -23,9 +25,11 @@
 
 // Interface for dependency injection between ConsolidatedConsentScreen and its
 // WebUI representation.
-class ConsolidatedConsentScreenView {
+class ConsolidatedConsentScreenView
+    : public base::SupportsWeakPtr<ConsolidatedConsentScreenView> {
  public:
-  constexpr static StaticOobeScreenId kScreenId{"consolidated-consent"};
+  inline constexpr static StaticOobeScreenId kScreenId{
+      "consolidated-consent", "ConsolidatedConsentScreen"};
 
   struct ScreenConfig {
     ScreenConfig();
@@ -49,13 +53,7 @@
   virtual ~ConsolidatedConsentScreenView() = default;
 
   // Shows the contents of the screen.
-  virtual void Show(const ScreenConfig& config) = 0;
-
-  // Binds |screen| to the view.
-  virtual void Bind(ash::ConsolidatedConsentScreen* screen) = 0;
-
-  // Unbinds the screen from the view.
-  virtual void Unbind() = 0;
+  virtual void Show(base::Value::Dict data) = 0;
 
   // Updates the UI of the opt-ins.
   // When an opt-in is managed, its toggle would be disabled.
@@ -84,28 +82,15 @@
 
  private:
   // ConsolidatedConsentScreenView
-  void Show(const ScreenConfig& config) override;
-  void Bind(ash::ConsolidatedConsentScreen* screen) override;
-  void Unbind() override;
+  void Show(base::Value::Dict data) override;
   void SetUsageMode(bool enabled, bool managed) override;
   void SetBackupMode(bool enabled, bool managed) override;
   void SetLocationMode(bool enabled, bool managed) override;
   void SetUsageOptinOptinHidden(bool hidden) override;
 
-  // content::WebUIMessageHandler:
-  void RegisterMessages() override;
-
   // BaseScreenHandler:
   void DeclareLocalizedValues(
       ::login::LocalizedValuesBuilder* builder) override;
-  void InitializeDeprecated() override;
-
-  void HandleAccept(bool enable_stats_usage,
-                    bool enable_backup_restore,
-                    bool enable_location_services,
-                    const std::string& tos_content);
-
-  ash::ConsolidatedConsentScreen* screen_ = nullptr;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
index ab28da9..05c366f 100644
--- a/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.h"
 
+#include "base/containers/fixed_flat_map.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h"
 #include "chrome/browser/ash/login/screens/fingerprint_setup_screen.h"
@@ -14,6 +15,62 @@
 
 namespace chromeos {
 
+struct SensorLocationToString {
+  uint32_t description_id = 0;
+  uint32_t description_child_id = 0;
+  uint32_t aria_label_id = 0;
+  bool aria_label_includes_device = false;
+};
+
+constexpr auto kLocationToStringMap = base::MakeFixedFlatMap<
+    ash::quick_unlock::FingerprintLocation,
+    SensorLocationToString>(
+    {{ash::quick_unlock::FingerprintLocation::TABLET_POWER_BUTTON,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL,
+       false /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_LEFT,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_LEFT_ARIA_LABEL,
+       false /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_RIGHT,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL,
+       false /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::KEYBOARD_TOP_RIGHT,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL,
+       false /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::RIGHT_SIDE,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_RIGHT_SIDE_ARIA_LABEL,
+       true /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::LEFT_SIDE,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_LEFT_SIDE_ARIA_LABEL,
+       true /*aria_label_includes_device*/}},
+     {ash::quick_unlock::FingerprintLocation::LEFT_OF_POWER_BUTTON_TOP_RIGHT,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT_CHILD}},
+     {ash::quick_unlock::FingerprintLocation::UNKNOWN,
+      {IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD,
+       IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION,
+       true /*aria_label_includes_device*/}}});
+
+SensorLocationToString GetSensorInfo() {
+  auto* location_string_it =
+      kLocationToStringMap.find(quick_unlock::GetFingerprintLocation());
+  CHECK(location_string_it != kLocationToStringMap.end());
+  return location_string_it->second;
+}
+
 FingerprintSetupScreenHandler::FingerprintSetupScreenHandler()
     : BaseScreenHandler(kScreenId) {}
 
@@ -47,78 +104,24 @@
   builder->Add("setupFingerprintScanTryAgain",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_TRY_AGAIN);
 
-  int description_id, aria_label_id, description_id_for_child;
-  bool aria_label_includes_device = false;
-  switch (quick_unlock::GetFingerprintLocation()) {
-    case quick_unlock::FingerprintLocation::TABLET_POWER_BUTTON:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL;
-      break;
-    case quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_LEFT:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_LEFT_ARIA_LABEL;
-      break;
-    case quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_RIGHT:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL;
-      break;
-    case quick_unlock::FingerprintLocation::KEYBOARD_TOP_RIGHT:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL;
-      break;
-    case quick_unlock::FingerprintLocation::RIGHT_SIDE:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_RIGHT_SIDE_ARIA_LABEL;
-      aria_label_includes_device = true;
-      break;
-    case quick_unlock::FingerprintLocation::LEFT_SIDE:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_LEFT_SIDE_ARIA_LABEL;
-      aria_label_includes_device = true;
-      break;
-    case quick_unlock::FingerprintLocation::UNKNOWN:
-      description_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      description_id_for_child =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
-      aria_label_id =
-          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
-      aria_label_includes_device = true;
-      break;
-  }
-  builder->AddF("setupFingerprintScreenDescription", description_id,
+  auto* location_string_it =
+      kLocationToStringMap.find(quick_unlock::GetFingerprintLocation());
+  CHECK(location_string_it != kLocationToStringMap.end());
+  auto sensor_info = GetSensorInfo();
+
+  builder->AddF("setupFingerprintScreenDescription", sensor_info.description_id,
                 ui::GetChromeOSDeviceName());
   builder->AddF("setupFingerprintScreenDescriptionForChild",
-                description_id_for_child, ui::GetChromeOSDeviceName());
-  if (aria_label_includes_device) {
-    builder->AddF("setupFingerprintScreenAriaLabel", aria_label_id,
-                  ui::GetChromeOSDeviceName());
-  } else {
-    builder->Add("setupFingerprintScreenAriaLabel", aria_label_id);
+                sensor_info.description_child_id, ui::GetChromeOSDeviceName());
+
+  if (sensor_info.aria_label_id != 0) {
+    if (sensor_info.aria_label_includes_device) {
+      builder->AddF("setupFingerprintScreenAriaLabel",
+                    sensor_info.aria_label_id, ui::GetChromeOSDeviceName());
+    } else {
+      builder->Add("setupFingerprintScreenAriaLabel",
+                   sensor_info.aria_label_id);
+    }
   }
 }
 
@@ -126,6 +129,7 @@
   auto* user_manager = user_manager::UserManager::Get();
   base::Value::Dict data;
   data.Set("isChildAccount", user_manager->IsLoggedInAsChildUser());
+  data.Set("hasAriaLabel", GetSensorInfo().aria_label_id != 0);
   ShowInWebUI(std::move(data));
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/saml_challenge_key_handler.cc b/chrome/browser/ui/webui/chromeos/login/saml_challenge_key_handler.cc
index a3268fa..221bfe1 100644
--- a/chrome/browser/ui/webui/chromeos/login/saml_challenge_key_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/saml_challenge_key_handler.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/ash/attestation/tpm_challenge_key_result.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
-#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
+#include "chrome/browser/enterprise/connectors/device_trust/prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/ash/components/install_attributes/install_attributes.h"
 #include "chromeos/login/login_state/login_state.h"
@@ -55,12 +55,9 @@
   if (!prefs || !prefs->HasPrefPath(kContextAwareAccessSignalsAllowlistPref))
     return false;
 
-  if (!ash::ProfileHelper::IsRegularProfile(profile) &&
-      !prefs->IsManagedPreference(kContextAwareAccessSignalsAllowlistPref))
-    return false;
-
-  return UrlMatchesPattern(
-      url, prefs->GetValueList(kContextAwareAccessSignalsAllowlistPref));
+  return prefs->IsManagedPreference(kContextAwareAccessSignalsAllowlistPref) &&
+         UrlMatchesPattern(
+             url, prefs->GetValueList(kContextAwareAccessSignalsAllowlistPref));
 }
 }  // namespace
 
@@ -103,7 +100,7 @@
       base::BindOnce(&SamlChallengeKeyHandler::BuildResponseForAllowlistedUrl,
                      weak_factory_.GetWeakPtr(), url));
 
-  const base::ListValue* patterns = nullptr;
+  const base::Value::List* patterns = nullptr;
   switch (status) {
     case CrosSettingsProvider::TRUSTED:
       if (!settings->GetList(kDeviceWebBasedAttestationAllowedUrls,
@@ -120,7 +117,7 @@
       break;
   }
 
-  if (!patterns || !UrlMatchesPattern(url, patterns->GetList())) {
+  if (!patterns || !UrlMatchesPattern(url, *patterns)) {
     ReturnResult(attestation::TpmChallengeKeyResult::MakeError(
         attestation::TpmChallengeKeyResultCode::
             kDeviceWebBasedAttestationUrlError));
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
index 608f73c..b3aa28d 100644
--- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
@@ -28,8 +28,8 @@
 void GetConsentIDs(const std::unordered_map<std::string, int>& known_strings,
                    const login::StringList& consent_description,
                    const std::string& consent_confirmation,
-                   std::vector<int>* consent_description_ids,
-                   int* consent_confirmation_id) {
+                   std::vector<int>& consent_description_ids,
+                   int& consent_confirmation_id) {
   // The strings returned by the WebUI are not free-form, they must belong into
   // a pre-determined set of strings (stored in `string_to_grd_id_map_`). As
   // this has privacy and legal implications, CHECK the integrity of the strings
@@ -37,25 +37,21 @@
   for (const std::string& text : consent_description) {
     auto iter = known_strings.find(text);
     CHECK(iter != known_strings.end()) << "Unexpected string:\n" << text;
-    consent_description_ids->push_back(iter->second);
+    consent_description_ids.push_back(iter->second);
   }
 
   auto iter = known_strings.find(consent_confirmation);
   CHECK(iter != known_strings.end()) << "Unexpected string:\n"
                                      << consent_confirmation;
-  *consent_confirmation_id = iter->second;
+  consent_confirmation_id = iter->second;
 }
 
 }  // namespace
 
 namespace chromeos {
 
-constexpr StaticOobeScreenId SyncConsentScreenView::kScreenId;
-
 SyncConsentScreenHandler::SyncConsentScreenHandler()
-    : BaseScreenHandler(kScreenId) {
-  set_user_acted_method_path_deprecated("login.SyncConsentScreen.userActed");
-}
+    : BaseScreenHandler(kScreenId) {}
 
 SyncConsentScreenHandler::~SyncConsentScreenHandler() = default;
 
@@ -140,53 +136,27 @@
                          IDS_LOGIN_SYNC_CONSENT_SCREEN_DECLINE2, builder);
 }
 
-void SyncConsentScreenHandler::Bind(SyncConsentScreen* screen) {
-  screen_ = screen;
-  BaseScreenHandler::SetBaseScreenDeprecated(screen);
-}
-
 void SyncConsentScreenHandler::Show(bool is_arc_restricted) {
   base::Value::Dict data;
   data.Set("isArcRestricted", is_arc_restricted);
   ShowInWebUI(std::move(data));
 }
 
-void SyncConsentScreenHandler::Hide() {}
-
 void SyncConsentScreenHandler::ShowLoadedStep() {
-  CallJS("login.SyncConsentScreen.showLoadedStep");
+  CallExternalAPI("showLoadedStep");
 }
 
 void SyncConsentScreenHandler::SetIsMinorMode(bool value) {
-  CallJS("login.SyncConsentScreen.setIsMinorMode", value);
+  CallExternalAPI("setIsMinorMode", value);
 }
 
-void SyncConsentScreenHandler::InitializeDeprecated() {}
-
-void SyncConsentScreenHandler::RegisterMessages() {
-  AddCallback("login.SyncConsentScreen.continue",
-              &SyncConsentScreenHandler::HandleContinue);
-}
-
-void SyncConsentScreenHandler::HandleContinue(
-    const bool opted_in,
-    const bool review_sync,
-    const base::Value::List& consent_description_list,
-    const std::string& consent_confirmation) {
-  auto consent_description =
-      login::ConvertToStringList(consent_description_list);
-  std::vector<int> consent_description_ids;
-  int consent_confirmation_id;
+void SyncConsentScreenHandler::RetrieveConsentIDs(
+    ::login::StringList& consent_description,
+    const std::string& consent_confirmation,
+    std::vector<int>& consent_description_ids,
+    int& consent_confirmation_id) {
   GetConsentIDs(known_strings_, consent_description, consent_confirmation,
-                &consent_description_ids, &consent_confirmation_id);
-  screen_->OnContinue(opted_in, review_sync, consent_description_ids,
-                      consent_confirmation_id);
-  SyncConsentScreen::SyncConsentScreenTestDelegate* test_delegate =
-      screen_->GetDelegateForTesting();
-  if (test_delegate) {
-    test_delegate->OnConsentRecordedStrings(consent_description,
-                                            consent_confirmation);
-  }
+                consent_description_ids, consent_confirmation_id);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h
index d5a1bb6..e0f263b 100644
--- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h
@@ -8,32 +8,25 @@
 #include <string>
 #include <unordered_map>
 
+#include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace ash {
-class SyncConsentScreen;
-}
-
 namespace chromeos {
 
 // Interface for dependency injection between SyncConsentScreen and its
 // WebUI representation.
-class SyncConsentScreenView {
+class SyncConsentScreenView
+    : public base::SupportsWeakPtr<SyncConsentScreenView> {
  public:
-  constexpr static StaticOobeScreenId kScreenId{"sync-consent"};
+  inline constexpr static StaticOobeScreenId kScreenId{"sync-consent",
+                                                       "SyncConsentScreen"};
 
   virtual ~SyncConsentScreenView() = default;
 
-  // Sets screen this view belongs to.
-  virtual void Bind(ash::SyncConsentScreen* screen) = 0;
-
   // Shows the contents of the screen.
   virtual void Show(bool is_arc_restricted) = 0;
 
-  // Hides the contents of the screen.
-  virtual void Hide() = 0;
-
   // The screen is initially shown in a loading state.
   // When SyncScreenBehavior becomes Shown, this method should be called to
   // advance the screen to the loaded state.
@@ -42,6 +35,11 @@
   // Set the minor mode flag, which controls whether we could use nudge
   // techinuque on the UI.
   virtual void SetIsMinorMode(bool value) = 0;
+
+  virtual void RetrieveConsentIDs(::login::StringList& consent_description,
+                                  const std::string& consent_confirmation,
+                                  std::vector<int>& consent_description_ids,
+                                  int& consent_confirmation_id) = 0;
 };
 
 // The sole implementation of the SyncConsentScreenView, using WebUI.
@@ -66,23 +64,16 @@
       ::login::LocalizedValuesBuilder* builder) override;
 
   // SyncConsentScreenView:
-  void Bind(ash::SyncConsentScreen* screen) override;
   void Show(bool is_arc_restricted) override;
-  void Hide() override;
   void ShowLoadedStep() override;
   void SetIsMinorMode(bool value) override;
 
+  void RetrieveConsentIDs(::login::StringList& consent_description,
+                          const std::string& consent_confirmation,
+                          std::vector<int>& consent_description_ids,
+                          int& consent_confirmation_id) override;
+
  private:
-  // BaseScreenHandler:
-  void InitializeDeprecated() override;
-  void RegisterMessages() override;
-
-  // WebUI message handlers
-  void HandleContinue(const bool opted_in,
-                      const bool review_sync,
-                      const base::Value::List& consent_description_list,
-                      const std::string& consent_confirmation);
-
   // Adds resource `resource_id` both to `builder` and to `known_string_ids_`.
   void RememberLocalizedValue(const std::string& name,
                               const int resource_id,
@@ -94,8 +85,6 @@
 
   // Resource IDs of the displayed strings.
   std::unordered_map<std::string, int> known_strings_;
-
-  ash::SyncConsentScreen* screen_ = nullptr;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 1c147c9..be66c16 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -267,10 +267,14 @@
 
   // When ResolveHost() in network process completes, OnResolveHostDone() method
   // is called.
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
   mojo::PendingReceiver<network::mojom::ResolveHostClient> receiver;
-  GetNetworkContext()->ResolveHost(host_port_pair, net::NetworkIsolationKey(),
-                                   /*optional_parameters=*/nullptr,
-                                   receiver.InitWithNewPipeAndPassRemote());
+  GetNetworkContext()->ResolveHost(
+      network::mojom::HostResolverHost::NewHostPortPair(
+          std::move(host_port_pair)),
+      net::NetworkIsolationKey(),
+      /*optional_parameters=*/nullptr, receiver.InitWithNewPipeAndPassRemote());
 
   auto callback = base::BindOnce(&NetInternalsMessageHandler::OnResolveHostDone,
                                  weak_factory_.GetWeakPtr(), *callback_id);
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index c555d83..c3f041a8 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -236,8 +236,10 @@
       ->profile()
       ->GetDefaultStoragePartition()
       ->GetNetworkContext()
-      ->ResolveHost(net::HostPortPair(hostname, 80), network_isolation_key_,
-                    std::move(resolve_host_parameters), std::move(client));
+      ->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                        net::HostPortPair(hostname, 80)),
+                    network_isolation_key_, std::move(resolve_host_parameters),
+                    std::move(client));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
index 88f8d575..133f2dda4 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/cfi_buildflags.h"
 #include "base/containers/flat_map.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
@@ -415,8 +416,12 @@
   EXPECT_EQ(expected, *value_ptr);
 }
 
-#if !defined(NDEBUG)
-// Slow and hangs often in debug builds. https://crbug.com/1338642
+#if !defined(NDEBUG) ||                                          \
+    (BUILDFLAG(IS_LINUX) &&                                      \
+     (BUILDFLAG(CFI_CAST_CHECK) || BUILDFLAG(CFI_ICALL_CHECK) || \
+      BUILDFLAG(CFI_ENFORCEMENT_TRAP) ||                         \
+      BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC)))
+// Slow in debug and CFI builds crbug.com/1338642
 #define MAYBE_WritePoliciesToJSONFile DISABLED_WritePoliciesToJSONFile
 #else
 #define MAYBE_WritePoliciesToJSONFile WritePoliciesToJSONFile
diff --git a/chrome/browser/ui/webui/settings/captions_handler.cc b/chrome/browser/ui/webui/settings/captions_handler.cc
index ba3c326..6f21241 100644
--- a/chrome/browser/ui/webui/settings/captions_handler.cc
+++ b/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -110,9 +110,22 @@
     return;
   }
 
+  std::u16string error_message;
+  switch (error_code) {
+    case speech::SodaInstaller::ErrorCode::kUnspecifiedError: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR);
+      break;
+    }
+    case speech::SodaInstaller::ErrorCode::kNeedsReboot: {
+      error_message = l10n_util::GetStringUTF16(
+          IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR_REBOOT_REQUIRED);
+      break;
+    }
+  }
+
   FireWebUIListener("soda-download-progress-changed",
-                    base::Value(l10n_util::GetStringUTF16(
-                        IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR)),
+                    base::Value(error_message),
                     base::Value(speech::GetLanguageName(language_code)));
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
index 756a56b..354f0e1 100644
--- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
+++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -208,6 +208,7 @@
   kQuickDim = 1115,
   kCameraOnOff = 1116,
   kMicrophoneOnOff = 1117,
+  kGeolocationOnOff = 1118,
 
   // Languages and Input section.
   kAddLanguage = 1200,
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
index d36d5b9..f7d8c97 100644
--- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -362,6 +362,7 @@
 
   int instruction_id, aria_label_id;
   bool aria_label_includes_device = false;
+  bool instruction_includes_device = false;
   using FingerprintLocation = quick_unlock::FingerprintLocation;
   switch (quick_unlock::GetFingerprintLocation()) {
     case FingerprintLocation::TABLET_POWER_BUTTON:
@@ -402,6 +403,14 @@
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_LEFT_SIDE_ARIA_LABEL;
       aria_label_includes_device = true;
       break;
+    case FingerprintLocation::LEFT_OF_POWER_BUTTON_TOP_RIGHT:
+      instruction_id =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_LEFT_OF_POWER_BUTTON_TOP_RIGHT;
+      // Use the dialog title as the aria-label, since this location does not
+      // require an aria-label.
+      aria_label_id = IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE;
+      instruction_includes_device = true;
+      break;
     case FingerprintLocation::UNKNOWN:
       instruction_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
@@ -409,8 +418,14 @@
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
       break;
   }
-  html_source->AddLocalizedString(
-      "configureFingerprintInstructionLocateScannerStep", instruction_id);
+  if (instruction_includes_device) {
+    html_source->AddString("configureFingerprintInstructionLocateScannerStep",
+                           l10n_util::GetStringFUTF16(
+                               instruction_id, ui::GetChromeOSDeviceName()));
+  } else {
+    html_source->AddLocalizedString(
+        "configureFingerprintInstructionLocateScannerStep", instruction_id);
+  }
   if (aria_label_includes_device) {
     html_source->AddString(
         "configureFingerprintScannerStepAriaLabel",
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
index d9332d4..bc532cbc 100644
--- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -331,6 +331,7 @@
       {"microphoneToggleTitle", IDS_OS_SETTINGS_MICROPHONE_TOGGLE_TITLE},
       {"microphoneToggleSublabelActive",
        IDS_OS_SETTINGS_PRIVACY_HUB_MICROPHONE_HARDWARE_TOGGLE_ACTIVE_SUBTEXT},
+      {"geolocationToggleTitle", IDS_OS_SETTINGS_GEOLOCATION_TOGGLE_TITLE},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
@@ -478,7 +479,8 @@
       mojom::kPrivacyHubSubpagePath);
   RegisterNestedSettingBulk(
       mojom::Subpage::kPrivacyHub,
-      {{mojom::Setting::kCameraOnOff, mojom::Setting::kMicrophoneOnOff}},
+      {{mojom::Setting::kCameraOnOff, mojom::Setting::kMicrophoneOnOff,
+        mojom::Setting::kGeolocationOnOff}},
       generator);
 }
 
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 7e8b90d8..43dd221 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2491,6 +2491,8 @@
      IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_SIGN_OUT},
     {"siteSettingsClearDisplayedStorageSignOut",
      IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_SIGN_OUT},
+    {"firstPartySetsMembershipLabel",
+     IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL},
     {"firstPartySetsShowRelatedSitesButton",
      IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON},
     {"firstPartySetsSiteClearStorageButton",
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index e72297a..c2f8d71 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -15,14 +15,17 @@
 #include "base/containers/contains.h"
 #include "base/containers/flat_set.h"
 #include "base/feature_list.h"
+#include "base/i18n/message_formatter.h"
 #include "base/i18n/number_formatting.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
+#include "chrome/browser/browsing_data/cookies_tree_model.h"
 #include "chrome/browser/browsing_topics/browsing_topics_service_factory.h"
 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -516,6 +519,53 @@
     model->DeleteCookieNode(node);
 }
 
+// Returns the registable domain (eTLD+1) for the `origin`. If it doesn't exist,
+// returns the host.
+std::string GetEtldPlusOne(const url::Origin& origin) {
+  auto eltd_plus_one = net::registry_controlled_domains::GetDomainAndRegistry(
+      origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+  return eltd_plus_one.empty() ? origin.host() : eltd_plus_one;
+}
+
+// Converts |etld_plus1| into an HTTPS SchemefulSite.
+net::SchemefulSite ConvertEtldToSchemefulSite(const std::string etld_plus1) {
+  return net::SchemefulSite(GURL(std::string(url::kHttpsScheme) +
+                                 url::kStandardSchemeSeparator + etld_plus1 +
+                                 "/"));
+}
+
+// Iterates over host nodes in `tree_model` which contains all sites that have
+// storage set and uses them to retrieve first party set membership information.
+// Returns a map of site eTLD+1 matched with their FPS owner and count of first
+// party set members.
+std::map<std::string, std::pair<std::string, int>> GetFpsMap(
+    PrivacySandboxService* privacy_sandbox_service,
+    CookiesTreeModel* tree_model) {
+  // Used to count unique eTLD+1 owned by a FPS owner.
+  std::map<std::string, std::set<std::string>> fps_owner_to_members;
+  auto first_party_sets = privacy_sandbox_service->GetFirstPartySets();
+  // Count members by unique eTLD+1 for each first party set.
+  for (const auto& host_node : tree_model->GetRoot()->children()) {
+    std::string etld_plus1 =
+        GetEtldPlusOne(host_node->GetDetailedInfo().origin);
+    auto schemeful_site = ConvertEtldToSchemefulSite(etld_plus1);
+    if (first_party_sets.count(schemeful_site)) {
+      auto fps_owner = first_party_sets[schemeful_site];
+      fps_owner_to_members[fps_owner.GetURL().host()].insert(etld_plus1);
+    }
+  }
+
+  // site eTLD+1 : {owner site eTLD+1, # of sites in that first party set}
+  std::map<std::string, std::pair<std::string, int>> fps_map;
+  for (auto fps : fps_owner_to_members) {
+    // Set fps owner and count of members for each eTLD+1
+    for (auto member : fps.second) {
+      fps_map[member] = {fps.first, fps.second.size()};
+    }
+  }
+
+  return fps_map;
+}
 }  // namespace
 
 SiteSettingsHandler::SiteSettingsHandler(Profile* profile)
@@ -696,6 +746,7 @@
   const CookieTreeNode* root = cookies_tree_model_->GetRoot();
   std::string usage_string;
   std::string cookie_string;
+  std::string fps_string;
   for (const auto& site : root->children()) {
     std::string title = base::UTF16ToUTF8(site->GetTitle());
     if (title != usage_host_)
@@ -729,10 +780,24 @@
       cookie_string = base::UTF16ToUTF8(l10n_util::GetPluralStringFUTF16(
           IDS_SETTINGS_SITE_SETTINGS_NUM_COOKIES, num_cookies));
     }
+
+    auto fps_map =
+        GetFpsMap(PrivacySandboxServiceFactory::GetForProfile(profile_),
+                  cookies_tree_model_.get());
+    auto etld_plus1 = GetEtldPlusOne(site->GetDetailedInfo().origin);
+    if (fps_map.count(etld_plus1)) {
+      fps_string =
+          base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNamedArgs(
+              l10n_util::GetStringUTF16(
+                  IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL),
+              "MEMBERS", static_cast<int>(fps_map[etld_plus1].second),
+              "FPS_OWNER", fps_map[etld_plus1].first));
+    }
     break;
   }
   FireWebUIListener("usage-total-changed", base::Value(usage_host_),
-                    base::Value(usage_string), base::Value(cookie_string));
+                    base::Value(usage_string), base::Value(cookie_string),
+                    base::Value(fps_string));
 }
 
 void SiteSettingsHandler::OnContentSettingChanged(
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index 695f13c..5b7fade 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -486,21 +486,25 @@
 
   void ValidateUsageInfo(const std::string& expected_usage_host,
                          const std::string& expected_usage_string,
-                         const std::string& expected_cookie_string) {
+                         const std::string& expected_cookie_string,
+                         const std::string& expected_fps_member_count_string) {
     const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
     EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
 
-    ASSERT_TRUE(data.arg1()->is_string());
-    EXPECT_EQ("usage-total-changed", data.arg1()->GetString());
+    ASSERT_TRUE(data.arg_nth(0)->is_string());
+    EXPECT_EQ("usage-total-changed", data.arg_nth(0)->GetString());
 
-    ASSERT_TRUE(data.arg2()->is_string());
-    EXPECT_EQ(expected_usage_host, data.arg2()->GetString());
+    ASSERT_TRUE(data.arg_nth(1)->is_string());
+    EXPECT_EQ(expected_usage_host, data.arg_nth(1)->GetString());
 
-    ASSERT_TRUE(data.arg3()->is_string());
-    EXPECT_EQ(expected_usage_string, data.arg3()->GetString());
+    ASSERT_TRUE(data.arg_nth(2)->is_string());
+    EXPECT_EQ(expected_usage_string, data.arg_nth(2)->GetString());
 
-    ASSERT_TRUE(data.arg4()->is_string());
-    EXPECT_EQ(expected_cookie_string, data.arg4()->GetString());
+    ASSERT_TRUE(data.arg_nth(3)->is_string());
+    EXPECT_EQ(expected_cookie_string, data.arg_nth(3)->GetString());
+
+    ASSERT_TRUE(data.arg_nth(4)->is_string());
+    EXPECT_EQ(expected_fps_member_count_string, data.arg_nth(4)->GetString());
   }
 
   void CreateIncognitoProfile() {
@@ -2977,6 +2981,19 @@
 }
 
 TEST_F(SiteSettingsHandlerTest, HandleGetUsageInfo) {
+  base::flat_map<net::SchemefulSite, net::SchemefulSite> first_party_sets = {
+      {ConvertEtldToSchemefulSite("google.com"),
+       ConvertEtldToSchemefulSite("google.com")},
+      {ConvertEtldToSchemefulSite("google.com.au"),
+       ConvertEtldToSchemefulSite("google.com")},
+      {ConvertEtldToSchemefulSite("unrelated.com"),
+       ConvertEtldToSchemefulSite("unrelated.com")},
+  };
+
+  EXPECT_CALL(*mock_privacy_sandbox_service(), GetFirstPartySets())
+      .Times(3)
+      .WillRepeatedly(Return(first_party_sets));
+
   // Confirm that usage info only returns unpartitioned storage.
   SetUpCookiesTreeModel();
 
@@ -2987,13 +3004,20 @@
   args.Append("www.example.com");
   handler()->HandleFetchUsageTotal(args);
   handler()->OnGetUsageInfo();
-  ValidateUsageInfo("www.example.com", "2 B", "1 cookie");
+  ValidateUsageInfo("www.example.com", "2 B", "1 cookie", "");
 
   args.clear();
   args.Append("example.com");
   handler()->HandleFetchUsageTotal(args);
   handler()->OnGetUsageInfo();
-  ValidateUsageInfo("example.com", "", "1 cookie");
+  ValidateUsageInfo("example.com", "", "1 cookie", "");
+
+  args.clear();
+  args.Append("google.com");
+  handler()->HandleFetchUsageTotal(args);
+  handler()->OnGetUsageInfo();
+  ValidateUsageInfo("google.com", "", "2 cookies",
+                    "Allowed for 2 google.com sites");
 }
 
 TEST_F(SiteSettingsHandlerTest, NonTreeModelDeletion) {
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
index 3ea7ec7..d5ffdaf1 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
@@ -41,18 +41,19 @@
 }
 
 ReadAnythingPageHandler::~ReadAnythingPageHandler() {
-  delegate_ = static_cast<ReadAnythingPageHandler::Delegate*>(
-      coordinator_->GetController());
-  if (delegate_)
-    delegate_->OnUIDestroyed();
+  if (!coordinator_)
+    return;
 
   // If |this| is destroyed before the |ReadAnythingCoordinator|, then remove
   // |this| from the observer lists. In the cases where the coordinator is
   // destroyed first, these will have been destroyed before this call.
-  if (coordinator_) {
-    coordinator_->RemoveObserver(this);
-    coordinator_->RemoveModelObserver(this);
-  }
+  coordinator_->RemoveObserver(this);
+  coordinator_->RemoveModelObserver(this);
+
+  delegate_ = static_cast<ReadAnythingPageHandler::Delegate*>(
+      coordinator_->GetController());
+  if (delegate_)
+    delegate_->OnUIDestroyed();
 }
 
 void ReadAnythingPageHandler::OnCoordinatorDestroyed() {
diff --git a/chrome/browser/usb/web_usb_detector_unittest.cc b/chrome/browser/usb/web_usb_detector_unittest.cc
index d49d1fc..5141851 100644
--- a/chrome/browser/usb/web_usb_detector_unittest.cc
+++ b/chrome/browser/usb/web_usb_detector_unittest.cc
@@ -75,10 +75,10 @@
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::make_unique<ash::FakeChromeUserManager>());
 
-    GetFakeUserManager()->AddUser(user_manager::StubAccountId());
-    GetFakeUserManager()->LoginUser(user_manager::StubAccountId());
-
-    ash::ProfileHelper::Get()->SetActiveUserIdForTesting(kProfileName);
+    auto* user =
+        GetFakeUserManager()->AddUser(AccountId::FromUserEmail(kProfileName));
+    GetFakeUserManager()->LoginUser(user->GetAccountId());
+    ash::ProfileHelper::Get()->ActiveUserHashChanged(user->username_hash());
 #endif
     BrowserList::SetLastActive(browser());
     TestingBrowserProcess::GetGlobal()->SetSystemNotificationHelper(
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 540d5fe..5fa8c1a 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -57,6 +57,8 @@
     "install_bounce_metric.h",
     "isolated_web_apps/install_isolated_app_from_command_line.cc",
     "isolated_web_apps/install_isolated_app_from_command_line.h",
+    "isolated_web_apps/signed_web_bundle_reader.cc",
+    "isolated_web_apps/signed_web_bundle_reader.h",
     "isolation_prefs_utils.cc",
     "isolation_prefs_utils.h",
     "locks/app_lock.cc",
@@ -322,6 +324,7 @@
     "//components/site_engagement/core/mojom:mojo_bindings",
     "//components/sync",
     "//components/user_manager",
+    "//components/web_package",
     "//components/webapps/browser",
     "//components/webapps/common:common",
     "//components/webapps/common:mojo_bindings",
@@ -330,6 +333,7 @@
     "//content/public/browser",
     "//mojo/public/cpp/bindings",
     "//net",
+    "//services/data_decoder/public/cpp",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/cpp",
     "//services/preferences/public/cpp",
@@ -447,6 +451,8 @@
     "test/mock_os_integration_manager.h",
     "test/service_worker_registration_waiter.cc",
     "test/service_worker_registration_waiter.h",
+    "test/signed_web_bundle_utils.cc",
+    "test/signed_web_bundle_utils.h",
     "test/test_file_utils.cc",
     "test/test_file_utils.h",
     "test/test_web_app_url_loader.cc",
@@ -487,8 +493,10 @@
     "//components/services/app_service/public/cpp:types",
     "//components/sync:test_support",
     "//components/sync_preferences:test_support",
+    "//components/web_package/test_support",
     "//components/webapps/browser",
     "//content/test:test_support",
+    "//services/data_decoder/public/cpp:test_support",
     "//testing/gtest",
     "//ui/webui",
   ]
@@ -518,6 +526,7 @@
     "externally_managed_app_manager_impl_unittest.cc",
     "externally_managed_app_manager_unittest.cc",
     "isolated_web_apps/install_isolated_app_from_command_line_unittest.cc",
+    "isolated_web_apps/signed_web_bundle_reader_unittest.cc",
     "isolation_prefs_utils_unittest.cc",
     "manifest_update_task_unittest.cc",
     "os_integration/os_integration_manager_unittest.cc",
@@ -605,6 +614,7 @@
     "//chrome/test:test_support",
     "//components/services/app_service/public/cpp:app_url_handling",
     "//components/services/app_service/public/cpp:protocol_handling",
+    "//components/web_package/test_support",
     "//components/webapps/browser",
     "//components/webapps/browser:test_support",
     "//components/webapps/common:mojo_bindings",
diff --git a/chrome/browser/web_applications/DEPS b/chrome/browser/web_applications/DEPS
index 807c8c7..5e66e02 100644
--- a/chrome/browser/web_applications/DEPS
+++ b/chrome/browser/web_applications/DEPS
@@ -2,6 +2,7 @@
   "+base",
   "+chrome/browser",
   "+components/services/storage/indexed_db/locks",
+  "+components/web_package",
   "+components/webapps/services/web_app_origin_association",
   "+mojo/public/cpp/bindings",
   "+services/network/public/cpp",
diff --git a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc
new file mode 100644
index 0000000..91522aba
--- /dev/null
+++ b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc
@@ -0,0 +1,421 @@
+// 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/web_applications/isolated_web_apps/signed_web_bundle_reader.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/check_is_test.h"
+#include "base/check_op.h"
+#include "base/memory/ptr_util.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/web_package/mojom/web_bundle_parser.mojom.h"
+#include "mojo/public/cpp/system/data_pipe_producer.h"
+#include "net/base/url_util.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "url/gurl.h"
+
+namespace web_app {
+
+SignedWebBundleReader::SignedWebBundleReader(
+    const base::FilePath& web_bundle_path)
+    : web_bundle_path_(web_bundle_path) {}
+
+SignedWebBundleReader::~SignedWebBundleReader() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+// static
+std::unique_ptr<SignedWebBundleReader>
+SignedWebBundleReader::CreateAndStartReading(
+    const base::FilePath& web_bundle_path,
+    IntegrityBlockReadResultCallback integrity_block_result_callback,
+    ReadErrorCallback read_error_callback) {
+  // Using `new` to access a non-public constructor.
+  auto reader = base::WrapUnique(new SignedWebBundleReader(web_bundle_path));
+  reader->Initialize(std::move(integrity_block_result_callback),
+                     std::move(read_error_callback));
+
+  return reader;
+}
+
+void SignedWebBundleReader::Initialize(
+    IntegrityBlockReadResultCallback integrity_block_result_callback,
+    ReadErrorCallback read_error_callback) {
+  CHECK_EQ(state_, State::kInitializing);
+
+  parser_ = std::make_unique<data_decoder::SafeWebBundleParser>();
+  file_ = base::MakeRefCounted<web_package::SharedFile>(base::BindOnce(
+      [](const base::FilePath& file_path) -> std::unique_ptr<base::File> {
+        return std::make_unique<base::File>(
+            file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+      },
+      web_bundle_path_));
+
+  ReadIntegrityBlock(std::move(integrity_block_result_callback),
+                     std::move(read_error_callback));
+}
+
+void SignedWebBundleReader::ReadIntegrityBlock(
+    IntegrityBlockReadResultCallback integrity_block_result_callback,
+    ReadErrorCallback read_error_callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  file_->DuplicateFile(base::BindOnce(
+      &SignedWebBundleReader::SetFile, weak_ptr_factory_.GetWeakPtr(),
+      std::move(integrity_block_result_callback),
+      std::move(read_error_callback)));
+}
+
+void SignedWebBundleReader::SetFile(
+    IntegrityBlockReadResultCallback integrity_block_result_callback,
+    ReadErrorCallback read_error_callback,
+    base::File file) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  if (!file.IsValid()) {
+    FulfillWithError(
+        std::move(read_error_callback),
+        web_package::mojom::BundleIntegrityBlockParseError::New(
+            web_package::mojom::BundleParseErrorType::kParserInternalError,
+            "Unable to open file."));
+    return;
+  }
+
+  base::File::Error error = parser_->OpenFile(std::move(file));
+  if (error != base::File::FILE_OK) {
+    FulfillWithError(
+        std::move(read_error_callback),
+        web_package::mojom::BundleIntegrityBlockParseError::New(
+            web_package::mojom::BundleParseErrorType::kParserInternalError,
+            base::File::ErrorToString(error)));
+    return;
+  }
+
+  parser_->ParseIntegrityBlock(
+      base::BindOnce(&SignedWebBundleReader::OnIntegrityBlockParsed,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(integrity_block_result_callback),
+                     std::move(read_error_callback)));
+}
+
+void SignedWebBundleReader::OnIntegrityBlockParsed(
+    IntegrityBlockReadResultCallback integrity_block_result_callback,
+    ReadErrorCallback read_error_callback,
+    web_package::mojom::BundleIntegrityBlockPtr integrity_block,
+    web_package::mojom::BundleIntegrityBlockParseErrorPtr error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  if (error) {
+    FulfillWithError(std::move(read_error_callback), std::move(error));
+    return;
+  }
+
+  if (integrity_block->size == 0) {
+    FulfillWithError(std::move(read_error_callback),
+                     web_package::mojom::BundleIntegrityBlockParseError::New(
+                         web_package::mojom::BundleParseErrorType::kFormatError,
+                         "The Web Bundle must contain an integrity block."));
+    return;
+  }
+
+  integrity_block_size_ = integrity_block->size;
+  std::move(integrity_block_result_callback)
+      .Run(base::BindOnce(
+          &SignedWebBundleReader::OnShouldContinueParsingAfterIntegrityBlock,
+          weak_ptr_factory_.GetWeakPtr(), std::move(read_error_callback)));
+}
+
+void SignedWebBundleReader::OnShouldContinueParsingAfterIntegrityBlock(
+    ReadErrorCallback callback,
+    IntegrityVerificationAction action) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  switch (action) {
+    case IntegrityVerificationAction::kAbort:
+      return;
+    case IntegrityVerificationAction::kContinueAndVerifyIntegrity:
+      VerifyIntegrity(std::move(callback));
+      return;
+#if BUILDFLAG(IS_CHROMEOS)
+    case IntegrityVerificationAction::kContinueAndSkipIntegrityVerification:
+      ReadMetadata(std::move(callback));
+      return;
+#endif
+  }
+}
+
+void SignedWebBundleReader::VerifyIntegrity(ReadErrorCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  // TODO(crbug.com/1315947): Actually verify integrity here.
+  OnIntegrityVerified(std::move(callback));
+}
+
+void SignedWebBundleReader::OnIntegrityVerified(ReadErrorCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  // TODO(crbug.com/1315947): Check whether the integrity has been verified
+  // successfully here, once it is implemented.
+
+  ReadMetadata(std::move(callback));
+}
+
+void SignedWebBundleReader::ReadMetadata(ReadErrorCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  parser_->ParseMetadata(
+      /*offset=*/base::checked_cast<int64_t>(integrity_block_size_),
+      base::BindOnce(&SignedWebBundleReader::OnMetadataParsed,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void SignedWebBundleReader::OnMetadataParsed(
+    ReadErrorCallback callback,
+    web_package::mojom::BundleMetadataPtr metadata,
+    web_package::mojom::BundleMetadataParseErrorPtr error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitializing);
+
+  if (error) {
+    FulfillWithError(std::move(callback), std::move(error));
+    return;
+  }
+
+  primary_url_ = metadata->primary_url;
+  entries_ = std::move(metadata->requests);
+
+  state_ = State::kInitialized;
+
+  parser_->SetDisconnectCallback(
+      base::BindOnce(&SignedWebBundleReader::OnParserDisconnected,
+                     // `base::Unretained` is okay to use here, since
+                     // `parser_` will be deleted before `this` is deleted.
+                     base::Unretained(this)));
+
+  std::move(callback).Run(absl::nullopt);
+}
+
+void SignedWebBundleReader::FulfillWithError(ReadErrorCallback callback,
+                                             ReadError error) {
+  state_ = State::kError;
+
+  // This is an irrecoverable error state, thus we can safely delete `parser_`
+  // here to free up resources. We do so asynchronously, since this method might
+  // be called in response to `SafeWebBundleParser::OnDisconnect` if the parser
+  // disconnects while parsing the integrity block or metadata. Deleting
+  // `parser_` synchronously here might cause a use after free if `callback`
+  // deletes `this` in response to the error, because `parser_` would attempt to
+  // access its already freed instance variables when its `OnDisconnect` method
+  // continues execution after running this callback.
+  base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
+                                                     std::move(parser_));
+
+  std::move(callback).Run(std::move(error));
+}
+
+GURL SignedWebBundleReader::GetPrimaryURL() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitialized);
+
+  return primary_url_;
+}
+
+std::vector<GURL> SignedWebBundleReader::GetEntries() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitialized);
+
+  std::vector<GURL> entries;
+  entries.reserve(entries_.size());
+  base::ranges::transform(entries_, std::back_inserter(entries),
+                          [](const auto& entry) { return entry.first; });
+  return entries;
+}
+
+void SignedWebBundleReader::ReadResponse(
+    const network::ResourceRequest& resource_request,
+    ResponseCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitialized);
+
+  // TODO(crbug.com/1315947): Decide and document the exact behavior of Isolated
+  // Web Apps with regards to query parameters. Currently, query parameters and
+  // fragment are stripped from all requests when looking up an exchange in the
+  // Web Bundle.
+  GURL::Replacements replacements;
+  replacements.ClearQuery();
+  replacements.ClearRef();
+  auto entry_it =
+      entries_.find(resource_request.url.ReplaceComponents(replacements));
+
+  if (entry_it == entries_.end()) {
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            std::move(callback),
+            base::unexpected(web_package::mojom::BundleResponseParseError::New(
+                web_package::mojom::BundleParseErrorType::kParserInternalError,
+                "URL not found inside the Web Bundle."))));
+    return;
+  }
+
+  auto response_location = entry_it->second->Clone();
+  if (is_disconnected_) {
+    // Try reconnecting the parser if it hasn't been attempted yet.
+    if (pending_read_responses_.empty())
+      Reconnect();
+    pending_read_responses_.emplace_back(std::move(response_location),
+                                         std::move(callback));
+    return;
+  }
+
+  ReadResponseInternal(std::move(response_location), std::move(callback));
+}
+
+void SignedWebBundleReader::ReadResponseInternal(
+    web_package::mojom::BundleResponseLocationPtr location,
+    ResponseCallback callback) {
+  CHECK_EQ(state_, State::kInitialized);
+
+  parser_->ParseResponse(
+      location->offset, location->length,
+      base::BindOnce(&SignedWebBundleReader::OnResponseParsed,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void SignedWebBundleReader::OnResponseParsed(
+    ResponseCallback callback,
+    web_package::mojom::BundleResponsePtr response,
+    web_package::mojom::BundleResponseParseErrorPtr error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitialized);
+
+  if (error) {
+    std::move(callback).Run(base::unexpected(std::move(error)));
+  } else {
+    std::move(callback).Run(std::move(response));
+  }
+}
+
+void SignedWebBundleReader::ReadResponseBody(
+    web_package::mojom::BundleResponsePtr response,
+    mojo::ScopedDataPipeProducerHandle producer_handle,
+    ReadResponseBodyCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK_EQ(state_, State::kInitialized);
+
+  auto data_producer =
+      std::make_unique<mojo::DataPipeProducer>(std::move(producer_handle));
+  mojo::DataPipeProducer* raw_producer = data_producer.get();
+  raw_producer->Write(
+      file_->CreateDataSource(response->payload_offset,
+                              response->payload_length),
+      base::BindOnce(
+          // `producer` is passed to this callback purely for its lifetime
+          // management so that it is deleted once this callback runs.
+          [](std::unique_ptr<mojo::DataPipeProducer> producer,
+             MojoResult result) -> net::Error {
+            return result == MOJO_RESULT_OK ? net::Error::OK
+                                            : net::Error::ERR_UNEXPECTED;
+          },
+          std::move(data_producer))
+          .Then(std::move(callback)));
+}
+
+void SignedWebBundleReader::SetParserDisconnectCallbackForTesting(
+    base::RepeatingClosure callback) {
+  parser_disconnect_callback_for_testing_ = std::move(callback);
+}
+
+void SignedWebBundleReader::SetReconnectionFileErrorForTesting(
+    base::File::Error file_error) {
+  reconnection_file_error_for_testing_ = file_error;
+}
+
+void SignedWebBundleReader::OnParserDisconnected() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!is_disconnected_);
+
+  is_disconnected_ = true;
+  parser_ = nullptr;
+  if (!parser_disconnect_callback_for_testing_.is_null()) {
+    CHECK_IS_TEST();
+    parser_disconnect_callback_for_testing_.Run();
+  }
+  // Reconnection will be attempted on the next call to `ReadResponse`.
+}
+
+void SignedWebBundleReader::Reconnect() {
+  DCHECK(!parser_);
+  parser_ = std::make_unique<data_decoder::SafeWebBundleParser>();
+
+  file_->DuplicateFile(base::BindOnce(&SignedWebBundleReader::ReconnectForFile,
+                                      weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SignedWebBundleReader::ReconnectForFile(base::File file) {
+  base::File::Error file_error;
+  if (reconnection_file_error_for_testing_.has_value()) {
+    CHECK_IS_TEST();
+    file_error = *reconnection_file_error_for_testing_;
+  } else {
+    file_error = parser_->OpenFile(std::move(file));
+  }
+
+  absl::optional<std::string> error;
+  if (file_error != base::File::FILE_OK)
+    error = base::File::ErrorToString(file_error);
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&SignedWebBundleReader::DidReconnect,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(error)));
+}
+
+void SignedWebBundleReader::DidReconnect(absl::optional<std::string> error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(is_disconnected_);
+  DCHECK(parser_);
+  std::vector<std::pair<web_package::mojom::BundleResponseLocationPtr,
+                        ResponseCallback>>
+      read_tasks;
+  read_tasks.swap(pending_read_responses_);
+
+  if (error) {
+    for (auto& [response_location, response_callback] : read_tasks) {
+      base::SequencedTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE,
+          base::BindOnce(std::move(response_callback),
+                         base::unexpected(
+                             web_package::mojom::BundleResponseParseError::New(
+                                 web_package::mojom::BundleParseErrorType::
+                                     kParserInternalError,
+                                 *error))));
+    }
+    return;
+  }
+
+  is_disconnected_ = false;
+  parser_->SetDisconnectCallback(
+      base::BindOnce(&SignedWebBundleReader::OnParserDisconnected,
+                     // `base::Unretained` is okay to use here, since `parser_`
+                     // will be deleted before `this` is deleted.
+                     base::Unretained(this)));
+  for (auto& [response_location, response_callback] : read_tasks) {
+    ReadResponseInternal(std::move(response_location),
+                         std::move(response_callback));
+  }
+}
+
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h
new file mode 100644
index 0000000..8b321469
--- /dev/null
+++ b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h
@@ -0,0 +1,232 @@
+// 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_WEB_APPLICATIONS_ISOLATED_WEB_APPS_SIGNED_WEB_BUNDLE_READER_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_SIGNED_WEB_BUNDLE_READER_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/files/file_path.h"
+#include "base/sequence_checker.h"
+#include "base/types/expected.h"
+#include "components/web_package/mojom/web_bundle_parser.mojom-forward.h"
+#include "components/web_package/shared_file.h"
+#include "net/base/net_errors.h"
+#include "services/data_decoder/public/cpp/safe_web_bundle_parser.h"
+
+namespace network {
+struct ResourceRequest;
+}
+
+namespace web_app {
+
+// This class is a reader for Signed Web Bundles. Calling
+// `CreateAndStartReading` creates a new instance of this class and starts the
+// process to read the Signed Web Bundle's integrity block and metadata, as well
+// as to verify that the signatures contained in the integrity block sign the
+// bundle correctly. If everything is parsed successfully, then the caller can
+// make requests to responses contained in the Signed Web Bundle using
+// `ReadResponse` and `ReadResponseBody`. The caller can then also access the
+// metadata contained in the Signed Web Bundle. Potential errors occurring
+// during initialization are irrecoverable. Whether initialization has completed
+// can be determined by either waiting for the callback passed to
+// `CreateAndStartReading` to run or by querying `GetState`.
+//
+// Internally, this class wraps a `data_decoder::SafeWebBundleParser` with
+// support for automatic reconnection in case it disconnects while parsing
+// responses. The `SafeWebBundleParser` might disconnect, for example, if one of
+// the other `DataDecoder`s that run on the same utility process crashes, or
+// when the utility process is terminated by Android's OOM killer.
+class SignedWebBundleReader {
+ public:
+  // Callers of this class can decide whether parsing the Signed Web Bundle
+  // should continue or stop after the integrity block has been read.
+  enum class IntegrityVerificationAction {
+    kAbort,
+    kContinueAndVerifyIntegrity,
+
+  // On ChromeOS, we only verify integrity at install-time. On other OSes, we
+  // verify integrity once per session, so skipping integrity verification is
+  // not an option for other OSes.
+#if BUILDFLAG(IS_CHROMEOS)
+    kContinueAndSkipIntegrityVerification,
+#endif
+  };
+
+  // TODO(crbug.com/1315947): This is where information about the integrity
+  // block should be passed back to the caller, e.g. which public keys it
+  // contains, so that the caller can make a decision on whether they want to
+  // continue with integrity verification and metadata parsing, or just want to
+  // abort.
+  using IntegrityBlockReadResultCallback = base::OnceCallback<void(
+      /* TODO(crbug.com/1315947): pass information about integrity block here */
+      base::OnceCallback<void(IntegrityVerificationAction)> callback)>;
+
+  using ReadError =
+      absl::variant<web_package::mojom::BundleIntegrityBlockParseErrorPtr,
+                    // TODO(crbug.com/1315947): Add type for a signature
+                    // verification error here once it is implemented.
+                    web_package::mojom::BundleMetadataParseErrorPtr>;
+  using ReadErrorCallback =
+      base::OnceCallback<void(absl::optional<ReadError> result)>;
+
+  // Create a new instance of this class and start reading the Signed Web
+  // Bundle. This will invoke `integrity_block_result_callback` after reading
+  // the integrity block, which must then, based on the information contained in
+  // the integrity block, determine whether reading should continue with
+  // integrity verification and metadata reading, or abort altogether.
+  static std::unique_ptr<SignedWebBundleReader> CreateAndStartReading(
+      const base::FilePath& web_bundle_path,
+      IntegrityBlockReadResultCallback integrity_block_result_callback,
+      ReadErrorCallback read_error_callback);
+
+  // This class internally transitions through the following states:
+  //
+  // kInitializing -> kInitialized
+  //       |
+  //       `--------> kError
+  //
+  // If initialization fails, the callback passed to `CreateAndStartReading()`
+  // is called with the corresponding error, and the state changes to `kError`.
+  // Recovery from an initialization error is not possible.
+  enum class State {
+    kInitializing,
+    kInitialized,
+    kError,
+  };
+
+  // This class is ready to read responses from the Signed Web Bundle iff its
+  // state is `kInitialized`.
+  State GetState() const { return state_; }
+
+  SignedWebBundleReader(const SignedWebBundleReader&) = delete;
+  SignedWebBundleReader& operator=(const SignedWebBundleReader&) = delete;
+
+  ~SignedWebBundleReader();
+
+  // Returns the primary URL, as specified in the metadata of the Web Bundle.
+  // Will CHECK if `GetState()` != `kInitialized`.
+  GURL GetPrimaryURL() const;
+
+  // Returns the URLs of all exchanges contained in the Web Bundle, as specified
+  // in the metadata. Will CHECK if `GetState()` != `kInitialized`.
+  std::vector<GURL> GetEntries() const;
+
+  // Reads the status code and headers, as well as the length and offset of the
+  // response body within the Web Bundle. Will CHECK if `GetState()` !=
+  // `kInitialized`.
+  using ResponseCallback = base::OnceCallback<void(
+      base::expected<web_package::mojom::BundleResponsePtr,
+                     web_package::mojom::BundleResponseParseErrorPtr>)>;
+  void ReadResponse(const network::ResourceRequest& resource_request,
+                    ResponseCallback callback);
+
+  // Reads the response body given a `response` read with `ReadResponse`. Will
+  // CHECK if `GetState()` != `kInitialized`.
+  using ReadResponseBodyCallback =
+      base::OnceCallback<void(net::Error net_error)>;
+  void ReadResponseBody(web_package::mojom::BundleResponsePtr response,
+                        mojo::ScopedDataPipeProducerHandle producer_handle,
+                        ReadResponseBodyCallback callback);
+
+  // Can be used in tests to set a callback that will be called if the
+  // underlying `SafeWebBundleParser` disconnects.
+  void SetParserDisconnectCallbackForTesting(base::RepeatingClosure callback);
+
+  // Can be used in tests to simulate an error occurring when reconnecting the
+  // parser after it has disconnected.
+  void SetReconnectionFileErrorForTesting(base::File::Error file_error);
+
+ private:
+  explicit SignedWebBundleReader(const base::FilePath& web_bundle_path);
+
+  void Initialize(
+      IntegrityBlockReadResultCallback integrity_block_result_callback,
+      ReadErrorCallback read_error_callback);
+
+  void ReadIntegrityBlock(
+      IntegrityBlockReadResultCallback integrity_block_result_callback,
+      ReadErrorCallback read_error_callback);
+
+  void OpenFile(
+      IntegrityBlockReadResultCallback integrity_block_result_callback,
+      ReadErrorCallback read_error_callback);
+
+  void SetFile(IntegrityBlockReadResultCallback integrity_block_result_callback,
+               ReadErrorCallback read_error_callback,
+               base::File file);
+
+  void OnIntegrityBlockParsed(
+      IntegrityBlockReadResultCallback integrity_block_result_callback,
+      ReadErrorCallback read_error_callback,
+      web_package::mojom::BundleIntegrityBlockPtr integrity_block,
+      web_package::mojom::BundleIntegrityBlockParseErrorPtr error);
+
+  void OnShouldContinueParsingAfterIntegrityBlock(
+      ReadErrorCallback callback,
+      IntegrityVerificationAction action);
+
+  void VerifyIntegrity(ReadErrorCallback callback);
+
+  void OnIntegrityVerified(ReadErrorCallback callback);
+
+  void ReadMetadata(ReadErrorCallback callback);
+
+  void OnMetadataParsed(ReadErrorCallback callback,
+                        web_package::mojom::BundleMetadataPtr metadata,
+                        web_package::mojom::BundleMetadataParseErrorPtr error);
+
+  void FulfillWithError(ReadErrorCallback callback, ReadError error);
+
+  void ReadResponseInternal(
+      web_package::mojom::BundleResponseLocationPtr location,
+      ResponseCallback callback);
+
+  void OnResponseParsed(ResponseCallback callback,
+                        web_package::mojom::BundleResponsePtr response,
+                        web_package::mojom::BundleResponseParseErrorPtr error);
+
+  // The following methods are for reconnection handling if the
+  // `SafeWebBundleParser` disconnects at some point after integrity block and
+  // metadata have been read. Reconnecting to a new parser will be attempted on
+  // the next call to `ReadResponse`.
+  void OnParserDisconnected();
+  void Reconnect();
+  void ReconnectForFile(base::File file);
+  void DidReconnect(absl::optional<std::string> error);
+
+  State state_ = State::kInitializing;
+
+  bool is_disconnected_ = false;
+  base::FilePath web_bundle_path_;
+  std::unique_ptr<data_decoder::SafeWebBundleParser> parser_;
+  base::RepeatingClosure parser_disconnect_callback_for_testing_;
+  absl::optional<base::File::Error> reconnection_file_error_for_testing_;
+
+  scoped_refptr<web_package::SharedFile> file_;
+
+  // Integrity Block
+  uint64_t integrity_block_size_;
+  //  TODO(crbug.com/1315947): More properties from the integrity block will
+  //  follow here once we support verification of the integrity.
+
+  // Metadata
+  GURL primary_url_;
+  base::flat_map<GURL, web_package::mojom::BundleResponseLocationPtr> entries_;
+
+  // Accumulates `ReadResponse` requests while the parser is disconnected, and
+  // runs them after reconnection of the parser succeeds or fails.
+  std::vector<std::pair<web_package::mojom::BundleResponseLocationPtr,
+                        ResponseCallback>>
+      pending_read_responses_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+  base::WeakPtrFactory<SignedWebBundleReader> weak_ptr_factory_{this};
+};
+
+}  // namespace web_app
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_SIGNED_WEB_BUNDLE_H_
diff --git a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader_unittest.cc
new file mode 100644
index 0000000..cf619f3
--- /dev/null
+++ b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader_unittest.cc
@@ -0,0 +1,462 @@
+// 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/web_applications/isolated_web_apps/signed_web_bundle_reader.h"
+
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/web_applications/test/signed_web_bundle_utils.h"
+#include "components/web_package/mojom/web_bundle_parser.mojom.h"
+#include "components/web_package/test_support/mock_web_bundle_parser_factory.h"
+#include "content/public/test/browser_task_environment.h"
+#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+namespace web_app {
+
+class SignedWebBundleReaderTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    parser_factory_ =
+        std::make_unique<web_package::MockWebBundleParserFactory>();
+
+    response_ = web_package::mojom::BundleResponse::New();
+    response_->response_code = 200;
+    response_->payload_offset = 0;
+    response_->payload_length = sizeof(kResponseBody) - 1;
+
+    GURL primary_url("isolated-app://foo");
+
+    base::flat_map<GURL, web_package::mojom::BundleResponseLocationPtr> items;
+    items.insert({primary_url,
+                  web_package::mojom::BundleResponseLocation::New(
+                      response_->payload_offset, response_->payload_length)});
+    metadata_ = web_package::mojom::BundleMetadata::New();
+    metadata_->primary_url = primary_url;
+    metadata_->requests = std::move(items);
+
+    std::vector<web_package::mojom::BundleIntegrityBlockSignatureStackEntryPtr>
+        signature_stack;
+    signature_stack.push_back(
+        web_package::mojom::BundleIntegrityBlockSignatureStackEntry::New());
+
+    integrity_block_ = web_package::mojom::BundleIntegrityBlock::New();
+    // TODO(crbug.com/1315947): Provide proper integrity block data here once
+    // integrity verification is implemented.
+    integrity_block_->size = 123;
+    integrity_block_->signature_stack = std::move(signature_stack);
+  }
+
+  void TearDown() override {
+    // Allow cleanup tasks posted by the destructor of `web_package::SharedFile`
+    // to run.
+    task_environment_.RunUntilIdle();
+  }
+
+  std::unique_ptr<SignedWebBundleReader> CreateReaderAndInitialize(
+      SignedWebBundleReader::ReadErrorCallback callback,
+      const std::string test_file_data = kResponseBody) {
+    // Provide a buffer that contains the contents of just a single response.
+    // We do not need to provide an integrity block or metadata here, since
+    // reading them is completely mocked. Only response bodies are read from an
+    // actual (temporary) file.
+    base::FilePath temp_file_path;
+    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+    EXPECT_TRUE(CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file_path));
+    EXPECT_EQ(test_file_data.size(), static_cast<size_t>(base::WriteFile(
+                                         temp_file_path, test_file_data.data(),
+                                         test_file_data.size())));
+
+    in_process_data_decoder_.service()
+        .SetWebBundleParserFactoryBinderForTesting(base::BindRepeating(
+            &web_package::MockWebBundleParserFactory::AddReceiver,
+            base::Unretained(parser_factory_.get())));
+
+    return SignedWebBundleReader::CreateAndStartReading(
+        temp_file_path,
+        base::BindOnce(
+            [](base::OnceCallback<void(
+                   SignedWebBundleReader::IntegrityVerificationAction)>
+                   callback) {
+              // TODO(crbug.com/1315947): Test integrity block verification.
+              std::move(callback).Run(
+                  SignedWebBundleReader::IntegrityVerificationAction::
+                      kContinueAndVerifyIntegrity);
+            }),
+        std::move(callback));
+  }
+
+  base::expected<web_package::mojom::BundleResponsePtr,
+                 web_package::mojom::BundleResponseParseErrorPtr>
+  ReadAndFulfillResponse(
+      SignedWebBundleReader& reader,
+      const network::ResourceRequest& resource_request,
+      web_package::mojom::BundleResponseLocationPtr expected_read_response_args,
+      web_package::mojom::BundleResponsePtr response,
+      web_package::mojom::BundleResponseParseErrorPtr error = nullptr) {
+    base::test::TestFuture<
+        base::expected<web_package::mojom::BundleResponsePtr,
+                       web_package::mojom::BundleResponseParseErrorPtr>>
+        response_result;
+    reader.ReadResponse(resource_request, response_result.GetCallback());
+
+    parser_factory_->RunResponseCallback(std::move(expected_read_response_args),
+                                         std::move(response), std::move(error));
+
+    return response_result.Take();
+  }
+
+  void SimulateAndWaitForParserDisconnect(SignedWebBundleReader& reader) {
+    base::RunLoop run_loop;
+    reader.SetParserDisconnectCallbackForTesting(run_loop.QuitClosure());
+    parser_factory_->SimulateParserDisconnect();
+    run_loop.Run();
+  }
+
+  content::BrowserTaskEnvironment task_environment_;
+  data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
+  base::ScopedTempDir temp_dir_;
+
+  std::unique_ptr<web_package::MockWebBundleParserFactory> parser_factory_;
+  web_package::mojom::BundleIntegrityBlockPtr integrity_block_;
+  web_package::mojom::BundleMetadataPtr metadata_;
+
+  constexpr static char kResponseBody[] = "test";
+  web_package::mojom::BundleResponsePtr response_;
+};
+
+TEST_F(SignedWebBundleReaderTest, ReadValidIntegrityBlockAndMetadata) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  EXPECT_EQ(reader->GetPrimaryURL(), metadata_->primary_url);
+  EXPECT_EQ(reader->GetEntries().size(), 1ul);
+  EXPECT_EQ(reader->GetEntries()[0], metadata_->primary_url);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadIntegrityBlockError) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(
+      nullptr, web_package::mojom::BundleIntegrityBlockParseError::New());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_TRUE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kError);
+  EXPECT_TRUE(
+      absl::holds_alternative<
+          web_package::mojom::BundleIntegrityBlockParseErrorPtr>(*parse_error));
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadInvalidIntegrityBlockSize) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  web_package::mojom::BundleIntegrityBlockPtr integrity_block =
+      web_package::mojom::BundleIntegrityBlock::New();
+  integrity_block->size = 0;
+  parser_factory_->RunIntegrityBlockCallback(std::move(integrity_block));
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_TRUE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kError);
+  EXPECT_TRUE(
+      absl::holds_alternative<
+          web_package::mojom::BundleIntegrityBlockParseErrorPtr>(*parse_error));
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadIntegrityBlockWithParserCrash) {
+  parser_factory_->SimulateParseIntegrityBlockCrash();
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_TRUE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kError);
+  EXPECT_TRUE(
+      absl::holds_alternative<
+          web_package::mojom::BundleIntegrityBlockParseErrorPtr>(*parse_error));
+  EXPECT_EQ(absl::get<web_package::mojom::BundleIntegrityBlockParseErrorPtr>(
+                *parse_error)
+                ->type,
+            web_package::mojom::BundleParseErrorType::kParserInternalError);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadMetadataError) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(
+      integrity_block_->size, nullptr,
+      web_package::mojom::BundleMetadataParseError::New());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_TRUE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kError);
+  EXPECT_TRUE(
+      absl::holds_alternative<web_package::mojom::BundleMetadataParseErrorPtr>(
+          *parse_error));
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadMetadataWithParserCrash) {
+  parser_factory_->SimulateParseMetadataCrash();
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_TRUE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kError);
+  EXPECT_TRUE(
+      absl::holds_alternative<web_package::mojom::BundleMetadataParseErrorPtr>(
+          *parse_error));
+  EXPECT_EQ(
+      absl::get<web_package::mojom::BundleMetadataParseErrorPtr>(*parse_error)
+          ->type,
+      web_package::mojom::BundleParseErrorType::kParserInternalError);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponse) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  auto response = ReadAndFulfillResponse(
+      *reader.get(), resource_request,
+      metadata_->requests[metadata_->primary_url]->Clone(), response_->Clone());
+  EXPECT_TRUE(response.has_value()) << response.error()->message;
+  EXPECT_EQ((*response)->response_code, 200);
+  EXPECT_EQ((*response)->payload_offset, response_->payload_offset);
+  EXPECT_EQ((*response)->payload_length, response_->payload_length);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseWithRefAndQuery) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  GURL::Replacements replacements;
+  replacements.SetQueryStr("?foo=bar");
+  replacements.SetRefStr("baz");
+  resource_request.url = metadata_->primary_url.ReplaceComponents(replacements);
+
+  auto response = ReadAndFulfillResponse(
+      *reader.get(), resource_request,
+      metadata_->requests[metadata_->primary_url]->Clone(), response_->Clone());
+  EXPECT_TRUE(response.has_value()) << response.error()->message;
+  EXPECT_EQ((*response)->response_code, 200);
+  EXPECT_EQ((*response)->payload_offset, response_->payload_offset);
+  EXPECT_EQ((*response)->payload_length, response_->payload_length);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseThatDoesNotExist) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  GURL::Replacements replacements;
+  replacements.SetPathStr("/foo");
+  resource_request.url = metadata_->primary_url.ReplaceComponents(replacements);
+
+  base::test::TestFuture<
+      base::expected<web_package::mojom::BundleResponsePtr,
+                     web_package::mojom::BundleResponseParseErrorPtr>>
+      response_result;
+  reader->ReadResponse(resource_request, response_result.GetCallback());
+
+  auto response = response_result.Take();
+  ASSERT_FALSE(response.has_value());
+  EXPECT_EQ(response.error()->message, "URL not found inside the Web Bundle.");
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseError) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  auto response = ReadAndFulfillResponse(
+      *reader.get(), resource_request,
+      metadata_->requests[metadata_->primary_url]->Clone(), nullptr,
+      web_package::mojom::BundleResponseParseError::New());
+  EXPECT_TRUE(response.error());
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseWithParserDisconnect) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  SimulateAndWaitForParserDisconnect(*reader.get());
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  auto response = ReadAndFulfillResponse(
+      *reader.get(), resource_request,
+      metadata_->requests[metadata_->primary_url]->Clone(), response_->Clone());
+  EXPECT_TRUE(response.has_value()) << response.error()->message;
+  EXPECT_EQ((*response)->response_code, 200);
+  EXPECT_EQ((*response)->payload_offset, response_->payload_offset);
+  EXPECT_EQ((*response)->payload_length, response_->payload_length);
+
+  EXPECT_EQ(parser_factory_->GetParserCreationCount(), 2);
+}
+
+TEST_F(SignedWebBundleReaderTest,
+       SimulateParserDisconnectWithFileErrorWhenReconnecting) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  SimulateAndWaitForParserDisconnect(*reader.get());
+  reader->SetReconnectionFileErrorForTesting(
+      base::File::Error::FILE_ERROR_ACCESS_DENIED);
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  base::test::TestFuture<
+      base::expected<web_package::mojom::BundleResponsePtr,
+                     web_package::mojom::BundleResponseParseErrorPtr>>
+      response_result;
+  reader->ReadResponse(resource_request, response_result.GetCallback());
+  auto response = response_result.Take();
+  ASSERT_FALSE(response.has_value());
+  EXPECT_EQ(response.error()->message, "FILE_ERROR_ACCESS_DENIED");
+  EXPECT_EQ(parser_factory_->GetParserCreationCount(), 1);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseWithParserCrash) {
+  parser_factory_->SimulateParseResponseCrash();
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  base::test::TestFuture<
+      base::expected<web_package::mojom::BundleResponsePtr,
+                     web_package::mojom::BundleResponseParseErrorPtr>>
+      response_result;
+  reader->ReadResponse(resource_request, response_result.GetCallback());
+
+  auto response = response_result.Take();
+  EXPECT_FALSE(response.has_value());
+  EXPECT_EQ(response.error()->type,
+            web_package::mojom::BundleParseErrorType::kParserInternalError);
+}
+
+TEST_F(SignedWebBundleReaderTest, ReadResponseBody) {
+  base::test::TestFuture<absl::optional<SignedWebBundleReader::ReadError>>
+      parse_error_future;
+  auto reader = CreateReaderAndInitialize(parse_error_future.GetCallback());
+
+  parser_factory_->RunIntegrityBlockCallback(integrity_block_->Clone());
+  parser_factory_->RunMetadataCallback(integrity_block_->size,
+                                       metadata_->Clone());
+
+  auto parse_error = parse_error_future.Take();
+  EXPECT_FALSE(parse_error.has_value());
+  EXPECT_EQ(reader->GetState(), SignedWebBundleReader::State::kInitialized);
+
+  network::ResourceRequest resource_request;
+  resource_request.url = metadata_->primary_url;
+
+  auto response = ReadAndFulfillResponse(
+      *reader.get(), resource_request,
+      metadata_->requests[metadata_->primary_url]->Clone(), response_->Clone());
+  EXPECT_TRUE(response.has_value()) << response.error()->message;
+
+  std::string response_body =
+      ReadAndFulfillResponseBody(*reader.get(), std::move(*response));
+  EXPECT_EQ(response_body, kResponseBody);
+}
+
+}  // namespace web_app
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 55d8c00..f5398b1e 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
@@ -1376,22 +1376,18 @@
     const base::FilePath& app_path) const {
   auto closure = base::BindOnce(
       [](const base::FilePath& app_path) {
-        // Use selectFile:inFileViewerRootedAtPath:  to show the contents of
-        // the parent directory with the app shim selected.
-        //
-        // Despite calling this API with a rooted path, the Finder creates a
-        // new window each time the app shim is revealed (at least during
-        // tests). We skip revealing the app shim during testing to avoid an
-        // avalanche of new Finder windows.
+        // The Finder creates a new window each time the app shim is revealed.
+        // Skip revealing the app shim during testing to avoid an avalanche of
+        // new Finder windows.
         if (AppShimRevealDisabledForTest()) {
           return;
         }
+        NSURL* path_url = base::mac::FilePathToNSURL(app_path);
         [[NSWorkspace sharedWorkspace]
-                          selectFile:base::mac::FilePathToNSString(app_path)
-            inFileViewerRootedAtPath:@""];
+            activateFileViewerSelectingURLs:@[ path_url ]];
       },
       app_path);
-  // Perform the call to NSWorkSpace on the UI thread. Calling it on the IO
+  // Perform the call to NSWorkspace on the UI thread. Calling it on the IO
   // thread appears to cause crashes.
   // https://crbug.com/1067367
   content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(closure));
diff --git a/chrome/browser/web_applications/test/signed_web_bundle_utils.cc b/chrome/browser/web_applications/test/signed_web_bundle_utils.cc
new file mode 100644
index 0000000..d54a7ac
--- /dev/null
+++ b/chrome/browser/web_applications/test/signed_web_bundle_utils.cc
@@ -0,0 +1,54 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/web_applications/test/signed_web_bundle_utils.h"
+
+#include "base/bind.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h"
+#include "components/web_package/mojom/web_bundle_parser.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace web_app {
+
+std::string ReadAndFulfillResponseBody(
+    SignedWebBundleReader& reader,
+    web_package::mojom::BundleResponsePtr response) {
+  uint64_t response_length = response->payload_length;
+  return ReadAndFulfillResponseBody(
+      response_length,
+      base::BindOnce(&SignedWebBundleReader::ReadResponseBody,
+                     // It is okay to use a bare pointer here, since the
+                     // callback is executed synchronously.
+                     base::Unretained(&reader), std::move(response)));
+}
+
+std::string ReadAndFulfillResponseBody(
+    uint32_t response_length,
+    base::OnceCallback<void(mojo::ScopedDataPipeProducerHandle producer_handle,
+                            base::OnceCallback<void(net::Error net_error)>)>
+        read_response_body_callback) {
+  mojo::ScopedDataPipeProducerHandle producer;
+  mojo::ScopedDataPipeConsumerHandle consumer;
+  MojoCreateDataPipeOptions options;
+  options.struct_size = sizeof(MojoCreateDataPipeOptions);
+  options.element_num_bytes = 1;
+  options.capacity_num_bytes = response_length + 1;
+  EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, producer, consumer));
+
+  base::test::TestFuture<net::Error> error_future;
+  std::move(read_response_body_callback)
+      .Run(std::move(producer), error_future.GetCallback());
+  EXPECT_EQ(net::OK, error_future.Get());
+
+  std::vector<char> buffer(response_length);
+  uint32_t bytes_read = buffer.size();
+  MojoResult read_result =
+      consumer->ReadData(buffer.data(), &bytes_read, /*flags=*/0);
+  EXPECT_EQ(MOJO_RESULT_OK, read_result);
+  EXPECT_EQ(buffer.size(), bytes_read);
+  return std::string(buffer.data(), bytes_read);
+}
+
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/test/signed_web_bundle_utils.h b/chrome/browser/web_applications/test/signed_web_bundle_utils.h
new file mode 100644
index 0000000..bea65026
--- /dev/null
+++ b/chrome/browser/web_applications/test/signed_web_bundle_utils.h
@@ -0,0 +1,33 @@
+// 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_WEB_APPLICATIONS_TEST_SIGNED_WEB_BUNDLE_UTILS_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_TEST_SIGNED_WEB_BUNDLE_UTILS_H_
+
+#include <memory>
+
+#include "base/callback_forward.h"
+#include "components/web_package/mojom/web_bundle_parser.mojom-forward.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "net/base/net_errors.h"
+
+namespace web_app {
+
+class SignedWebBundleReader;
+
+// Given the `reader`, read the body of `response` from it and return the result
+// as a string.
+std::string ReadAndFulfillResponseBody(
+    SignedWebBundleReader& reader,
+    web_package::mojom::BundleResponsePtr response);
+
+std::string ReadAndFulfillResponseBody(
+    uint32_t response_length,
+    base::OnceCallback<void(mojo::ScopedDataPipeProducerHandle producer_handle,
+                            base::OnceCallback<void(net::Error net_error)>)>
+        read_response_body_callback);
+
+}  // namespace web_app
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_TEST_SIGNED_WEB_BUNDLE_UTILS_H_
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 4f883e3..47e791c2 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -841,15 +841,19 @@
     return;
   }
 
-  bool last_used_native_api = false;
+  bool jump_to_native_ui = false;
 #if BUILDFLAG(IS_WIN)
-  PrefService* const prefs =
-      user_prefs::UserPrefs::Get(GetRenderFrameHost()->GetBrowserContext());
-  last_used_native_api = prefs->GetBoolean(kWebAuthnLastOperationWasNativeAPI);
+  // Conditional requests always show the Chrome UI first because the UI is
+  // triggered from "Use passkey from another device" in autofill, and it would
+  // be confusing if the caBLE option wasn't presented after that.
+  if (!is_conditional_) {
+    PrefService* const prefs =
+        user_prefs::UserPrefs::Get(GetRenderFrameHost()->GetBrowserContext());
+    jump_to_native_ui = prefs->GetBoolean(kWebAuthnLastOperationWasNativeAPI);
+  }
 #endif
 
-  dialog_model_->StartFlow(std::move(data), is_conditional_,
-                           last_used_native_api);
+  dialog_model_->StartFlow(std::move(data), is_conditional_, jump_to_native_ui);
 
   if (g_observer) {
     g_observer->UIShown(this);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 12008d4..f559d30d 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1661774378-51ed3fdabf6f10bd8349e2bed9382c5d2508c464.profdata
+chrome-linux-main-1661838792-647f23e1a79f3b3df1b551f8cea721ce29228163.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index b38057b..f463a9f 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1661752129-b587e96bc360c4fbea1553a31aeb87facaccd380.profdata
+chrome-mac-arm-main-1661795912-b3a8ade0e5501d80e21313496a039eaa35c8c5de.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 437209f8..3f91f5a 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1661752129-1963f7c72bdd473ccade8769b18154a1dd7093f8.profdata
+chrome-mac-main-1661817478-bd4432bd24e26a769b01ce19d19052ddfc9a7a7b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index e376ae8b..121290f 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1661763558-200c737de5aaab18cfb573ba21777753a86ff1be.profdata
+chrome-win32-main-1661827788-68e70d5a75098b5d63a6e5082e5e4672458ef81d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 05f1e73b..fd16f7da4 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1661763558-4c25265704c9be9e3ba00cceedc24bf781bbdefd.profdata
+chrome-win64-main-1661838792-7cc0da21d85fea293d341860c712234d8572ec79.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 2e90c09..411f774 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -376,8 +376,14 @@
     }
 
     if (is_win || is_mac || is_linux || is_fuchsia) {
-      sources += [ "$root_gen_dir/chrome/apps_resources.pak" ]
-      deps += [ "//chrome/browser/resources/ntp4:apps_resources" ]
+      sources += [
+        "$root_gen_dir/chrome/app_home_resources.pak",
+        "$root_gen_dir/chrome/apps_resources.pak",
+      ]
+      deps += [
+        "//chrome/browser/resources/app_home:resources",
+        "//chrome/browser/resources/ntp4:apps_resources",
+      ]
     }
 
     if (is_win || is_mac || is_linux) {
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index 9067796..6f44a25 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -78,7 +78,7 @@
 #endif
 
 #if BUILDFLAG(ENABLE_PLUGINS)
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #endif
 
 #if BUILDFLAG(ENABLE_PDF)
@@ -98,9 +98,9 @@
 namespace {
 
 #if BUILDFLAG(ENABLE_NACL)
-content::PepperPluginInfo::GetInterfaceFunc g_nacl_get_interface;
-content::PepperPluginInfo::PPP_InitializeModuleFunc g_nacl_initialize_module;
-content::PepperPluginInfo::PPP_ShutdownModuleFunc g_nacl_shutdown_module;
+content::ContentPluginInfo::GetInterfaceFunc g_nacl_get_interface;
+content::ContentPluginInfo::PPP_InitializeModuleFunc g_nacl_initialize_module;
+content::ContentPluginInfo::PPP_ShutdownModuleFunc g_nacl_shutdown_module;
 #endif
 
 }  // namespace
@@ -111,9 +111,9 @@
 
 #if BUILDFLAG(ENABLE_NACL)
 void ChromeContentClient::SetNaClEntryFunctions(
-    content::PepperPluginInfo::GetInterfaceFunc get_interface,
-    content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module,
-    content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module) {
+    content::ContentPluginInfo::GetInterfaceFunc get_interface,
+    content::ContentPluginInfo::PPP_InitializeModuleFunc initialize_module,
+    content::ContentPluginInfo::PPP_ShutdownModuleFunc shutdown_module) {
   g_nacl_get_interface = get_interface;
   g_nacl_initialize_module = initialize_module;
   g_nacl_shutdown_module = shutdown_module;
@@ -134,14 +134,12 @@
   gpu::SetKeysForCrashLogging(gpu_info);
 }
 
-void ChromeContentClient::AddPepperPlugins(
-    std::vector<content::PepperPluginInfo>* plugins) {
+void ChromeContentClient::AddPlugins(
+    std::vector<content::ContentPluginInfo>* plugins) {
 #if BUILDFLAG(ENABLE_PDF)
-  // TODO(crbug.com/1344644): Expose the PDF viewer without using
-  // `PepperPluginInfo`.
   static constexpr char kPDFPluginExtension[] = "pdf";
   static constexpr char kPDFPluginDescription[] = "Portable Document Format";
-  content::PepperPluginInfo pdf_info;
+  content::ContentPluginInfo pdf_info;
   pdf_info.is_internal = true;
   pdf_info.is_out_of_process = true;
   pdf_info.name = ChromeContentClient::kPDFInternalPluginName;
@@ -158,10 +156,10 @@
   // enabled by default for the non-portable case.  This allows apps installed
   // from the Chrome Web Store to use NaCl even if the command line switch
   // isn't set.  For other uses of NaCl we check for the command line switch.
-  content::PepperPluginInfo nacl;
+  content::ContentPluginInfo nacl;
   // The nacl plugin is now built into the Chromium binary.
   nacl.is_internal = true;
-  nacl.path = base::FilePath(ChromeContentClient::kNaClPluginFileName);
+  nacl.path = base::FilePath(nacl::kInternalNaClPluginFileName);
   nacl.name = nacl::kNaClPluginName;
   content::WebPluginMimeType nacl_mime_type(nacl::kNaClPluginMimeType,
                                             nacl::kNaClPluginExtension,
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h
index dec45574..9f78de2 100644
--- a/chrome/common/chrome_content_client.h
+++ b/chrome/common/chrome_content_client.h
@@ -20,7 +20,7 @@
 #include "ppapi/buildflags/buildflags.h"
 
 #if BUILDFLAG(ENABLE_NACL)
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #endif  // BUILDFLAG(ENABLE_NACL)
 
 namespace embedder_support {
@@ -36,10 +36,6 @@
   static const base::FilePath::CharType kNotPresent[];
 #endif
 
-#if BUILDFLAG(ENABLE_NACL)
-  static const base::FilePath::CharType kNaClPluginFileName[];
-#endif
-
   static const char kPDFExtensionPluginName[];
   static const char kPDFInternalPluginName[];
   static const base::FilePath::CharType kPDFPluginPath[];
@@ -53,15 +49,14 @@
   // the split DLL.
 #if BUILDFLAG(ENABLE_NACL)
   static void SetNaClEntryFunctions(
-      content::PepperPluginInfo::GetInterfaceFunc get_interface,
-      content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module,
-      content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module);
+      content::ContentPluginInfo::GetInterfaceFunc get_interface,
+      content::ContentPluginInfo::PPP_InitializeModuleFunc initialize_module,
+      content::ContentPluginInfo::PPP_ShutdownModuleFunc shutdown_module);
 #endif
 
   void SetActiveURL(const GURL& url, std::string top_origin) override;
   void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
-  void AddPepperPlugins(
-      std::vector<content::PepperPluginInfo>* plugins) override;
+  void AddPlugins(std::vector<content::ContentPluginInfo>* plugins) override;
   void AddContentDecryptionModules(
       std::vector<content::CdmInfo>* cdms,
       std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
diff --git a/chrome/common/chrome_content_client_constants.cc b/chrome/common/chrome_content_client_constants.cc
index fb2b34d..f8ba7f63 100644
--- a/chrome/common/chrome_content_client_constants.cc
+++ b/chrome/common/chrome_content_client_constants.cc
@@ -10,11 +10,6 @@
     FILE_PATH_LITERAL("internal-not-yet-present");
 #endif
 
-#if BUILDFLAG(ENABLE_NACL)
-const base::FilePath::CharType ChromeContentClient::kNaClPluginFileName[] =
-    FILE_PATH_LITERAL("internal-nacl-plugin");
-#endif
-
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 const char ChromeContentClient::kPDFExtensionPluginName[] = "Chrome PDF Viewer";
 const char ChromeContentClient::kPDFInternalPluginName[] = "Chrome PDF Plugin";
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
index c6a68a61..e5013f284 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
@@ -37,7 +37,7 @@
   static const ChromeOSSystemExtensionInfos kExtensionIdToExtensionInfoMap{
       {/*extension_id=*/"gogonhoemckpdpadfnjnpgbjpbjnodgc",
        {/*manufacturers=*/{"HP", "ASUS"},
-        /*pwa_origin=*/"*://www.google.com/*"}},
+        /*pwa_origin=*/"*://googlechromelabs.github.io/*"}},
       {/*extension_id=*/"alnedpmllcfpgldkagbfbjkloonjlfjb",
        {/*manufacturers=*/{"HP"},
         /*pwa_origin=*/"https://hpcs-appschr.hpcloud.hp.com/*"}},
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
index fe4b0cc..fd8e767 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
@@ -20,7 +20,7 @@
       chromeos::GetChromeOSExtensionInfoForId(google_extension_id);
   EXPECT_THAT(extension_info.manufacturers,
               testing::UnorderedElementsAre("ASUS", "HP"));
-  EXPECT_EQ("*://www.google.com/*", extension_info.pwa_origin);
+  EXPECT_EQ("*://googlechromelabs.github.io/*", extension_info.pwa_origin);
 }
 
 TEST(ChromeOSSystemExtensionInfo, HPExtension) {
@@ -54,7 +54,8 @@
 
   const auto google_extension_info = chromeos::GetChromeOSExtensionInfoForId(
       "gogonhoemckpdpadfnjnpgbjpbjnodgc");
-  EXPECT_EQ("*://www.google.com/*", google_extension_info.pwa_origin);
+  EXPECT_EQ("*://googlechromelabs.github.io/*",
+            google_extension_info.pwa_origin);
   EXPECT_THAT(google_extension_info.manufacturers,
               testing::UnorderedElementsAre(kManufacturerOverride));
 
diff --git a/chrome/common/extensions/api/common_extension_api_unittest.cc b/chrome/common/extensions/api/common_extension_api_unittest.cc
index 4a6d573..e1bf4c5 100644
--- a/chrome/common/extensions/api/common_extension_api_unittest.cc
+++ b/chrome/common/extensions/api/common_extension_api_unittest.cc
@@ -840,17 +840,16 @@
   }
 }
 
-static const base::DictionaryValue* GetDictChecked(
-    const base::DictionaryValue* dict,
-    const std::string& key) {
-  const base::DictionaryValue* out = nullptr;
-  CHECK(dict->GetDictionary(key, &out)) << key;
+static const base::Value::Dict* GetDictChecked(const base::Value::Dict* dict,
+                                               const std::string& key) {
+  const base::Value::Dict* out = dict->FindDict(key);
+  CHECK(out) << key;
   return out;
 }
 
-static std::string GetStringChecked(const base::DictionaryValue* dict,
+static std::string GetStringChecked(const base::Value::Dict* dict,
                                     const std::string& key) {
-  const std::string* out = dict->FindStringKey(key);
+  const std::string* out = dict->FindString(key);
   CHECK(out) << key;
   return *out;
 }
@@ -860,59 +859,55 @@
       ExtensionAPI::CreateWithDefaultConfiguration());
 
   // Returns the dictionary that has |key|: |value|.
-  auto get_dict_from_list = [](
-      const base::ListValue* list, const std::string& key,
-      const std::string& value) -> const base::DictionaryValue* {
-    const base::DictionaryValue* ret = nullptr;
-    for (const auto& val : list->GetListDeprecated()) {
-      const base::DictionaryValue* dict = nullptr;
-      if (!val.GetAsDictionary(&dict))
+  auto get_dict_from_list =
+      [](const base::Value::List* list, const std::string& key,
+         const std::string& value) -> const base::Value::Dict* {
+    for (const auto& val : *list) {
+      const base::Value::Dict* dict = val.GetIfDict();
+      if (!dict)
         continue;
-      if (const std::string* str = dict->FindStringKey(key)) {
-        if (*str == value) {
-          ret = dict;
-          break;
-        }
+      if (const std::string* str = dict->FindString(key)) {
+        if (*str == value)
+          return dict;
       }
     }
-    return ret;
+    return nullptr;
   };
 
-  const base::DictionaryValue* schema = api->GetSchema("sessions");
+  const base::Value::Dict* schema = api->GetSchema("sessions");
   ASSERT_TRUE(schema);
 
-  const base::ListValue* types = nullptr;
-  ASSERT_TRUE(schema->GetList("types", &types));
+  const base::Value::List* types = schema->FindList("types");
+  ASSERT_TRUE(types);
   {
-    const base::DictionaryValue* session_type =
+    const base::Value::Dict* session_type =
         get_dict_from_list(types, "id", "sessions.Session");
     ASSERT_TRUE(session_type);
-    const base::DictionaryValue* props =
-        GetDictChecked(session_type, "properties");
-    const base::DictionaryValue* tab = GetDictChecked(props, "tab");
+    const base::Value::Dict* props = GetDictChecked(session_type, "properties");
+    const base::Value::Dict* tab = GetDictChecked(props, "tab");
     EXPECT_EQ("tabs.Tab", GetStringChecked(tab, "$ref"));
-    const base::DictionaryValue* window = GetDictChecked(props, "window");
+    const base::Value::Dict* window = GetDictChecked(props, "window");
     EXPECT_EQ("windows.Window", GetStringChecked(window, "$ref"));
   }
   {
-    const base::DictionaryValue* device_type =
+    const base::Value::Dict* device_type =
         get_dict_from_list(types, "id", "sessions.Device");
     ASSERT_TRUE(device_type);
-    const base::DictionaryValue* props =
-        GetDictChecked(device_type, "properties");
-    const base::DictionaryValue* sessions = GetDictChecked(props, "sessions");
-    const base::DictionaryValue* items = GetDictChecked(sessions, "items");
+    const base::Value::Dict* props = GetDictChecked(device_type, "properties");
+    const base::Value::Dict* sessions = GetDictChecked(props, "sessions");
+    const base::Value::Dict* items = GetDictChecked(sessions, "items");
     EXPECT_EQ("sessions.Session", GetStringChecked(items, "$ref"));
   }
-  const base::ListValue* functions = nullptr;
-  ASSERT_TRUE(schema->GetList("functions", &functions));
+  const base::Value::List* functions = schema->FindList("functions");
+  ASSERT_TRUE(functions);
   {
-    const base::DictionaryValue* get_recently_closed =
+    const base::Value::Dict* get_recently_closed =
         get_dict_from_list(functions, "name", "getRecentlyClosed");
     ASSERT_TRUE(get_recently_closed);
-    const base::ListValue* parameters = nullptr;
-    ASSERT_TRUE(get_recently_closed->GetList("parameters", &parameters));
-    const base::DictionaryValue* filter =
+    const base::Value::List* parameters =
+        get_recently_closed->FindList("parameters");
+    ASSERT_TRUE(parameters);
+    const base::Value::Dict* filter =
         get_dict_from_list(parameters, "name", "filter");
     ASSERT_TRUE(filter);
     EXPECT_EQ("sessions.Filter", GetStringChecked(filter, "$ref"));
@@ -920,9 +915,10 @@
 
   schema = api->GetSchema("types");
   ASSERT_TRUE(schema);
-  ASSERT_TRUE(schema->GetList("types", &types));
+  types = schema->FindList("types");
+  ASSERT_TRUE(types);
   {
-    const base::DictionaryValue* chrome_setting =
+    const base::Value::Dict* chrome_setting =
         get_dict_from_list(types, "id", "types.ChromeSetting");
     ASSERT_TRUE(chrome_setting);
     EXPECT_EQ("types.ChromeSetting",
@@ -1026,10 +1022,10 @@
   ASSERT_TRUE(t.Start());
 
   base::RunLoop run_loop;
-  const base::DictionaryValue* another_thread_schema = nullptr;
+  const base::Value::Dict* another_thread_schema = nullptr;
 
   auto result_cb =
-      base::BindLambdaForTesting([&](const base::DictionaryValue* res) {
+      base::BindLambdaForTesting([&](const base::Value::Dict* res) {
         another_thread_schema = res;
         run_loop.Quit();
       });
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index 5002241..4a4795e 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -1032,6 +1032,9 @@
   // The estimate time to finish the operation.
   double remainingSeconds;
 
+  // Whether notifications should be shown on progress status.
+  boolean showNotification;
+
   // The name of the last error that happened.
   DOMString errorName;
 
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc
index 3d58fbb..6ed50df 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller.cc
+++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -96,10 +96,10 @@
 void SetAXNodeDataHtmlTag(v8::Isolate* isolate,
                           gin::Dictionary* v8_dict,
                           ui::AXNodeData* ax_node_data) {
-  v8::Local<v8::Value> v8_url;
-  v8_dict->Get("htmlTag", &v8_url);
+  v8::Local<v8::Value> v8_html_tag;
+  v8_dict->Get("htmlTag", &v8_html_tag);
   std::string html_tag;
-  gin::Converter<std::string>::FromV8(isolate, v8_url, &html_tag);
+  gin::Converter<std::string>::FromV8(isolate, v8_html_tag, &html_tag);
   ax_node_data->AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag,
                                    html_tag);
 }
@@ -114,6 +114,41 @@
   ax_node_data->AddStringAttribute(ax::mojom::StringAttribute::kUrl, url);
 }
 
+void SetSelectionAnchorObjectId(v8::Isolate* isolate,
+                                gin::Dictionary* v8_dict,
+                                ui::AXTreeData* ax_tree_data) {
+  v8::Local<v8::Value> v8_anchor_object_id;
+  v8_dict->Get("anchor_object_id", &v8_anchor_object_id);
+  gin::ConvertFromV8(isolate, v8_anchor_object_id,
+                     &ax_tree_data->sel_anchor_object_id);
+}
+
+void SetSelectionFocusObjectId(v8::Isolate* isolate,
+                               gin::Dictionary* v8_dict,
+                               ui::AXTreeData* ax_tree_data) {
+  v8::Local<v8::Value> v8_focus_object_id;
+  v8_dict->Get("focus_object_id", &v8_focus_object_id);
+  gin::ConvertFromV8(isolate, v8_focus_object_id,
+                     &ax_tree_data->sel_focus_object_id);
+}
+
+void SetSelectionAnchorOffset(v8::Isolate* isolate,
+                              gin::Dictionary* v8_dict,
+                              ui::AXTreeData* ax_tree_data) {
+  v8::Local<v8::Value> v8_anchor_offset;
+  v8_dict->Get("anchor_offset", &v8_anchor_offset);
+  gin::ConvertFromV8(isolate, v8_anchor_offset,
+                     &ax_tree_data->sel_anchor_offset);
+}
+
+void SetSelectionFocusOffset(v8::Isolate* isolate,
+                             gin::Dictionary* v8_dict,
+                             ui::AXTreeData* ax_tree_data) {
+  v8::Local<v8::Value> v8_focus_offset;
+  v8_dict->Get("focus_offset", &v8_focus_offset);
+  gin::ConvertFromV8(isolate, v8_focus_offset, &ax_tree_data->sel_focus_offset);
+}
+
 void SetAXTreeUpdateRootId(v8::Isolate* isolate,
                            gin::Dictionary* v8_dict,
                            ui::AXTreeUpdate* snapshot) {
@@ -150,6 +185,20 @@
     SetAXNodeDataUrl(isolate, &v8_node_dict, &ax_node_data);
     snapshot.nodes.push_back(ax_node_data);
   }
+
+  v8::Local<v8::Value> v8_selection;
+  v8_snapshot_dict.Get("selection", &v8_selection);
+  gin::Dictionary v8_selection_dict(isolate);
+  if (!gin::ConvertFromV8(isolate, v8_selection, &v8_selection_dict))
+    return snapshot;
+  ui::AXTreeData ax_tree_data;
+  SetSelectionAnchorObjectId(isolate, &v8_selection_dict, &ax_tree_data);
+  SetSelectionFocusObjectId(isolate, &v8_selection_dict, &ax_tree_data);
+  SetSelectionAnchorOffset(isolate, &v8_selection_dict, &ax_tree_data);
+  SetSelectionFocusOffset(isolate, &v8_selection_dict, &ax_tree_data);
+  snapshot.has_tree_data = true;
+  snapshot.tree_data = ax_tree_data;
+
   return snapshot;
 }
 
@@ -205,6 +254,35 @@
   if (!tree_->Unserialize(snapshot))
     NOTREACHED() << tree_->error();
 
+  // Store state about the selection for easy access later.
+  selection_ = tree_->GetUnignoredSelection();
+  has_selection_ = selection_.anchor_object_id != ui::kInvalidAXNodeID &&
+                   selection_.focus_object_id != ui::kInvalidAXNodeID;
+  if (has_selection_) {
+    ui::AXNode* anchor_node = GetAXNode(selection_.anchor_object_id);
+    ui::AXNode* focus_node = GetAXNode(selection_.focus_object_id);
+    start_node_ = selection_.is_backward ? focus_node : anchor_node;
+    end_node_ = selection_.is_backward ? anchor_node : focus_node;
+    start_offset_ = selection_.is_backward ? selection_.focus_offset
+                                           : selection_.anchor_offset;
+    end_offset_ = selection_.is_backward ? selection_.anchor_offset
+                                         : selection_.focus_offset;
+
+    // Store the lowest common ancestor between the start and end nodes as
+    // the selection node ID. This is the lowest node in the tree which entirely
+    // contains the selection.
+    ui::AXNode* common_ancestor =
+        start_node_->GetLowestCommonAncestor(*end_node_);
+    selection_node_ids_.push_back(common_ancestor->id());
+  } else {
+    // Reset selection-related state to default values.
+    selection_node_ids_.clear();
+    start_node_ = nullptr;
+    end_node_ = nullptr;
+    start_offset_ = -1;
+    end_offset_ = -1;
+  }
+
   // TODO(abigailbklein): Use v8::Function rather than javascript. If possible,
   // replace this function call with firing an event.
   std::string script = "chrome.readAnything.updateContent();";
@@ -227,7 +305,7 @@
     v8::Isolate* isolate) {
   return gin::Wrappable<ReadAnythingAppController>::GetObjectTemplateBuilder(
              isolate)
-      .SetProperty("contentNodeIds", &ReadAnythingAppController::ContentNodeIds)
+      .SetProperty("displayNodeIds", &ReadAnythingAppController::DisplayNodeIds)
       .SetProperty("fontName", &ReadAnythingAppController::FontName)
       .SetProperty("fontSize", &ReadAnythingAppController::FontSize)
       .SetProperty("foregroundColor",
@@ -246,7 +324,9 @@
                  &ReadAnythingAppController::SetThemeForTesting);
 }
 
-std::vector<ui::AXNodeID> ReadAnythingAppController::ContentNodeIds() {
+std::vector<ui::AXNodeID> ReadAnythingAppController::DisplayNodeIds() {
+  if (has_selection_)
+    return selection_node_ids_;
   return content_node_ids_;
 }
 
@@ -274,7 +354,11 @@
     return std::vector<ui::AXNodeID>();
   for (auto it = ax_node->UnignoredChildrenBegin();
        it != ax_node->UnignoredChildrenEnd(); ++it) {
-    child_ids.push_back(it->id());
+    // If there is no selection, always add the node ID to the list. If there
+    // is a selection and the node is partially or entirely contained in the
+    // selection, also add the node ID to the list.
+    if (!has_selection_ || SelectionContainsNode(&*it))
+      child_ids.push_back(it->id());
   }
   return child_ids;
 }
@@ -297,7 +381,16 @@
   ui::AXNode* ax_node = GetAXNode(ax_node_id);
   if (!ax_node)
     return std::string();
-  return ax_node->GetTextContentUTF8();
+  std::string text_content = ax_node->GetTextContentUTF8();
+  // If this node is the start or end node, truncate the text content by the
+  // corresponding offset.
+  if (has_selection_) {
+    if (ax_node == start_node_)
+      text_content.erase(0, start_offset_);
+    if (ax_node == end_node_)
+      text_content.resize(end_offset_);
+  }
+  return text_content;
 }
 
 std::string ReadAnythingAppController::GetUrl(ui::AXNodeID ax_node_id) {
@@ -340,3 +433,11 @@
     return nullptr;
   return tree_->GetFromId(ax_node_id);
 }
+
+bool ReadAnythingAppController::SelectionContainsNode(ui::AXNode* ax_node) {
+  DCHECK(has_selection_);
+  return (start_node_->IsDescendantOf(ax_node) ||
+          end_node_->IsDescendantOf(ax_node) ||
+          (ax_node->CompareTo(*start_node_) > 0 &&
+           ax_node->CompareTo(*end_node_) < 0));
+}
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything_app_controller.h
index 7eacf36..1fda363 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller.h
+++ b/chrome/renderer/accessibility/read_anything_app_controller.h
@@ -15,6 +15,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/accessibility/ax_node_id_forward.h"
+#include "ui/accessibility/ax_selection.h"
 #include "ui/accessibility/ax_tree_update_forward.h"
 
 namespace content {
@@ -71,7 +72,7 @@
       read_anything::mojom::ReadAnythingThemePtr new_theme) override;
 
   // gin templates:
-  std::vector<ui::AXNodeID> ContentNodeIds();
+  std::vector<ui::AXNodeID> DisplayNodeIds();
   std::string FontName();
   float FontSize();
   SkColor ForegroundColor();
@@ -109,6 +110,12 @@
 
   ui::AXNode* GetAXNode(ui::AXNodeID ax_node_id);
 
+  // Returns whether the node is part of the selection. Returns true for partial
+  // containment as well; it also returns true if part of the node is part of
+  // the selection (e.g. a node in which some children are part of the selection
+  // and others are not).
+  bool SelectionContainsNode(ui::AXNode* ax_node);
+
   content::RenderFrame* render_frame_;
   mojo::Remote<read_anything::mojom::PageHandlerFactory> page_handler_factory_;
   mojo::Remote<read_anything::mojom::PageHandler> page_handler_;
@@ -117,6 +124,13 @@
   // State
   std::unique_ptr<ui::AXTree> tree_;
   std::vector<ui::AXNodeID> content_node_ids_;
+  std::vector<ui::AXNodeID> selection_node_ids_;
+  ui::AXSelection selection_;
+  bool has_selection_ = false;
+  ui::AXNode* start_node_ = nullptr;
+  ui::AXNode* end_node_ = nullptr;
+  int32_t start_offset_ = -1;
+  int32_t end_offset_ = -1;
   std::string font_name_;
   float font_size_;
   SkColor foreground_color_;
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
index 2b9ecfb..5cd1746 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
+++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -32,6 +32,12 @@
     basic_snapshot_.nodes[1].id = 2;
     basic_snapshot_.nodes[2].id = 3;
     basic_snapshot_.nodes[3].id = 4;
+
+    // Create simple AXTreeData with selection.
+    basic_tree_data_with_selection_.sel_anchor_object_id = 2;
+    basic_tree_data_with_selection_.sel_focus_object_id = 3;
+    basic_tree_data_with_selection_.sel_anchor_offset = 0;
+    basic_tree_data_with_selection_.sel_focus_offset = 0;
   }
 
   void SetThemeForTesting(const std::string& font_name,
@@ -46,8 +52,8 @@
     controller_->OnAXTreeDistilled(snapshot, content_node_ids);
   }
 
-  std::vector<ui::AXNodeID> ContentNodeIds() {
-    return controller_->ContentNodeIds();
+  std::vector<ui::AXNodeID> DisplayNodeIds() {
+    return controller_->DisplayNodeIds();
   }
 
   std::string FontName() { return controller_->FontName(); }
@@ -74,7 +80,13 @@
     return controller_->GetUrl(ax_node_id);
   }
 
+  bool SelectionContainsNode(ui::AXNodeID ax_node_id) {
+    ui::AXNode* ax_node = controller_->GetAXNode(ax_node_id);
+    return controller_->SelectionContainsNode(ax_node);
+  }
+
   ui::AXTreeUpdate basic_snapshot_;
+  ui::AXTreeData basic_tree_data_with_selection_;
 
  private:
   // ReadAnythingAppController constructor and destructor are private so it's
@@ -94,16 +106,34 @@
   EXPECT_EQ(background, BackgroundColor());
 }
 
-TEST_F(ReadAnythingAppControllerTest, ContentNodeIds) {
+TEST_F(ReadAnythingAppControllerTest, DisplayNodeIds_NoSelection) {
   std::vector<ui::AXNodeID> content_node_ids = {2, 4};
   OnAXTreeDistilled(basic_snapshot_, content_node_ids);
-  EXPECT_EQ(content_node_ids.size(), ContentNodeIds().size());
+  EXPECT_EQ(content_node_ids.size(), DisplayNodeIds().size());
   for (size_t i = 0; i < content_node_ids.size(); i++) {
-    EXPECT_EQ(content_node_ids[i], ContentNodeIds()[i]);
+    EXPECT_EQ(content_node_ids[i], DisplayNodeIds()[i]);
   }
 }
 
-TEST_F(ReadAnythingAppControllerTest, GetChildren) {
+TEST_F(ReadAnythingAppControllerTest,
+       DisplayNodeIds_WithSelectionAndContentNodeIds) {
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {2, 4});
+  EXPECT_EQ(1u, DisplayNodeIds().size());
+  EXPECT_EQ(basic_snapshot_.root_id, DisplayNodeIds()[0]);
+}
+
+TEST_F(ReadAnythingAppControllerTest,
+       DisplayNodeIds_WithSelectionButNoContentNodeIds) {
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ(1u, DisplayNodeIds().size());
+  EXPECT_EQ(basic_snapshot_.root_id, DisplayNodeIds()[0]);
+}
+
+TEST_F(ReadAnythingAppControllerTest, GetChildren_NoSelection) {
   basic_snapshot_.nodes[2].role = ax::mojom::Role::kNone;
   OnAXTreeDistilled(basic_snapshot_, {});
   EXPECT_EQ(2u, GetChildren(1).size());
@@ -115,6 +145,39 @@
   EXPECT_EQ(4, GetChildren(1)[1]);
 }
 
+TEST_F(ReadAnythingAppControllerTest, GetChildren_WithSelection) {
+  // Create selection from node 3-4.
+  basic_tree_data_with_selection_.sel_anchor_object_id = 3;
+  basic_tree_data_with_selection_.sel_focus_object_id = 4;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ(2u, GetChildren(1).size());
+  EXPECT_EQ(0u, GetChildren(2).size());
+  EXPECT_EQ(0u, GetChildren(3).size());
+  EXPECT_EQ(0u, GetChildren(4).size());
+
+  EXPECT_EQ(3, GetChildren(1)[0]);
+  EXPECT_EQ(4, GetChildren(1)[1]);
+}
+
+TEST_F(ReadAnythingAppControllerTest, GetChildren_WithBackwardSelection) {
+  // Create backward selection from node 4-3.
+  basic_tree_data_with_selection_.sel_is_backward = true;
+  basic_tree_data_with_selection_.sel_anchor_object_id = 4;
+  basic_tree_data_with_selection_.sel_focus_object_id = 3;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ(2u, GetChildren(1).size());
+  EXPECT_EQ(0u, GetChildren(2).size());
+  EXPECT_EQ(0u, GetChildren(3).size());
+  EXPECT_EQ(0u, GetChildren(4).size());
+
+  EXPECT_EQ(3, GetChildren(1)[0]);
+  EXPECT_EQ(4, GetChildren(1)[1]);
+}
+
 TEST_F(ReadAnythingAppControllerTest, GetHtmlTag) {
   std::string span = "span";
   std::string h1 = "h1";
@@ -131,7 +194,7 @@
   EXPECT_EQ(ul, GetHtmlTag(4));
 }
 
-TEST_F(ReadAnythingAppControllerTest, GetTextContent) {
+TEST_F(ReadAnythingAppControllerTest, GetTextContent_NoSelection) {
   std::string text_content = "Hello";
   std::string missing_text_content = "";
   std::string more_text_content = " world";
@@ -151,6 +214,88 @@
   EXPECT_EQ(more_text_content, GetTextContent(4));
 }
 
+TEST_F(ReadAnythingAppControllerTest, GetTextContent_With2NodeSelection) {
+  std::string text_content_1 = "Hello";
+  std::string text_content_2 = " world";
+  std::string text_content_3 = " friend";
+  basic_snapshot_.nodes[1].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[1].SetName(text_content_1);
+  basic_snapshot_.nodes[1].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[2].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[2].SetName(text_content_2);
+  basic_snapshot_.nodes[2].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[3].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[3].SetName(text_content_3);
+  basic_snapshot_.nodes[3].SetNameFrom(ax::mojom::NameFrom::kContents);
+  // Create selection from node 2-3.
+  basic_tree_data_with_selection_.sel_anchor_object_id = 2;
+  basic_tree_data_with_selection_.sel_focus_object_id = 3;
+  basic_tree_data_with_selection_.sel_anchor_offset = 1;
+  basic_tree_data_with_selection_.sel_focus_offset = 3;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ("Hello world friend", GetTextContent(1));
+  EXPECT_EQ("ello", GetTextContent(2));
+  EXPECT_EQ(" wo", GetTextContent(3));
+  EXPECT_EQ(" friend", GetTextContent(4));
+}
+
+TEST_F(ReadAnythingAppControllerTest, GetTextContent_With3NodeSelection) {
+  std::string text_content_1 = "Hello";
+  std::string text_content_2 = " world";
+  std::string text_content_3 = " friend";
+  basic_snapshot_.nodes[1].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[1].SetName(text_content_1);
+  basic_snapshot_.nodes[1].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[2].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[2].SetName(text_content_2);
+  basic_snapshot_.nodes[2].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[3].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[3].SetName(text_content_3);
+  basic_snapshot_.nodes[3].SetNameFrom(ax::mojom::NameFrom::kContents);
+  // Create selection from node 2-4.
+  basic_tree_data_with_selection_.sel_anchor_object_id = 2;
+  basic_tree_data_with_selection_.sel_focus_object_id = 4;
+  basic_tree_data_with_selection_.sel_anchor_offset = 1;
+  basic_tree_data_with_selection_.sel_focus_offset = 3;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ("Hello world friend", GetTextContent(1));
+  EXPECT_EQ("ello", GetTextContent(2));
+  EXPECT_EQ(" world", GetTextContent(3));
+  EXPECT_EQ(" fr", GetTextContent(4));
+}
+
+TEST_F(ReadAnythingAppControllerTest, GetTextContent_WithBackwardSelection) {
+  std::string text_content_1 = "Hello";
+  std::string text_content_2 = " world";
+  std::string text_content_3 = " friend";
+  basic_snapshot_.nodes[1].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[1].SetName(text_content_1);
+  basic_snapshot_.nodes[1].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[2].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[2].SetName(text_content_2);
+  basic_snapshot_.nodes[2].SetNameFrom(ax::mojom::NameFrom::kContents);
+  basic_snapshot_.nodes[3].role = ax::mojom::Role::kStaticText;
+  basic_snapshot_.nodes[3].SetName(text_content_3);
+  basic_snapshot_.nodes[3].SetNameFrom(ax::mojom::NameFrom::kContents);
+  // Create backward selection from node 4-3.
+  basic_tree_data_with_selection_.sel_is_backward = true;
+  basic_tree_data_with_selection_.sel_anchor_object_id = 4;
+  basic_tree_data_with_selection_.sel_focus_object_id = 3;
+  basic_tree_data_with_selection_.sel_anchor_offset = 5;
+  basic_tree_data_with_selection_.sel_focus_offset = 2;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_EQ("Hello world friend", GetTextContent(1));
+  EXPECT_EQ("Hello", GetTextContent(2));
+  EXPECT_EQ("orld", GetTextContent(3));
+  EXPECT_EQ(" frie", GetTextContent(4));
+}
+
 TEST_F(ReadAnythingAppControllerTest, GetUrl) {
   std::string url = "http://www.google.com";
   std::string invalid_url = "cats";
@@ -166,3 +311,26 @@
   EXPECT_EQ(invalid_url, GetUrl(3));
   EXPECT_EQ(missing_url, GetUrl(4));
 }
+
+TEST_F(ReadAnythingAppControllerTest, SelectionContainsNode) {
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_TRUE(SelectionContainsNode(1));
+  EXPECT_TRUE(SelectionContainsNode(2));
+  EXPECT_TRUE(SelectionContainsNode(3));
+  EXPECT_FALSE(SelectionContainsNode(4));
+}
+
+TEST_F(ReadAnythingAppControllerTest, SelectionContainsNode_BackwardSelection) {
+  basic_tree_data_with_selection_.sel_is_backward = true;
+  basic_tree_data_with_selection_.sel_anchor_object_id = 3;
+  basic_tree_data_with_selection_.sel_focus_object_id = 2;
+  basic_snapshot_.has_tree_data = true;
+  basic_snapshot_.tree_data = basic_tree_data_with_selection_;
+  OnAXTreeDistilled(basic_snapshot_, {});
+  EXPECT_TRUE(SelectionContainsNode(1));
+  EXPECT_TRUE(SelectionContainsNode(2));
+  EXPECT_TRUE(SelectionContainsNode(3));
+  EXPECT_FALSE(SelectionContainsNode(4));
+}
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index a7ffa18..0a325eaa 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1472,7 +1472,7 @@
 
 #if BUILDFLAG(ENABLE_NACL)
   // Don't isolate the NaCl plugin (preserving legacy behavior).
-  if (plugin_path.value() == ChromeContentClient::kNaClPluginFileName)
+  if (plugin_path.value() == nacl::kInternalNaClPluginFileName)
     return false;
 #endif
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9024f09..1273665 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2436,6 +2436,7 @@
       deps += [
         ":pdf_extension_test_utils",
         "//components/pdf/browser",
+        "//components/pdf/common",
         "//pdf:features",
         "//pdf/loader",
       ]
@@ -2745,7 +2746,7 @@
 
     if (enable_plugins) {
       sources += [
-        "../browser/chrome_plugin_browsertest.cc",
+        "../browser/plugins/plugin_info_host_impl_browsertest.cc",
         "../browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc",
       ]
     }
@@ -3098,6 +3099,7 @@
 
         deps += [
           "//chrome/browser/enterprise/connectors/device_trust:features",
+          "//chrome/browser/enterprise/connectors/device_trust:prefs",
           "//chrome/browser/enterprise/connectors/device_trust/common",
           "//chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands:test_support",
           "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
@@ -4503,6 +4505,10 @@
         "chrome/test/data/perf/frame_rate/content/googleblog/images/bse%e2%80%99s+solar+energy+development+center..jpg",
       ]
 
+      if (enable_library_cdms) {
+        excluded_files += [ "lib.unstripped/libclearkeycdm.so" ]
+      }
+
       # Tests depend on having a Python interpreter present on-device.
       # TODO(crbug.com/1292144): Determine whether a solution can be devised
       # for Fuchsia.
@@ -4703,6 +4709,7 @@
       "../browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc",
       "../browser/extensions/api/preference/preference_api_lacros_browsertest.cc",
       "../browser/extensions/api/vpn_provider/vpn_provider_apitest.cc",
+      "../browser/lacros/browser_launcher_browsertest.cc",
       "../browser/lacros/browser_service_lacros_browsertest.cc",
       "../browser/lacros/cert/cert_db_initializer_browsertest.cc",
       "../browser/lacros/clipboard_lacros_browsertest.cc",
@@ -7114,6 +7121,7 @@
       "../browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc",
       "../browser/apps/app_service/publishers/arc_apps_unittest.cc",
       "../browser/apps/app_service/publishers/crostini_apps_unittest.cc",
+      "../browser/apps/app_service/publishers/plugin_vm_apps_unittest.cc",
       "../browser/apps/app_service/webapk/webapk_install_task_unittest.cc",
       "../browser/apps/app_service/webapk/webapk_manager_unittest.cc",
       "../browser/ash/attestation/attestation_policy_unittest.cc",
@@ -8325,6 +8333,7 @@
 
     deps += [
       "../browser/enterprise/connectors/device_trust:features",
+      "../browser/enterprise/connectors/device_trust:prefs",
       "../browser/enterprise/connectors/device_trust/key_management/browser:test_support",
     ]
   }
@@ -8340,6 +8349,7 @@
 
     deps += [
       "../browser/enterprise/connectors/device_trust:features",
+      "../browser/enterprise/connectors/device_trust:prefs",
       "../browser/enterprise/connectors/device_trust:test_support",
       "../browser/enterprise/connectors/device_trust/attestation/common",
       "../browser/enterprise/connectors/device_trust/attestation/common:test_support",
@@ -10325,6 +10335,10 @@
         "//media/cdm/library_cdm/clear_key_cdm",
         "//third_party/widevine/cdm",
       ]
+
+      if (is_fuchsia) {
+        excluded_files = [ "lib.unstripped/libclearkeycdm.so" ]
+      }
     }
 
     # This target should not require the Chrome executable to run.
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index 6244da4..8c24cdf 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -7,6 +7,7 @@
   "+chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java",
   "+chrome/grit",
   "+chromeos",
+  "+components/account_id",
   "+components/account_manager_core",
   "+components/autofill/content",
   "+components/autofill/core",
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index 50b5bfa..c8d98cf2 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -29,6 +29,8 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/profiles/profile_helper.h"
+#include "components/account_id/account_id.h"
+#include "components/user_manager/fake_user_manager.h"
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -96,8 +98,8 @@
             : profile_name;
     profile_path =
         profile_path.Append(ash::ProfileHelper::Get()->GetUserProfileDir(
-            ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
-                AccountId::FromUserEmail(fake_email).GetUserEmail())));
+            user_manager::FakeUserManager::GetFakeUsernameHash(
+                AccountId::FromUserEmail(fake_email))));
   } else {
     profile_path = profile_path.AppendASCII(profile_name);
   }
diff --git a/chrome/test/data/extensions/api_test/wm_desks_private/background.js b/chrome/test/data/extensions/api_test/wm_desks_private/background.js
index ea31ce0..7490267 100644
--- a/chrome/test/data/extensions/api_test/wm_desks_private/background.js
+++ b/chrome/test/data/extensions/api_test/wm_desks_private/background.js
@@ -1,10 +1,15 @@
 // 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.
-var templateUuid;
 
 // Basic browser tests for the wmDesksPrivate API.
 chrome.test.runTests([
+  function testGetDeskTemplateJson() {
+    chrome.wmDesksPrivate.getDeskTemplateJson(
+        // Get desk template JSON with an invalid UUID.
+        'invalid-uuid', chrome.test.callbackFail('Invalid template UUID.'));
+  },
+
   // Test launch empty desk with a desk name.
   function testLaunchEmptyDeskWithName() {
     // Launch empty desk with `deskName`
@@ -55,5 +60,5 @@
     chrome.wmDesksPrivate.setWindowProperties(1234, { allDesks: false },
       // Launch desk fail with invalid templateUuid
       chrome.test.callbackFail("The window cannot be found."));
-    }
+  }
 ]);
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
index 7a3c363..7c75263 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
@@ -16,7 +16,7 @@
     "chromeos_system_extension": {},
     "externally_connectable": {
       "matches": [
-        "*://www.google.com/*"
+        "*://googlechromelabs.github.io/*"
       ]
     },
     "options_page": "options.html"
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index e7ba4cc..bc8cb3dc 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -237,7 +237,6 @@
         "chromeos/print_management/print_management_browsertest.js",
         "chromeos/scanning/scanning_app_browsertest.js",
         "chromeos/shimless_rma/shimless_rma_browsertest.js",
-        "chromeos/shortcut_customization/shortcut_customization_browsertest.js",
         "nearby_share/nearby_browsertest.js",
         "nearby_share/shared/nearby_shared_v3_browsertest.js",
       ]
@@ -267,6 +266,7 @@
         "chromeos/parent_access/parent_access_browsertest.js",
         "chromeos/personalization_app/personalization_app_component_browsertest.js",
         "chromeos/personalization_app/personalization_app_controller_browsertest.js",
+        "chromeos/shortcut_customization/shortcut_customization_browsertest.js",
       ]
     }
     if (is_win || is_mac || is_linux || is_fuchsia) {
@@ -580,12 +580,14 @@
       "chromeos/cloud_upload:build_grdp",
       "chromeos/manage_mirrorsync:build_grdp",
       "chromeos/personalization_app:build_grdp",
+      "chromeos/shortcut_customization:build_grdp",
       "//ui/file_manager:build_tests_gen_grdp",
       "//ui/file_manager:build_tests_grdp",
     ]
     grdp_files += [
       "$target_gen_dir/chromeos/cloud_upload/resources.grdp",
       "$target_gen_dir/chromeos/personalization_app/resources.grdp",
+      "$target_gen_dir/chromeos/shortcut_customization/resources.grdp",
       "$target_gen_dir/chromeos/manage_mirrorsync/resources.grdp",
       "$root_gen_dir/ui/file_manager/tests_resources.grdp",
       "$root_gen_dir/ui/file_manager/tests_gen_resources.grdp",
diff --git a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn
index 1172eca9..24cadc8 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn
@@ -159,8 +159,9 @@
     "//ash/webui/diagnostics_ui/resources:routine_result_entry",
     "//ash/webui/diagnostics_ui/resources:routine_result_list",
     "//ash/webui/diagnostics_ui/resources:routine_section",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("diagnostics_utils_test") {
@@ -261,8 +262,9 @@
     "//ash/webui/diagnostics_ui/resources:fake_data",
     "//ash/webui/diagnostics_ui/resources:fake_system_data_provider",
     "//ash/webui/diagnostics_ui/resources:memory_card",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("mojo_interface_provider_test") {
@@ -406,8 +408,9 @@
     "//ash/webui/diagnostics_ui/resources:routine_section",
     "//ash/webui/diagnostics_ui/resources:text_badge",
     "//third_party/polymer/v3_0/components-chromium/iron-collapse:iron-collapse",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("system_page_test") {
diff --git a/chrome/test/data/webui/chromeos/diagnostics/battery_status_card_test.js b/chrome/test/data/webui/chromeos/diagnostics/battery_status_card_test.js
index 2b6e645f..27b0013e 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/battery_status_card_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/battery_status_card_test.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://diagnostics/battery_status_card.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {BatteryChargeStatus, BatteryHealth, BatteryInfo, ExternalPowerSource, RoutineType} from 'chrome://diagnostics/diagnostics_types.js';
 import {getDiagnosticsIcon} from 'chrome://diagnostics/diagnostics_utils.js';
@@ -10,7 +11,6 @@
 import {FakeSystemDataProvider} from 'chrome://diagnostics/fake_system_data_provider.js';
 import {getSystemDataProvider, setSystemDataProviderForTesting} from 'chrome://diagnostics/mojo_interface_provider.js';
 import {mojoString16ToString} from 'chrome://diagnostics/mojo_utils.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
index e3ee736..da44a71 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://diagnostics/diagnostics_app.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {DiagnosticsBrowserProxyImpl} from 'chrome://diagnostics/diagnostics_browser_proxy.js';
 import {BatteryChargeStatus, BatteryHealth, BatteryInfo, CpuUsage, KeyboardInfo, MemoryUsage, SystemInfo} from 'chrome://diagnostics/diagnostics_types.js';
@@ -12,7 +13,6 @@
 import {FakeSystemDataProvider} from 'chrome://diagnostics/fake_system_data_provider.js';
 import {FakeSystemRoutineController} from 'chrome://diagnostics/fake_system_routine_controller.js';
 import {setInputDataProviderForTesting, setNetworkHealthProviderForTesting, setSystemDataProviderForTesting, setSystemRoutineControllerForTesting} from 'chrome://diagnostics/mojo_interface_provider.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test_utils.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test_utils.js
index 2396007fb..5c57fd0 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test_utils.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test_utils.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {assertEquals, assertTrue} from '../../chai_assert.js';
 import {isVisible} from '../../test_util.js';
diff --git a/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js b/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js
index e26046c..b0685172 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js
@@ -3,13 +3,13 @@
 // found in the LICENSE file.
 
 import 'chrome://diagnostics/memory_card.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {MemoryUsage} from 'chrome://diagnostics/diagnostics_types.js';
 import {convertKibToGibDecimalString} from 'chrome://diagnostics/diagnostics_utils.js';
 import {fakeMemoryUsage, fakeMemoryUsageLowAvailableMemory} from 'chrome://diagnostics/fake_data.js';
 import {FakeSystemDataProvider} from 'chrome://diagnostics/fake_system_data_provider.js';
 import {setSystemDataProviderForTesting} from 'chrome://diagnostics/mojo_interface_provider.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
index 0abe3d6..3ff14f32 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://diagnostics/routine_section.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {RoutineType, StandardRoutineResult} from 'chrome://diagnostics/diagnostics_types.js';
 import {createRoutine} from 'chrome://diagnostics/diagnostics_utils.js';
@@ -13,7 +14,6 @@
 import {ExecutionProgress, TestSuiteStatus} from 'chrome://diagnostics/routine_list_executor.js';
 import {getRoutineType} from 'chrome://diagnostics/routine_result_entry.js';
 import {BadgeType} from 'chrome://diagnostics/text_badge.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
index e14eeb7..5fb2c930 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://diagnostics/system_page.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {DiagnosticsBrowserProxyImpl} from 'chrome://diagnostics/diagnostics_browser_proxy.js';
 import {BatteryChargeStatus, BatteryHealth, BatteryInfo, CpuUsage, MemoryUsage, NavigationView, RoutineType, StandardRoutineResult, SystemInfo} from 'chrome://diagnostics/diagnostics_types.js';
@@ -12,7 +13,6 @@
 import {FakeSystemRoutineController} from 'chrome://diagnostics/fake_system_routine_controller.js';
 import {setNetworkHealthProviderForTesting, setSystemDataProviderForTesting, setSystemRoutineControllerForTesting} from 'chrome://diagnostics/mojo_interface_provider.js';
 import {TestSuiteStatus} from 'chrome://diagnostics/routine_list_executor.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn b/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn
index e540843..e636a0c 100644
--- a/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn
@@ -50,10 +50,12 @@
     "//ash/webui/firmware_update_ui/resources:firmware_update_dialog",
     "//ash/webui/firmware_update_ui/resources:firmware_update_types",
     "//ash/webui/firmware_update_ui/resources:mojo_utils",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("firmware_update_test") {
@@ -69,11 +71,13 @@
     "//ash/webui/firmware_update_ui/resources:mojo_interface_provider",
     "//ash/webui/firmware_update_ui/resources:mojo_utils",
     "//ash/webui/firmware_update_ui/resources:update_card",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("peripheral_updates_list_test") {
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
index f82369c..904688a7 100644
--- a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
+++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+
 import {fakeFirmwareUpdates} from 'chrome://accessory-update/fake_data.js';
 import {FakeUpdateController} from 'chrome://accessory-update/fake_update_controller.js';
 import {FakeUpdateProvider} from 'chrome://accessory-update/fake_update_provider.js';
@@ -10,8 +13,6 @@
 import {getUpdateProvider, setUpdateControllerForTesting, setUpdateProviderForTesting} from 'chrome://accessory-update/mojo_interface_provider.js';
 import {mojoString16ToString} from 'chrome://accessory-update/mojo_utils.js';
 import {UpdateCardElement} from 'chrome://accessory-update/update_card.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/chromeos/gaia_action_buttons/gaia_action_buttons_test.js b/chrome/test/data/webui/chromeos/gaia_action_buttons/gaia_action_buttons_test.js
index fa0df87..e5d396e 100644
--- a/chrome/test/data/webui/chromeos/gaia_action_buttons/gaia_action_buttons_test.js
+++ b/chrome/test/data/webui/chromeos/gaia_action_buttons/gaia_action_buttons_test.js
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+
 import {GaiaActionButtonsElement} from 'chrome://chrome-signin/gaia_action_buttons/gaia_action_buttons.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js
index f540dd7..87c6b05 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {fakeFeedbackContext, fakePngData, fakeSearchResponse} from 'chrome://os-feedback/fake_data.js';
+import {fakeFeedbackContext, fakeInternalUserFeedbackContext, fakePngData, fakeSearchResponse} from 'chrome://os-feedback/fake_data.js';
 import {FakeFeedbackServiceProvider} from 'chrome://os-feedback/fake_feedback_service_provider.js';
 import {FakeHelpContentProvider} from 'chrome://os-feedback/fake_help_content_provider.js';
 import {AdditionalContextQueryParam, FeedbackFlowElement, FeedbackFlowState} from 'chrome://os-feedback/feedback_flow.js';
@@ -13,7 +13,7 @@
 import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
-import {eventToPromise, flushTasks} from '../../test_util.js';
+import {eventToPromise, flushTasks, isVisible} from '../../test_util.js';
 
 export function FeedbackFlowTestSuite() {
   /** @type {?FeedbackFlowElement} */
@@ -309,6 +309,74 @@
     assertEquals(SendReportStatus.kSuccess, activePage.sendReportStatus);
   });
 
+  // Test the bluetooth logs will show up if logged with internal account and
+  // input description is related.
+  test('ShowBluetoothLogsWithRelatedDescription', async () => {
+    feedbackServiceProvider = new FakeFeedbackServiceProvider();
+    feedbackServiceProvider.setFakeFeedbackContext(
+        fakeInternalUserFeedbackContext);
+    setFeedbackServiceProviderForTesting(feedbackServiceProvider);
+    await initializePage();
+
+    // Check the bluetooth checkbox component hidden when input is not related
+    // to bluetooth.
+    let activePage = page.shadowRoot.querySelector('.iron-selected');
+    assertTrue(!!activePage);
+    assertEquals('searchPage', activePage.id);
+
+    activePage.shadowRoot.querySelector('textarea').value = 'abc';
+    activePage.shadowRoot.querySelector('#buttonContinue').click();
+    await flushTasks();
+
+    activePage = page.shadowRoot.querySelector('.iron-selected');
+    assertEquals('shareDataPage', activePage.id);
+    const bluetoothCheckbox =
+        activePage.shadowRoot.querySelector('#bluetoothCheckboxContainer');
+    assertTrue(!!bluetoothCheckbox);
+    assertFalse(isVisible(bluetoothCheckbox));
+
+    activePage.shadowRoot.querySelector('#buttonBack').click();
+    await flushTasks();
+
+    // Go back to search page and set description input related to bluetooth.
+    activePage = page.shadowRoot.querySelector('.iron-selected');
+    assertTrue(!!activePage);
+    assertEquals('searchPage', activePage.id);
+
+    const descriptionElement = activePage.shadowRoot.querySelector('textarea');
+    descriptionElement.value = 'bluetooth';
+
+    activePage.shadowRoot.querySelector('#buttonContinue').click();
+    await flushTasks();
+
+    activePage = page.shadowRoot.querySelector('.iron-selected');
+    assertTrue(!!activePage);
+    assertEquals('shareDataPage', activePage.id);
+
+    assertTrue(!!bluetoothCheckbox);
+    assertTrue(isVisible(bluetoothCheckbox));
+  });
+
+  // Test the bluetooth logs will not show up if not logged with an Internal
+  // google account.
+  test('BluetoothHiddenWithoutInternalAccount', async () => {
+    await initializePage();
+
+    // Set input description related to bluetooth.
+    let activePage = page.shadowRoot.querySelector('.iron-selected');
+
+    activePage.shadowRoot.querySelector('textarea').value = 'bluetooth';
+    activePage.shadowRoot.querySelector('#buttonContinue').click();
+    await flushTasks();
+
+    activePage = page.shadowRoot.querySelector('.iron-selected');
+    assertEquals('shareDataPage', activePage.id);
+    const bluetoothCheckbox =
+        activePage.shadowRoot.querySelector('#bluetoothCheckboxContainer');
+    assertTrue(!!bluetoothCheckbox);
+    assertFalse(isVisible(bluetoothCheckbox));
+  });
+
   // Test the navigation from confirmation page to search page after the
   // send new report button is clicked.
   test('NavigateFromConfirmationPageToSearchPage', async () => {
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
index 0806376..eaa17391 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
@@ -646,31 +646,6 @@
   });
 
   /**
-   * Test that when not logged as internal google account, the bluetooth
-   * checkbox container is hidden, and sendBluetoothLogs flag is set false.
-   */
-  test('bluetoothCheckboxHiddenWithoutInternalAccount', async () => {
-    await initializePage();
-    page.feedbackContext = fakeFeedbackContext;
-
-    await flushTasks();
-    // Verify the bluetooth checkbox is hidden.
-    assertFalse(isVisible(getElement('#bluetoothCheckboxContainer')));
-
-    // Check the bluetooth checkbox.
-    const bluetoothCheckbox = getElement('#bluetoothLogsCheckbox');
-    assertTrue(!!bluetoothCheckbox);
-    bluetoothCheckbox.checked = true;
-
-    // Send report with the checkbox checked somehow, but without an internal
-    // account. The report should not have sendBluetoothLogs flag.
-    const request = (await clickSendAndWait(page)).report;
-
-    assertFalse(request.sendBluetoothLogs);
-    assertFalse(!!request.feedbackContext.categoryTag);
-  });
-
-  /**
    * Test that sendBluetoothLogs flag is true and categoryTag is marked as
    * 'BluetoothReportWithLogs' when bluetooth logs checkbox is checked.
    */
@@ -683,7 +658,7 @@
     // checkbox container should be visible.
     assertEquals(
         getElement('#userEmailDropDown').value, 'test.user@google.com');
-    assertTrue(isVisible(getElement('#bluetoothCheckboxContainer')));
+    getElement('#bluetoothCheckboxContainer').hidden = false;
 
     const bluetoothLogsCheckbox = getElement('#bluetoothLogsCheckbox');
 
@@ -715,7 +690,7 @@
     // checkbox container should be visible.
     assertEquals(
         getElement('#userEmailDropDown').value, 'test.user@google.com');
-    assertTrue(isVisible(getElement('#bluetoothCheckboxContainer')));
+    getElement('#bluetoothCheckboxContainer').hidden = false;
 
     // BluetoothLogs checkbox is default to be checked.
     const bluetoothLogsCheckbox = getElement('#bluetoothLogsCheckbox');
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts
index c887958..fd4989a 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts
@@ -6,11 +6,11 @@
 import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {fetchGooglePhotosAlbums, getCountText, GooglePhotosAlbum, GooglePhotosAlbums, initializeGooglePhotosData, PersonalizationActionName, PersonalizationRouter, SetErrorAction, WallpaperGridItem} from 'chrome://personalization/js/personalization_app.js';
-import {assertDeepEquals, assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js';
+import {assertDeepEquals, assertEquals, assertGT, assertNotEquals} from 'chrome://webui-test/chai_assert.js';
 import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
 import {waitAfterNextRender} from 'chrome://webui-test/test_util.js';
 
-import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js';
+import {baseSetup, createSvgDataUrl, initElement, teardownElement} from './personalization_app_test_utils.js';
 import {TestPersonalizationStore} from './test_personalization_store.js';
 import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js';
 
@@ -53,19 +53,25 @@
         id: '9bd1d7a3-f995-4445-be47-53c5b58ce1cb',
         title: 'Album 0',
         photoCount: 0,
-        preview: {url: 'foo.com'},
+        preview: {
+          url: createSvgDataUrl('svg-0'),
+        },
       },
       {
         id: '0ec40478-9712-42e1-b5bf-3e75870ca042',
         title: 'Album 1',
         photoCount: 1,
-        preview: {url: 'bar.com'},
+        preview: {
+          url: createSvgDataUrl('svg-1'),
+        },
       },
       {
         id: '0a268a37-877a-4936-81d4-38cc84b0f596',
         title: 'Album 2',
         photoCount: 2,
-        preview: {url: 'baz.com'},
+        preview: {
+          url: createSvgDataUrl('svg-2'),
+        },
       },
     ];
 
@@ -81,7 +87,9 @@
     // rendered initially.
     const albumSelector =
         'wallpaper-grid-item:not([hidden]).album:not([placeholder])';
-    assertEquals(querySelectorAll(albumSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(albumSelector)!.length, 0,
+        'no wallpaper grid items yet');
 
     // Initialize Google Photos data in the |personalizationStore|.
     await initializeGooglePhotosData(wallpaperProvider, personalizationStore);
@@ -93,7 +101,9 @@
 
     // Verify that the expected |albums| are rendered.
     const albumEls = querySelectorAll(albumSelector) as WallpaperGridItem[];
-    assertEquals(albumEls.length, albums.length);
+
+    assertEquals(
+        albumEls.length, albums.length, 'one wallpaper grid item per album');
     albumEls.forEach((albumEl, i) => {
       assertDeepEquals(albumEl.src, albums[i]!.preview);
       assertEquals(albumEl.primaryText, albums[i]!.title);
@@ -103,69 +113,67 @@
 
 
   [true, false].forEach(
-      (dismissFromUser: boolean) =>
-          test('displays error when albums fail to load', async () => {
-            // Set values returned by |wallpaperProvider|.
-            wallpaperProvider.setGooglePhotosAlbums(undefined);
+      (dismissFromUser:
+           boolean) => test('displays error when albums fail to load', async () => {
+        // Set values returned by |wallpaperProvider|.
+        wallpaperProvider.setGooglePhotosAlbums(undefined);
 
-            // Initialize |googlePhotosAlbumsElement|.
-            googlePhotosAlbumsElement =
-                initElement(GooglePhotosAlbums, {hidden: false});
-            await waitAfterNextRender(googlePhotosAlbumsElement);
+        // Initialize |googlePhotosAlbumsElement|.
+        googlePhotosAlbumsElement =
+            initElement(GooglePhotosAlbums, {hidden: false});
+        await waitAfterNextRender(googlePhotosAlbumsElement);
 
-            // Initialize Google Photos data in the |personalizationStore| and
-            // expect an |error|.
-            personalizationStore.expectAction(
-                PersonalizationActionName.SET_ERROR);
-            await initializeGooglePhotosData(
-                wallpaperProvider, personalizationStore);
-            await fetchGooglePhotosAlbums(
-                wallpaperProvider, personalizationStore);
-            const {error} =
-                await personalizationStore.waitForAction(
-                    PersonalizationActionName.SET_ERROR) as SetErrorAction;
+        // Initialize Google Photos data in the |personalizationStore| and
+        // expect an |error|.
+        personalizationStore.expectAction(PersonalizationActionName.SET_ERROR);
+        await initializeGooglePhotosData(
+            wallpaperProvider, personalizationStore);
+        await fetchGooglePhotosAlbums(wallpaperProvider, personalizationStore);
+        const {error} =
+            await personalizationStore.waitForAction(
+                PersonalizationActionName.SET_ERROR) as SetErrorAction;
 
-            // Verify |error| expectations.
-            assertEquals(
-                error.message,
-                'Couldn’t load images. Check your network connection or try loading the images again.');
-            assertEquals(error.dismiss?.message, 'Try again');
-            assertNotEquals(error.dismiss?.callback, undefined);
+        // Verify |error| expectations.
+        assertEquals(
+            error.message,
+            'Couldn’t load images. Check your network connection or try loading the images again.');
+        assertEquals(error.dismiss?.message, 'Try again');
+        assertNotEquals(error.dismiss?.callback, undefined);
 
-            wallpaperProvider.reset();
+        wallpaperProvider.reset();
 
-            // Simulate dismissal of |error| conditionally |fromUser| and verify
-            // expected interactions with wallpaper provider.
-            error.dismiss?.callback?.(/*fromUser=*/ dismissFromUser);
-            await new Promise<void>(resolve => setTimeout(resolve));
-            assertEquals(
-                wallpaperProvider.getCallCount('fetchGooglePhotosAlbums'),
-                dismissFromUser ? 1 : 0);
+        // Simulate dismissal of |error| conditionally |fromUser| and verify
+        // expected interactions with wallpaper provider.
+        error.dismiss?.callback?.(/*fromUser=*/ dismissFromUser);
+        await new Promise<void>(resolve => setTimeout(resolve));
+        assertEquals(
+            wallpaperProvider.getCallCount('fetchGooglePhotosAlbums'),
+            dismissFromUser ? 1 : 0);
 
-            wallpaperProvider.reset();
+        wallpaperProvider.reset();
 
-            // Simulate hiding |googlePhotosAlbumsElement| and verify the
-            // |error| is dismissed though not |fromUser|.
-            const dismissCallbackPromise = new Promise<boolean>(resolve => {
-              personalizationStore.data.error!.dismiss!.callback = resolve;
-            });
-            googlePhotosAlbumsElement.hidden = true;
-            assertEquals(await dismissCallbackPromise, /*fromUser=*/ false);
-            await new Promise<void>(resolve => setTimeout(resolve));
-            assertEquals(
-                wallpaperProvider.getCallCount('fetchGooglePhotosAlbums'), 0);
-          }));
+        // Simulate hiding |googlePhotosAlbumsElement| and verify the
+        // |error| is dismissed though not |fromUser|.
+        const dismissCallbackPromise = new Promise<boolean>(resolve => {
+          personalizationStore.data.error!.dismiss!.callback = resolve;
+        });
+        googlePhotosAlbumsElement.hidden = true;
+        assertEquals(await dismissCallbackPromise, /*fromUser=*/ false);
+        await new Promise<void>(resolve => setTimeout(resolve));
+        assertEquals(
+            wallpaperProvider.getCallCount('fetchGooglePhotosAlbums'), 0);
+      }));
 
   test('displays placeholders until albums are present', async () => {
     // Prepare Google Photos data.
     const photosCount = 5;
-    const albums: GooglePhotosAlbum[] =
-        Array.from({length: photosCount}, (_, i) => ({
-                                            id: `id-${i}`,
-                                            title: `title-${i}`,
-                                            photoCount: 1,
-                                            preview: {url: `url-${i}`},
-                                          }));
+    const albums: GooglePhotosAlbum[] = Array.from(
+        {length: photosCount}, (_, i) => ({
+                                 id: `id-${i}`,
+                                 title: `title-${i}`,
+                                 photoCount: 1,
+                                 preview: {url: createSvgDataUrl(`svg-${i}`)},
+                               }));
 
     // Initialize |googlePhotosAlbumsElement|.
     googlePhotosAlbumsElement =
@@ -179,7 +187,7 @@
     const albumListSelector = 'iron-list:not([hidden])#grid';
     assertEquals(querySelectorAll(albumSelector)!.length, 0);
     const placeholderEls = querySelectorAll(placeholderSelector);
-    assertNotEquals(placeholderEls!.length, 0);
+    assertGT(placeholderEls!.length, 0, 'some placeholders are shown');
     let albumListEl = querySelectorAll(albumListSelector);
     assertEquals(albumListEl!.length, 1);
     assertEquals(
@@ -213,7 +221,7 @@
     // Only albums should be present.
     await waitAfterNextRender(googlePhotosAlbumsElement);
     const albumEls = querySelectorAll(albumSelector);
-    assertNotEquals(albumEls!.length, 0);
+    assertGT(albumEls!.length, 0, 'some album elements should be shown');
     assertEquals(querySelectorAll(placeholderSelector)!.length, 0);
 
     // The album list's aria-setsize should be consistent with the number of
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts
index 33ad0d0..ffb488e6 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts
@@ -9,7 +9,7 @@
 import {assertDeepEquals, assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js';
 import {waitAfterNextRender} from 'chrome://webui-test/test_util.js';
 
-import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js';
+import {baseSetup, createSvgDataUrl, initElement, teardownElement} from './personalization_app_test_utils.js';
 import {TestPersonalizationStore} from './test_personalization_store.js';
 import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js';
 
@@ -119,14 +119,16 @@
       id: '1',
       title: 'foo',
       photoCount: 2,
-      preview: {url: 'foo.com'},
+      // Use svg data urls so that img on-load event fires and removes the
+      // placeholder attribute.
+      preview: {url: createSvgDataUrl('svg-1')},
     };
 
     const otherAlbum: GooglePhotosAlbum = {
       id: '2',
       title: 'bar',
       photoCount: 1,
-      preview: {url: 'bar.com'},
+      preview: {url: createSvgDataUrl('svg-2')},
     };
 
     const photosByAlbumId: Record<string, GooglePhotosPhoto[]> = {
@@ -136,7 +138,7 @@
           dedupKey: '2d0d1595-14af-4471-b2db-b9c8eae3a491',
           name: 'foo',
           date: {data: []},
-          url: {url: 'foo.com'},
+          url: {url: createSvgDataUrl('svg-3')},
           location: 'home1',
         },
         {
@@ -144,7 +146,7 @@
           dedupKey: '2cb1b955-0b7e-4f59-b9d0-802227aeeb28',
           name: 'bar',
           date: {data: []},
-          url: {url: 'bar.com'},
+          url: {url: createSvgDataUrl('svg-4')},
           location: 'home2',
         },
       ],
@@ -154,7 +156,7 @@
           dedupKey: 'd99eedfa-43e5-4bca-8882-b881222b8db9',
           name: 'baz',
           date: {data: []},
-          url: {url: 'baz.com'},
+          url: {url: createSvgDataUrl('svg-5')},
           location: 'home3',
         },
       ],
@@ -169,15 +171,17 @@
         initElement(GooglePhotosPhotosByAlbumId, {hidden: false});
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
 
-    // Initially no album id selected. Photos should be absent.
     const photoSelector =
         'wallpaper-grid-item:not([hidden]):not([placeholder]).photo';
-    assertEquals(querySelectorAll(photoSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(photoSelector)!.length, 0,
+        'Initially no album id selected so photos should be absent');
 
-    // Select an album id. Photos should be absent since albums have not loaded.
     googlePhotosPhotosByAlbumIdElement.setAttribute('album-id', album.id);
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
-    assertEquals(querySelectorAll(photoSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(photoSelector)!.length, 0,
+        'photos should be absent since albums have not loaded');
 
     // Load albums. Photos should be absent since they are not loaded.
     personalizationStore.data.wallpaper.googlePhotos.albums =
@@ -189,8 +193,7 @@
         await wallpaperProvider.whenCalled('fetchGooglePhotosPhotos'),
         [/*itemId=*/ null, /*albumId=*/ album.id, /*resumeToken=*/ null]);
 
-    // Start loading photos for the selected album id. Photos should still be
-    // absent since they are still not loaded.
+    // Start loading photos for the selected album id.
     personalizationStore.data.wallpaper.loading.googlePhotos.photosByAlbumId = {
       ...personalizationStore.data.wallpaper.loading.googlePhotos
           .photosByAlbumId,
@@ -198,7 +201,9 @@
     };
     personalizationStore.notifyObservers();
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
-    assertEquals(querySelectorAll(photoSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(photoSelector)!.length, 0,
+        'photos should still be absent since they are still not loaded');
 
     // Load photos for an album id other than that which is selected. Photos
     // should still be absent since they are still not loaded for the selected
@@ -214,7 +219,9 @@
     };
     personalizationStore.notifyObservers();
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
-    assertEquals(querySelectorAll(photoSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(photoSelector)!.length, 0,
+        'photos still not loaded for selected album id');
 
     // Finish loading photos for the selected album id. Photos should now be
     // present since they are finished loading for the selected album id.
@@ -230,9 +237,13 @@
     personalizationStore.notifyObservers();
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
     const photosEls = querySelectorAll(photoSelector) as WallpaperGridItem[];
-    assertEquals(photosEls.length, photosByAlbumId[album.id]?.length);
+    assertEquals(
+        photosEls.length, photosByAlbumId[album.id]?.length,
+        'correct number of photo elements for album');
     photosEls.forEach((photoEl, i) => {
-      assertEquals(photoEl.src, photosByAlbumId[album.id]![i]!.url);
+      assertEquals(
+          photoEl.src, photosByAlbumId[album.id]![i]!.url,
+          `correct url for album.id ${album.id} index ${i}`);
     });
 
     // Select the other album id for which data is already loaded. Photos should
@@ -242,13 +253,15 @@
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
     assertEquals(
         querySelectorAll(photoSelector)!.length,
-        photosByAlbumId[otherAlbum.id]?.length);
+        photosByAlbumId[otherAlbum.id]?.length,
+        'correct number of photos visible for other album id');
 
-    // Un-select the album id. Photos should be absent since no album id is
-    // selected.
+    // Un-select the album id.
     googlePhotosPhotosByAlbumIdElement.removeAttribute('album-id');
     await waitAfterNextRender(googlePhotosPhotosByAlbumIdElement);
-    assertEquals(querySelectorAll(photoSelector)!.length, 0);
+    assertEquals(
+        querySelectorAll(photoSelector)!.length, 0,
+        'photos should be absent since no album id selected');
   });
 
   test('displays photo selected', async () => {
@@ -423,15 +436,15 @@
     const photosCount = 5;
     const album: GooglePhotosAlbum =
         {id: '1', title: '', photoCount: photosCount, preview: {url: ''}};
-    const photos: GooglePhotosPhoto[] =
-        Array.from({length: photosCount}, (_, i) => ({
-                                            id: `id-${i}`,
-                                            dedupKey: `dedupKey-${i}`,
-                                            name: `name-${i}`,
-                                            date: {data: []},
-                                            url: {url: `url-${i}`},
-                                            location: `location-${i}`,
-                                          }));
+    const photos: GooglePhotosPhoto[] = Array.from(
+        {length: photosCount}, (_, i) => ({
+                                 id: `id-${i}`,
+                                 dedupKey: `dedupKey-${i}`,
+                                 name: `name-${i}`,
+                                 date: {data: []},
+                                 url: {url: createSvgDataUrl(`svg-${i}`)},
+                                 location: `location-${i}`,
+                               }));
 
     // Initialize |googlePhotosPhotosByAlbumIdElement|.
     googlePhotosPhotosByAlbumIdElement =
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts
index daaaad0..faec19ec 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts
@@ -9,7 +9,7 @@
 import {assertDeepEquals, assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js';
 import {waitAfterNextRender} from 'chrome://webui-test/test_util.js';
 
-import {baseSetup, initElement, teardownElement, toString16} from './personalization_app_test_utils.js';
+import {baseSetup, createSvgDataUrl, initElement, teardownElement, toString16} from './personalization_app_test_utils.js';
 import {TestPersonalizationStore} from './test_personalization_store.js';
 import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js';
 
@@ -144,7 +144,7 @@
         dedupKey: '1',
         name: '1',
         date: toString16('First row'),
-        url: {url: '1'},
+        url: {url: createSvgDataUrl('1')},
         location: '1',
       },
       // Second row.
@@ -153,7 +153,7 @@
         dedupKey: '2',
         name: '2',
         date: toString16('Second row'),
-        url: {url: '2'},
+        url: {url: createSvgDataUrl('2')},
         location: '2',
       },
       {
@@ -161,7 +161,7 @@
         dedupKey: '3',
         name: '3',
         date: toString16('Second row'),
-        url: {url: '3'},
+        url: {url: createSvgDataUrl('3')},
         location: '3',
       },
       // Third row.
@@ -170,7 +170,7 @@
         dedupKey: '4',
         name: '4',
         date: toString16('Third row'),
-        url: {url: '4'},
+        url: {url: createSvgDataUrl('4')},
         location: '4',
       },
     ];
@@ -301,7 +301,7 @@
         dedupKey: '2d0d1595-14af-4471-b2db-b9c8eae3a491',
         name: 'foo',
         date: toString16('Wednesday, February 16, 2022'),
-        url: {url: 'foo.com'},
+        url: {url: createSvgDataUrl('svg-0')},
         location: undefined,
       },
       // Section of photos with one location.
@@ -310,7 +310,7 @@
         dedupKey: '2cb1b955-0b7e-4f59-b9d0-802227aeeb28',
         name: 'bar',
         date: toString16('Friday, November 12, 2021'),
-        url: {url: 'bar.com'},
+        url: {url: createSvgDataUrl('svg-1')},
         location: 'home1',
       },
       {
@@ -318,7 +318,7 @@
         dedupKey: 'd99eedfa-43e5-4bca-8882-b881222b8db9',
         name: 'baz',
         date: toString16('Friday, November 12, 2021'),
-        url: {url: 'baz.com'},
+        url: {url: createSvgDataUrl('svg-2')},
         location: 'home1',
       },
       // Section of photos with different locations.
@@ -327,7 +327,7 @@
         dedupKey: 'ef8795ae-e6c8-4580-8184-0bcad20fd013',
         name: 'bare',
         date: toString16('Friday, July 16, 2021'),
-        url: {url: 'bare.com'},
+        url: {url: createSvgDataUrl('svg-3')},
         location: 'home2',
       },
       {
@@ -335,7 +335,7 @@
         dedupKey: 'c8817402-822f-4ee8-9716-1f4b36c3263f',
         name: 'baze',
         date: toString16('Friday, July 16, 2021'),
-        url: {url: 'baze.com'},
+        url: {url: createSvgDataUrl('svg-4')},
         location: 'home3',
       },
     ];
@@ -558,15 +558,15 @@
   test('displays placeholders until photos are present', async () => {
     // Prepare Google Photos data.
     const photosCount = 5;
-    const photos: GooglePhotosPhoto[] =
-        Array.from({length: photosCount}, (_, i) => ({
-                                            id: `id-${i}`,
-                                            dedupKey: `dedupKey-${i}`,
-                                            name: `name-${i}`,
-                                            date: {data: []},
-                                            url: {url: `url-${i}`},
-                                            location: `location-${i}`,
-                                          }));
+    const photos: GooglePhotosPhoto[] = Array.from(
+        {length: photosCount}, (_, i) => ({
+                                 id: `id-${i}`,
+                                 dedupKey: `dedupKey-${i}`,
+                                 name: `name-${i}`,
+                                 date: {data: []},
+                                 url: {url: createSvgDataUrl(`url-${i}`)},
+                                 location: `location-${i}`,
+                               }));
 
     // Initialize |googlePhotosPhotosElement|.
     googlePhotosPhotosElement =
@@ -642,7 +642,7 @@
             dedupKey: `dedupKey-${nextPhotoId}`,
             name: `name-${nextPhotoId}`,
             date: {data: []},
-            url: {url: `url-${nextPhotoId}`},
+            url: {url: createSvgDataUrl(`url-${nextPhotoId}`)},
             location: `location-${nextPhotoId++}`,
           };
         }));
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test_utils.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test_utils.ts
index 8a451bd..2a5109c 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test_utils.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test_utils.ts
@@ -81,3 +81,15 @@
   }
   return {data};
 }
+
+/**
+ * Returns a svg data url. This is useful in tests to force img on-load events
+ * to fire so that wallpaper-grid-item resolves its loading state.
+ */
+export function createSvgDataUrl(id: string): string {
+  return 'data:image/svg+xml;utf8,' +
+      '<svg xmlns="http://www.w3.org/2000/svg" ' +
+      `height="100px" width="100px" id="${id}">` +
+      '<rect fill="red" height="100px" width="100px"></rect>' +
+      '</svg>';
+}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
index 49d06fc..20a9c938 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
@@ -7,10 +7,10 @@
 
 import {WallpaperGridItem} from 'chrome://personalization/js/personalization_app.js';
 import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
-import {assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {waitAfterNextRender} from 'chrome://webui-test/test_util.js';
 
-import {initElement, teardownElement} from './personalization_app_test_utils.js';
+import {createSvgDataUrl, initElement, teardownElement} from './personalization_app_test_utils.js';
 
 suite('WallpaperGridItemTest', function() {
   let wallpaperGridItemElement: WallpaperGridItem|null;
@@ -33,6 +33,10 @@
     wallpaperGridItemElement = initElement(WallpaperGridItem);
     await waitAfterNextRender(wallpaperGridItemElement);
 
+    assertTrue(
+        wallpaperGridItemElement.hasAttribute('placeholder'),
+        'placeholder attribute is set when no src is supplied');
+
     // Verify state.
     const img = querySelector('img');
     assertEquals(img?.getAttribute('auto-src'), null);
@@ -46,39 +50,45 @@
   });
 
   test('displays image', async () => {
-    const src: Url = {
-      url: 'data:image/svg+xml;utf8,' +
-          '<svg xmlns="http://www.w3.org/2000/svg" height="100px" width="100px">' +
-          '<rect fill="red" height="100px" width="100px"></rect>' +
-          '</svg>',
-    };
+    const src: Url = {url: createSvgDataUrl('svg-test')};
 
     // Initialize |wallpaperGridItemElement|.
     wallpaperGridItemElement = initElement(WallpaperGridItem, {src});
+    const img = querySelector('img');
+    assertTrue(img!.hasAttribute('hidden'), 'image should be hidden at first');
+    assertTrue(
+        wallpaperGridItemElement.hasAttribute('placeholder'),
+        'placeholder attribute set while image is loading');
     await waitAfterNextRender(wallpaperGridItemElement);
 
+    assertFalse(
+        wallpaperGridItemElement.hasAttribute('placeholder'),
+        'placeholder attribute removed');
+
     // Verify state. Note that |img| is shown as |imageSrc| has already loaded.
-    const img = querySelector('img');
-    assertEquals(img?.getAttribute('auto-src'), src.url);
-    assertEquals(img?.getAttribute('aria-hidden'), 'true');
-    assertEquals(img?.hasAttribute('clear-src'), true);
-    assertEquals(img?.hasAttribute('hidden'), false);
-    assertEquals(img?.hasAttribute('is-google-photos'), true);
+    assertEquals(
+        img?.getAttribute('auto-src'), src.url, 'auto-src set to correct url');
+    assertEquals(
+        img?.getAttribute('aria-hidden'), 'true', 'img is always aria-hidden');
+    assertEquals(
+        img?.hasAttribute('clear-src'), true, 'clear-src attribute always set');
+    assertFalse(
+        img!.hasAttribute('hidden'),
+        'no longer hidden because image has loaded');
+    assertEquals(
+        img?.hasAttribute('is-google-photos'), true,
+        'is-google-photos is always set');
 
     // Update state. Note that |img| is hidden as |imageSrc| hasn't yet loaded.
     const newSrc: Url = {url: src.url.replace('red', 'blue')};
     wallpaperGridItemElement.src = newSrc;
-    assertEquals(img?.getAttribute('auto-src'), newSrc.url);
-    assertEquals(img?.hasAttribute('hidden'), true);
-
-    // Verify that once |imageSrc| has loaded, |img| will be shown.
-    await new Promise<void>(resolve => {
-      setInterval(() => {
-        if (!img?.hasAttribute('hidden')) {
-          resolve();
-        }
-      }, 100);
-    });
+    assertTrue(
+        wallpaperGridItemElement.hasAttribute('placeholder'),
+        'placeholder attribute set while new image is loading');
+    assertEquals(img?.getAttribute('auto-src'), newSrc.url, 'new url is set');
+    assertTrue(
+        img!.hasAttribute('hidden'),
+        'image should be hidden because src changed');
   });
 
   test('displays primary text', async () => {
diff --git a/chrome/test/data/webui/chromeos/scanning/BUILD.gn b/chrome/test/data/webui/chromeos/scanning/BUILD.gn
index 0cb9611e..fbab0eb8 100644
--- a/chrome/test/data/webui/chromeos/scanning/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/scanning/BUILD.gn
@@ -138,9 +138,11 @@
     "../..:test_util",
     "//ash/webui/scanning/resources:scanning_app",
     "//third_party/polymer/v3_0/components-chromium/iron-collapse:iron-collapse",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("scanning_app_test_utils") {
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
index 2d4b295..ccf84a6c 100644
--- a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
+++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 import 'chrome://scanning/scanning_app.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
 import {setScanServiceForTesting} from 'chrome://scanning/mojo_interface_provider.js';
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
index f17b3fd..23c08d2a 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
@@ -295,9 +295,11 @@
   deps = [
     "../..:chai_assert",
     "//ash/webui/shimless_rma/resources:repair_component_chip",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("shimless_rma_unified_test") {
@@ -309,9 +311,11 @@
   deps = [
     "../..:chai_assert",
     "//ash/webui/shimless_rma/resources:wrapup_finalize_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("wrapup_repair_complete_page_test") {
@@ -320,10 +324,12 @@
     "//ash/webui/shimless_rma/resources:fake_shimless_rma_service",
     "//ash/webui/shimless_rma/resources:mojo_interface_provider",
     "//ash/webui/shimless_rma/resources:wrapup_repair_complete_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+  ]
 }
 
 js_library("wrapup_restock_page_test") {
@@ -331,16 +337,20 @@
     "../..:chai_assert",
     "//ash/webui/shimless_rma/resources:shimless_rma",
     "//ash/webui/shimless_rma/resources:wrapup_restock_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("wrapup_wait_for_manual_wp_enable_page_test") {
   deps = [
     "../..:chai_assert",
     "//ash/webui/shimless_rma/resources:wrapup_wait_for_manual_wp_enable_page",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
+  externs_list = [
+    "$externs_path/mocha-2.5.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn b/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn
index 74f8293..6f4bfc26 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/BUILD.gn
@@ -2,105 +2,43 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/typescript/ts_library.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
 
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  closure_flags = default_closure_args + [
-                    "browser_resolver_prefix_replacements=\"chrome://shortcut-customization/=../../ash/webui/shortcut_customization_ui/resources/\"",
-                    "js_module_root=../../chrome/test/data/webui/",
-                    "js_module_root=./gen/chrome/test/data/webui/",
-                  ]
-  deps = [
-    ":accelerator_edit_dialog_test",
-    ":accelerator_edit_view_test",
-    ":accelerator_lookup_manager_test",
-    ":accelerator_row_test",
-    ":accelerator_view_test",
-    ":fake_shortcut_provider_test",
-    ":shortcut_customization_test",
-    ":shortcut_customization_test_util",
+ts_library("build_ts") {
+  root_dir = "."
+  out_dir = "$target_gen_dir/tsc"
+  tsconfig_base = "tsconfig_base.json"
+  path_mappings = [
+    "chrome://shortcut-customization/*|" +
+        rebase_path(
+            "$root_gen_dir/ash/webui/shortcut_customization_ui/resources/tsc/*",
+            target_gen_dir),
+    "chrome://webui-test/*|" +
+        rebase_path("$root_gen_dir/chrome/test/data/webui/tsc/*",
+                    target_gen_dir),
   ]
+  in_files = [
+    "accelerator_edit_dialog_test.js",
+    "accelerator_edit_view_test.js",
+    "accelerator_lookup_manager_test.js",
+    "accelerator_row_test.js",
+    "accelerator_subsection_test.js",
+    "accelerator_view_test.js",
+    "fake_shortcut_provider_test.js",
+    "shortcut_customization_test.js",
+    "shortcut_customization_test_util.js",
+  ]
+  deps = [ "//ash/webui/shortcut_customization_ui/resources:build_ts" ]
+  extra_deps = [ "../..:generate_definitions" ]
 }
 
-js_library("accelerator_edit_dialog_test") {
-  deps = [
-    ":shortcut_customization_test_util",
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_edit_dialog",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
+generate_grd("build_grdp") {
+  grd_prefix = "webui_chromeos_shortcut_customization"
+  out_grd = "$target_gen_dir/resources.grdp"
 
-js_library("accelerator_edit_view_test") {
-  deps = [
-    ":shortcut_customization_test_util",
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_edit_view",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("accelerator_lookup_manager_test") {
-  deps = [
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_lookup_manager",
-    "//ash/webui/shortcut_customization_ui/resources:fake_data",
-    "//ash/webui/shortcut_customization_ui/resources:fake_shortcut_provider",
-    "//ash/webui/shortcut_customization_ui/resources:shortcut_types",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("accelerator_row_test") {
-  deps = [
-    ":shortcut_customization_test_util",
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_row",
-    "//ash/webui/shortcut_customization_ui/resources:fake_data",
-    "//ash/webui/shortcut_customization_ui/resources:shortcut_types",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("accelerator_subsection_test") {
-  deps = [
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_subsection",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("accelerator_view_test") {
-  deps = [
-    ":shortcut_customization_test_util",
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_view",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("fake_shortcut_provider_test") {
-  deps = [
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:fake_data",
-    "//ash/webui/shortcut_customization_ui/resources:fake_shortcut_provider",
-    "//ash/webui/shortcut_customization_ui/resources:shortcut_types",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("shortcut_customization_test") {
-  deps = [
-    "../..:chai_assert",
-    "//ash/webui/shortcut_customization_ui/resources:accelerator_subsection",
-    "//ash/webui/shortcut_customization_ui/resources:mojo_interface_provider",
-    "//ash/webui/shortcut_customization_ui/resources:shortcut_customization_app",
-    "//ash/webui/shortcut_customization_ui/resources:shortcut_types",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
-js_library("shortcut_customization_test_util") {
-  deps = []
+  deps = [ ":build_ts" ]
+  manifest_files =
+      filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
+  resource_path_prefix = "chromeos/shortcut_customization"
 }
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js
index 6c46e8a..4e1deeb 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/accelerator_edit_dialog.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {AcceleratorEditDialogElement} from 'chrome://shortcut-customization/accelerator_edit_dialog.js';
 import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 import {CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js
index 60f8ab6..6856d1d 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/accelerator_edit_view.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {AcceleratorEditViewElement} from 'chrome://shortcut-customization/accelerator_edit_view.js';
 import {AcceleratorLookupManager} from 'chrome://shortcut-customization/accelerator_lookup_manager.js';
 import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/fake_data.js';
 import {AcceleratorSource, Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
-import {flushTasks} from '../../test_util.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 import {CreateDefaultAccelerator, CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.js
index 6600a8b..8f05b24 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.js
@@ -2,15 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {AcceleratorLookupManager} from 'chrome://shortcut-customization/accelerator_lookup_manager.js';
 import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/fake_data.js';
 import {FakeShortcutProvider} from 'chrome://shortcut-customization/fake_shortcut_provider.js';
 import {AcceleratorSource, AcceleratorState, Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertDeepEquals, assertEquals} from '../../chai_assert.js';
-import {flushTasks} from '../../test_util.js';
+import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 suite('acceleratorLookupManagerTest', function() {
   /** @type {?FakeShortcutProvider} */
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js
index 50432a4..8b7771f1 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/accelerator_row.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {AcceleratorRowElement} from 'chrome://shortcut-customization/accelerator_row.js';
 import {AcceleratorSource, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
-import {flushTasks} from '../../test_util.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 import {CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js
index 8d79326..e16bfe5 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/accelerator_subsection.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {AcceleratorLookupManager} from 'chrome://shortcut-customization/accelerator_lookup_manager.js';
 import {AcceleratorSubsectionElement} from 'chrome://shortcut-customization/accelerator_subsection.js';
 import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/fake_data.js';
 import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals} from '../../chai_assert.js';
-import {flushTasks} from '../../test_util.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 import {CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js
index 68871f9..ad09d93c9 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/accelerator_view.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {AcceleratorLookupManager} from 'chrome://shortcut-customization/accelerator_lookup_manager.js';
 import {AcceleratorViewElement, ViewState} from 'chrome://shortcut-customization/accelerator_view.js';
 import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/fake_data.js';
 import {AcceleratorSource, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals, assertTrue} from '../../chai_assert.js';
+import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 import {CreateDefaultAccelerator, CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.js
index dc3e09f..7f7fca7 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.js
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/fake_data.js';
 import {FakeShortcutProvider} from 'chrome://shortcut-customization/fake_shortcut_provider.js';
 import {AcceleratorConfigResult, AcceleratorSource, Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
+import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 suite('fakeShortcutProviderTest', function() {
   /** @type {?FakeShortcutProvider} */
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js
index 1884b34..f8f3556 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js
@@ -45,7 +45,7 @@
     /** @override */
     get browsePreload() {
       return `chrome://shortcut-customization/test_loader.html` +
-          `?module=chromeos/shortcut_customization/${module}&host=test`;
+          `?module=chromeos/shortcut_customization/${module}`;
     }
   };
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js
index 83df0413..b118df6d 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.js
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://shortcut-customization/shortcut_customization_app.js';
+import 'chrome://webui-test/mojo_webui_test_support.js';
 
 import {AcceleratorLookupManager} from 'chrome://shortcut-customization/accelerator_lookup_manager.js';
 import {AcceleratorSubsectionElement} from 'chrome://shortcut-customization/accelerator_subsection.js';
@@ -10,9 +11,8 @@
 import {getShortcutProvider, setShortcutProviderForTesting} from 'chrome://shortcut-customization/mojo_interface_provider.js';
 import {ShortcutCustomizationAppElement} from 'chrome://shortcut-customization/shortcut_customization_app.js';
 import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
-import {flushTasks} from '../../test_util.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 import {CreateUserAccelerator} from './shortcut_customization_test_util.js';
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/tsconfig_base.json b/chrome/test/data/webui/chromeos/shortcut_customization/tsconfig_base.json
new file mode 100644
index 0000000..a5a361c
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/tsconfig_base.json
@@ -0,0 +1,9 @@
+{
+    "extends": "../../../../../../tools/typescript/tsconfig_base.json",
+    "compilerOptions": {
+      "allowJs": true,
+      "typeRoots": [
+         "../../../../../../third_party/node/node_modules/@types"
+      ]
+    }
+}
diff --git a/chrome/test/data/webui/password_manager/password_manager_side_bar_test.ts b/chrome/test/data/webui/password_manager/password_manager_side_bar_test.ts
index 23f0f07b..4df273e 100644
--- a/chrome/test/data/webui/password_manager/password_manager_side_bar_test.ts
+++ b/chrome/test/data/webui/password_manager/password_manager_side_bar_test.ts
@@ -4,9 +4,9 @@
 
 import 'chrome://password-manager/password_manager.js';
 
-import {PasswordManagerSideBarElement} from 'chrome://password-manager/password_manager.js';
+import {Page, PasswordManagerSideBarElement, Router} from 'chrome://password-manager/password_manager.js';
 import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
-import {isVisible} from 'chrome://webui-test/test_util.js';
+import {flushTasks, isVisible} from 'chrome://webui-test/test_util.js';
 
 suite('PasswordManagerSideBarTest', function() {
   let sidebar: PasswordManagerSideBarElement;
@@ -15,6 +15,7 @@
     document.body.innerHTML = '';
     sidebar = document.createElement('password-manager-side-bar');
     document.body.appendChild(sidebar);
+    return flushTasks();
   });
 
   test('check layout', function() {
@@ -22,4 +23,24 @@
     const sideBarEntries = sidebar.shadowRoot!.querySelectorAll('a');
     assertEquals(3, sideBarEntries.length);
   });
+
+  [Page.PASSWORDS, Page.CHECKUP, Page.SETTINGS].forEach(
+      page => test(`clicking ${page} updates path`, function() {
+        const differentPage =
+            page === Page.PASSWORDS ? Page.CHECKUP : Page.PASSWORDS;
+        Router.getInstance().navigateTo(differentPage);
+        assertEquals(differentPage, Router.getInstance().currentPage);
+
+        const element =
+            sidebar.shadowRoot!.querySelector<HTMLElement>(`#${page}`)!;
+        element.click();
+        assertEquals(page, Router.getInstance().currentPage);
+      }));
+
+  [Page.PASSWORDS, Page.CHECKUP, Page.SETTINGS].forEach(
+      page => test(`navigating to ${page} updates selected item`, function() {
+        Router.getInstance().navigateTo(page);
+        assertEquals(page, Router.getInstance().currentPage);
+        assertEquals(page, (sidebar.$.menu.selectedItem as HTMLElement).id);
+      }));
 });
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js
index 494eb188..7c8cf2b0 100644
--- a/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/multidevice_permissions_setup_dialog_tests.js
@@ -775,7 +775,7 @@
       isScreenLockEnabled_: true,
       flowState_: SetupFlowStatus.SET_LOCKSCREEN,
       isPinNumberSelected_: true,
-      isSetPinDone_: true,
+      isPinSet_: true,
       isPasswordDialogShowing: true,
     });
     flush();
diff --git a/chrome/test/data/webui/settings/chromeos/privacy_hub_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/privacy_hub_subpage_tests.js
index a1580ac..5dfdb540 100644
--- a/chrome/test/data/webui/settings/chromeos/privacy_hub_subpage_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/privacy_hub_subpage_tests.js
@@ -100,6 +100,22 @@
         'Microphone toggle should be focused for settingId=1117.');
   });
 
+  test('Deep link to Geolocation toggle on privacy hub', async () => {
+    const params = new URLSearchParams();
+    params.append('settingId', '1118');
+    Router.getInstance().navigateTo(routes.PRIVACY_HUB, params);
+
+    flush();
+
+    const deepLinkElement =
+        privacyHubSubpage.shadowRoot.querySelector('#geolocationToggle')
+            .shadowRoot.querySelector('cr-toggle');
+    await waitAfterNextRender(deepLinkElement);
+    assertEquals(
+        deepLinkElement, getDeepActiveElement(),
+        'Geolocation toggle should be focused for settingId=1118.');
+  });
+
   test('Update camera setting sub-label', async () => {
     const params = new URLSearchParams();
     params.append('settingId', '1116');
diff --git a/chrome/test/data/webui/settings/site_details_tests.ts b/chrome/test/data/webui/settings/site_details_tests.ts
index f99e0ad..00219620 100644
--- a/chrome/test/data/webui/settings/site_details_tests.ts
+++ b/chrome/test/data/webui/settings/site_details_tests.ts
@@ -483,4 +483,43 @@
     testElement = createSiteDetails(origin);
     return browserProxy.whenCalled('fetchBlockAutoplayStatus');
   });
+
+  test('check first party set membership label empty string', async function() {
+    const origin = 'https://foo.com:443';
+    browserProxy.setPrefs(prefs);
+    testElement = createSiteDetails(origin);
+
+    const results = await Promise.all([
+      websiteUsageProxy.whenCalled('fetchUsageTotal'),
+    ]);
+
+    const hostRequested = results[0];
+    assertEquals('foo.com', hostRequested);
+    webUIListenerCallback(
+        'usage-total-changed', hostRequested, '1 KB', '10 cookies', '');
+    assertTrue(testElement.$.fpsMembership.hidden);
+    assertEquals('', testElement.$.fpsMembership.textContent!.trim());
+  });
+
+  test(
+      'check first party set membership label populated string',
+      async function() {
+        const origin = 'https://foo.com:443';
+        browserProxy.setPrefs(prefs);
+        testElement = createSiteDetails(origin);
+
+        const results = await Promise.all([
+          websiteUsageProxy.whenCalled('fetchUsageTotal'),
+        ]);
+
+        const hostRequested = results[0];
+        assertEquals('foo.com', hostRequested);
+        webUIListenerCallback(
+            'usage-total-changed', hostRequested, '1 KB', '10 cookies',
+            'Allowed for 1 foo.com site');
+        assertFalse(testElement.$.fpsMembership.hidden);
+        assertEquals(
+            'Allowed for 1 foo.com site',
+            testElement.$.fpsMembership.textContent!.trim());
+      });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
index c12b59d..76051ba 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
@@ -517,4 +517,77 @@
     const expected2: string = 'Second set of content.';
     assertContainerInnerHTML(expected2);
   });
+
+  test('updateContent selection', () => {
+    // root htmlTag='#document' id=1
+    // ++paragraph htmlTag='p' id=2
+    // ++++staticText name='Hello' id=3
+    // ++paragraph htmlTag='p' id=4
+    // ++++staticText name='World' id=5
+    // ++paragraph htmlTag='p' id=6
+    // ++++staticText name='Friend' id=7
+    // ++++staticText name='!' id=8
+    const axTree = {
+      rootId: 1,
+      nodes: [
+        {
+          id: 1,
+          role: 'rootWebArea',
+          htmlTag: '#document',
+          childIds: [2, 4, 6],
+        },
+        {
+          id: 2,
+          role: 'paragraph',
+          htmlTag: 'p',
+          childIds: [3],
+        },
+        {
+          id: 3,
+          role: 'staticText',
+          name: 'Hello',
+        },
+        {
+          id: 4,
+          role: 'paragraph',
+          htmlTag: 'p',
+          childIds: [5],
+        },
+        {
+          id: 5,
+          role: 'staticText',
+          name: 'World',
+        },
+        {
+          id: 6,
+          role: 'paragraph',
+          htmlTag: 'p',
+          childIds: [7, 8],
+        },
+        {
+          id: 7,
+          role: 'staticText',
+          name: 'Friend',
+        },
+        {
+          id: 8,
+          role: 'staticText',
+          name: '!',
+        },
+      ],
+      selection: {
+        anchor_object_id: 3,
+        focus_object_id: 7,
+        anchor_offset: 1,
+        focus_offset: 2,
+      },
+    };
+    chrome.readAnything.setContentForTesting(axTree, []);
+    // The expected string contains the selected text only inside of the node
+    // that is common to the entire selection, which is the root node in this
+    // example. Since the root node's html tag is '#document' which isn't valid,
+    // we replace it with a div.
+    const expected: string = '<div><p>ello</p><p>World</p><p>Fr</p></div>';
+    assertContainerInnerHTML(expected);
+  });
 });
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 6933546..993aee5 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -765,7 +765,7 @@
         tcp_failure_type_, std::move(receiver), std::move(callback)));
   }
 
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/chrome/test/v8/OWNERS b/chrome/test/v8/OWNERS
index 3e7311f5..4cac6ef3 100644
--- a/chrome/test/v8/OWNERS
+++ b/chrome/test/v8/OWNERS
@@ -1,3 +1,2 @@
 adamk@chromium.org
 ahaas@chromium.org
-titzer@chromium.org
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h
index ef8c4eb..adc6d46d 100644
--- a/chrome/updater/test/integration_test_commands.h
+++ b/chrome/updater/test/integration_test_commands.h
@@ -71,6 +71,7 @@
   virtual void WaitForUpdaterExit() const = 0;
 #if BUILDFLAG(IS_WIN)
   virtual void ExpectInterfacesRegistered() const = 0;
+  virtual void ExpectMarshalInterfaceSucceeds() const = 0;
   virtual void ExpectLegacyUpdate3WebSucceeds(
       const std::string& app_id,
       int expected_final_state,
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc
index 1768728..ea44511 100644
--- a/chrome/updater/test/integration_test_commands_system.cc
+++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -196,6 +196,10 @@
     RunCommand("expect_interfaces_registered");
   }
 
+  void ExpectMarshalInterfaceSucceeds() const override {
+    RunCommand("expect_marshal_interface_succeeds");
+  }
+
   void ExpectLegacyUpdate3WebSucceeds(const std::string& app_id,
                                       int expected_final_state,
                                       int expected_error_code) const override {
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc
index 2a5d765..a86bc3b1 100644
--- a/chrome/updater/test/integration_test_commands_user.cc
+++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -169,6 +169,10 @@
     updater::test::ExpectInterfacesRegistered(updater_scope_);
   }
 
+  void ExpectMarshalInterfaceSucceeds() const override {
+    updater::test::ExpectMarshalInterfaceSucceeds(updater_scope_);
+  }
+
   void ExpectLegacyUpdate3WebSucceeds(const std::string& app_id,
                                       int expected_final_state,
                                       int expected_error_code) const override {
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index e385312..f5d7f1e2 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -154,6 +154,10 @@
     test_commands_->ExpectInterfacesRegistered();
   }
 
+  void ExpectMarshalInterfaceSucceeds() {
+    test_commands_->ExpectMarshalInterfaceSucceeds();
+  }
+
   void ExpectLegacyUpdate3WebSucceeds(const std::string& app_id,
                                       int expected_final_state,
                                       int expected_error_code) {
@@ -550,6 +554,12 @@
 }
 
 #if BUILDFLAG(IS_WIN)
+TEST_F(IntegrationTest, MarshalInterface) {
+  Install();
+  ExpectMarshalInterfaceSucceeds();
+  Uninstall();
+}
+
 TEST_F(IntegrationTest, LegacyUpdate3Web) {
   ScopedServer test_server(test_commands_);
   Install();
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc
index eb2f9de..e681c71 100644
--- a/chrome/updater/test/integration_tests_helper.cc
+++ b/chrome/updater/test/integration_tests_helper.cc
@@ -246,6 +246,8 @@
 #if BUILDFLAG(IS_WIN)
     {"expect_interfaces_registered",
      WithSystemScope(Wrap(&ExpectInterfacesRegistered))},
+    {"expect_marshal_interface_succeeds",
+     WithSystemScope(Wrap(&ExpectMarshalInterfaceSucceeds))},
     {"expect_legacy_update3web_succeeds",
      WithSwitch("expected_error_code",
                 WithSwitch("expected_final_state",
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h
index 52c7489..ec1128b 100644
--- a/chrome/updater/test/integration_tests_impl.h
+++ b/chrome/updater/test/integration_tests_impl.h
@@ -176,6 +176,7 @@
 
 #if BUILDFLAG(IS_WIN)
 void ExpectInterfacesRegistered(UpdaterScope scope);
+void ExpectMarshalInterfaceSucceeds(UpdaterScope scope);
 void ExpectLegacyUpdate3WebSucceeds(UpdaterScope scope,
                                     const std::string& app_id,
                                     int expected_final_state,
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 2241f6fd..c4b18ba 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -4,6 +4,7 @@
 
 #include <shlobj.h>
 #include <wrl/client.h>
+#include <wrl/implements.h>
 
 #include <regstr.h>
 
@@ -13,6 +14,7 @@
 #include <string>
 #include <vector>
 
+#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/files/file_path.h"
@@ -40,7 +42,9 @@
 #include "base/win/registry.h"
 #include "base/win/scoped_bstr.h"
 #include "base/win/scoped_variant.h"
+#include "base/win/win_util.h"
 #include "build/build_config.h"
+#include "chrome/updater/app/server/win/com_classes.h"
 #include "chrome/updater/app/server/win/updater_idl.h"
 #include "chrome/updater/app/server/win/updater_internal_idl.h"
 #include "chrome/updater/app/server/win/updater_legacy_idl.h"
@@ -633,6 +637,68 @@
   WaitFor(base::BindRepeating([]() { return !IsUpdaterRunning(); }));
 }
 
+// Verify registry entries for all interfaces.
+// IID entries under `Software\Classes\Interface`:
+// * ProxyStubClsid32 entry should point to the OLE automation marshaler
+// * TypeLib entry should be equal to the IID.
+//
+// TypeLib entries under `Software\Classes\TypeLib`:
+// * Read the typelib path under both `win32` and `win64`.
+// * Confirm that the typelib can be loaded using ::LoadTypeLib.
+// * Confirm that the typeinfo for each interface can be loaded from the
+// typelib.
+void VerifyInterfacesRegistryEntries(UpdaterScope scope) {
+  for (const auto is_internal : {true, false}) {
+    for (const auto& iid : GetInterfaces(is_internal)) {
+      const HKEY root = UpdaterScopeToHKeyRoot(scope);
+      const std::wstring iid_reg_path = GetComIidRegistryPath(iid);
+      const std::wstring typelib_reg_path = GetComTypeLibRegistryPath(iid);
+      const std::wstring iid_string = base::win::WStringFromGUID(iid);
+
+      std::wstring val;
+      {
+        const auto& path = iid_reg_path + L"\\ProxyStubClsid32";
+        EXPECT_EQ(base::win::RegKey(root, path.c_str(), KEY_READ)
+                      .ReadValue(L"", &val),
+                  ERROR_SUCCESS)
+            << ": " << root << ": " << path << ": " << iid_string;
+        EXPECT_EQ(val, L"{00020424-0000-0000-C000-000000000046}");
+      }
+
+      {
+        const auto& path = iid_reg_path + L"\\TypeLib";
+        EXPECT_EQ(base::win::RegKey(root, path.c_str(), KEY_READ)
+                      .ReadValue(L"", &val),
+                  ERROR_SUCCESS)
+            << ": " << root << ": " << path << ": " << iid_string;
+        EXPECT_EQ(val, iid_string);
+      }
+
+      const std::wstring typelib_reg_path_win32 =
+          typelib_reg_path + L"\\1.0\\0\\win32";
+      const std::wstring typelib_reg_path_win64 =
+          typelib_reg_path + L"\\1.0\\0\\win64";
+
+      for (const auto& path :
+           {typelib_reg_path_win32, typelib_reg_path_win64}) {
+        std::wstring typelib_path;
+        EXPECT_EQ(base::win::RegKey(root, path.c_str(), KEY_READ)
+                      .ReadValue(L"", &typelib_path),
+                  ERROR_SUCCESS)
+            << ": " << root << ": " << path << ": " << iid_string;
+
+        Microsoft::WRL::ComPtr<ITypeLib> type_lib;
+        EXPECT_HRESULT_SUCCEEDED(::LoadTypeLib(typelib_path.c_str(), &type_lib))
+            << ": Typelib path: " << typelib_path;
+
+        Microsoft::WRL::ComPtr<ITypeInfo> type_info;
+        EXPECT_HRESULT_SUCCEEDED(type_lib->GetTypeInfoOfGuid(iid, &type_info))
+            << ": Typelib path: " << typelib_path << ": IID: " << iid_string;
+      }
+    }
+  }
+}
+
 // Tests if the typelibs and some of the public, internal, and
 // legacy interfaces are available. Failure to query these interfaces indicates
 // an issue with typelib registration.
@@ -662,14 +728,75 @@
     EXPECT_HRESULT_SUCCEEDED(dispatch.As(&app_bundle));
   }
 
-  // IUpdaterInternal.
-  Microsoft::WRL::ComPtr<IUnknown> updater_internal_server;
-  ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
-      scope == UpdaterScope::kSystem ? __uuidof(UpdaterInternalSystemClass)
-                                     : __uuidof(UpdaterInternalUserClass),
-      nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&updater_internal_server)));
+  {  // IUpdaterInternal.
+    Microsoft::WRL::ComPtr<IUnknown> updater_internal_server;
+    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+        scope == UpdaterScope::kSystem ? __uuidof(UpdaterInternalSystemClass)
+                                       : __uuidof(UpdaterInternalUserClass),
+        nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&updater_internal_server)));
+    Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
+    EXPECT_HRESULT_SUCCEEDED(updater_internal_server.As(&updater_internal));
+  }
+
+  VerifyInterfacesRegistryEntries(scope);
+}
+
+void ExpectMarshalInterfaceSucceeds(UpdaterScope scope) {
+  // Create proxy/stubs for the IUpdaterInternal interface.
+  // Look up the ProxyStubClsid32.
+  CLSID psclsid = {};
+  EXPECT_HRESULT_SUCCEEDED(
+      ::CoGetPSClsid(__uuidof(IUpdaterInternal), &psclsid));
+  EXPECT_EQ(base::ToUpperASCII(base::win::WStringFromGUID(psclsid)),
+            L"{00020424-0000-0000-C000-000000000046}");
+
+  // Get the proxy/stub factory buffer.
+  Microsoft::WRL::ComPtr<IPSFactoryBuffer> psfb;
+  EXPECT_HRESULT_SUCCEEDED(
+      ::CoGetClassObject(psclsid, CLSCTX_INPROC, 0, IID_PPV_ARGS(&psfb)));
+
+  // Create the interface proxy.
+  Microsoft::WRL::ComPtr<IRpcProxyBuffer> proxy_buffer;
+  Microsoft::WRL::ComPtr<IUpdaterInternal> object;
+  EXPECT_HRESULT_SUCCEEDED(
+      psfb->CreateProxy(nullptr, __uuidof(IUpdaterInternal), &proxy_buffer,
+                        IID_PPV_ARGS_Helper(&object)));
+
+  // Create the interface stub.
+  Microsoft::WRL::ComPtr<IRpcStubBuffer> stub_buffer;
+  EXPECT_HRESULT_SUCCEEDED(
+      psfb->CreateStub(__uuidof(IUpdaterInternal), nullptr, &stub_buffer));
+
+  // Marshal and unmarshal an IUpdaterInternal object.
   Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
-  EXPECT_HRESULT_SUCCEEDED(updater_internal_server.As(&updater_internal));
+  EXPECT_HRESULT_SUCCEEDED(
+      Microsoft::WRL::MakeAndInitialize<UpdaterInternalImpl>(
+          &updater_internal));
+
+  Microsoft::WRL::ComPtr<IStream> stream;
+  EXPECT_HRESULT_SUCCEEDED(::CoMarshalInterThreadInterfaceInStream(
+      __uuidof(IUpdaterInternal), updater_internal.Get(), &stream));
+
+  base::WaitableEvent unmarshal_complete_event;
+
+  base::ThreadPool::CreateCOMSTATaskRunner({base::MayBlock()})
+      ->PostTask(
+          FROM_HERE,
+          base::BindOnce(
+              [](Microsoft::WRL::ComPtr<IStream> stream,
+                 base::WaitableEvent& event) {
+                const base::ScopedClosureRunner signal_event(base::BindOnce(
+                    [](base::WaitableEvent& event) { event.Signal(); },
+                    std::ref(event)));
+
+                Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
+                EXPECT_HRESULT_SUCCEEDED(::CoUnmarshalInterface(
+                    stream.Get(), IID_PPV_ARGS(&updater_internal)));
+              },
+              stream, std::ref(unmarshal_complete_event)));
+
+  EXPECT_TRUE(
+      unmarshal_complete_event.TimedWait(TestTimeouts::action_max_timeout()));
 }
 
 void InitializeBundle(UpdaterScope scope,
diff --git a/chrome/updater/win/setup/setup.cc b/chrome/updater/win/setup/setup.cc
index 151b03a..bb32f7c 100644
--- a/chrome/updater/win/setup/setup.cc
+++ b/chrome/updater/win/setup/setup.cc
@@ -167,6 +167,7 @@
   VLOG(1) << "Setup succeeded.";
 
   CheckComInterfaceTypeLib(scope, true);
+  MarshalUpdaterInternal();
 
   return 0;
 }
diff --git a/chrome/updater/win/setup/setup_util.cc b/chrome/updater/win/setup/setup_util.cc
index 57ffbce..a456759 100644
--- a/chrome/updater/win/setup/setup_util.cc
+++ b/chrome/updater/win/setup/setup_util.cc
@@ -8,11 +8,13 @@
 #include <shlobj.h>
 #include <windows.h>
 #include <wrl/client.h>
+#include <wrl/implements.h>
 
 #include <string>
 #include <unordered_map>
 #include <vector>
 
+#include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
@@ -25,11 +27,15 @@
 #include "base/strings/strcat.h"
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/task/thread_pool.h"
+#include "base/threading/thread_restrictions.h"
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
 #include "chrome/installer/util/install_service_work_item.h"
 #include "chrome/installer/util/registry_util.h"
 #include "chrome/installer/util/work_item_list.h"
+#include "chrome/updater/app/server/win/com_classes.h"
 #include "chrome/updater/app/server/win/updater_idl.h"
 #include "chrome/updater/app/server/win/updater_internal_idl.h"
 #include "chrome/updater/app/server/win/updater_legacy_idl.h"
@@ -436,4 +442,72 @@
   }
 }
 
+void MarshalUpdaterInternal() {
+  constexpr REFIID iid = __uuidof(IUpdaterInternal);
+
+  // Create proxy/stubs for the IUpdaterInternal interface.
+  // Look up the ProxyStubClsid32.
+  CLSID psclsid = {};
+  HRESULT hr = ::CoGetPSClsid(iid, &psclsid);
+
+  CHECK(SUCCEEDED(hr)) << std::hex << hr;
+  CHECK_EQ(base::ToUpperASCII(base::win::WStringFromGUID(psclsid)),
+           L"{00020424-0000-0000-C000-000000000046}");
+
+  // Get the proxy/stub factory buffer.
+  Microsoft::WRL::ComPtr<IPSFactoryBuffer> psfb;
+  hr = ::CoGetClassObject(psclsid, CLSCTX_INPROC, 0, IID_PPV_ARGS(&psfb));
+
+  CHECK(SUCCEEDED(hr)) << std::hex << hr;
+
+  // Create the interface proxy.
+  Microsoft::WRL::ComPtr<IRpcProxyBuffer> proxy_buffer;
+  Microsoft::WRL::ComPtr<IUpdaterInternal> object;
+  hr = psfb->CreateProxy(nullptr, iid, &proxy_buffer,
+                         IID_PPV_ARGS_Helper(&object));
+  LOG_IF(ERROR, FAILED(hr))
+      << __func__ << ": CreateProxy failed: " << std::hex << hr;
+
+  // Create the interface stub.
+  Microsoft::WRL::ComPtr<IRpcStubBuffer> stub_buffer;
+  hr = psfb->CreateStub(iid, nullptr, &stub_buffer);
+  LOG_IF(ERROR, FAILED(hr))
+      << __func__ << ": CreateStub failed: " << std::hex << hr;
+
+  // Marshal and unmarshal an IUpdaterInternal object.
+  Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
+  hr =
+      Microsoft::WRL::MakeAndInitialize<UpdaterInternalImpl>(&updater_internal);
+  CHECK(SUCCEEDED(hr)) << std::hex << hr;
+
+  Microsoft::WRL::ComPtr<IStream> stream;
+  hr = ::CoMarshalInterThreadInterfaceInStream(iid, updater_internal.Get(),
+                                               &stream);
+  CHECK(SUCCEEDED(hr)) << std::hex << hr;
+
+  base::ScopedAllowBaseSyncPrimitivesForTesting blocking_allowed_here;
+  base::WaitableEvent unmarshal_complete_event;
+
+  base::ThreadPool::CreateCOMSTATaskRunner({base::MayBlock()})
+      ->PostTask(
+          FROM_HERE,
+          base::BindOnce(
+              [](Microsoft::WRL::ComPtr<IStream> stream,
+                 base::WaitableEvent& event) {
+                const base::ScopedClosureRunner signal_event(base::BindOnce(
+                    [](base::WaitableEvent& event) { event.Signal(); },
+                    std::ref(event)));
+
+                Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
+                HRESULT hr = ::CoUnmarshalInterface(
+                    stream.Get(), IID_PPV_ARGS(&updater_internal));
+                CHECK(SUCCEEDED(hr)) << std::hex << hr;
+              },
+              stream, std::ref(unmarshal_complete_event)));
+
+  if (!unmarshal_complete_event.TimedWait(base::Seconds(60))) {
+    NOTREACHED();
+  }
+}
+
 }  // namespace updater
diff --git a/chrome/updater/win/setup/setup_util.h b/chrome/updater/win/setup/setup_util.h
index 24cce22..cb81be6 100644
--- a/chrome/updater/win/setup/setup_util.h
+++ b/chrome/updater/win/setup/setup_util.h
@@ -49,6 +49,11 @@
 // that can only be installed for the active instance of the updater.
 std::vector<IID> GetActiveInterfaces();
 
+// Returns the interfaces ids of all interfaces declared in IDL of the updater
+// that can be installed side-by-side (if `is_internal` is `true`) or for the
+// active instance (if `is_internal` is `false`) .
+std::vector<IID> GetInterfaces(bool is_internal);
+
 // Returns the CLSIDs of servers that can be installed side-by-side with other
 // instances of the updater.
 std::vector<CLSID> GetSideBySideServers(UpdaterScope scope);
@@ -57,6 +62,11 @@
 // instance of the updater.
 std::vector<CLSID> GetActiveServers(UpdaterScope scope);
 
+// Returns the CLSIDs of servers that can be installed side-by-side (if
+// `is_internal` is `true`) or for the active instance (if `is_internal` is
+// `false`) .
+std::vector<CLSID> GetServers(bool is_internal, UpdaterScope scope);
+
 // Helper function that joins two vectors and returns the resultant vector.
 template <typename T>
 std::vector<T> JoinVectors(const std::vector<T>& vector1,
@@ -106,6 +116,13 @@
 // bug is resolved.
 void CheckComInterfaceTypeLib(UpdaterScope scope, bool is_internal);
 
+// Marshals an instance of UpdaterInternal and unmarshals it into another
+// thread. The test also checks for successful creation of proxy/stubs for the
+// IUpdaterInternal interface.
+// TODO(crbug.com/1341471) - revert the CL that introduced the check after the
+// bug is resolved.
+void MarshalUpdaterInternal();
+
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_WIN_SETUP_SETUP_UTIL_H_
diff --git a/chrome/updater/win/update_service_internal_proxy.cc b/chrome/updater/win/update_service_internal_proxy.cc
index f072f24..6b837ee 100644
--- a/chrome/updater/win/update_service_internal_proxy.cc
+++ b/chrome/updater/win/update_service_internal_proxy.cc
@@ -150,9 +150,17 @@
 
   // TODO(crbug.com/1341471) - revert the CL that introduced the check after
   // the bug is resolved.
-  VLOG_IF(2, FAILED(hr)) << "Failed to query the updater_internal interface. "
-                         << std::hex << hr;
-  CHECK(SUCCEEDED(hr));
+  if (hr == TYPE_E_CANTLOADLIBRARY) {
+    CheckComInterfaceTypeLib(scope_, true);
+    CheckComInterfaceTypeLib(scope_, false);
+    NOTREACHED();
+  }
+  if (FAILED(hr)) {
+    VLOG(2) << "Failed to query the updater_internal interface. " << std::hex
+            << hr;
+    std::move(callback).Run();
+    return;
+  }
 
   // The COM RPC takes ownership of the `rpc_callback` and owns a reference to
   // the `updater_internal` object as well. As long as the `rpc_callback`
@@ -206,22 +214,18 @@
 
   Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
   hr = server.As(&updater_internal);
+
+  // TODO(crbug.com/1341471) - revert the CL that introduced the check after
+  // the bug is resolved.
+  if (hr == TYPE_E_CANTLOADLIBRARY) {
+    CheckComInterfaceTypeLib(scope_, true);
+    CheckComInterfaceTypeLib(scope_, false);
+    NOTREACHED();
+  }
+
   if (FAILED(hr)) {
     VLOG(2) << "Failed to query the updater_internal interface. " << std::hex
             << hr;
-
-    // TODO(crbug.com/1341471) - revert the CL that introduced this check after
-    // the bug is resolved.
-    for (int i = 0; i < 10; ++i) {
-      base::WaitableEvent().TimedWait(base::Seconds(1));
-      CHECK(FAILED(server.As(&updater_internal)))
-          << "Unexpectedly succeeded in querying the updater_internal "
-             "interface after retrying: "
-          << i;
-    }
-
-    CheckComInterfaceTypeLib(scope_, true);
-    CheckComInterfaceTypeLib(scope_, false);
     std::move(callback).Run();
     return;
   }
diff --git a/chrome/updater/win/win_util.cc b/chrome/updater/win/win_util.cc
index 848ebce4..a701b625 100644
--- a/chrome/updater/win/win_util.cc
+++ b/chrome/updater/win/win_util.cc
@@ -874,9 +874,9 @@
 
 absl::optional<base::ScopedTempDir> CreateSecureTempDir() {
   base::FilePath temp_dir;
-  if (!base::PathService::Get(
-          ::IsUserAnAdmin() ? base::DIR_PROGRAM_FILES : base::DIR_TEMP,
-          &temp_dir)) {
+  if (!base::PathService::Get(::IsUserAnAdmin() ? int{base::DIR_PROGRAM_FILES}
+                                                : int{base::DIR_TEMP},
+                              &temp_dir)) {
     return absl::nullopt;
   }
 
diff --git a/chromeos/OWNERS b/chromeos/OWNERS
index fd69a11..b22b3a2 100644
--- a/chromeos/OWNERS
+++ b/chromeos/OWNERS
@@ -32,7 +32,7 @@
 # CET
 antrim@chromium.org
 emaxx@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 
 # JST
 hashimoto@chromium.org
diff --git a/chromeos/ash/components/dbus/authpolicy/OWNERS b/chromeos/ash/components/dbus/authpolicy/OWNERS
index a8183f4..1f6c549 100644
--- a/chromeos/ash/components/dbus/authpolicy/OWNERS
+++ b/chromeos/ash/components/dbus/authpolicy/OWNERS
@@ -1 +1 @@
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/chromeos/ash/components/dbus/shill/fake_shill_manager_client.cc b/chromeos/ash/components/dbus/shill/fake_shill_manager_client.cc
index 63496111..55c01ae 100644
--- a/chromeos/ash/components/dbus/shill/fake_shill_manager_client.cc
+++ b/chromeos/ash/components/dbus/shill/fake_shill_manager_client.cc
@@ -206,10 +206,10 @@
          state == shill::kStateReady;
 }
 
-void UpdatePortaledWifiState(const std::string& service_path) {
+void UpdatePortaledState(const std::string& service_path,
+                         const std::string& state) {
   ShillServiceClient::Get()->GetTestInterface()->SetServiceProperty(
-      service_path, shill::kStateProperty,
-      base::Value(shill::kStateNoConnectivity));
+      service_path, shill::kStateProperty, base::Value(state));
 }
 
 bool IsCellularTechnology(const std::string& type) {
@@ -924,8 +924,10 @@
   state = GetInitialStateForType(shill::kTypeWifi, &enabled);
   if (state != kTechnologyUnavailable) {
     bool portaled = false;
+    std::string portal_state;
     if (IsPortalledState(state)) {
       portaled = true;
+      portal_state = state;
       state = shill::kStateIdle;
     }
     AddTechnology(shill::kTypeWifi, enabled);
@@ -989,7 +991,8 @@
                                    base::Value(shill::kSecurityClassNone));
       services->SetConnectBehavior(
           kPortaledWifiPath,
-          base::BindRepeating(&UpdatePortaledWifiState, kPortaledWifiPath));
+          base::BindRepeating(&UpdatePortaledState, kPortaledWifiPath,
+                              portal_state));
       services->SetServiceProperty(
           kPortaledWifiPath, shill::kConnectableProperty, base::Value(true));
       profiles->AddService(shared_profile, kPortaledWifiPath);
@@ -1366,8 +1369,17 @@
   } else if (state_arg == "initializing") {
     // Technology available but not initialized.
     state = kTechnologyInitializing;
-  } else if (state_arg == "portal") {
-    // Technology is enabled, a service is connected and in Portal state.
+  } else if (state_arg == "redirect-found" || state_arg == "portal") {
+    // Technology is enabled, a service is connected and in redirect-found
+    // state.
+    state = shill::kStateRedirectFound;
+  } else if (state_arg == "portal-suspected") {
+    // Technology is enabled, a service is connected and in portal-suspected
+    // state.
+    state = shill::kStatePortalSuspected;
+  } else if (state_arg == "no-connectivity") {
+    // Technology is enabled, a service is connected and in no-connectivity
+    // state.
     state = shill::kStateNoConnectivity;
   } else if (state_arg == "active" || state_arg == "activated") {
     // Technology is enabled, a service is connected and Activated.
diff --git a/chromeos/ash/components/drivefs/drivefs_http_client.cc b/chromeos/ash/components/drivefs/drivefs_http_client.cc
index 0f2d227..ba555466 100644
--- a/chromeos/ash/components/drivefs/drivefs_http_client.cc
+++ b/chromeos/ash/components/drivefs/drivefs_http_client.cc
@@ -101,8 +101,10 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     DCHECK(IsFirstCall(CallbackState::kResponseReceived));
     std::vector<mojom::HttpHeaderPtr> headers;
     size_t iter = 0;
@@ -131,8 +133,6 @@
     std::move(ack_callback).Run();
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
 
   void OnComplete(const network::URLLoaderCompletionStatus& status) override {
diff --git a/chromeos/ash/components/feature_usage/OWNERS b/chromeos/ash/components/feature_usage/OWNERS
index 896e981..887fd8c 100644
--- a/chromeos/ash/components/feature_usage/OWNERS
+++ b/chromeos/ash/components/feature_usage/OWNERS
@@ -1,2 +1,2 @@
-rsorokin@chromium.org
+rsorokin@google.com
 hsuregan@chromium.org
diff --git a/chromeos/ash/components/network/BUILD.gn b/chromeos/ash/components/network/BUILD.gn
index ffc6b17..3cde057 100644
--- a/chromeos/ash/components/network/BUILD.gn
+++ b/chromeos/ash/components/network/BUILD.gn
@@ -97,6 +97,8 @@
     "hidden_network_handler.h",
     "hotspot_state_handler.cc",
     "hotspot_state_handler.h",
+    "hotspot_util.cc",
+    "hotspot_util.h",
     "managed_cellular_pref_handler.cc",
     "managed_cellular_pref_handler.h",
     "managed_network_configuration_handler.cc",
diff --git a/chromeos/ash/components/network/hotspot_state_handler.cc b/chromeos/ash/components/network/hotspot_state_handler.cc
index 5bd3f29..0a0ef21 100644
--- a/chromeos/ash/components/network/hotspot_state_handler.cc
+++ b/chromeos/ash/components/network/hotspot_state_handler.cc
@@ -4,8 +4,8 @@
 
 #include "chromeos/ash/components/network/hotspot_state_handler.h"
 
-#include "base/values.h"
 #include "chromeos/ash/components/dbus/shill/shill_manager_client.h"
+#include "chromeos/ash/components/network/hotspot_util.h"
 #include "chromeos/ash/components/network/network_event_log.h"
 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
 
@@ -17,30 +17,6 @@
 
 namespace {
 
-hotspot_config::mojom::HotspotState ShillTetheringStateToMojomState(
-    const std::string& shill_state) {
-  using HotspotState = hotspot_config::mojom::HotspotState;
-
-  if (shill_state == shill::kTetheringStateActive) {
-    return HotspotState::kEnabled;
-  }
-
-  if (shill_state == shill::kTetheringStateIdle) {
-    return HotspotState::kDisabled;
-  }
-
-  if (shill_state == shill::kTetheringStateStarting) {
-    return HotspotState::kEnabling;
-  }
-
-  if (shill_state == shill::kTetheringStateStopping) {
-    return HotspotState::kDisabling;
-  }
-
-  NOTREACHED() << "Unexpeted shill tethering state: " << shill_state;
-  return HotspotState::kDisabled;
-}
-
 size_t GetActiveClientCount(const base::Value& status) {
   const base::Value* active_clients =
       status.FindListKey(shill::kTetheringStatusClientsProperty);
@@ -60,15 +36,23 @@
   if (ShillManagerClient::Get()) {
     ShillManagerClient::Get()->RemovePropertyChangedObserver(this);
   }
+  if (LoginState::IsInitialized()) {
+    LoginState::Get()->RemoveObserver(this);
+  }
 }
 
 void HotspotStateHandler::Init() {
+  if (LoginState::IsInitialized()) {
+    LoginState::Get()->AddObserver(this);
+  }
   // Add as an observer here so that new hotspot state updated after this call
   // are recognized.
   ShillManagerClient::Get()->AddPropertyChangedObserver(this);
   ShillManagerClient::Get()->GetProperties(
       base::BindOnce(&HotspotStateHandler::OnManagerProperties,
                      weak_ptr_factory_.GetWeakPtr()));
+  if (LoginState::IsInitialized())
+    LoggedInStateChanged();
 }
 
 void HotspotStateHandler::AddObserver(Observer* observer) {
@@ -92,6 +76,100 @@
   return active_client_count_;
 }
 
+hotspot_config::mojom::HotspotConfigPtr HotspotStateHandler::GetHotspotConfig()
+    const {
+  if (!hotspot_config_)
+    return nullptr;
+
+  return ShillTetheringConfigToMojomConfig(*hotspot_config_);
+}
+
+void HotspotStateHandler::SetHotspotConfig(
+    hotspot_config::mojom::HotspotConfigPtr mojom_config,
+    SetHotspotConfigCallback callback) {
+  using SetHotspotConfigResult = hotspot_config::mojom::SetHotspotConfigResult;
+
+  if (!LoginState::Get()->IsUserLoggedIn()) {
+    NET_LOG(ERROR) << "Could not set hotspot config without login first.";
+    std::move(callback).Run(SetHotspotConfigResult::kFailedNotLogin);
+    return;
+  }
+
+  if (!mojom_config) {
+    NET_LOG(ERROR) << "Invalid hotspot configurations.";
+    std::move(callback).Run(
+        SetHotspotConfigResult::kFailedInvalidConfiguration);
+    return;
+  }
+
+  base::Value shill_tethering_config =
+      MojomConfigToShillConfig(std::move(mojom_config));
+  auto callback_split = base::SplitOnceCallback(std::move(callback));
+  ShillManagerClient::Get()->SetProperty(
+      shill::kTetheringConfigProperty, std::move(shill_tethering_config),
+      base::BindOnce(&HotspotStateHandler::OnSetHotspotConfigSuccess,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(callback_split.first)),
+      base::BindOnce(&HotspotStateHandler::OnSetHotspotConfigFailure,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(callback_split.second)));
+}
+
+void HotspotStateHandler::OnSetHotspotConfigSuccess(
+    SetHotspotConfigCallback callback) {
+  ShillManagerClient::Get()->GetProperties(
+      base::BindOnce(&HotspotStateHandler::UpdateHotspotConfigAndRunCallback,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void HotspotStateHandler::OnSetHotspotConfigFailure(
+    SetHotspotConfigCallback callback,
+    const std::string& error_name,
+    const std::string& error_message) {
+  NET_LOG(ERROR) << "Error setting hotspot config, error name:" << error_name
+                 << ", message" << error_message;
+  std::move(callback).Run(hotspot_config::mojom::SetHotspotConfigResult::
+                              kFailedInvalidConfiguration);
+}
+
+void HotspotStateHandler::LoggedInStateChanged() {
+  if (!LoginState::Get()->IsUserLoggedIn()) {
+    if (hotspot_config_) {
+      hotspot_config_ = absl::nullopt;
+      NotifyHotspotStatusChanged();
+    }
+    return;
+  }
+  ShillManagerClient::Get()->GetProperties(
+      base::BindOnce(&HotspotStateHandler::UpdateHotspotConfigAndRunCallback,
+                     weak_ptr_factory_.GetWeakPtr(), base::DoNothing()));
+}
+
+void HotspotStateHandler::UpdateHotspotConfigAndRunCallback(
+    SetHotspotConfigCallback callback,
+    absl::optional<base::Value> properties) {
+  if (!properties) {
+    NET_LOG(ERROR) << "Error getting Shill manager properties.";
+    std::move(callback).Run(
+        hotspot_config::mojom::SetHotspotConfigResult::kSuccess);
+    return;
+  }
+  const base::Value* shill_tethering_config =
+      properties->FindDictKey(shill::kTetheringConfigProperty);
+  if (!shill_tethering_config) {
+    NET_LOG(ERROR) << "Error getting " << shill::kTetheringConfigProperty
+                   << " in Shill manager properties";
+    std::move(callback).Run(
+        hotspot_config::mojom::SetHotspotConfigResult::kSuccess);
+    return;
+  }
+
+  hotspot_config_ = shill_tethering_config->Clone();
+  std::move(callback).Run(
+      hotspot_config::mojom::SetHotspotConfigResult::kSuccess);
+  NotifyHotspotStatusChanged();
+}
+
 void HotspotStateHandler::OnPropertyChanged(const std::string& key,
                                             const base::Value& value) {
   if (key == shill::kTetheringStatusProperty)
diff --git a/chromeos/ash/components/network/hotspot_state_handler.h b/chromeos/ash/components/network/hotspot_state_handler.h
index e53505a..fe680124 100644
--- a/chromeos/ash/components/network/hotspot_state_handler.h
+++ b/chromeos/ash/components/network/hotspot_state_handler.h
@@ -10,27 +10,27 @@
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/values.h"
 #include "chromeos/ash/components/dbus/shill/shill_property_changed_observer.h"
+#include "chromeos/login/login_state/login_state.h"
 #include "chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace base {
-class Value;
-}  // namespace base
-
 namespace ash {
 
 // This class caches hotspot related status and implements methods to get
 // current state, active client count, capabilities and configure the hotspot
 // configurations.
 class COMPONENT_EXPORT(CHROMEOS_NETWORK) HotspotStateHandler
-    : public ShillPropertyChangedObserver {
+    : public ShillPropertyChangedObserver,
+      public LoginState::Observer {
  public:
   class Observer : public base::CheckedObserver {
    public:
     ~Observer() override = default;
 
-    // Invoked when hotspot state or active client count is changed.
+    // Invoked when hotspot state, active client count or hotspot config is
+    // changed.
     virtual void OnHotspotStatusChanged() = 0;
     // Invoked when hotspot state is failed.
     virtual void OnHotspotStateFailed(const std::string& error) = 0;
@@ -46,6 +46,19 @@
   const chromeos::hotspot_config::mojom::HotspotState& GetHotspotState() const;
   // Return the latest hotspot active client count
   size_t GetHotspotActiveClientCount() const;
+  // Return the current hotspot configuration
+  chromeos::hotspot_config::mojom::HotspotConfigPtr GetHotspotConfig() const;
+
+  // Return callback for the SetHotspotConfig method. |success| indicates
+  // whether the operation is success or not.
+  using SetHotspotConfigCallback = base::OnceCallback<void(
+      chromeos::hotspot_config::mojom::SetHotspotConfigResult result)>;
+
+  // Set hotspot configuration with given |config|. |callback| is called with
+  // the success result of SetHotspotConfig operation.
+  void SetHotspotConfig(
+      chromeos::hotspot_config::mojom::HotspotConfigPtr config,
+      SetHotspotConfigCallback callback);
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
@@ -56,6 +69,9 @@
   void OnPropertyChanged(const std::string& key,
                          const base::Value& value) override;
 
+  // LoginState::Observer
+  void LoggedInStateChanged() override;
+
   // Callback to handle the manager properties with hotspot related properties.
   void OnManagerProperties(absl::optional<base::Value> properties);
 
@@ -73,8 +89,23 @@
   // Notify observers that hotspot state was failure.
   void NotifyHotspotStateFailed(const std::string& error);
 
+  // Update the cached hotspot_config_ with the tethering configuration
+  // from |manager_properties|, and then run the |callback|.
+  void UpdateHotspotConfigAndRunCallback(
+      SetHotspotConfigCallback callback,
+      absl::optional<base::Value> manager_properties);
+
+  // Callback when the SetHotspotConfig operation succeeded.
+  void OnSetHotspotConfigSuccess(SetHotspotConfigCallback callback);
+
+  // Callback when the SetHotspotConfig operation failed.
+  void OnSetHotspotConfigFailure(SetHotspotConfigCallback callback,
+                                 const std::string& error_name,
+                                 const std::string& error_message);
+
   chromeos::hotspot_config::mojom::HotspotState hotspot_state_ =
       chromeos::hotspot_config::mojom::HotspotState::kDisabled;
+  absl::optional<base::Value> hotspot_config_ = absl::nullopt;
   size_t active_client_count_ = 0;
   base::ObserverList<Observer> observer_list_;
   base::WeakPtrFactory<HotspotStateHandler> weak_ptr_factory_{this};
diff --git a/chromeos/ash/components/network/hotspot_state_handler_unittest.cc b/chromeos/ash/components/network/hotspot_state_handler_unittest.cc
index b26d2661..0b27308 100644
--- a/chromeos/ash/components/network/hotspot_state_handler_unittest.cc
+++ b/chromeos/ash/components/network/hotspot_state_handler_unittest.cc
@@ -5,6 +5,7 @@
 #include "chromeos/ash/components/network/hotspot_state_handler.h"
 
 #include "ash/constants/ash_features.h"
+#include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/values.h"
@@ -16,6 +17,24 @@
 
 namespace ash {
 
+namespace {
+
+const char kHotspotConfigSSID[] = "hotspot_SSID";
+const char kHotspotConfigPassphrase[] = "hotspot_passphrase";
+
+chromeos::hotspot_config::mojom::HotspotConfigPtr GenerateTestConfig() {
+  auto mojom_config = chromeos::hotspot_config::mojom::HotspotConfig::New();
+  mojom_config->auto_disable = false;
+  mojom_config->band = chromeos::hotspot_config::mojom::WiFiBand::k5GHz;
+  mojom_config->security =
+      chromeos::hotspot_config::mojom::WiFiSecurityMode::kWpa2;
+  mojom_config->ssid = kHotspotConfigSSID;
+  mojom_config->passphrase = kHotspotConfigPassphrase;
+  return mojom_config;
+}
+
+}  // namespace
+
 class TestObserver : public HotspotStateHandler::Observer {
  public:
   TestObserver() = default;
@@ -49,6 +68,8 @@
   void SetUp() override {
     feature_list_.InitAndEnableFeature(features::kHotspot);
     shill_clients::InitializeFakes();
+    LoginState::Initialize();
+    LoginState::Get()->set_always_logged_in(false);
     base::RunLoop().RunUntilIdle();
 
     if (hotspot_state_handler_ &&
@@ -64,6 +85,35 @@
     hotspot_state_handler_->RemoveObserver(&observer_);
     hotspot_state_handler_.reset();
     shill_clients::Shutdown();
+    LoginState::Shutdown();
+  }
+
+  chromeos::hotspot_config::mojom::SetHotspotConfigResult SetHotspotConfig(
+      chromeos::hotspot_config::mojom::HotspotConfigPtr mojom_config) {
+    base::RunLoop run_loop;
+    chromeos::hotspot_config::mojom::SetHotspotConfigResult result;
+    hotspot_state_handler_->SetHotspotConfig(
+        std::move(mojom_config),
+        base::BindLambdaForTesting(
+            [&](chromeos::hotspot_config::mojom::SetHotspotConfigResult
+                    success) {
+              result = success;
+              run_loop.QuitClosure();
+            }));
+    run_loop.RunUntilIdle();
+    return result;
+  }
+
+  void LoginToRegularUser() {
+    LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_ACTIVE,
+                                        LoginState::LOGGED_IN_USER_REGULAR);
+    task_environment_.RunUntilIdle();
+  }
+
+  void Logout() {
+    LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_NONE,
+                                        LoginState::LOGGED_IN_USER_NONE);
+    task_environment_.RunUntilIdle();
   }
 
  protected:
@@ -189,4 +239,30 @@
   EXPECT_EQ(3u, observer_.hotspot_status_changed_count());
 }
 
+TEST_F(HotspotStateHandlerTest, SetAndGetHotspotConfig) {
+  EXPECT_EQ(
+      chromeos::hotspot_config::mojom::SetHotspotConfigResult::kFailedNotLogin,
+      SetHotspotConfig(GenerateTestConfig()));
+  ASSERT_FALSE(hotspot_state_handler_->GetHotspotConfig());
+  EXPECT_EQ(0u, observer_.hotspot_status_changed_count());
+
+  LoginToRegularUser();
+  EXPECT_EQ(chromeos::hotspot_config::mojom::SetHotspotConfigResult::kSuccess,
+            SetHotspotConfig(GenerateTestConfig()));
+  EXPECT_EQ(1u, observer_.hotspot_status_changed_count());
+  auto hotspot_config = hotspot_state_handler_->GetHotspotConfig();
+  ASSERT_TRUE(hotspot_config);
+  ASSERT_FALSE(hotspot_config->auto_disable);
+  EXPECT_EQ(hotspot_config->band,
+            chromeos::hotspot_config::mojom::WiFiBand::k5GHz);
+  EXPECT_EQ(hotspot_config->security,
+            chromeos::hotspot_config::mojom::WiFiSecurityMode::kWpa2);
+  EXPECT_EQ(hotspot_config->ssid, kHotspotConfigSSID);
+  EXPECT_EQ(hotspot_config->passphrase, kHotspotConfigPassphrase);
+
+  Logout();
+  ASSERT_FALSE(hotspot_state_handler_->GetHotspotConfig());
+  EXPECT_EQ(2u, observer_.hotspot_status_changed_count());
+}
+
 }  // namespace ash
diff --git a/chromeos/ash/components/network/hotspot_util.cc b/chromeos/ash/components/network/hotspot_util.cc
new file mode 100644
index 0000000..86cbbab
--- /dev/null
+++ b/chromeos/ash/components/network/hotspot_util.cc
@@ -0,0 +1,172 @@
+// 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/ash/components/network/hotspot_util.h"
+
+#include "base/values.h"
+#include "chromeos/ash/components/network/network_event_log.h"
+#include "chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+
+namespace ash {
+
+namespace hotspot_config {
+namespace mojom = ::chromeos::hotspot_config::mojom;
+}  // namespace hotspot_config
+
+namespace {
+
+// TODO (jiajunz): Use shill constants after they are added.
+const char kShillTetheringBand2_4GHz[] = "2.4GHz";
+const char kShillTetheringBand5GHz[] = "5GHz";
+
+hotspot_config::mojom::WiFiBand ShillBandToMojom(
+    const std::string& shill_band) {
+  using hotspot_config::mojom::WiFiBand;
+
+  if (shill_band == kShillTetheringBand2_4GHz) {
+    return WiFiBand::k2_4GHz;
+  }
+  if (shill_band == kShillTetheringBand5GHz) {
+    return WiFiBand::k5GHz;
+  }
+  NOTREACHED() << "Unexpected shill tethering band: " << shill_band;
+  return WiFiBand::k5GHz;
+}
+
+hotspot_config::mojom::WiFiSecurityMode ShillSecurityToMojom(
+    const std::string& shill_security) {
+  using hotspot_config::mojom::WiFiSecurityMode;
+
+  if (shill_security == shill::kSecurityWpa2) {
+    return WiFiSecurityMode::kWpa2;
+  }
+  if (shill_security == shill::kSecurityWpa2) {
+    return WiFiSecurityMode::kWpa3;
+  }
+  if (shill_security == shill::kSecurityWpa2Wpa3) {
+    return WiFiSecurityMode::kWpa2Wpa3;
+  }
+
+  NOTREACHED() << "Unexpected shill tethering security mode: "
+               << shill_security;
+  return WiFiSecurityMode::kWpa2;
+}
+
+std::string MojomBandToString(hotspot_config::mojom::WiFiBand mojom_band) {
+  using hotspot_config::mojom::WiFiBand;
+
+  switch (mojom_band) {
+    case WiFiBand::k2_4GHz:
+      return kShillTetheringBand2_4GHz;
+    case WiFiBand::k5GHz:
+      return kShillTetheringBand5GHz;
+  }
+}
+
+std::string MojomSecurityToString(
+    hotspot_config::mojom::WiFiSecurityMode mojom_security) {
+  using hotspot_config::mojom::WiFiSecurityMode;
+
+  switch (mojom_security) {
+    case WiFiSecurityMode::kWpa2:
+      return shill::kSecurityWpa2;
+    case WiFiSecurityMode::kWpa3:
+      return shill::kSecurityWpa3;
+    case WiFiSecurityMode::kWpa2Wpa3:
+      return shill::kSecurityWpa2Wpa3;
+  }
+}
+
+}  // namespace
+
+hotspot_config::mojom::HotspotState ShillTetheringStateToMojomState(
+    const std::string& shill_state) {
+  using hotspot_config::mojom::HotspotState;
+
+  if (shill_state == shill::kTetheringStateActive) {
+    return HotspotState::kEnabled;
+  }
+
+  if (shill_state == shill::kTetheringStateIdle) {
+    return HotspotState::kDisabled;
+  }
+
+  if (shill_state == shill::kTetheringStateStarting) {
+    return HotspotState::kEnabling;
+  }
+
+  if (shill_state == shill::kTetheringStateStopping) {
+    return HotspotState::kDisabling;
+  }
+
+  NOTREACHED() << "Unexpected shill tethering state: " << shill_state;
+  return HotspotState::kDisabled;
+}
+
+hotspot_config::mojom::HotspotConfigPtr ShillTetheringConfigToMojomConfig(
+    const base::Value& shill_tethering_config) {
+  using hotspot_config::mojom::HotspotConfig;
+
+  auto result = HotspotConfig::New();
+  absl::optional<bool> auto_disable = shill_tethering_config.GetDict().FindBool(
+      shill::kTetheringConfAutoDisableProperty);
+  if (!auto_disable) {
+    NET_LOG(ERROR) << "Auto_disable not found in tethering config.";
+  }
+  result->auto_disable = auto_disable ? *auto_disable : false;
+  const std::string* wifi_band = shill_tethering_config.GetDict().FindString(
+      shill::kTetheringConfBandProperty);
+  if (!wifi_band) {
+    NET_LOG(ERROR) << "WiFi band not found in tethering config.";
+    result->band = hotspot_config::mojom::WiFiBand::k5GHz;
+  } else {
+    result->band = ShillBandToMojom(*wifi_band);
+  }
+
+  const std::string* security = shill_tethering_config.GetDict().FindString(
+      shill::kTetheringConfSecurityProperty);
+  if (!security) {
+    NET_LOG(ERROR) << "WiFi security mode not found in tethering config.";
+    result->security = hotspot_config::mojom::WiFiSecurityMode::kWpa2;
+  } else {
+    result->security = ShillSecurityToMojom(*security);
+  }
+
+  const std::string* ssid = shill_tethering_config.GetDict().FindString(
+      shill::kTetheringConfSSIDProperty);
+  if (!ssid) {
+    NET_LOG(ERROR) << "SSID not found in tethering config.";
+  }
+  result->ssid = ssid ? *ssid : std::string();
+  const std::string* passphrase = shill_tethering_config.GetDict().FindString(
+      shill::kTetheringConfPassphraseProperty);
+  if (!passphrase) {
+    NET_LOG(ERROR) << "Passphrase not found in tethering config.";
+  }
+  result->passphrase = passphrase ? *passphrase : std::string();
+  return result;
+}
+
+base::Value MojomConfigToShillConfig(
+    const hotspot_config::mojom::HotspotConfigPtr mojom_config) {
+  using hotspot_config::mojom::HotspotConfig;
+
+  base::Value result(base::Value::Type::DICTIONARY);
+  result.GetDict().Set(shill::kTetheringConfAutoDisableProperty,
+                       base::Value(mojom_config->auto_disable));
+  result.GetDict().Set(shill::kTetheringConfBandProperty,
+                       base::Value(MojomBandToString(mojom_config->band)));
+  result.GetDict().Set(
+      shill::kTetheringConfSecurityProperty,
+      base::Value(MojomSecurityToString(mojom_config->security)));
+  result.GetDict().Set(shill::kTetheringConfSSIDProperty,
+                       base::Value(mojom_config->ssid));
+  result.GetDict().Set(shill::kTetheringConfPassphraseProperty,
+                       base::Value(mojom_config->passphrase));
+  return result;
+}
+
+}  // namespace ash
\ No newline at end of file
diff --git a/chromeos/ash/components/network/hotspot_util.h b/chromeos/ash/components/network/hotspot_util.h
new file mode 100644
index 0000000..c473209b
--- /dev/null
+++ b/chromeos/ash/components/network/hotspot_util.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_HOTSPOT_UTIL_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_HOTSPOT_UTIL_H_
+
+#include <string>
+
+#include "base/component_export.h"
+#include "chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom-forward.h"
+
+namespace base {
+class Value;
+}  // namespace base
+
+namespace ash {
+
+// Convert shill tethering state string value to mojom::HotspotState enum
+COMPONENT_EXPORT(CHROMEOS_NETWORK)
+chromeos::hotspot_config::mojom::HotspotState ShillTetheringStateToMojomState(
+    const std::string& shill_state);
+
+// Convert shill tethering config dictionary value to mojom::HotspotConfigPtr
+COMPONENT_EXPORT(CHROMEOS_NETWORK)
+chromeos::hotspot_config::mojom::HotspotConfigPtr
+ShillTetheringConfigToMojomConfig(const base::Value& shill_tethering_config);
+
+// Convert mojom::HotspotConfigPtr to the corresponding shill tethering config
+// value
+COMPONENT_EXPORT(CHROMEOS_NETWORK)
+base::Value MojomConfigToShillConfig(
+    const chromeos::hotspot_config::mojom::HotspotConfigPtr mojom_config);
+
+}  // namespace ash
+
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_HOTSPOT_UTIL_H_
diff --git a/chromeos/ash/components/string_matching/diacritic_utils.cc b/chromeos/ash/components/string_matching/diacritic_utils.cc
index 9fda6a7..5a123b7 100644
--- a/chromeos/ash/components/string_matching/diacritic_utils.cc
+++ b/chromeos/ash/components/string_matching/diacritic_utils.cc
@@ -7,42 +7,55 @@
 #include <string>
 #include <vector>
 
-#include "base/containers/flat_map.h"
+#include "base/containers/fixed_flat_map.h"
 
 namespace ash::string_matching {
 
-// Intentionally only covering Latin-script accented characters for our initial
-// implementation of diacritic-insensitive search.
-DiacriticUtils::DiacriticUtils() {
-  std::vector<std::pair<std::u16string, std::u16string>>
-      diacritics_to_stripped = {
-          {u"áàâäāå", u"a"}, {u"ÁÀÂÄĀÅ", u"A"}, {u"éèêëē", u"e"},
-          {u"ÉÈÊËĒ", u"E"},  {u"íìîïī", u"i"},  {u"óòôöōø", u"o"},
-          {u"úùûüū", u"u"},  {u"ÚÙÛÜŪ", u"U"},  {u"ýỳŷÿȳ", u"y"},
-          {u"ÝỲŶŸȲ", u"Y"},  {u"ç", u"c"},      {u"Ç", u"C"},
-          {u"ñ", u"n"},      {u"Ñ", u"N"},      {u"æ", u"ae"},
-          {u"Æ", u"AE"},     {u"œ", u"oe"},     {u"Œ", u"OE"},
-      };
+const std::u16string RemoveDiacritics(const std::u16string& str) {
+  // For the initial implementation of diacritic-insensitive search:
+  // 1) Intentionally only covering Latin-script accented characters.
+  // 2) Only deal with 1-to-1 char mapping i.e., "æ > ae; œ > oe; Æ > AE; Œ >
+  // OE" are ignored in this implementation. The implemented ones are listed
+  // as below:
 
-  for (const auto& mapping_pair : diacritics_to_stripped) {
-    for (const auto& diacritic : mapping_pair.first) {
-      conversion_map_[diacritic] = mapping_pair.second;
-    }
-  }
-}
+  // "[ á à â ä ā å ] > a; "
+  // "[ Á À Â Ä Ā Å ] > A; "
+  // "[ é è ê ë ē   ] > e; "
+  // "[ É È Ê Ë Ē   ] > E; "
+  // "[ í ì î ï ī   ] > i; "
+  // "[ Í Ì Î Ï Ī   ] > I; "
+  // "[ ó ò ô ö ō ø ] > o; "
+  // "[ Ó Ò Ô Ö Ō Ø ] > O; "
+  // "[ ú ù û ü ū   ] > u; "
+  // "[ Ú Ù Û Ü Ū   ] > U; "
+  // "[ ý ỳ ŷ ÿ ȳ   ] > y; "
+  // "[ Ý Ỳ Ŷ Ÿ Ȳ   ] > Y; "
+  // "ç > c; ñ > n; "
+  // "Ç > C; Ñ > N;"
 
-DiacriticUtils::~DiacriticUtils() = default;
+  // clang-format off
+  static constexpr auto kConversionMap =
+    base::MakeFixedFlatMap<char16_t, char16_t>({
+      {u'á', u'a'}, {u'à', u'a'}, {u'â', u'a'}, {u'ä', u'a'}, {u'ā', u'a'}, {u'å', u'a'},
+      {u'Á', u'A'}, {u'À', u'A'}, {u'Â', u'A'}, {u'Ä', u'A'}, {u'Ā', u'A'}, {u'Å', u'A'},
+      {u'é', u'e'}, {u'è', u'e'}, {u'ê', u'e'}, {u'ë', u'e'}, {u'ē', u'e'},
+      {u'É', u'E'}, {u'È', u'E'}, {u'Ê', u'E'}, {u'Ë', u'E'}, {u'Ē', u'E'},
+      {u'í', u'i'}, {u'ì', u'i'}, {u'î', u'i'}, {u'ï', u'i'}, {u'ī', u'i'},
+      {u'Í', u'I'}, {u'Ì', u'I'}, {u'Î', u'I'}, {u'Ï', u'I'}, {u'Ī', u'I'},
+      {u'ó', u'o'}, {u'ò', u'o'}, {u'ô', u'o'}, {u'ö', u'o'}, {u'ō', u'o'}, {u'ø', u'o'},
+      {u'Ó', u'O'}, {u'Ò', u'O'}, {u'Ô', u'O'}, {u'Ö', u'O'}, {u'Ō', u'O'}, {u'Ø', u'O'},
+      {u'ú', u'u'}, {u'ù', u'u'}, {u'û', u'u'}, {u'ü', u'u'}, {u'ū', u'u'},
+      {u'Ú', u'U'}, {u'Ù', u'U'}, {u'Û', u'U'}, {u'Ü', u'U'}, {u'Ū', u'U'},
+      {u'ý', u'y'}, {u'ỳ', u'y'}, {u'ŷ', u'y'}, {u'ÿ', u'y'}, {u'ȳ', u'y'},
+      {u'Ý', u'Y'}, {u'Ỳ', u'Y'}, {u'Ŷ', u'Y'}, {u'Ÿ', u'Y'}, {u'Ȳ', u'Y'},
+      {u'ç', u'c'}, {u'Ç', u'C'}, {u'ñ', u'n'}, {u'Ñ', u'N'},
+      });
+  // clang-format on
 
-const std::u16string DiacriticUtils::RemoveDiacritics(
-    const std::u16string& str) {
   std::u16string result;
   for (auto letter : str) {
-    auto it = conversion_map_.find(letter);
-    if (it == conversion_map_.end()) {
-      result.push_back(letter);
-    } else {
-      result.append(it->second);
-    }
+    auto* it = kConversionMap.find(letter);
+    result.push_back(it == kConversionMap.end() ? letter : it->second);
   }
   return result;
 }
diff --git a/chromeos/ash/components/string_matching/diacritic_utils.h b/chromeos/ash/components/string_matching/diacritic_utils.h
index 3bfd955..59c18a02 100644
--- a/chromeos/ash/components/string_matching/diacritic_utils.h
+++ b/chromeos/ash/components/string_matching/diacritic_utils.h
@@ -6,24 +6,12 @@
 #define CHROMEOS_ASH_COMPONENTS_STRING_MATCHING_DIACRITIC_UTILS_H_
 
 #include <string>
-#include "base/containers/flat_map.h"
 
 namespace ash::string_matching {
-class DiacriticUtils {
- public:
-  DiacriticUtils();
-  ~DiacriticUtils();
 
-  DiacriticUtils(const DiacriticUtils&) = delete;
-  DiacriticUtils& operator=(const DiacriticUtils&) = delete;
-
-  // Removes diacritics from 'str' and return the result. e.g.:
-  // RemoveDiacritics(hölzle) => holzle
-  const std::u16string RemoveDiacritics(const std::u16string& str);
-
- private:
-  base::flat_map<char16_t, std::u16string> conversion_map_;
-};
+// Removes diacritics from 'str' and return the result. e.g.:
+// RemoveDiacritics(hölzle) => holzle
+const std::u16string RemoveDiacritics(const std::u16string& str);
 
 }  // namespace ash::string_matching
 #endif  // CHROMEOS_ASH_COMPONENTS_STRING_MATCHING_DIACRITIC_UTILS_H_
diff --git a/chromeos/ash/components/string_matching/diacritic_utils_unittest.cc b/chromeos/ash/components/string_matching/diacritic_utils_unittest.cc
index 34e7c91..582b439 100644
--- a/chromeos/ash/components/string_matching/diacritic_utils_unittest.cc
+++ b/chromeos/ash/components/string_matching/diacritic_utils_unittest.cc
@@ -10,30 +10,28 @@
 class DiacriticUtilsTest : public testing::Test {};
 
 TEST(DiacriticUtilsTest, TestEqual) {
-  DiacriticUtils util;
-  EXPECT_EQ(util.RemoveDiacritics(u"français"), u"francais");
-  EXPECT_EQ(util.RemoveDiacritics(u"déjà"), u"deja");
-  EXPECT_EQ(util.RemoveDiacritics(u"Español"), u"Espanol");
-  EXPECT_EQ(util.RemoveDiacritics(u"École"), u"Ecole");
-  EXPECT_EQ(util.RemoveDiacritics(u"cœur"), u"coeur");
-  EXPECT_EQ(util.RemoveDiacritics(u"København"), u"Kobenhavn");
-  EXPECT_EQ(util.RemoveDiacritics(u"ångström"), u"angstrom");
-  EXPECT_EQ(util.RemoveDiacritics(u"Neuchâtel"), u"Neuchatel");
-  EXPECT_EQ(util.RemoveDiacritics(u"jamón"), u"jamon");
-  EXPECT_EQ(util.RemoveDiacritics(u"NOËL"), u"NOEL");
+  EXPECT_EQ(RemoveDiacritics(u"français"), u"francais");
+  EXPECT_EQ(RemoveDiacritics(u"déjà"), u"deja");
+  EXPECT_EQ(RemoveDiacritics(u"Español"), u"Espanol");
+  EXPECT_EQ(RemoveDiacritics(u"École"), u"Ecole");
+  EXPECT_EQ(RemoveDiacritics(u"còēur"), u"coeur");
+  EXPECT_EQ(RemoveDiacritics(u"København"), u"Kobenhavn");
+  EXPECT_EQ(RemoveDiacritics(u"ångström"), u"angstrom");
+  EXPECT_EQ(RemoveDiacritics(u"Neuchâtel"), u"Neuchatel");
+  EXPECT_EQ(RemoveDiacritics(u"jamón"), u"jamon");
+  EXPECT_EQ(RemoveDiacritics(u"NOËL"), u"NOEL");
 }
 
 TEST(DiacriticUtilsTest, TestNotEqual) {
-  DiacriticUtils util;
-  EXPECT_NE(util.RemoveDiacritics(u"français"), u"français");
-  EXPECT_NE(util.RemoveDiacritics(u"Déjà"), u"deja");
-  EXPECT_NE(util.RemoveDiacritics(u"español"), u"français");
-  EXPECT_NE(util.RemoveDiacritics(u"École"), u"ecole");
-  EXPECT_NE(util.RemoveDiacritics(u"œufs"), u"coeur");
-  EXPECT_NE(util.RemoveDiacritics(u"København"), u"Copenhagen");
-  EXPECT_NE(util.RemoveDiacritics(u"ångström"), u"angstroms");
-  EXPECT_NE(util.RemoveDiacritics(u"Neuchâtel"), u"Newcastle");
-  EXPECT_NE(util.RemoveDiacritics(u"jamón"), u"jambon");
-  EXPECT_NE(util.RemoveDiacritics(u"NOËL"), u"Christmas");
+  EXPECT_NE(RemoveDiacritics(u"français"), u"français");
+  EXPECT_NE(RemoveDiacritics(u"Déjà"), u"deja");
+  EXPECT_NE(RemoveDiacritics(u"español"), u"français");
+  EXPECT_NE(RemoveDiacritics(u"École"), u"ecole");
+  EXPECT_NE(RemoveDiacritics(u"çufs"), u"coeur");
+  EXPECT_NE(RemoveDiacritics(u"København"), u"Copenhagen");
+  EXPECT_NE(RemoveDiacritics(u"ångström"), u"angstroms");
+  EXPECT_NE(RemoveDiacritics(u"Neuchâtel"), u"Newcastle");
+  EXPECT_NE(RemoveDiacritics(u"jamón"), u"jambon");
+  EXPECT_NE(RemoveDiacritics(u"NOËL"), u"Christmas");
 }
 }  // namespace ash::string_matching
diff --git a/chromeos/ash/services/libassistant/audio/audio_input_impl.cc b/chromeos/ash/services/libassistant/audio/audio_input_impl.cc
index 1ad58804..87af5e1 100644
--- a/chromeos/ash/services/libassistant/audio/audio_input_impl.cc
+++ b/chromeos/ash/services/libassistant/audio/audio_input_impl.cc
@@ -480,7 +480,7 @@
 void AudioInputImpl::StartRecording() {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!HasOpenAudioStream());
-  RecreateAudioInputStream(IsHotwordAvailable());
+  RecreateAudioInputStream(IsHotwordAvailable() && IsHotwordEnabled());
 }
 
 void AudioInputImpl::StopRecording() {
diff --git a/chromeos/ash/services/libassistant/audio/audio_input_impl.h b/chromeos/ash/services/libassistant/audio/audio_input_impl.h
index f9d358c..b5a42ecb 100644
--- a/chromeos/ash/services/libassistant/audio/audio_input_impl.h
+++ b/chromeos/ash/services/libassistant/audio/audio_input_impl.h
@@ -25,6 +25,10 @@
 class AudioInputStream;
 class AudioCapturer;
 
+// AudioInputImpl automatically falls back to libassistant based hotword
+// detection if DSP device id is not available.
+// TODO(b/242776750): Remove this behavior if possible to simplify
+// AudioInputImpl.
 class AudioInputImpl : public assistant_client::AudioInput {
  public:
   explicit AudioInputImpl(const absl::optional<std::string>& device_id);
diff --git a/chromeos/ash/services/libassistant/audio_input_controller_unittest.cc b/chromeos/ash/services/libassistant/audio_input_controller_unittest.cc
index 5faf8cdb..973f1b7 100644
--- a/chromeos/ash/services/libassistant/audio_input_controller_unittest.cc
+++ b/chromeos/ash/services/libassistant/audio_input_controller_unittest.cc
@@ -24,6 +24,10 @@
 using mojom::LidState;
 using Resolution = assistant_client::ConversationStateListener::Resolution;
 
+constexpr char kNormalDeviceId[] = "normal-device-id";
+constexpr char kHotwordDeviceId[] = "hotword-device-id";
+constexpr char kSkipForNonDspMessage[] = "This test case is for DSP";
+
 class FakeAudioInputObserver : public assistant_client::AudioInput::Observer {
  public:
   FakeAudioInputObserver() = default;
@@ -38,14 +42,42 @@
   void OnAudioStopped() override {}
 };
 
-class AssistantAudioInputControllerTest : public testing::Test {
+class AssistantAudioInputControllerTest : public testing::TestWithParam<bool> {
  public:
-  AssistantAudioInputControllerTest() : controller_() {
+  AssistantAudioInputControllerTest() : enable_dsp_(GetParam()), controller_() {
     controller_.Bind(client_.BindNewPipeAndPassReceiver(), &platform_delegate_);
 
-    // Enable DSP feature flag.
-    scoped_feature_list_.InitAndEnableFeature(
-        assistant::features::kEnableDspHotword);
+    if (enable_dsp_) {
+      // Enable DSP feature flag.
+      scoped_feature_list_.InitAndEnableFeature(
+          assistant::features::kEnableDspHotword);
+    }
+  }
+
+  void TearDown() override {
+    if (IsSkipped()) {
+      return;
+    }
+
+    EXPECT_TRUE(pre_condition_checked_)
+        << "You must call AssertHotwordAvailableState or MarkPreconditionMet "
+           "to confirm that you are testing the expected environment";
+  }
+
+  // Hotword test requires some set up. AudioInputImpl automatically falls back
+  // to non-DSP hotword if it doesn't meet the condition. This function checks
+  // whether the test is exercising the expected environment.
+  void AssertHotwordAvailableState() {
+    ASSERT_EQ(enable_dsp_, audio_input().IsHotwordAvailable());
+    pre_condition_checked_ = true;
+  }
+
+  // Some test cases exercises non-DSP behavior even for DSP available variant.
+  // Call this function at the end of its test body to mark that the test is
+  // intentionally exercising that scenario.
+  void MarkPreconditionMet() {
+    ASSERT_FALSE(pre_condition_checked_) << "Pre-condition is already checked.";
+    pre_condition_checked_ = true;
   }
 
   // See |InitializeForTestOfType| for an explanation of this enum.
@@ -64,6 +96,9 @@
   // that we're testing. So for example if you call
   // InitializeForTestOfType(kLidState) then this will ensure all requirements
   // are set but not the lid state (which is left in its initial value).
+  //
+  // TODO(b/242776750): Set up in test body instead of using this utility method
+  // to make it clear what set up the test is testing.
   void InitializeForTestOfType(TestType type) {
     if (type != kLidStateTest)
       SetLidState(LidState::kOpen);
@@ -72,10 +107,13 @@
       AddAudioInputObserver();
 
     if (type != kDeviceIdTest)
-      SetDeviceId("fake-audio-device");
+      SetDeviceId(kNormalDeviceId);
 
     if (type != kHotwordEnabledTest)
       SetHotwordEnabled(true);
+
+    if (type != kHotwordDeviceIdTest && enable_dsp_)
+      SetHotwordDeviceId(kHotwordDeviceId);
   }
 
   mojo::Remote<mojom::AudioInputController>& client() { return client_; }
@@ -86,8 +124,33 @@
     return controller().audio_input_provider().GetAudioInput();
   }
 
+  bool IsEnableDspFlagOn() { return enable_dsp_; }
+
+  // TODO(b/242776750): Change this to NotRecordingAudio. If we test that it's
+  // recording, we should test expected channel (query or hotword) as well with
+  // using IsRecordingForQuery or IsRecordingHotword.
   bool IsRecordingAudio() { return audio_input().IsRecordingForTesting(); }
 
+  // TODO(b/242776750): Make this a custom matcher to provide better error
+  // message.
+  bool IsRecordingForQuery() {
+    return audio_input().IsRecordingForTesting() &&
+           audio_input().IsMicOpenForTesting() &&
+           audio_input().GetOpenDeviceIdForTesting() == kNormalDeviceId;
+  }
+
+  bool IsRecordingHotword() {
+    if (enable_dsp_) {
+      return audio_input().IsRecordingForTesting() &&
+             !audio_input().IsMicOpenForTesting() &&
+             audio_input().GetOpenDeviceIdForTesting() == kHotwordDeviceId;
+    } else {
+      return audio_input().IsRecordingForTesting() &&
+             !audio_input().IsMicOpenForTesting() &&
+             audio_input().GetOpenDeviceIdForTesting() == kNormalDeviceId;
+    }
+  }
+
   bool IsUsingDeadStreamDetection() {
     return audio_input().IsUsingDeadStreamDetectionForTesting().value_or(false);
   }
@@ -96,8 +159,6 @@
     return audio_input().GetOpenDeviceIdForTesting().value_or("<none>");
   }
 
-  bool IsMicOpen() { return audio_input().IsMicOpenForTesting(); }
-
   void SetLidState(LidState new_state) {
     client()->SetLidState(new_state);
     client().FlushForTesting();
@@ -134,6 +195,8 @@
   }
 
  private:
+  const bool enable_dsp_;
+  bool pre_condition_checked_ = false;
   base::test::TaskEnvironment environment_;
   base::test::ScopedFeatureList scoped_feature_list_;
   mojo::Remote<mojom::AudioInputController> client_;
@@ -142,10 +205,18 @@
   assistant::FakePlatformDelegate platform_delegate_;
 };
 
+INSTANTIATE_TEST_SUITE_P(Assistant,
+                         AssistantAudioInputControllerTest,
+                         testing::Bool(),
+                         [](const testing::TestParamInfo<bool>& param) {
+                           return param.param ? "DSP" : "NonDSP";
+                         });
+
 }  // namespace
 
-TEST_F(AssistantAudioInputControllerTest, ShouldOnlyRecordWhenLidIsOpen) {
+TEST_P(AssistantAudioInputControllerTest, ShouldOnlyRecordWhenLidIsOpen) {
   InitializeForTestOfType(kLidStateTest);
+  AssertHotwordAvailableState();
 
   // Initially the lid is considered closed.
   EXPECT_FALSE(IsRecordingAudio());
@@ -157,85 +228,110 @@
   EXPECT_FALSE(IsRecordingAudio());
 }
 
-TEST_F(AssistantAudioInputControllerTest, ShouldOnlyRecordWhenDeviceIdIsSet) {
+TEST_P(AssistantAudioInputControllerTest, ShouldOnlyRecordWhenDeviceIdIsSet) {
   InitializeForTestOfType(kDeviceIdTest);
 
   // Initially there is no device id.
   EXPECT_FALSE(IsRecordingAudio());
 
-  SetDeviceId("device-id");
-  EXPECT_TRUE(IsRecordingAudio());
+  SetDeviceId(kNormalDeviceId);
+  AssertHotwordAvailableState();
+  EXPECT_TRUE(IsRecordingHotword());
 
   SetDeviceId(absl::nullopt);
   EXPECT_FALSE(IsRecordingAudio());
 }
 
-TEST_F(AssistantAudioInputControllerTest, StopOnlyRecordWhenHotwordIsEnabled) {
+TEST_P(AssistantAudioInputControllerTest, StopOnlyRecordWhenHotwordIsEnabled) {
   InitializeForTestOfType(kHotwordEnabledTest);
+  AssertHotwordAvailableState();
 
-  // Hotword is enabled by default.
-  EXPECT_TRUE(IsRecordingAudio());
+  // Hotword is enabled by InitializeForTestOfType.
+  EXPECT_TRUE(IsRecordingHotword());
 
   SetHotwordEnabled(false);
+  EXPECT_FALSE(IsRecordingHotword());
+  // Double check that AudioInputImpl is not recording any other type of audio.
   EXPECT_FALSE(IsRecordingAudio());
 
   SetHotwordEnabled(true);
-  EXPECT_TRUE(IsRecordingAudio());
+  EXPECT_TRUE(IsRecordingHotword());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        StartRecordingWhenDisableHotwordAndForceOpenMic) {
   InitializeForTestOfType(kHotwordEnabledTest);
   SetHotwordEnabled(false);
+  AssertHotwordAvailableState();
+
   EXPECT_FALSE(IsRecordingAudio());
 
   // Force open mic should start recording.
+  // This is exercising a corner case. OnConversationTurnStarted() should be
+  // called if mic gets opened.
+  // TODO(b/242776750): Change the query recording condition as mic open +
+  // OnConversationTurnStarted, i.e. do not record for a query if
+  // OnConversationTurnStarted not called.
   SetMicOpen(true);
-  EXPECT_TRUE(IsRecordingAudio());
+  EXPECT_TRUE(IsRecordingForQuery());
 
   SetMicOpen(false);
   EXPECT_FALSE(IsRecordingAudio());
 }
 
-TEST_F(AssistantAudioInputControllerTest, ShouldUseProvidedDeviceId) {
+TEST_P(AssistantAudioInputControllerTest, ShouldUseProvidedDeviceId) {
   InitializeForTestOfType(kDeviceIdTest);
   SetDeviceId("the-expected-device-id");
+  AssertHotwordAvailableState();
 
+  SetMicOpen(true);
+  OnConversationTurnStarted();
   EXPECT_TRUE(IsRecordingAudio());
   EXPECT_EQ("the-expected-device-id", GetOpenDeviceId());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldSwitchToHotwordDeviceIdWhenSet) {
+  if (!IsEnableDspFlagOn()) {
+    GTEST_SKIP() << kSkipForNonDspMessage;
+  }
+
   InitializeForTestOfType(kHotwordDeviceIdTest);
 
-  SetDeviceId("the-device-id");
+  SetDeviceId(kNormalDeviceId);
   EXPECT_TRUE(IsRecordingAudio());
-  EXPECT_EQ("the-device-id", GetOpenDeviceId());
+  EXPECT_EQ(kNormalDeviceId, GetOpenDeviceId());
 
-  SetHotwordDeviceId("the-hotword-device-id");
+  SetHotwordDeviceId(kHotwordDeviceId);
+  AssertHotwordAvailableState();
   EXPECT_TRUE(IsRecordingAudio());
-  EXPECT_EQ("the-hotword-device-id", GetOpenDeviceId());
+  EXPECT_EQ(kHotwordDeviceId, GetOpenDeviceId());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldKeepUsingHotwordDeviceIdWhenDeviceIdChanges) {
+  if (!IsEnableDspFlagOn()) {
+    GTEST_SKIP() << kSkipForNonDspMessage;
+  }
+
   InitializeForTestOfType(kHotwordDeviceIdTest);
 
-  SetDeviceId("the-original-device-id");
-  SetHotwordDeviceId("the-hotword-device-id");
+  SetDeviceId(kNormalDeviceId);
+  SetHotwordDeviceId(kHotwordDeviceId);
+  AssertHotwordAvailableState();
 
   EXPECT_TRUE(IsRecordingAudio());
-  EXPECT_EQ("the-hotword-device-id", GetOpenDeviceId());
+  EXPECT_EQ(kHotwordDeviceId, GetOpenDeviceId());
 
-  SetDeviceId("the-new-device-id");
+  SetDeviceId("new-normal-device-id");
   EXPECT_TRUE(IsRecordingAudio());
-  EXPECT_EQ("the-hotword-device-id", GetOpenDeviceId());
+  EXPECT_EQ(kHotwordDeviceId, GetOpenDeviceId());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldUseDefaultDeviceIdIfNoDeviceIdIsSet) {
   InitializeForTestOfType(kDeviceIdTest);
+
   // Mic must be open, otherwise we will not start recording audio if the
   // device id is not set.
   SetMicOpen(true);
@@ -244,24 +340,36 @@
 
   EXPECT_TRUE(IsRecordingAudio());
   EXPECT_EQ(media::AudioDeviceDescription::kDefaultDeviceId, GetOpenDeviceId());
+
+  MarkPreconditionMet();
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        DeadStreamDetectionShouldBeDisabledWhenUsingHotwordDevice) {
+  if (!IsEnableDspFlagOn()) {
+    GTEST_SKIP() << kSkipForNonDspMessage;
+  }
+
   InitializeForTestOfType(kHotwordDeviceIdTest);
 
   SetHotwordDeviceId(absl::nullopt);
   EXPECT_TRUE(IsUsingDeadStreamDetection());
 
-  SetHotwordDeviceId("fake-hotword-device");
+  SetHotwordDeviceId(kHotwordDeviceId);
+  AssertHotwordAvailableState();
   EXPECT_FALSE(IsUsingDeadStreamDetection());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldSwitchToNormalAudioDeviceWhenConversationTurnStarts) {
+  if (!IsEnableDspFlagOn()) {
+    GTEST_SKIP() << kSkipForNonDspMessage;
+  }
+
   InitializeForTestOfType(kDeviceIdTest);
   SetDeviceId("normal-device-id");
   SetHotwordDeviceId("hotword-device-id");
+  AssertHotwordAvailableState();
 
   // While checking for hotword we should be using the hotword device.
   EXPECT_EQ("hotword-device-id", GetOpenDeviceId());
@@ -272,11 +380,16 @@
   EXPECT_EQ("normal-device-id", GetOpenDeviceId());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldSwitchToHotwordAudioDeviceWhenConversationIsFinished) {
+  if (!IsEnableDspFlagOn()) {
+    GTEST_SKIP() << kSkipForNonDspMessage;
+  }
+
   InitializeForTestOfType(kDeviceIdTest);
   SetDeviceId("normal-device-id");
   SetHotwordDeviceId("hotword-device-id");
+  AssertHotwordAvailableState();
 
   // During the conversation we should be using the normal audio device.
   OnConversationTurnStarted();
@@ -288,38 +401,61 @@
   EXPECT_EQ("hotword-device-id", GetOpenDeviceId());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldCloseMicWhenConversationIsFinishedNormally) {
   InitializeForTestOfType(kDeviceIdTest);
   SetMicOpen(true);
-  SetDeviceId("normal-device-id");
-  SetHotwordDeviceId("hotword-device-id");
+  SetDeviceId(kNormalDeviceId);
+  SetHotwordDeviceId(kHotwordDeviceId);
+  AssertHotwordAvailableState();
 
   // Mic should keep opened during the conversation.
   OnConversationTurnStarted();
-  EXPECT_EQ(true, IsMicOpen());
+  EXPECT_TRUE(IsRecordingForQuery());
 
   // Once the conversation has finished normally without needing mic to keep
   // opened, we should close it.
   OnConversationTurnFinished();
-  EXPECT_EQ(false, IsMicOpen());
+  EXPECT_TRUE(IsRecordingHotword());
 }
 
-TEST_F(AssistantAudioInputControllerTest,
+TEST_P(AssistantAudioInputControllerTest,
        ShouldKeepMicOpenedIfNeededWhenConversationIsFinished) {
   InitializeForTestOfType(kDeviceIdTest);
   SetMicOpen(true);
-  SetDeviceId("normal-device-id");
-  SetHotwordDeviceId("hotword-device-id");
+  SetDeviceId(kNormalDeviceId);
+  SetHotwordDeviceId(kHotwordDeviceId);
+  AssertHotwordAvailableState();
 
   // Mic should keep opened during the conversation.
   OnConversationTurnStarted();
-  EXPECT_EQ(true, IsMicOpen());
+  EXPECT_EQ(true, IsRecordingForQuery());
 
   // If the conversation is finished where mic should still be kept opened
   // (i.e. there's a follow-up interaction), we should keep mic opened.
   OnConversationTurnFinished(Resolution::NORMAL_WITH_FOLLOW_ON);
-  EXPECT_EQ(true, IsMicOpen());
+
+  // TODO(b/242776750): MicOpen=true doesn't mean that AudioInputImpl is
+  // recording. Double check that whether it's expected behavior, i.e. whether
+  // this expects that IsRecordingForQuery=true or not.
+  EXPECT_EQ(true, audio_input().IsMicOpenForTesting());
+}
+
+TEST_P(AssistantAudioInputControllerTest,
+       ShouldCloseMicWhenConversationIsFinishedNormallyHotwordOff) {
+  InitializeForTestOfType(kDeviceIdTest);
+  SetDeviceId(kNormalDeviceId);
+  SetHotwordDeviceId(kHotwordDeviceId);
+  SetHotwordEnabled(false);
+  AssertHotwordAvailableState();
+  ASSERT_EQ(false, IsRecordingAudio());
+
+  SetMicOpen(true);
+  OnConversationTurnStarted();
+  EXPECT_EQ(true, IsRecordingForQuery());
+
+  OnConversationTurnFinished();
+  EXPECT_EQ(false, IsRecordingAudio());
 }
 
 }  // namespace libassistant
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index ba1abc2..977cafc 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -2087,6 +2087,9 @@
       <message name="IDS_PERSONALIZATION_APP_BACK_BUTTON" desc="Aria label for the back button to return to a prior page">
         Back to <ph name="PAGE_NAME">$1<ex>Wallpaper</ex></ph>
       </message>
+      <message name="IDS_PERSONALIZATION_APP_GUEST_NAME" desc="Name of the guest user in personalization hub">
+        Guest
+      </message>
       <message name="IDS_PERSONALIZATION_APP_WALLPAPER_COLLECTIONS" desc="Aria label for the wallpaper collections grid">
         Wallpaper Collections
       </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_GUEST_NAME.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_GUEST_NAME.png.sha1
new file mode 100644
index 0000000..30b52cb
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_GUEST_NAME.png.sha1
@@ -0,0 +1 @@
+8a64ace7ad2666ec9c6b08ba116a8d24becc5f6a
\ No newline at end of file
diff --git a/chromeos/login/OWNERS b/chromeos/login/OWNERS
index 2bffa11..47e22b3d 100644
--- a/chromeos/login/OWNERS
+++ b/chromeos/login/OWNERS
@@ -1,6 +1,6 @@
 # in CET
 antrim@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 
 # in PST
 achuith@chromium.org
diff --git a/chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom b/chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom
index bde091f..742712a 100644
--- a/chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom
+++ b/chromeos/services/hotspot_config/public/mojom/cros_hotspot_config.mojom
@@ -9,4 +9,43 @@
   kEnabled,
   kEnabling,
   kDisabling,
-};
\ No newline at end of file
+};
+
+// Represents security modes for WiFi downstream.
+enum WiFiSecurityMode {
+  kWpa2,
+  kWpa3,
+  kWpa2Wpa3,
+};
+
+// Represents bandwidth for WiFi downstream.
+enum WiFiBand {
+  // 2.4GHz bandwidth
+  k2_4GHz,
+  k5GHz,
+};
+
+// Configuration properties for Hotspot.
+struct HotspotConfig {
+  // When set Hotspot will disable automatically when inactive for a fixed
+  // amount of time.
+  bool auto_disable;
+  // Security mode for WiFi downstream.
+  WiFiSecurityMode security;
+  // The tethering band preference, this should be one of "2.4GHz" or "5GHz".
+  WiFiBand band;
+  // SSID of WiFi downstream.
+  string ssid;
+  // Passphrase for WiFi downstream.
+  string passphrase;
+};
+
+// Result code when setting hotspot configuration.
+enum SetHotspotConfigResult {
+  // Operation succeeded.
+  kSuccess,
+  // Failed because the user is not logged in.
+  kFailedNotLogin,
+  // Failed for invalid hotspot configuration.
+  kFailedInvalidConfiguration,
+};
diff --git a/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc b/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc
index ba397a4..23b329f 100644
--- a/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc
+++ b/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc
@@ -69,53 +69,49 @@
                                                 kMultitaskMenuPortraitHeight)
                                     : gfx::Size(kMultitaskMenuLandscapeWidth,
                                                 kMultitaskMenuLandscapeHeight));
-
-  half_button_ =
-      static_cast<SplitButtonView*>(AddChildView(CreateButtonContainer(
-          std::make_unique<SplitButtonView>(
-              SplitButton::SplitButtonType::kHalfButtons,
-              base::BindRepeating(&MultitaskMenuView::SplitButtonPressed,
-                                  base::Unretained(this),
-                                  SnapDirection::kPrimary),
-              base::BindRepeating(&MultitaskMenuView::SplitButtonPressed,
-                                  base::Unretained(this),
-                                  SnapDirection::kSecondary),
-              is_portrait_mode),
-          IDS_APP_ACCNAME_HALF)));
+  // Half button.
+  auto half_button = std::make_unique<SplitButtonView>(
+      SplitButton::SplitButtonType::kHalfButtons,
+      base::BindRepeating(&MultitaskMenuView::SplitButtonPressed,
+                          base::Unretained(this), SnapDirection::kPrimary),
+      base::BindRepeating(&MultitaskMenuView::SplitButtonPressed,
+                          base::Unretained(this), SnapDirection::kSecondary),
+      is_portrait_mode);
+  half_button_ = half_button.get();
+  AddChildView(
+      CreateButtonContainer(std::move(half_button), IDS_APP_ACCNAME_HALF));
 
   // Partial button.
-  partial_button_ =
-      static_cast<SplitButtonView*>(AddChildView(CreateButtonContainer(
-          std::make_unique<SplitButtonView>(
-              SplitButton::SplitButtonType::kPartialButtons,
-              base::BindRepeating(&MultitaskMenuView::PartialButtonPressed,
-                                  base::Unretained(this),
-                                  SnapDirection::kPrimary),
-              base::BindRepeating(&MultitaskMenuView::PartialButtonPressed,
-                                  base::Unretained(this),
-                                  SnapDirection::kSecondary),
-              is_portrait_mode),
-          IDS_APP_ACCNAME_PARTIAL)));
+  auto partial_button = std::make_unique<SplitButtonView>(
+      SplitButton::SplitButtonType::kPartialButtons,
+      base::BindRepeating(&MultitaskMenuView::PartialButtonPressed,
+                          base::Unretained(this), SnapDirection::kPrimary),
+      base::BindRepeating(&MultitaskMenuView::PartialButtonPressed,
+                          base::Unretained(this), SnapDirection::kSecondary),
+      is_portrait_mode);
+  partial_button_ = partial_button.get();
+  AddChildView(CreateButtonContainer(std::move(partial_button),
+                                     IDS_APP_ACCNAME_PARTIAL));
 
   // Full screen button.
-  full_button_ =
-      static_cast<MultitaskBaseButton*>(AddChildView(CreateButtonContainer(
-          std::make_unique<MultitaskBaseButton>(
-              base::BindRepeating(&MultitaskMenuView::FullScreenButtonPressed,
-                                  base::Unretained(this)),
-              MultitaskBaseButton::Type::kFull, is_portrait_mode,
-              l10n_util::GetStringUTF16(IDS_APP_ACCNAME_FULL)),
-          IDS_APP_ACCNAME_FULL)));
+  auto full_button = std::make_unique<MultitaskBaseButton>(
+      base::BindRepeating(&MultitaskMenuView::FullScreenButtonPressed,
+                          base::Unretained(this)),
+      MultitaskBaseButton::Type::kFull, is_portrait_mode,
+      l10n_util::GetStringUTF16(IDS_APP_ACCNAME_FULL));
+  full_button_ = full_button.get();
+  AddChildView(
+      CreateButtonContainer(std::move(full_button), IDS_APP_ACCNAME_FULL));
 
   // Float on top button.
-  float_button_ =
-      static_cast<MultitaskBaseButton*>(AddChildView(CreateButtonContainer(
-          std::make_unique<MultitaskBaseButton>(
-              base::BindRepeating(&MultitaskMenuView::FloatButtonPressed,
-                                  base::Unretained(this)),
-              MultitaskBaseButton::Type::kFloat, is_portrait_mode,
-              l10n_util::GetStringUTF16(IDS_APP_ACCNAME_FLOAT_ON_TOP)),
-          IDS_APP_ACCNAME_FLOAT_ON_TOP)));
+  auto float_button = std::make_unique<MultitaskBaseButton>(
+      base::BindRepeating(&MultitaskMenuView::FloatButtonPressed,
+                          base::Unretained(this)),
+      MultitaskBaseButton::Type::kFloat, is_portrait_mode,
+      l10n_util::GetStringUTF16(IDS_APP_ACCNAME_FLOAT_ON_TOP));
+  float_button_ = float_button.get();
+  AddChildView(CreateButtonContainer(std::move(float_button),
+                                     IDS_APP_ACCNAME_FLOAT_ON_TOP));
 }
 
 MultitaskMenuView::~MultitaskMenuView() = default;
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 117d5e2..2909518 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -464,6 +464,7 @@
     deps += [
       "//base:base_java_unittest_support",
       "//components/android_autofill/browser:unit_tests",
+      "//components/autofill_assistant/browser/android:unit_tests",
       "//components/autofill_assistant/content/browser:unit_tests",
       "//components/autofill_assistant/content/renderer:unit_tests",
       "//components/browser_ui/sms/android:unit_tests",
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 29b1c2e..3a97bba 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -322,8 +322,8 @@
 }
 
 void ArcIntentHelperBridge::OnSupportedLinksChanged(
-    std::vector<arc::mojom::SupportedLinksPtr> added_packages,
-    std::vector<arc::mojom::SupportedLinksPtr> removed_packages,
+    std::vector<arc::mojom::SupportedLinksPackagePtr> added_packages,
+    std::vector<arc::mojom::SupportedLinksPackagePtr> removed_packages,
     arc::mojom::SupportedLinkChangeSource source) {
   for (auto& observer : observer_list_)
     observer.OnArcSupportedLinksChanged(added_packages, removed_packages,
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.h b/components/arc/intent_helper/arc_intent_helper_bridge.h
index 1c825fb5..319dce3 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.h
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.h
@@ -105,8 +105,8 @@
   void IsChromeAppEnabled(arc::mojom::ChromeApp app,
                           IsChromeAppEnabledCallback callback) override;
   void OnSupportedLinksChanged(
-      std::vector<arc::mojom::SupportedLinksPtr> added_packages,
-      std::vector<arc::mojom::SupportedLinksPtr> removed_packages,
+      std::vector<arc::mojom::SupportedLinksPackagePtr> added_packages,
+      std::vector<arc::mojom::SupportedLinksPackagePtr> removed_packages,
       arc::mojom::SupportedLinkChangeSource source) override;
   void OnDownloadAdded(const std::string& relative_path,
                        const std::string& owner_package_name) override;
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
index 9c03ff4..c97f8bb 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
@@ -180,13 +180,14 @@
                 OnIntentFiltersUpdated,
                 (const absl::optional<std::string>& package_name),
                 (override));
-    MOCK_METHOD(
-        void,
-        OnArcSupportedLinksChanged,
-        (const std::vector<arc::mojom::SupportedLinksPtr>& added_packages,
-         const std::vector<arc::mojom::SupportedLinksPtr>& removed_packages,
-         arc::mojom::SupportedLinkChangeSource source),
-        (override));
+    MOCK_METHOD(void,
+                OnArcSupportedLinksChanged,
+                (const std::vector<arc::mojom::SupportedLinksPackagePtr>&
+                     added_packages,
+                 const std::vector<arc::mojom::SupportedLinksPackagePtr>&
+                     removed_packages,
+                 arc::mojom::SupportedLinkChangeSource source),
+                (override));
   };
 
   // Create and add observer.
diff --git a/components/arc/intent_helper/arc_intent_helper_observer.h b/components/arc/intent_helper/arc_intent_helper_observer.h
index 59599cf..e3457d1 100644
--- a/components/arc/intent_helper/arc_intent_helper_observer.h
+++ b/components/arc/intent_helper/arc_intent_helper_observer.h
@@ -39,8 +39,8 @@
   // |added_packages| contains packages for which the setting was enabled,
   // |removed_packages| contains packages for which the setting was disabled.
   virtual void OnArcSupportedLinksChanged(
-      const std::vector<arc::mojom::SupportedLinksPtr>& added_packages,
-      const std::vector<arc::mojom::SupportedLinksPtr>& removed_packages,
+      const std::vector<arc::mojom::SupportedLinksPackagePtr>& added_packages,
+      const std::vector<arc::mojom::SupportedLinksPackagePtr>& removed_packages,
       arc::mojom::SupportedLinkChangeSource source) {}
 
   virtual void OnIconInvalidated(const std::string& package_name) {}
diff --git a/components/arc/test/fake_intent_helper_host.cc b/components/arc/test/fake_intent_helper_host.cc
index e9ab646..9c94a99 100644
--- a/components/arc/test/fake_intent_helper_host.cc
+++ b/components/arc/test/fake_intent_helper_host.cc
@@ -47,8 +47,8 @@
     arc::mojom::ChromeApp app,
     IsChromeAppEnabledCallback callback) {}
 void FakeIntentHelperHost::OnSupportedLinksChanged(
-    std::vector<arc::mojom::SupportedLinksPtr> added_packages,
-    std::vector<arc::mojom::SupportedLinksPtr> removed_packages,
+    std::vector<arc::mojom::SupportedLinksPackagePtr> added_packages,
+    std::vector<arc::mojom::SupportedLinksPackagePtr> removed_packages,
     arc::mojom::SupportedLinkChangeSource source) {}
 void FakeIntentHelperHost::OnDownloadAdded(
     const std::string& relative_path,
diff --git a/components/arc/test/fake_intent_helper_host.h b/components/arc/test/fake_intent_helper_host.h
index 7c674d65..e685d27 100644
--- a/components/arc/test/fake_intent_helper_host.h
+++ b/components/arc/test/fake_intent_helper_host.h
@@ -49,8 +49,8 @@
   void IsChromeAppEnabled(arc::mojom::ChromeApp app,
                           IsChromeAppEnabledCallback callback) override;
   void OnSupportedLinksChanged(
-      std::vector<arc::mojom::SupportedLinksPtr> added_packages,
-      std::vector<arc::mojom::SupportedLinksPtr> removed_packages,
+      std::vector<arc::mojom::SupportedLinksPackagePtr> added_packages,
+      std::vector<arc::mojom::SupportedLinksPackagePtr> removed_packages,
       arc::mojom::SupportedLinkChangeSource source) override;
   void OnDownloadAdded(const std::string& relative_path,
                        const std::string& owner_package_name) override;
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc
index b7ff941..460b794 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -368,16 +368,12 @@
                              suggestion_nickname, obfuscation_length),
                          Suggestion::Text::IsPrimary(true));
 
-    if (!base::FeatureList::IsEnabled(
-            features::kAutofillRemoveCardExpiryFromDownstreamSuggestion)) {
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
-      suggestion_label = credit_card.GetInfo(
-          AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale);
+    suggestion_label = credit_card.GetInfo(
+        AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale);
 #else
-      suggestion_label = credit_card.DescriptiveExpiration(app_locale);
+    suggestion_label = credit_card.DescriptiveExpiration(app_locale);
 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
-    }
-
   } else if (credit_card.number().empty()) {
     DCHECK_EQ(credit_card.record_type(), CreditCard::LOCAL_CARD);
     if (credit_card.HasNonEmptyValidNickname()) {
@@ -407,7 +403,7 @@
   }
 
   if (!suggestion_label.empty())
-    suggestion.labels = {{Suggestion::Text(suggestion_label)}};
+    suggestion.labels = {{Suggestion::Text(std::move(suggestion_label))}};
 
   // For virtual cards, use issuer's card art icon instead of network icon.
   if (virtual_card_option) {
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index dda4c844..ebe0169 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -766,6 +766,27 @@
   }
 
   submitted_form->set_submission_source(source);
+
+  // Update Personal Data with the form's submitted data.
+  // Also triggers offering local/upload credit card save, if applicable.
+  if (submitted_form->IsAutofillable() ||
+      ContainsAutofillableValue(*submitted_form)) {
+    FormDataImporter* form_data_importer = client()->GetFormDataImporter();
+    form_data_importer->ImportFormData(*submitted_form,
+                                       IsAutofillProfileEnabled(),
+                                       IsAutofillCreditCardEnabled());
+    // Associate the form signatures of recently submitted address/credit card
+    // forms to `submitted_form`, if it is an address/credit card form itself.
+    // This information is attached to the vote.
+    if (base::FeatureList::IsEnabled(features::kAutofillAssociateForms)) {
+      if (absl::optional<FormStructure::FormAssociations> associations =
+              form_data_importer->GetFormAssociations(
+                  submitted_form->form_signature())) {
+        submitted_form->set_form_associations(*associations);
+      }
+    }
+  }
+
   MaybeStartVoteUploadProcess(std::move(submitted_form),
                               /*observed_submission=*/true);
 
@@ -785,17 +806,6 @@
     credit_card_form_event_logger_->OnFormSubmitted(sync_state_,
                                                     *submitted_form);
   }
-
-  if (!submitted_form->IsAutofillable() &&
-      !ContainsAutofillableValue(*submitted_form)) {
-    return;
-  }
-
-  // Update Personal Data with the form's submitted data.
-  // Also triggers offering local/upload credit card save, if applicable.
-  client()->GetFormDataImporter()->ImportFormData(
-      *submitted_form, IsAutofillProfileEnabled(),
-      IsAutofillCreditCardEnabled());
 }
 
 bool BrowserAutofillManager::MaybeStartVoteUploadProcess(
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index bac4f22..60b7a665 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -109,7 +109,6 @@
 
 namespace autofill {
 
-using features::kAutofillRemoveCardExpiryFromDownstreamSuggestion;
 using mojom::SubmissionIndicatorEvent;
 using mojom::SubmissionSource;
 
@@ -2375,44 +2374,6 @@
                  browser_autofill_manager_->GetPackedCreditCardID(1)));
 }
 
-// Test that a suggestion does not have label (expiration date) if the
-// suggestion is poped up from a credit card number field.
-TEST_F(BrowserAutofillManagerTest,
-       GetCreditCardSuggestions_NoLabelForCCNumberField) {
-  scoped_feature_list_.InitAndEnableFeature(
-      kAutofillRemoveCardExpiryFromDownstreamSuggestion);
-
-  personal_data().ClearCreditCards();
-  ASSERT_EQ(0U, personal_data().GetCreditCards().size());
-
-  CreditCard credit_card0("287151C8-6AB1-487C-9095-28E80BE5DA15",
-                          test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card0, "Clyde Barrow",
-                          "378282246310005" /* American Express */, "04",
-                          "2999", "1");
-  credit_card0.set_guid("00000000-0000-0000-0000-000000000001");
-  personal_data().AddCreditCard(credit_card0);
-
-  ASSERT_EQ(1U, personal_data().GetCreditCards().size());
-
-  // Set up our form data.
-  FormData form;
-  CreateTestCreditCardFormData(&form, true, false);
-  std::vector<FormData> forms(1, form);
-  FormsSeen(forms);
-
-  // Query by card number field.
-  FormFieldData field = form.fields[1];
-  GetAutofillSuggestions(form, field);
-
-  CheckSuggestions(
-      kDefaultPageID,
-      Suggestion(
-          std::string("Amex  ") + test::ObfuscatedCardDigitsAsUTF8("0005"),
-          std::string(), kAmericanExpressCard,
-          browser_autofill_manager_->GetPackedCreditCardID(1)));
-}
-
 TEST_F(BrowserAutofillManagerTest, OnCreditCardFetched_StoreInstrumentId) {
   FormData form;
   CreateTestCreditCardFormData(&form, true, false);
@@ -6234,56 +6195,6 @@
   EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 }
 
-// Test that we are able to save form data after the possible types have been
-// determined. We do two submissions and verify that only at the second
-// submission are the possible types able to be inferred.
-TEST_P(BrowserAutofillManagerStructuredProfileTest,
-       FormSubmittedPossibleTypesTwoSubmissions) {
-  // Set up our form data.
-  FormData form;
-  std::vector<ServerFieldTypeSet> expected_types;
-  test::CreateTestAddressFormData(&form, &expected_types);
-  FormsSeen(std::vector<FormData>(1, form));
-
-  // Fill the form.
-  const char guid[] = "00000000-0000-0000-0000-000000000001";
-  int response_page_id = 0;
-  FormData response_data;
-  FillAutofillFormDataAndSaveResults(kDefaultPageID, form, form.fields[0],
-                                     MakeFrontendId(std::string(), guid),
-                                     &response_page_id, &response_data);
-  ExpectFilledAddressFormElvis(response_page_id, response_data, kDefaultPageID,
-                               false);
-
-  personal_data().ClearProfiles();
-  // The default credit card is a Elvis card. It must be removed because name
-  // fields would be detected. However at least one profile or card is needed to
-  // start the upload process, which is why this other card is created.
-  personal_data().ClearCreditCards();
-  CreditCard credit_card;
-  test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
-                          "4234567890654321",  // Visa
-                          "04", "2999", "1");
-  credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data().AddCreditCard(credit_card);
-  ASSERT_EQ(0u, personal_data().GetProfiles().size());
-
-  // Simulate form submission. The first submission should not count the data
-  // towards possible types. Therefore we expect all UNKNOWN_TYPE entries.
-  ServerFieldTypeSet type_set;
-  type_set.insert(UNKNOWN_TYPE);
-  std::vector<ServerFieldTypeSet> unknown_types(expected_types.size(),
-                                                type_set);
-  browser_autofill_manager_->SetExpectedSubmittedFieldTypes(unknown_types);
-  FormSubmitted(response_data);
-  ASSERT_EQ(1u, personal_data().GetProfiles().size());
-
-  // The second submission should now have data by which to infer types.
-  browser_autofill_manager_->SetExpectedSubmittedFieldTypes(expected_types);
-  FormSubmitted(response_data);
-  ASSERT_EQ(1u, personal_data().GetProfiles().size());
-}
-
 // Test that the form signature for an uploaded form always matches the form
 // signature from the query.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc
index 94d146c0..6fab039 100644
--- a/components/autofill/core/browser/form_data_importer.cc
+++ b/components/autofill/core/browser/form_data_importer.cc
@@ -16,7 +16,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/containers/contains.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -388,6 +387,21 @@
                                            address_profile_import_candidates);
   }
 
+  if (base::FeatureList::IsEnabled(features::kAutofillAssociateForms)) {
+    auto origin = url::Origin::Create(submitted_form.source_url());
+    FormSignature form_signature = submitted_form.form_signature();
+    // TODO(crbug.com/1347795): Associate multiple sections within a single form
+    // with each other.
+    if (address_import) {
+      form_associator_.TrackFormAssociations(
+          origin, form_signature, FormAssociator::FormType::kAddressForm);
+    }
+    if (cc_import) {
+      form_associator_.TrackFormAssociations(
+          origin, form_signature, FormAssociator::FormType::kCreditCardForm);
+    }
+  }
+
   if (cc_import || address_import || imported_upi_id->has_value())
     return true;
 
@@ -627,6 +641,9 @@
             features::kAutofillRemoveInvalidPhoneNumberOnImport)) {
       candidate_profile.ClearFields({PHONE_HOME_WHOLE_NUMBER});
       import_metadata.did_remove_invalid_phone_number = true;
+      LOG_AF(import_log_buffer)
+          << LogMessage::kImportAddressProfileFromFormRemoveInvalidValue
+          << "Phone number." << CTag{};
     } else {
       has_invalid_phone_number = true;
       LOG_AF(import_log_buffer)
@@ -1084,19 +1101,8 @@
 
 void FormDataImporter::OnBrowsingHistoryCleared(
     const history::DeletionInfo& deletion_info) {
-  // Delete all multi-step import candidates when:
-  // - The entire browsing history is cleared, or
-  // - At least one URL from the same origin as `multistep_importer_`
-  //   is deleted.
-  if (deletion_info.IsAllHistory() ||
-      (multistep_importer_.Origin() &&
-       base::Contains(deletion_info.deleted_rows(),
-                      *multistep_importer_.Origin(),
-                      [](const history::URLRow& url_row) {
-                        return url::Origin::Create(url_row.url());
-                      }))) {
-    ClearMultiStepImportCandidates();
-  }
+  multistep_importer_.OnBrowsingHistoryCleared(deletion_info);
+  form_associator_.OnBrowsingHistoryCleared(deletion_info);
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h
index 5a27bb32..277dee2 100644
--- a/components/autofill/core/browser/form_data_importer.h
+++ b/components/autofill/core/browser/form_data_importer.h
@@ -101,6 +101,12 @@
   void OnBrowsingHistoryCleared(
       const history::DeletionInfo& deletion_info) override;
 
+  // See `FormAssociator::GetFormAssociations()`.
+  absl::optional<FormStructure::FormAssociations> GetFormAssociations(
+      FormSignature form_signature) const {
+    return form_associator_.GetFormAssociations(form_signature);
+  }
+
  protected:
   // Exposed for testing.
   void set_credit_card_save_manager(
@@ -301,6 +307,9 @@
   // Enables importing from multi-step import flows.
   MultiStepImportMerger multistep_importer_;
 
+  // Enables associating recently submitted forms with each other.
+  FormAssociator form_associator_;
+
   friend class AutofillMergeTest;
   friend class FormDataImporterTest;
   friend class FormDataImporterTestBase;
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 842dc5ec..3247b25 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -4457,6 +4457,32 @@
   ImportAddressProfilesAndVerifyExpectation(*form_structure, {});
 }
 
+// Tests that the FormAssociator is correctly integrated in FormDataImporter.
+// The functionality itself is tested in form_data_importer_utils_unittest.cc.
+TEST_P(FormDataImporterTest, FormAssociator) {
+  base::test::ScopedFeatureList form_association_feature;
+  form_association_feature.InitAndEnableFeature(
+      features::kAutofillAssociateForms);
+
+  std::unique_ptr<FormStructure> form_structure =
+      ConstructDefaultProfileFormStructure();
+  // Don't use `ImportAddressProfileAndVerifyImportOfDefaultProfile()`, as this
+  // function assumes we know it's an address form already. Form associations
+  // are tracked in `ImportFormData()` instead.
+  EXPECT_TRUE(ImportFormDataAndProcessAddressCandidates(
+      *form_structure, /*profile_autofill_enabled=*/true,
+      /*credit_card_autofill_enabled=*/false,
+      /*should_return_local_card=*/false, nullptr, nullptr));
+
+  auto associations = form_data_importer_->GetFormAssociations(
+      form_structure->form_signature());
+  EXPECT_TRUE(associations);
+  EXPECT_EQ(associations->last_address_form_submitted,
+            form_structure->form_signature());
+  EXPECT_FALSE(associations->second_last_address_form_submitted);
+  EXPECT_FALSE(associations->last_credit_card_form_submitted);
+}
+
 // Runs the suite with the feature `kAutofillEnableSupportForApartmentNumbers`
 // and `kAutofillConsiderVariationCountryCodeForPhoneNumbers` enabled and
 // disabled.
diff --git a/components/autofill/core/browser/form_data_importer_utils.cc b/components/autofill/core/browser/form_data_importer_utils.cc
index 978b2d8..b0f87a8 100644
--- a/components/autofill/core/browser/form_data_importer_utils.cc
+++ b/components/autofill/core/browser/form_data_importer_utils.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/form_data_importer_utils.h"
 
+#include "base/containers/contains.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/data_model/autofill_profile_comparator.h"
 #include "components/autofill/core/browser/geo/autofill_country.h"
@@ -19,6 +20,17 @@
 using AddressImportRequirement =
     AutofillMetrics::AddressProfileImportRequirementMetric;
 
+bool IsOriginPartOfDeletionInfo(const absl::optional<url::Origin>& origin,
+                                const history::DeletionInfo& deletion_info) {
+  if (!origin)
+    return false;
+  return deletion_info.IsAllHistory() ||
+         base::Contains(deletion_info.deleted_rows(), *origin,
+                        [](const history::URLRow& url_row) {
+                          return url::Origin::Create(url_row.url());
+                        });
+}
+
 }  // anonymous namespace
 
 bool IsMinimumAddress(const AutofillProfile& profile,
@@ -241,4 +253,67 @@
   }
 }
 
+void MultiStepImportMerger::OnBrowsingHistoryCleared(
+    const history::DeletionInfo& deletion_info) {
+  if (IsOriginPartOfDeletionInfo(multistep_candidates_.origin(), deletion_info))
+    Clear();
+}
+
+FormAssociator::FormAssociator() = default;
+FormAssociator::~FormAssociator() = default;
+
+void FormAssociator::TrackFormAssociations(const url::Origin& origin,
+                                           FormSignature form_signature,
+                                           FormType form_type) {
+  const base::TimeDelta ttl = features::kAutofillAssociateFormsTTL.Get();
+  // This ensures that `recent_address_forms_` and `recent_credit_card_forms`
+  // share the same origin (if they are non-empty).
+  recent_address_forms_.RemoveOutdatedItems(ttl, origin);
+  recent_credit_card_forms_.RemoveOutdatedItems(ttl, origin);
+
+  auto& container = form_type == FormType::kAddressForm
+                        ? recent_address_forms_
+                        : recent_credit_card_forms_;
+  container.Push(form_signature, origin);
+}
+
+absl::optional<FormStructure::FormAssociations>
+FormAssociator::GetFormAssociations(FormSignature form_signature) const {
+  FormStructure::FormAssociations associations;
+  if (!recent_address_forms_.empty())
+    associations.last_address_form_submitted = *recent_address_forms_.begin();
+  if (!recent_credit_card_forms_.empty()) {
+    associations.last_credit_card_form_submitted =
+        *recent_credit_card_forms_.begin();
+  }
+  if (associations.last_address_form_submitted != form_signature &&
+      associations.last_credit_card_form_submitted != form_signature) {
+    return absl::nullopt;
+  }
+  if (recent_address_forms_.size() > 1) {
+    associations.second_last_address_form_submitted =
+        *std::next(recent_address_forms_.begin());
+  }
+  return associations;
+}
+
+const absl::optional<url::Origin>& FormAssociator::origin() const {
+  DCHECK(
+      !recent_address_forms_.origin() || !recent_credit_card_forms_.origin() ||
+      *recent_address_forms_.origin() == *recent_credit_card_forms_.origin());
+  return recent_address_forms_.origin() ? recent_address_forms_.origin()
+                                        : recent_credit_card_forms_.origin();
+}
+
+void FormAssociator::Clear() {
+  recent_address_forms_.Clear();
+  recent_credit_card_forms_.Clear();
+}
+
+void FormAssociator::OnBrowsingHistoryCleared(
+    const history::DeletionInfo& deletion_info) {
+  if (IsOriginPartOfDeletionInfo(origin(), deletion_info))
+    Clear();
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_data_importer_utils.h b/components/autofill/core/browser/form_data_importer_utils.h
index ee2b6459..0b11d38 100644
--- a/components/autofill/core/browser/form_data_importer_utils.h
+++ b/components/autofill/core/browser/form_data_importer_utils.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_DATA_IMPORTER_UTILS_H_
 
 #include <iterator>
+#include <limits>
 #include <list>
 #include <string>
 #include <utility>
@@ -13,8 +14,11 @@
 #include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_profile_import_process.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
+#include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/common/autofill_clock.h"
 #include "components/autofill/core/common/logging/log_buffer.h"
+#include "components/autofill/core/common/signatures.h"
+#include "components/history/core/browser/history_types.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
@@ -36,11 +40,17 @@
   };
   using const_iterator = typename std::list<value_type>::const_iterator;
 
+  explicit TimestampedSameOriginQueue(
+      size_t max_size = std::numeric_limits<size_t>::max())
+      : max_size_(max_size) {}
+
   // Pushes `item` at the current timestamp.
   void Push(T item, const url::Origin& item_origin) {
     DCHECK(!origin_ || *origin_ == item_origin);
     items_.emplace_front(std::move(item), AutofillClock::Now());
     origin_ = item_origin;
+    if (size() - 1 == max_size_)
+      Pop();
   }
 
   // Removes the oldest element from the queue.
@@ -63,7 +73,7 @@
 
   // Returns the origin shared by the elements in the queue. Or nullopt, if
   // the queue is currently `Empty()`.
-  const absl::optional<url::Origin>& Origin() const { return origin_; }
+  const absl::optional<url::Origin>& origin() const { return origin_; }
 
   size_t size() const { return items_.size(); }
   bool empty() const { return items_.empty(); }
@@ -85,6 +95,9 @@
   std::list<value_type> items_;
   // If the queue is not `empty()`, this represents the origin of all `items_`.
   absl::optional<url::Origin> origin_;
+  // The maximum number of elements stored in `items_`. If adding a new item
+  // would exceed the `max_size_`, the oldest existing item is removed.
+  const size_t max_size_;
 };
 
 // Returns true if minimum requirements for import of a given `profile` have
@@ -128,12 +141,14 @@
                               ProfileImportMetadata& import_metadata,
                               const url::Origin& origin);
 
-  const absl::optional<url::Origin>& Origin() const {
-    return multistep_candidates_.Origin();
+  const absl::optional<url::Origin>& origin() const {
+    return multistep_candidates_.origin();
   }
 
   void Clear() { multistep_candidates_.Clear(); }
 
+  void OnBrowsingHistoryCleared(const history::DeletionInfo& deletion_info);
+
  private:
   // Merges a given `profile` stepwise with `multistep_candidates_` to
   // complete it. `profile` is assumed to contain no invalid information.
@@ -166,6 +181,48 @@
       multistep_candidates_;
 };
 
+// Tracks which address and credit card forms were submitted in close temporal
+// proximity.
+class FormAssociator {
+ public:
+  enum class FormType {
+    kAddressForm,
+    kCreditCardForm,
+  };
+
+  FormAssociator();
+  ~FormAssociator();
+
+  // Removes outdated (different `origin` or TTL) form signatures from
+  // `recent_credit_card_forms_` and `recent_address_forms_`. Adds
+  // `form_signature` to the appropriate list (depending on `form_type`).
+  void TrackFormAssociations(const url::Origin& origin,
+                             FormSignature form_signature,
+                             FormType form_type);
+
+  // Returns the form signatures that are associated with `form_signature`, if
+  // any. In particular, the two most recent address and the most recent
+  // submitted credit card form signatures from the same origin are returned.
+  // One of them is the `form_signature` itself.
+  absl::optional<FormStructure::FormAssociations> GetFormAssociations(
+      FormSignature form_signature) const;
+
+  const absl::optional<url::Origin>& origin() const;
+
+  void Clear();
+
+  void OnBrowsingHistoryCleared(const history::DeletionInfo& deletion_info);
+
+ private:
+  // Stores the two most recent address form signatures and the most recent
+  // credit card form signature submitted, within a small TTL and sharing the
+  // same origin.
+  TimestampedSameOriginQueue<FormSignature> recent_address_forms_{
+      /*max_size=*/2u};
+  TimestampedSameOriginQueue<FormSignature> recent_credit_card_forms_{
+      /*max_size=*/1u};
+};
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_DATA_IMPORTER_UTILS_H_
diff --git a/components/autofill/core/browser/form_data_importer_utils_unittest.cc b/components/autofill/core/browser/form_data_importer_utils_unittest.cc
index f20b207..36921ae 100644
--- a/components/autofill/core/browser/form_data_importer_utils_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_utils_unittest.cc
@@ -6,7 +6,10 @@
 
 #include <vector>
 
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
 #include "base/time/time.h"
+#include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -43,16 +46,24 @@
   EXPECT_TRUE(queue.empty());
 }
 
+TEST(FormDataImporterUtilsTest, TimestampedSameOriginQueue_MaxSize) {
+  TimestampedSameOriginQueue<IntWrapper> queue{/*max_size=*/1};
+  const url::Origin irrelevant_origin;
+  queue.Push({0}, irrelevant_origin);
+  queue.Push({1}, irrelevant_origin);
+  EXPECT_THAT(queue, testing::ElementsAre(1));
+}
+
 // RemoveOutdatedItems clears the queue if the origin doesn't match.
 TEST(FormDataImporterUtilsTest, TimestampedSameOriginQueue_DifferentOrigins) {
   TimestampedSameOriginQueue<IntWrapper> queue;
   auto foo_origin = url::Origin::Create(GURL("http://foo.com"));
   queue.Push({0}, foo_origin);
-  EXPECT_EQ(queue.Origin(), foo_origin);
+  EXPECT_EQ(queue.origin(), foo_origin);
   // The TTL or 1 hour is irrelevant here.
   queue.RemoveOutdatedItems(base::Hours(1),
                             url::Origin::Create(GURL("http://bar.com")));
-  EXPECT_EQ(queue.Origin(), absl::nullopt);
+  EXPECT_EQ(queue.origin(), absl::nullopt);
   EXPECT_TRUE(queue.empty());
 }
 
@@ -82,4 +93,74 @@
   EXPECT_EQ(GetPredictedCountryCode(empty_profile, "", "de-AT", nullptr), "AT");
 }
 
+// Each test describes a sequence of submitted forms, where 'a' and 'c' indicate
+// an address and a credit card form, respectively.
+// Using an upper case A or C, forms that are supposed to be part of the
+// association are marked.
+constexpr base::StringPiece kFormAssociatorTestCases[]{
+    // A single address/credit card form is associated with itself.
+    "A",
+    "C",
+    // The credit card form is associated with the address form, and vice-versa.
+    "AC",
+    "CA",
+    // Two address forms are associated with the credit card form.
+    "AAC",
+    // The first address form is not associated to the credit card form.
+    "aAAC",
+    // Only the last credit card form is kept.
+    "AAcC",
+};
+
+class FormAssociatorTest : public testing::TestWithParam<base::StringPiece> {};
+
+INSTANTIATE_TEST_SUITE_P(FormDataImporterUtilsTest,
+                         FormAssociatorTest,
+                         testing::ValuesIn(kFormAssociatorTestCases));
+
+// Tests that all `kFormAssociationTestCases` yield the correct associations.
+TEST_P(FormAssociatorTest, FormAssociator) {
+  FormAssociator form_associator;
+  url::Origin irrelevant_origin;
+  FormStructure::FormAssociations expected_associations;
+  const base::StringPiece& test = GetParam();
+  // Each test verifies the association of the last form. If the last form is
+  // not expected to be included, that's likely a typo.
+  EXPECT_TRUE(!test.empty() && base::IsAsciiUpper(test.back()));
+
+  for (size_t i = 0; i < test.size(); i++) {
+    FormSignature signature{i};
+    auto type = base::ToLowerASCII(test[i]) == 'a'
+                    ? FormAssociator::FormType::kAddressForm
+                    : FormAssociator::FormType::kCreditCardForm;
+    form_associator.TrackFormAssociations(irrelevant_origin, signature, type);
+    // Fill `expected_associations` depending on `type`.
+    if (base::IsAsciiLower(test[i]))
+      continue;
+    if (type == FormAssociator::FormType::kAddressForm) {
+      if (expected_associations.last_address_form_submitted) {
+        // There should be at most two address form associations expected.
+        EXPECT_FALSE(expected_associations.second_last_address_form_submitted);
+        expected_associations.second_last_address_form_submitted =
+            expected_associations.last_address_form_submitted;
+      }
+      expected_associations.last_address_form_submitted = signature;
+    } else {
+      // There should be at most one credit card form association expected.
+      EXPECT_FALSE(expected_associations.last_credit_card_form_submitted);
+      expected_associations.last_credit_card_form_submitted = signature;
+    }
+  }
+
+  auto associations =
+      form_associator.GetFormAssociations(FormSignature{test.size() - 1});
+  EXPECT_TRUE(associations);
+  EXPECT_EQ(expected_associations.last_address_form_submitted,
+            associations->last_address_form_submitted);
+  EXPECT_EQ(expected_associations.second_last_address_form_submitted,
+            associations->second_last_address_form_submitted);
+  EXPECT_EQ(expected_associations.last_credit_card_form_submitted,
+            associations->last_credit_card_form_submitted);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 870d220a..8a08d1c8 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -446,6 +446,19 @@
   if (single_username_data_)
     upload.mutable_single_username_data()->CopyFrom(*single_username_data_);
 
+  if (form_associations_.last_address_form_submitted) {
+    upload.set_last_address_form_submitted(
+        form_associations_.last_address_form_submitted->value());
+  }
+  if (form_associations_.second_last_address_form_submitted) {
+    upload.set_second_last_address_form_submitted(
+        form_associations_.second_last_address_form_submitted->value());
+  }
+  if (form_associations_.last_credit_card_form_submitted) {
+    upload.set_last_credit_card_form_submitted(
+        form_associations_.last_credit_card_form_submitted->value());
+  }
+
   auto triggering_event = (submission_event_ != SubmissionIndicatorEvent::NONE)
                               ? submission_event_
                               : ToSubmissionIndicatorEvent(submission_source_);
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 1c0859d..ba72caf 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -450,6 +450,18 @@
     return single_username_data_;
   }
 
+  // The signatures of forms recently submitted on the same origin within a
+  // small period of time.
+  struct FormAssociations {
+    absl::optional<FormSignature> last_address_form_submitted;
+    absl::optional<FormSignature> second_last_address_form_submitted;
+    absl::optional<FormSignature> last_credit_card_form_submitted;
+  };
+
+  void set_form_associations(FormAssociations associations) {
+    form_associations_ = associations;
+  }
+
  private:
   friend class FormStructureTestApi;
 
@@ -720,6 +732,11 @@
   // Single username details, if applicable.
   absl::optional<AutofillUploadContents::SingleUsernameData>
       single_username_data_;
+
+  // The signatures of forms recently submitted on the same origin within a
+  // small period of time.
+  // Only used for voting-purposes.
+  FormAssociations form_associations_;
 };
 
 LogBuffer& operator<<(LogBuffer& buffer, const FormStructure& form);
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 0be3c82..85de109 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -4870,10 +4870,10 @@
 TEST_F(FormStructureTestImpl, EncodeUploadRequest_WithSingleUsernameData) {
   FormData form;
   form.url = GURL("http://www.foo.com/");
-  FormFieldData field;
-  field.name = u"text field";
-  field.unique_renderer_id = test::MakeFieldRendererId();
-  form.fields.push_back(field);
+  FormFieldData field_data;
+  field_data.name = u"text field";
+  field_data.unique_renderer_id = test::MakeFieldRendererId();
+  form.fields.push_back(field_data);
 
   FormStructure form_structure(form);
   for (auto& field : form_structure)
@@ -8244,11 +8244,12 @@
                             AllOf(Not(NO_SERVER_DATA), Not(UNKNOWN_TYPE))))));
 
   for (PatternSource other_pattern_source : other_pattern_sources()) {
-    auto get_heuristic_type = [&](const AutofillField& field) {
+    auto get_other_pattern_heuristic_type = [&](const AutofillField& field) {
       return field.heuristic_type(other_pattern_source);
     };
     EXPECT_THAT(test_api(&form_structure).fields(),
-                Each(Pointee(ResultOf(get_heuristic_type, NO_SERVER_DATA))))
+                Each(Pointee(ResultOf(get_other_pattern_heuristic_type,
+                                      NO_SERVER_DATA))))
         << "PatternSource = " << static_cast<int>(other_pattern_source);
   }
 }
diff --git a/components/autofill/core/browser/proto/server.proto b/components/autofill/core/browser/proto/server.proto
index caa3efa..8656189 100644
--- a/components/autofill/core/browser/proto/server.proto
+++ b/components/autofill/core/browser/proto/server.proto
@@ -225,7 +225,7 @@
 
 // This message contains information about the field types in a single form.
 // It is sent by the toolbar to contribute to the field type statistics.
-// Next available id: 42
+// Next available id: 46
 message AutofillUploadContents {
   required string client_version = 1;
   required fixed64 form_signature = 2;
@@ -492,6 +492,13 @@
   // The message contains data on a preceding form with potential username
   // field.
   optional SingleUsernameData single_username_data = 42;
+
+  // The form signature of related forms, which were submitted on the same
+  // origin shortly prior. If set, `last_address_form_submitted` or
+  // `last_credit_card_form_submitted` is equal to `form_signature`.
+  optional fixed64 last_address_form_submitted = 43;
+  optional fixed64 second_last_address_form_submitted = 44;
+  optional fixed64 last_credit_card_form_submitted = 45;
 }
 
 // This proto contains information about the validity of each field in an
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index dcede577..8d01616 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -84,6 +84,15 @@
 const base::Feature kAutofillAllowNonHttpActivation{
     "AutofillAllowNonHttpActivation", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// If enabled, the two most recent address forms and the most recent credit card
+// forms, which were submitted on the same origin, are associated with each
+// other. The association only happens if at most `kAutofillAssociateFormsTTL`
+// time passes between all submissions.
+const base::Feature kAutofillAssociateForms{"AutofillAssociateForms",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+const base::FeatureParam<base::TimeDelta> kAutofillAssociateFormsTTL{
+    &kAutofillAssociateForms, "associate_forms_ttl", base::Minutes(5)};
+
 // If enabled, the country calling code for nationally formatted phone numbers
 // is inferred from the profile's country, if available.
 // TODO(crbug.com/1311937): Cleanup when launched.
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 56cff1a..d81ce4f 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -45,6 +45,10 @@
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillAllowNonHttpActivation;
 COMPONENT_EXPORT(AUTOFILL)
+extern const base::Feature kAutofillAssociateForms;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<base::TimeDelta> kAutofillAssociateFormsTTL;
+COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillInferCountryCallingCode;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillComplementCountryCodeOnImport;
diff --git a/components/autofill/core/common/autofill_internals/log_message.h b/components/autofill/core/common/autofill_internals/log_message.h
index 8842eef6..5432022 100644
--- a/components/autofill/core/common/autofill_internals/log_message.h
+++ b/components/autofill/core/common/autofill_internals/log_message.h
@@ -45,6 +45,8 @@
     "Source of country for address requirements: ")                            \
   T(ImportAddressProfileFromFormAddressRequirements,                           \
     "Requirements for the address import: ")                                   \
+  T(ImportAddressProfileFromFormRemoveInvalidValue,                            \
+    "Removing value because validation failed: ")                              \
   T(FormSubmissionDetected, "Form submission detected: ")                      \
   T(SendFillingData, "Sending data to fill to renderer: ")                     \
   T(CreditCardUploadEnabled, "Credit card upload is enabled.")                 \
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index 14a35a3..1f3aa0d 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -188,12 +188,6 @@
 const base::Feature kAutofillSaveCardDismissOnNavigation{
     "AutofillSaveCardDismissOnNavigation", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// When enabled, the expiration date of the card will not be shown in the
-// Autofill Suggestions.
-const base::Feature kAutofillRemoveCardExpiryFromDownstreamSuggestion{
-    "AutofillRemoveCardExpiryFromDownstreamSuggestion",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
 // When enabled, the Save Card infobar supports editing before submitting.
 const base::Feature kAutofillSaveCardInfobarEditSupport{
     "AutofillSaveCardInfobarEditSupport", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h
index 30be1e8..23bb7146 100644
--- a/components/autofill/core/common/autofill_payments_features.h
+++ b/components/autofill/core/common/autofill_payments_features.h
@@ -40,7 +40,6 @@
 extern const base::Feature kAutofillParseIBANFields;
 extern const base::Feature kAutofillParseMerchantPromoCodeFields;
 extern const base::Feature kAutofillParseVcnCardOnFileStandaloneCvcFields;
-extern const base::Feature kAutofillRemoveCardExpiryFromDownstreamSuggestion;
 extern const base::Feature kAutofillSaveCardDismissOnNavigation;
 extern const base::Feature kAutofillSaveCardInfobarEditSupport;
 extern const base::Feature kAutofillSaveCardUiExperiment;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn
index e056fb2..ac706ca4 100644
--- a/components/autofill_assistant/browser/BUILD.gn
+++ b/components/autofill_assistant/browser/BUILD.gn
@@ -253,6 +253,8 @@
     "service/cup_factory.h",
     "service/cup_impl.cc",
     "service/cup_impl.h",
+    "service/local_script_store.cc",
+    "service/local_script_store.h",
     "service/no_round_trip_service.cc",
     "service/no_round_trip_service.h",
     "service/rpc_type.h",
@@ -555,6 +557,7 @@
     "service/cup_factory_unittest.cc",
     "service/cup_impl_unittest.cc",
     "service/cup_unittest.cc",
+    "service/local_script_store_unittest.cc",
     "service/mock_access_token_fetcher.cc",
     "service/mock_access_token_fetcher.h",
     "service/mock_cup.cc",
@@ -565,7 +568,7 @@
     "service/mock_simple_url_loader_factory.h",
     "service/mock_url_loader.cc",
     "service/mock_url_loader.h",
-    "service/no_round_trip_service_unittests.cc",
+    "service/no_round_trip_service_unittest.cc",
     "service/server_url_fetcher_unittest.cc",
     "service/service_impl_unittest.cc",
     "service/service_request_sender_impl_unittest.cc",
diff --git a/components/autofill_assistant/browser/android/BUILD.gn b/components/autofill_assistant/browser/android/BUILD.gn
index df4d0d09..70d4ebc 100644
--- a/components/autofill_assistant/browser/android/BUILD.gn
+++ b/components/autofill_assistant/browser/android/BUILD.gn
@@ -24,6 +24,8 @@
     "assistant_qr_code_image_picker_model_wrapper.h",
     "assistant_qr_code_native_delegate.cc",
     "assistant_qr_code_native_delegate.h",
+    "assistant_ui_action_delegate.cc",
+    "assistant_ui_action_delegate.h",
     "client_android.cc",
     "client_android.h",
     "features_android.cc",
@@ -64,6 +66,8 @@
     "//components/autofill_assistant/browser:proto",
     "//components/autofill_assistant/browser/public",
     "//components/autofill_assistant/browser/public:password_change",
+    "//components/autofill_assistant/browser/public:proto",
+    "//components/autofill_assistant/browser/public/assistant_ui/proto:proto",
     "//components/autofill_assistant/content/browser",
     "//components/image_fetcher:android",
     "//components/keyed_service/content",
@@ -100,3 +104,19 @@
     "//content/public/browser",
   ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "assistant_ui_action_delegate_unittest.cc" ]
+  deps = [
+    ":android",
+    "//base",
+    "//base/test:test_support",
+    "//components/autofill_assistant/browser:proto",
+    "//components/autofill_assistant/browser/public:proto",
+    "//components/autofill_assistant/browser/public:public",
+    "//components/autofill_assistant/browser/public/assistant_ui/proto:proto",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/autofill_assistant/browser/android/assistant_ui_action_delegate.cc b/components/autofill_assistant/browser/android/assistant_ui_action_delegate.cc
new file mode 100644
index 0000000..0b04819
--- /dev/null
+++ b/components/autofill_assistant/browser/android/assistant_ui_action_delegate.cc
@@ -0,0 +1,106 @@
+// 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/autofill_assistant/browser/android/assistant_ui_action_delegate.h"
+
+#include "base/logging.h"
+#include "base/timer/timer.h"
+#include "components/autofill_assistant/browser/public/assistant_ui/proto/assistant_ui_action.pb.h"
+#include "components/autofill_assistant/browser/public/external_action_delegate.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace autofill_assistant {
+
+AssistantUiActionDelegate::AssistantUiActionDelegate() = default;
+AssistantUiActionDelegate::~AssistantUiActionDelegate() = default;
+
+void AssistantUiActionDelegate::OnActionRequested(
+    const external::Action& action,
+    base::OnceCallback<void(DomUpdateCallback)> start_dom_checks_callback,
+    base::OnceCallback<void(const external::Result& result)>
+        end_action_callback) {
+  end_action_callback_ = std::move(end_action_callback);
+  if (!action.info().has_assistant_ui_action()) {
+    VLOG(1) << "Action is not of type AssistantUiAction";
+    EndAction(false);
+    return;
+  }
+  const assistant_ui::AssistantUiAction assistant_action =
+      action.info().assistant_ui_action();
+
+  if (assistant_action.has_update_ui()) {
+    // TODO(b/242497041): Send UI update to Assistant.
+  }
+
+  assistant_ui::AssistantUiActionResult response;
+  switch (assistant_action.continue_mode_case()) {
+    case assistant_ui::AssistantUiAction::kBlockUntilUserAction:
+      if (assistant_action.block_until_user_action().has_timeout_ms()) {
+        timeout_timer_ = std::make_unique<base::OneShotTimer>();
+        timeout_timer_->Start(
+            FROM_HERE,
+            base::Milliseconds(
+                assistant_action.block_until_user_action().timeout_ms()),
+            base::BindOnce(&AssistantUiActionDelegate::OnTimeout,
+                           weak_ptr_factory_.GetWeakPtr()));
+      }
+      if (assistant_action.block_until_user_action().check_dom_conditions()) {
+        std::move(start_dom_checks_callback)
+            .Run(base::BindRepeating(
+                &AssistantUiActionDelegate::OnDomUpdateReceived,
+                base::Unretained(this)));
+      }
+      return;
+    case assistant_ui::AssistantUiAction::kContinueImmediately:
+      response.set_immediate(true);
+      EndAction(true, response);
+      return;
+    default:
+      DLOG(ERROR)
+          << "Assistant Ui External action didn't specify how to continue";
+      EndAction(false);
+  }
+}
+void AssistantUiActionDelegate::OnInterruptStarted() {
+  // TODO(b/242497041): Implement interrupts.
+  DCHECK(false) << "Interrupts aren't implemented yet";
+}
+
+void AssistantUiActionDelegate::OnInterruptFinished() {}
+void AssistantUiActionDelegate::OnTimeout() {
+  assistant_ui::AssistantUiActionResult response;
+  response.set_timeout(true);
+  EndAction(true, response);
+}
+
+void AssistantUiActionDelegate::OnDomUpdateReceived(
+    const external::ElementConditionsUpdate& update) {
+  assistant_ui::AssistantUiActionResult response;
+  bool any_satisfied = false;
+  for (const auto& condition : update.results()) {
+    if (condition.satisfied()) {
+      response.mutable_dom_conditions()->add_condition_id(condition.id());
+      any_satisfied = true;
+    }
+  }
+  if (any_satisfied) {
+    EndAction(true, response);
+  }
+}
+
+void AssistantUiActionDelegate::EndAction(
+    bool success,
+    absl::optional<assistant_ui::AssistantUiActionResult> action_result) {
+  timeout_timer_.reset();
+  external::Result result;
+  result.set_success(success);
+
+  if (action_result.has_value()) {
+    *result.mutable_result_info()->mutable_assistant_ui_action_result() =
+        action_result.value();
+  }
+  std::move(end_action_callback_).Run(std::move(result));
+}
+
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/android/assistant_ui_action_delegate.h b/components/autofill_assistant/browser/android/assistant_ui_action_delegate.h
new file mode 100644
index 0000000..a421756c
--- /dev/null
+++ b/components/autofill_assistant/browser/android/assistant_ui_action_delegate.h
@@ -0,0 +1,47 @@
+// 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_AUTOFILL_ASSISTANT_BROWSER_ANDROID_ASSISTANT_UI_ACTION_DELEGATE_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ANDROID_ASSISTANT_UI_ACTION_DELEGATE_H_
+
+#include "base/callback.h"
+#include "base/timer/timer.h"
+#include "components/autofill_assistant/browser/android/assistant_ui_action_delegate.h"
+#include "components/autofill_assistant/browser/public/external_action.pb.h"
+#include "components/autofill_assistant/browser/public/external_action_delegate.h"
+#include "components/autofill_assistant/browser/public/headless_script_controller.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace autofill_assistant {
+class AssistantUiActionDelegate : public ExternalActionDelegate {
+ public:
+  AssistantUiActionDelegate();
+  ~AssistantUiActionDelegate() override;
+
+  void OnActionRequested(
+      const external::Action& action_info,
+      base::OnceCallback<void(ExternalActionDelegate::DomUpdateCallback)>
+          start_dom_checks_callback,
+      base::OnceCallback<void(const external::Result& result)>
+          end_action_callback) override;
+  void OnInterruptStarted() override;
+  void OnInterruptFinished() override;
+
+ private:
+  void OnDomUpdateReceived(const external::ElementConditionsUpdate& update);
+  void OnTimeout();
+  void EndAction(bool success,
+                 absl::optional<assistant_ui::AssistantUiActionResult>
+                     action_result = absl::nullopt);
+
+  std::unique_ptr<base::OneShotTimer> timeout_timer_;
+
+  // The callback that terminates the current action.
+  base::OnceCallback<void(const external::Result& result)> end_action_callback_;
+
+  base::WeakPtrFactory<AssistantUiActionDelegate> weak_ptr_factory_{this};
+};
+}  // namespace autofill_assistant
+
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ANDROID_ASSISTANT_UI_ACTION_DELEGATE_H_
diff --git a/components/autofill_assistant/browser/android/assistant_ui_action_delegate_unittest.cc b/components/autofill_assistant/browser/android/assistant_ui_action_delegate_unittest.cc
new file mode 100644
index 0000000..bc6c9d91
--- /dev/null
+++ b/components/autofill_assistant/browser/android/assistant_ui_action_delegate_unittest.cc
@@ -0,0 +1,108 @@
+// 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/autofill_assistant/browser/android/assistant_ui_action_delegate.h"
+
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/mock_callback.h"
+#include "base/test/task_environment.h"
+#include "components/autofill_assistant/browser/public/assistant_ui/proto/assistant_ui_action.pb.h"
+#include "components/autofill_assistant/browser/public/external_action.pb.h"
+#include "components/autofill_assistant/browser/public/external_action_delegate.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill_assistant {
+namespace {
+
+using ::testing::ElementsAre;
+
+class AssistantUiActionDelegateTest : public testing::Test {
+ protected:
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  base::MockCallback<
+      base::OnceCallback<void(ExternalActionDelegate::DomUpdateCallback)>>
+      start_dom_checks_callback_;
+  base::MockCallback<base::OnceCallback<void(const external::Result& result)>>
+      end_action_callback_;
+  AssistantUiActionDelegate delegate_;
+
+  void RunOnActionRequested(const assistant_ui::AssistantUiAction& action) {
+    external::Action external_action;
+    *external_action.mutable_info()->mutable_assistant_ui_action() = action;
+    delegate_.OnActionRequested(external_action,
+                                start_dom_checks_callback_.Get(),
+                                end_action_callback_.Get());
+  }
+};
+
+TEST_F(AssistantUiActionDelegateTest, ContinueImmediately) {
+  EXPECT_CALL(start_dom_checks_callback_, Run).Times(0);
+  external::Result result;
+  EXPECT_CALL(end_action_callback_, Run).WillOnce(testing::SaveArg<0>(&result));
+
+  assistant_ui::AssistantUiAction action;
+  action.mutable_continue_immediately();
+  RunOnActionRequested(action);
+  EXPECT_TRUE(result.success());
+  EXPECT_TRUE(result.result_info().assistant_ui_action_result().immediate());
+}
+
+TEST_F(AssistantUiActionDelegateTest, BlockUntilUserActionWithTimeout) {
+  EXPECT_CALL(start_dom_checks_callback_, Run).Times(0);
+
+  assistant_ui::AssistantUiAction action;
+  action.mutable_block_until_user_action()->set_timeout_ms(100);
+  RunOnActionRequested(action);
+
+  external::Result result;
+  EXPECT_CALL(end_action_callback_, Run).WillOnce(testing::SaveArg<0>(&result));
+  task_environment_.FastForwardBy(base::Milliseconds(100));
+
+  EXPECT_TRUE(result.success());
+  EXPECT_TRUE(result.result_info().assistant_ui_action_result().timeout());
+}
+
+TEST_F(AssistantUiActionDelegateTest, BlockUntilUserActionWithDomChecks) {
+  assistant_ui::AssistantUiAction action;
+  action.mutable_block_until_user_action()->set_timeout_ms(100);
+  action.mutable_block_until_user_action()->set_check_dom_conditions(true);
+
+  ExternalActionDelegate::DomUpdateCallback dom_update_callback;
+  EXPECT_CALL(start_dom_checks_callback_, Run)
+      .WillOnce([&dom_update_callback](
+                    ExternalActionDelegate::DomUpdateCallback callback) {
+        dom_update_callback = std::move(callback);
+      });
+
+  RunOnActionRequested(action);
+
+  external::ElementConditionsUpdate update;
+  auto* result1 = update.add_results();
+  result1->set_satisfied(false);
+  result1->set_id(3);
+  auto* result2 = update.add_results();
+  result2->set_satisfied(false);
+  result2->set_id(5);
+
+  // Should not finish because none of the conditions are satisfied
+  EXPECT_CALL(end_action_callback_, Run).Times(0);
+  dom_update_callback.Run(update);
+
+  result1->set_satisfied(true);
+  external::Result result;
+  EXPECT_CALL(end_action_callback_, Run).WillOnce(testing::SaveArg<0>(&result));
+  dom_update_callback.Run(update);
+  EXPECT_TRUE(result.success());
+  const auto& action_result = result.result_info().assistant_ui_action_result();
+  EXPECT_EQ(action_result.response_type_case(),
+            assistant_ui::AssistantUiActionResult::kDomConditions);
+  EXPECT_THAT(action_result.dom_conditions().condition_id(), ElementsAre(3));
+}
+
+}  // namespace
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/android/client_android.cc b/components/autofill_assistant/browser/android/client_android.cc
index d75c69d..0f2d262c 100644
--- a/components/autofill_assistant/browser/android/client_android.cc
+++ b/components/autofill_assistant/browser/android/client_android.cc
@@ -30,6 +30,8 @@
 #include "components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h"
 #include "components/autofill_assistant/browser/public/ui_state.h"
 #include "components/autofill_assistant/browser/service/access_token_fetcher.h"
+#include "components/autofill_assistant/browser/service/local_script_store.h"
+#include "components/autofill_assistant/browser/service/no_round_trip_service.h"
 #include "components/autofill_assistant/browser/switches.h"
 #include "components/password_manager/content/browser/password_change_success_tracker_factory.h"
 #include "components/password_manager/core/browser/password_change_success_tracker.h"
@@ -145,7 +147,7 @@
 void ClientAndroid::Start(
     const GURL& url,
     std::unique_ptr<TriggerContext> trigger_context,
-    std::unique_ptr<Service> test_service_to_inject,
+    std::unique_ptr<Service> service,
     const base::android::JavaRef<jobject>& joverlay_coordinator,
     const absl::optional<TriggerScriptProto>& trigger_script) {
   // When Start() is called, AA_START should have been measured. From now on,
@@ -162,7 +164,13 @@
   Java_AutofillAssistantClient_chooseAccountAsyncIfNecessary(
       base::android::AttachCurrentThread(), java_object_, jaccount_name);
 
-  CreateController(std::move(test_service_to_inject), trigger_script);
+  if (trigger_context->GetScriptParameters().GetIsNoRoundtrip().value_or(
+          false)) {
+    service =
+        NoRoundTripService::Create(GetWebContents()->GetBrowserContext(), this);
+  }
+
+  CreateController(std::move(service), trigger_script);
 
   // If an overlay is already shown, then show the rest of the UI.
   if (joverlay_coordinator) {
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.cc b/components/autofill_assistant/browser/android/starter_delegate_android.cc
index ee2b1ca..14ed921 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.cc
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.cc
@@ -15,6 +15,7 @@
 #include "components/autofill_assistant/browser/android/trigger_script_bridge_android.h"
 #include "components/autofill_assistant/browser/android/ui_controller_android_utils.h"
 #include "components/autofill_assistant/browser/assistant_field_trial_util.h"
+#include "components/autofill_assistant/browser/features.h"
 #include "components/autofill_assistant/browser/headless/client_headless.h"
 #include "components/autofill_assistant/browser/headless/headless_script_controller_impl.h"
 #include "components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h"
@@ -294,6 +295,7 @@
 
 void StarterDelegateAndroid::HeadlessControllerDoneCallback(
     HeadlessScriptController::ScriptResult result) {
+  assistant_ui_delegate_.reset();
   headless_script_controller_.reset();
 }
 
@@ -314,11 +316,21 @@
       /* onboarding_shown = */ false, /* is_direct_action = */ false,
       jinitial_url, GetIsCustomTab());
 
-  if (trigger_context->GetScriptParameters().GetRunHeadless()) {
+  const bool use_assistant_ui =
+      base::FeatureList::IsEnabled(
+          features::kAutofillAssistantRemoteAssistantUi) &&
+      trigger_context->GetScriptParameters().GetUseAssistantUi();
+  const bool run_headless =
+      trigger_context->GetScriptParameters().GetRunHeadless();
+  if (use_assistant_ui || run_headless) {
+    if (use_assistant_ui) {
+      assistant_ui_delegate_ = std::make_unique<AssistantUiActionDelegate>();
+    }
     auto client = std::make_unique<ClientHeadless>(
         &GetWebContents(), starter_->GetCommonDependencies(),
-        /* action_extension_delegate= */ nullptr, GetWebsiteLoginManager(),
-        base::DefaultTickClock::GetInstance(),
+        /* action_extension_delegate= */
+        use_assistant_ui ? assistant_ui_delegate_.get() : nullptr,
+        GetWebsiteLoginManager(), base::DefaultTickClock::GetInstance(),
         RuntimeManager::GetForWebContents(&GetWebContents())->GetWeakPtr(),
         ukm::UkmRecorder::Get(),
         starter_->GetCommonDependencies()->GetOrCreateAnnotateDomModelService(
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.h b/components/autofill_assistant/browser/android/starter_delegate_android.h
index f96e9f1b..1b368b7 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.h
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.h
@@ -11,6 +11,7 @@
 #include "base/android/jni_weak_ref.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/android/assistant_ui_action_delegate.h"
 #include "components/autofill_assistant/browser/android/dependencies_android.h"
 #include "components/autofill_assistant/browser/assistant_field_trial_util.h"
 #include "components/autofill_assistant/browser/metrics.h"
@@ -139,6 +140,7 @@
   // Contains AssistantStaticDependencies which do not change.
   const std::unique_ptr<const DependenciesAndroid> dependencies_;
   std::unique_ptr<HeadlessScriptController> headless_script_controller_;
+  std::unique_ptr<AssistantUiActionDelegate> assistant_ui_delegate_;
   // Can change based on activity attachment.
   base::android::ScopedJavaGlobalRef<jobject> java_dependencies_;
 
diff --git a/components/autofill_assistant/browser/features.cc b/components/autofill_assistant/browser/features.cc
index 6b9873e..af8f168 100644
--- a/components/autofill_assistant/browser/features.cc
+++ b/components/autofill_assistant/browser/features.cc
@@ -34,6 +34,19 @@
     "AutofillAssistantSignGetActionsRequests",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls whether RPC requests to the backend should be signed for
+// |GetNoRoundTripScriptsByHash| calls.
+const base::Feature kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests{
+    "AutofillAssistantSignGetNoRoundTripByHashRequests",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Controls whether RPC responses from the backend should be verified for
+// |GetNoRoundTripScriptsByHash| calls.
+const base::Feature
+    kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses{
+        "AutofillAssistantVerifyGetNoRoundTripByHashResponses",
+        base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Controls whether to enable dialog onboarding for Autofill Assistant
 const base::Feature kAutofillAssistantDialogOnboarding{
     "AutofillAssistantDialogOnboarding", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -112,6 +125,11 @@
 const base::Feature kAutofillAssistantProactiveHelp{
     "AutofillAssistantProactiveHelp", base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Enables assistant UI (once the feature is enabled, scripts need to use the
+// USE_ASSISTANT_UI=true flag to use the assistant UI).
+const base::Feature kAutofillAssistantRemoteAssistantUi{
+    "AutofillAssistantRemoteAssistantUi", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Used to configure URL heuristics for upcoming new features.
 extern const base::Feature kAutofillAssistantUrlHeuristic1{
     "AutofillAssistantUrlHeuristic1", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/autofill_assistant/browser/features.h b/components/autofill_assistant/browser/features.h
index 6891292..509ea58 100644
--- a/components/autofill_assistant/browser/features.h
+++ b/components/autofill_assistant/browser/features.h
@@ -28,7 +28,10 @@
 extern const base::Feature kAutofillAssistantFeedbackChip;
 extern const base::Feature kAutofillAssistantLoadDFMForTriggerScripts;
 extern const base::Feature kAutofillAssistantProactiveHelp;
+extern const base::Feature kAutofillAssistantRemoteAssistantUi;
 extern const base::Feature kAutofillAssistantSignGetActionsRequests;
+extern const base::Feature
+    kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests;
 extern const base::Feature kAutofillAssistantUrlHeuristic1;
 extern const base::Feature kAutofillAssistantUrlHeuristic2;
 extern const base::Feature kAutofillAssistantUrlHeuristic3;
@@ -37,6 +40,8 @@
 extern const base::Feature kAutofillAssistantUrlHeuristics;
 extern const base::Feature kAutofillAssistantVerifyGetActionsResponses;
 extern const base::Feature kAutofillAssistantCudFilterProfiles;
+extern const base::Feature
+    kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses;
 
 }  // namespace features
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/headless/client_headless.cc b/components/autofill_assistant/browser/headless/client_headless.cc
index 75c8e27..f8688ae 100644
--- a/components/autofill_assistant/browser/headless/client_headless.cc
+++ b/components/autofill_assistant/browser/headless/client_headless.cc
@@ -21,6 +21,8 @@
 #include "components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h"
 #include "components/autofill_assistant/browser/public/ui_state.h"
 #include "components/autofill_assistant/browser/service/access_token_fetcher.h"
+#include "components/autofill_assistant/browser/service/local_script_store.h"
+#include "components/autofill_assistant/browser/service/no_round_trip_service.h"
 #include "components/autofill_assistant/browser/switches.h"
 #include "components/password_manager/content/browser/password_change_success_tracker_factory.h"
 #include "components/password_manager/core/browser/password_change_success_tracker.h"
@@ -74,6 +76,11 @@
     return;
   }
   script_ended_callback_ = std::move(script_ended_callback);
+  if (trigger_context->GetScriptParameters().GetIsNoRoundtrip().value_or(
+          false)) {
+    service =
+        NoRoundTripService::Create(web_contents_->GetBrowserContext(), this);
+  }
   controller_ = std::make_unique<Controller>(
       web_contents_, /* client= */ this, tick_clock_, runtime_manager_,
       std::move(service), std::move(web_controller), ukm_recorder_,
diff --git a/components/autofill_assistant/browser/headless/headless_script_controller_impl_unittest.cc b/components/autofill_assistant/browser/headless/headless_script_controller_impl_unittest.cc
index d7c862b7..a07364a 100644
--- a/components/autofill_assistant/browser/headless/headless_script_controller_impl_unittest.cc
+++ b/components/autofill_assistant/browser/headless/headless_script_controller_impl_unittest.cc
@@ -32,6 +32,7 @@
 #include "components/autofill_assistant/browser/mock_client.h"
 #include "components/autofill_assistant/browser/mock_controller_observer.h"
 #include "components/autofill_assistant/browser/mock_personal_data_manager.h"
+#include "components/autofill_assistant/browser/public/mock_external_action_delegate.h"
 #include "components/autofill_assistant/browser/public/mock_runtime_manager.h"
 #include "components/autofill_assistant/browser/service/mock_service.h"
 #include "components/autofill_assistant/browser/service/service.h"
@@ -118,9 +119,12 @@
     ON_CALL(*mock_web_controller_, FindElement)
         .WillByDefault(RunOnceCallback<2>(ClientStatus(), nullptr));
 
+    mock_external_action_delegate_ =
+        std::make_unique<MockExternalActionDelegate>();
     auto client = std::make_unique<ClientHeadless>(
-        web_contents_.get(), starter_->GetCommonDependencies(), nullptr,
-        nullptr, task_environment_.GetMockTickClock(),
+        web_contents_.get(), starter_->GetCommonDependencies(),
+        mock_external_action_delegate_.get(), nullptr,
+        task_environment_.GetMockTickClock(),
         mock_runtime_manager_->GetWeakPtr(), &ukm_recorder_, nullptr);
     headless_script_controller_ =
         std::make_unique<HeadlessScriptControllerImpl>(
@@ -129,12 +133,13 @@
 
   content::WebContents* web_contents() { return web_contents_.get(); }
 
-  // Note that calling this method moves |service_| and |web_controller_| so
-  // it should not be called more than once per test.
+  // Note that calling this method moves |mock_service_to_inject_| and
+  // |mock_web_controller_to_inject_| so it should not be called more than once
+  // per test.
   void Start(const base::flat_map<std::string, std::string>& params,
              bool expect_success) {
     // Since the callback is often called in a PostTask, we use this to make
-    // sure the test does not fininsh before the callback is called.
+    // sure the test does not finish before the callback is called.
     base::RunLoop run_loop;
 
     EXPECT_CALL(mock_script_ended_callback_, Run)
@@ -191,13 +196,14 @@
   std::unique_ptr<MockRuntimeManager> mock_runtime_manager_;
   std::unique_ptr<Starter> starter_;
   std::unique_ptr<HeadlessScriptControllerImpl> headless_script_controller_;
+  std::unique_ptr<MockExternalActionDelegate> mock_external_action_delegate_;
   ukm::TestAutoSetUkmRecorder ukm_recorder_;
   raw_ptr<MockService> mock_service_;
   raw_ptr<MockWebController> mock_web_controller_;
 
  private:
   // These will be moved when the |Start| method is called, so expectations
-  // should be written using |mock_service| and |mock_web_controller_| instead.
+  // should be written using |mock_service_| and |mock_web_controller_| instead.
   std::unique_ptr<MockService> mock_service_to_inject_;
   std::unique_ptr<MockWebController> mock_web_controller_to_inject_;
 };
@@ -238,4 +244,159 @@
   Start(params, /* expect_success= */ true);
 }
 
+TEST_F(HeadlessScriptControllerImplTest, ScriptWithExternalActionSucceeds) {
+  SupportsScriptResponseProto script_response;
+  auto* script = AddRunnableScript(&script_response, "script");
+  script->mutable_presentation()->set_autostart(true);
+  SetupScripts(script_response);
+
+  ActionsResponseProto script_actions;
+  script_actions.add_actions()->mutable_external_action()->mutable_info();
+  script_actions.add_actions()->mutable_stop();
+
+  std::vector<ProcessedActionProto> processed_actions_capture;
+  EXPECT_CALL(*mock_service_, GetNextActions)
+      .WillOnce(
+          DoAll(SaveArg<3>(&processed_actions_capture),
+                RunOnceCallback<6>(net::HTTP_OK, "",
+                                   ServiceRequestSender::ResponseInfo{})));
+
+  external::Result result;
+  result.set_success(true);
+  result.mutable_result_info();
+  EXPECT_CALL(*mock_external_action_delegate_, OnActionRequested)
+      .WillOnce(RunOnceCallback<2>(result));
+
+  SetupActionsForScript("script", script_actions);
+
+  base::flat_map<std::string, std::string> params = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  Start(params, /* expect_success= */ true);
+  ASSERT_THAT(processed_actions_capture, SizeIs(2));
+  EXPECT_EQ(processed_actions_capture[0].status(), ACTION_APPLIED);
+  EXPECT_EQ(processed_actions_capture[1].status(), ACTION_APPLIED);
+  EXPECT_TRUE(
+      processed_actions_capture[0].external_action_result().has_result_info());
+}
+
+TEST_F(HeadlessScriptControllerImplTest,
+       ReportMainActionFailureOnExternalActionFailure) {
+  SupportsScriptResponseProto script_response;
+  auto* script = AddRunnableScript(&script_response, "script");
+  script->mutable_presentation()->set_autostart(true);
+  SetupScripts(script_response);
+
+  ActionsResponseProto first_roundtrip_actions;
+  first_roundtrip_actions.add_actions()
+      ->mutable_external_action()
+      ->mutable_info();
+  SetupActionsForScript("script", first_roundtrip_actions);
+
+  external::Result result;
+  result.set_success(false);
+  result.mutable_result_info();
+  EXPECT_CALL(*mock_external_action_delegate_, OnActionRequested)
+      .WillOnce(RunOnceCallback<2>(result));
+
+  // An action failing causes all following actions to be ignored, so we need to
+  // put the stop action in the following roundtrip.
+  ActionsResponseProto second_roundtrip_actions;
+  second_roundtrip_actions.add_actions()->mutable_stop();
+  std::vector<ProcessedActionProto> processed_actions_capture;
+  EXPECT_CALL(*mock_service_, GetNextActions)
+      .WillOnce(
+          DoAll(SaveArg<3>(&processed_actions_capture),
+                RunOnceCallback<6>(net::HTTP_OK,
+                                   second_roundtrip_actions.SerializeAsString(),
+                                   ServiceRequestSender::ResponseInfo{})))
+      .WillOnce((RunOnceCallback<6>(net::HTTP_OK, "",
+                                    ServiceRequestSender::ResponseInfo{})));
+
+  base::flat_map<std::string, std::string> params = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  Start(params, /* expect_success= */ true);
+  ASSERT_THAT(processed_actions_capture, SizeIs(1));
+  EXPECT_EQ(processed_actions_capture[0].status(), UNKNOWN_ACTION_STATUS);
+  EXPECT_TRUE(
+      processed_actions_capture[0].external_action_result().has_result_info());
+}
+
+TEST_F(HeadlessScriptControllerImplTest,
+       ExternalActionEndingDuringDomUpdateSuccessfullyEndsMainAction) {
+  SupportsScriptResponseProto script_response;
+  auto* script = AddRunnableScript(&script_response, "script");
+  script->mutable_presentation()->set_autostart(true);
+  SetupScripts(script_response);
+
+  ActionsResponseProto script_actions;
+  auto* external_action =
+      script_actions.add_actions()->mutable_external_action();
+  external_action->mutable_info();
+  auto* condition = external_action->add_conditions();
+  condition->set_id(1);
+  *condition->mutable_element_condition()->mutable_match() =
+      ToSelectorProto("#element");
+  EXPECT_CALL(*mock_web_controller_, FindElement(Selector({"#element"}), _, _))
+      .WillRepeatedly(WithArgs<2>([](auto&& callback) {
+        std::move(callback).Run(OkClientStatus(),
+                                std::make_unique<ElementFinderResult>());
+      }));
+  script_actions.add_actions()->mutable_stop();
+
+  base::MockCallback<
+      base::RepeatingCallback<void(const external::ElementConditionsUpdate&)>>
+      dom_updates_callback;
+  base::OnceCallback<void(const external::Result&)> stored_end_action_callback;
+  // The external action is requested but the external execution does not end it
+  // right away.
+  EXPECT_CALL(*mock_external_action_delegate_, OnActionRequested)
+      .WillOnce([&stored_end_action_callback, &dom_updates_callback](
+                    const external::Action& action_info,
+                    base::OnceCallback<void(
+                        ExternalActionDelegate::DomUpdateCallback)>
+                        start_dom_checks_callback,
+                    base::OnceCallback<void(const external::Result&)>
+                        end_action_callback) {
+        stored_end_action_callback = std::move(end_action_callback);
+        std::move(start_dom_checks_callback).Run(dom_updates_callback.Get());
+      });
+
+  external::Result result;
+  result.set_success(true);
+  result.mutable_result_info();
+  // The action is ended as a result of a DOM update.
+  EXPECT_CALL(dom_updates_callback, Run)
+      .WillOnce([&result, &stored_end_action_callback](
+                    const external::ElementConditionsUpdate& update) {
+        ASSERT_THAT(update.results(), SizeIs(1));
+        EXPECT_EQ(update.results(0).id(), 1);
+        EXPECT_TRUE(update.results(0).satisfied());
+        std::move(stored_end_action_callback).Run(result);
+      });
+
+  SetupActionsForScript("script", script_actions);
+
+  std::vector<ProcessedActionProto> processed_actions_capture;
+  EXPECT_CALL(*mock_service_, GetNextActions)
+      .WillOnce(
+          DoAll(SaveArg<3>(&processed_actions_capture),
+                RunOnceCallback<6>(net::HTTP_OK, "",
+                                   ServiceRequestSender::ResponseInfo{})));
+
+  base::flat_map<std::string, std::string> params = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  Start(params, /* expect_success= */ true);
+  ASSERT_THAT(processed_actions_capture, SizeIs(2));
+  EXPECT_EQ(processed_actions_capture[0].status(), ACTION_APPLIED);
+  EXPECT_EQ(processed_actions_capture[1].status(), ACTION_APPLIED);
+  EXPECT_TRUE(
+      processed_actions_capture[0].external_action_result().has_result_info());
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc
index c094697..828f64f1 100644
--- a/components/autofill_assistant/browser/protocol_utils.cc
+++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -166,6 +166,40 @@
 }
 
 // static
+std::string ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+    const uint32_t hash_prefix_length,
+    const uint64_t hash_prefix,
+    const ClientContextProto& client_context,
+    const ScriptParameters& script_parameters) {
+  GetNoRoundTripScriptsByHashPrefixRequestProto request;
+  request.set_hash_prefix_length(hash_prefix_length);
+  request.set_hash_prefix(hash_prefix);
+  *request.mutable_script_parameters() =
+      script_parameters.ToProto(/* only_non_sensitive_allowlisted = */ true);
+
+  ClientContextProto non_sensitive_context;
+  if (client_context.has_locale()) {
+    non_sensitive_context.set_locale(client_context.locale());
+  }
+  if (client_context.has_country()) {
+    non_sensitive_context.set_country(client_context.country());
+  }
+  if (client_context.chrome().has_chrome_version()) {
+    non_sensitive_context.mutable_chrome()->set_chrome_version(
+        client_context.chrome().chrome_version());
+  }
+  if (client_context.has_platform_type()) {
+    non_sensitive_context.set_platform_type(client_context.platform_type());
+  }
+  *request.mutable_client_context() = non_sensitive_context;
+
+  std::string serialized_request;
+  bool success = request.SerializeToString(&serialized_request);
+  DCHECK(success);
+  return serialized_request;
+}
+
+// static
 void ProtocolUtils::AddScript(const SupportedScriptProto& script_proto,
                               std::vector<std::unique_ptr<Script>>* scripts) {
   auto script = std::make_unique<Script>();
diff --git a/components/autofill_assistant/browser/protocol_utils.h b/components/autofill_assistant/browser/protocol_utils.h
index 9486a1e76..1471b43 100644
--- a/components/autofill_assistant/browser/protocol_utils.h
+++ b/components/autofill_assistant/browser/protocol_utils.h
@@ -50,6 +50,15 @@
       const ClientContextProto& client_context,
       const ScriptParameters& script_parameters);
 
+  // Create request to get all available initial scripts via a url hash prefix.
+  // Note: Only a subset of allowed fields from |client_context| will be sent to
+  // the server.
+  static std::string CreateGetNoRoundTripScriptsByHashRequest(
+      const uint32_t hash_prefix_length,
+      const uint64_t hash_prefix,
+      const ClientContextProto& client_context,
+      const ScriptParameters& script_parameters);
+
   // Convert |script_proto| to a script struct and if the script is valid, add
   // it to |scripts|.
   static void AddScript(const SupportedScriptProto& script_proto,
diff --git a/components/autofill_assistant/browser/public/BUILD.gn b/components/autofill_assistant/browser/public/BUILD.gn
index f093e40f..372dcac 100644
--- a/components/autofill_assistant/browser/public/BUILD.gn
+++ b/components/autofill_assistant/browser/public/BUILD.gn
@@ -94,6 +94,8 @@
   sources = [
     "mock_autofill_assistant.cc",
     "mock_autofill_assistant.h",
+    "mock_external_action_delegate.cc",
+    "mock_external_action_delegate.h",
     "mock_headless_script_controller.cc",
     "mock_headless_script_controller.h",
     "mock_runtime_manager.cc",
diff --git a/components/autofill_assistant/browser/public/mock_external_action_delegate.cc b/components/autofill_assistant/browser/public/mock_external_action_delegate.cc
new file mode 100644
index 0000000..fd90b09
--- /dev/null
+++ b/components/autofill_assistant/browser/public/mock_external_action_delegate.cc
@@ -0,0 +1,10 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/public/mock_external_action_delegate.h"
+
+namespace autofill_assistant {
+MockExternalActionDelegate::MockExternalActionDelegate() = default;
+MockExternalActionDelegate::~MockExternalActionDelegate() = default;
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/public/mock_external_action_delegate.h b/components/autofill_assistant/browser/public/mock_external_action_delegate.h
new file mode 100644
index 0000000..9ec0a28c
--- /dev/null
+++ b/components/autofill_assistant/browser/public/mock_external_action_delegate.h
@@ -0,0 +1,38 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_MOCK_EXTERNAL_ACTION_DELEGATE_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_MOCK_EXTERNAL_ACTION_DELEGATE_H_
+
+#include "base/callback_helpers.h"
+#include "components/autofill_assistant/browser/public/external_action_delegate.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+
+class MockExternalActionDelegate : public ExternalActionDelegate {
+ public:
+  MockExternalActionDelegate();
+  ~MockExternalActionDelegate() override;
+
+  MOCK_METHOD(
+      void,
+      OnActionRequested,
+      (const external::Action& action_info,
+       base::OnceCallback<void(DomUpdateCallback)> start_dom_checks_callback,
+       base::OnceCallback<void(const external::Result&)> end_action_callback),
+      (override));
+  MOCK_METHOD(void, OnInterruptStarted, (), (override));
+  MOCK_METHOD(void, OnInterruptFinished, (), (override));
+  MOCK_METHOD(void,
+              OnTouchableAreaChanged,
+              (const RectF& visual_viewport,
+               const std::vector<RectF>& touchable_areas,
+               const std::vector<RectF>& restricted_areas),
+              (override));
+};
+
+}  // namespace autofill_assistant
+
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_MOCK_EXTERNAL_ACTION_DELEGATE_H_
diff --git a/components/autofill_assistant/browser/script_parameters.cc b/components/autofill_assistant/browser/script_parameters.cc
index 18e18fb..1d7eec4 100644
--- a/components/autofill_assistant/browser/script_parameters.cc
+++ b/components/autofill_assistant/browser/script_parameters.cc
@@ -79,6 +79,9 @@
 // expect the model to be used.
 const char kSendAnnotateDomModelVersion[] = "SEND_ANNOTATE_DOM_MODEL_VERSION";
 
+// Whether this script does not requires a round trip.
+const char kIsNoRoundTrip[] = "IS_NO_ROUND_TRIP";
+
 // The list of non sensitive script parameters that client requests are allowed
 // to send to the backend i.e., they do not require explicit approval in the
 // autofill-assistant onboarding. Even so, please always reach out to Chrome
@@ -109,6 +112,7 @@
 const char kDetailsTotalPrice[] = "DETAILS_TOTAL_PRICE";
 const char kRunHeadless[] = "RUN_HEADLESS";
 const char kFieldTrialPrefix[] = "FIELD_TRIAL_";
+const char kUseAssistantUi[] = "USE_ASSISTANT_UI";
 
 ScriptParameters::ScriptParameters(
     const base::flat_map<std::string, std::string>& parameters) {
@@ -265,8 +269,12 @@
   return GetTypedParameter<bool>(parameters_, kSendAnnotateDomModelVersion);
 }
 
-absl::optional<bool> ScriptParameters::GetRunHeadless() const {
-  return GetTypedParameter<bool>(parameters_, kRunHeadless);
+bool ScriptParameters::GetRunHeadless() const {
+  return GetTypedParameter<bool>(parameters_, kRunHeadless).value_or(false);
+}
+
+bool ScriptParameters::GetUseAssistantUi() const {
+  return GetTypedParameter<bool>(parameters_, kUseAssistantUi).value_or(false);
 }
 
 absl::optional<std::string> ScriptParameters::GetFieldTrialGroup(
@@ -325,6 +333,10 @@
   return GetParameter(kDetailsTotalPrice);
 }
 
+absl::optional<bool> ScriptParameters::GetIsNoRoundtrip() const {
+  return GetTypedParameter<bool>(parameters_, kIsNoRoundTrip);
+}
+
 void ScriptParameters::UpdateDeviceOnlyParameters(
     const base::flat_map<std::string, std::string>& parameters) {
   for (const auto& parameter : parameters) {
diff --git a/components/autofill_assistant/browser/script_parameters.h b/components/autofill_assistant/browser/script_parameters.h
index 5fef8e3..22323c5 100644
--- a/components/autofill_assistant/browser/script_parameters.h
+++ b/components/autofill_assistant/browser/script_parameters.h
@@ -67,9 +67,11 @@
   std::vector<std::string> GetExperiments() const;
   absl::optional<bool> GetDisableRpcSigning() const;
   absl::optional<bool> GetSendAnnotateDomModelVersion() const;
-  absl::optional<bool> GetRunHeadless() const;
+  bool GetRunHeadless() const;
+  bool GetUseAssistantUi() const;
   absl::optional<std::string> GetFieldTrialGroup(
       const int field_trial_slot) const;
+  absl::optional<bool> GetIsNoRoundtrip() const;
 
   // Details parameters.
   absl::optional<bool> GetDetailsShowInitial() const;
diff --git a/components/autofill_assistant/browser/script_parameters_unittest.cc b/components/autofill_assistant/browser/script_parameters_unittest.cc
index c335835..74c545d 100644
--- a/components/autofill_assistant/browser/script_parameters_unittest.cc
+++ b/components/autofill_assistant/browser/script_parameters_unittest.cc
@@ -110,6 +110,10 @@
        {"CALLER", "3"},
        {"SOURCE", "4"},
        {"EXPERIMENT_IDS", "123,456,789"},
+       {"FIELD_TRIAL_1", "1234"},
+       {"FIELD_TRIAL_3", "5555"},
+       {"RUN_HEADLESS", "true"},
+       {"USE_ASSISTANT_UI", "false"},
        {"DISABLE_RPC_SIGNING", "true"},
        {"DETAILS_SHOW_INITIAL", "true"},
        {"DETAILS_TITLE", "title"},
@@ -136,6 +140,11 @@
   EXPECT_THAT(
       parameters.GetExperiments(),
       UnorderedElementsAreArray(std::vector<std::string>{"123", "456", "789"}));
+  EXPECT_THAT(parameters.GetFieldTrialGroup(1), Eq("1234"));
+  EXPECT_THAT(parameters.GetFieldTrialGroup(3), Eq("5555"));
+  EXPECT_THAT(parameters.GetFieldTrialGroup(2).has_value(), Eq(false));
+  EXPECT_THAT(parameters.GetRunHeadless(), Eq(true));
+  EXPECT_THAT(parameters.GetUseAssistantUi(), Eq(false));
   EXPECT_THAT(parameters.GetDisableRpcSigning(), Eq(true));
   EXPECT_THAT(parameters.GetDetailsShowInitial(), Eq(true));
   EXPECT_THAT(parameters.GetDetailsTitle(), Eq("title"));
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index c77d264c..f42991c0 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -268,7 +268,7 @@
   repeated MatchInfoProto match_info = 1;
 }
 
-message GetNoRoundtripScriptsByHashPrefixRequestProto {
+message GetNoRoundTripScriptsByHashPrefixRequestProto {
   // The number of leading bits to consider from hash_prefix. The remaining
   // trailing bits from hash_prefix should be ignored.
   optional uint32 hash_prefix_length = 1;
@@ -283,16 +283,20 @@
   // Optional script parameters. Note that only a subset of parameters are
   // allowed to be sent from the client.
   repeated ScriptParameterProto script_parameters = 4;
+
+  // CUP-signed version of this proto. When set, the rest of the fields should
+  // be ignored.
+  optional CUPRequestData cup_data = 5;
 }
 
-message GetNoRoundtripScriptsByHashPrefixResponseProto {
+message GetNoRoundTripScriptsByHashPrefixResponseProto {
   // CUP-signed version of this proto. When set, the rest of the fields in
   // ScriptActionRequestProto should be ignored.
   optional CUPResponseData cup_data = 1;
 
   message MatchInfo {
     message RoutineScript {
-      optional SupportedScriptProto routine = 1;
+      optional string script_path = 1;
       // The set of actions to execute. If the last executed action is not a
       // stop action or a stop action inside a JS flow action the script will
       // fail.
@@ -312,6 +316,9 @@
   // List of potential scripts matches for the request URL hash prefix. Callers
   // should inspect each element of the list to find the exact match, if any.
   repeated MatchInfo match_infos = 2;
+
+  // Mentions non-fatal errors, such as an empty request.
+  repeated string warnings = 3;
 }
 
 // Request to get user data.
@@ -3686,6 +3693,8 @@
   // The JS flow to execute in a sandbox. If present
   // ActionsResponseProto::js_flow_library needs to be evaluated first.
   optional string js_flow = 1;
+
+  reserved 2;
 }
 
 // Action which forwards a proto to the owner of the |HeadlessScriptController|
diff --git a/components/autofill_assistant/browser/service/cup.cc b/components/autofill_assistant/browser/service/cup.cc
index 175bce68..7d30df61 100644
--- a/components/autofill_assistant/browser/service/cup.cc
+++ b/components/autofill_assistant/browser/service/cup.cc
@@ -7,31 +7,47 @@
 #include "base/feature_list.h"
 #include "components/autofill_assistant/browser/features.h"
 
-namespace autofill_assistant {
+namespace autofill_assistant::cup {
 
-namespace cup {
+using ::autofill_assistant::features::kAutofillAssistantSignGetActionsRequests;
+using ::autofill_assistant::features::
+    kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests;
+using ::autofill_assistant::features::
+    kAutofillAssistantVerifyGetActionsResponses;
+using ::autofill_assistant::features::
+    kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses;
+using ::base::FeatureList;
 
 bool ShouldSignRequests(RpcType rpc_type) {
-  return IsRpcTypeSupported(rpc_type) &&
-         base::FeatureList::IsEnabled(
-             autofill_assistant::features::
-                 kAutofillAssistantSignGetActionsRequests);
+  switch (rpc_type) {
+    case RpcType::GET_ACTIONS:
+      return FeatureList::IsEnabled(kAutofillAssistantSignGetActionsRequests);
+    case RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX:
+      return FeatureList::IsEnabled(
+          kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests);
+    default:
+      return false;
+  }
 }
 
 bool ShouldVerifyResponses(RpcType rpc_type) {
-  return IsRpcTypeSupported(rpc_type) &&
-         base::FeatureList::IsEnabled(
-             autofill_assistant::features::
-                 kAutofillAssistantSignGetActionsRequests) &&
-         base::FeatureList::IsEnabled(
-             autofill_assistant::features::
-                 kAutofillAssistantVerifyGetActionsResponses);
+  if (!ShouldSignRequests(rpc_type))
+    return false;
+  switch (rpc_type) {
+    case RpcType::GET_ACTIONS:
+      return FeatureList::IsEnabled(
+          kAutofillAssistantVerifyGetActionsResponses);
+    case RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX:
+      return FeatureList::IsEnabled(
+          kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses);
+    default:
+      return false;
+  }
 }
 
 bool IsRpcTypeSupported(RpcType rpc_type) {
-  return rpc_type == RpcType::GET_ACTIONS;
+  return rpc_type == RpcType::GET_ACTIONS ||
+         rpc_type == RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX;
 }
 
-}  // namespace cup
-
-}  // namespace autofill_assistant
+}  // namespace autofill_assistant::cup
diff --git a/components/autofill_assistant/browser/service/cup_impl.cc b/components/autofill_assistant/browser/service/cup_impl.cc
index a0797e1..c18348d 100644
--- a/components/autofill_assistant/browser/service/cup_impl.cc
+++ b/components/autofill_assistant/browser/service/cup_impl.cc
@@ -91,25 +91,35 @@
 CUPImpl::~CUPImpl() = default;
 
 std::string CUPImpl::PackAndSignRequest(const std::string& original_request) {
-  if (rpc_type_ != RpcType::GET_ACTIONS) {
-    // Failsafe in case the method is called for a non-supported |rpc_type|.
-    return original_request;
+  switch (rpc_type_) {
+    case RpcType::GET_ACTIONS:
+      return InternalPackAndSignRequest<ScriptActionRequestProto>(
+          original_request);
+    case RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX:
+      return InternalPackAndSignRequest<
+          GetNoRoundTripScriptsByHashPrefixRequestProto>(original_request);
+    default:  // Safety Net for unsupported RPC types
+      return original_request;
   }
-  return PackGetActionsRequest(original_request);
 }
 
 absl::optional<std::string> CUPImpl::UnpackResponse(
     const std::string& original_response) {
-  if (rpc_type_ != RpcType::GET_ACTIONS) {
-    // Failsafe in case the method is called for a non-supported |rpc_type|.
-    return original_response;
+  switch (rpc_type_) {
+    case RpcType::GET_ACTIONS:
+      return InternalUnpackResponse<ActionsResponseProto>(original_response);
+    case RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX:
+      return InternalUnpackResponse<
+          GetNoRoundTripScriptsByHashPrefixResponseProto>(original_response);
+    default:  // Safety Net for unsupported RPC types
+      return original_response;
   }
-  return UnpackGetActionsResponse(original_response);
 }
 
-std::string CUPImpl::PackGetActionsRequest(
+template <class RequestProtoType>
+std::string CUPImpl::InternalPackAndSignRequest(
     const std::string& original_request) {
-  autofill_assistant::ScriptActionRequestProto actions_request;
+  RequestProtoType actions_request;
   actions_request.mutable_cup_data()->set_request(original_request);
 
   client_update_protocol::Ecdsa::RequestParameters request_parameters =
@@ -123,26 +133,27 @@
   return serialized_request;
 }
 
-absl::optional<std::string> CUPImpl::UnpackGetActionsResponse(
+template <class ResponseProtoType>
+absl::optional<std::string> CUPImpl::InternalUnpackResponse(
     const std::string& original_response) {
-  autofill_assistant::ActionsResponseProto actions_response;
-  if (!actions_response.ParseFromString(original_response)) {
+  ResponseProtoType response;
+  if (!response.ParseFromString(original_response)) {
     LOG(ERROR) << "Failed to parse server response";
     Metrics::RecordCupRpcVerificationEvent(
         Metrics::CupRpcVerificationEvent::PARSING_FAILED);
     return absl::nullopt;
   }
 
-  if (actions_response.cup_data().ecdsa_signature().empty()) {
+  if (response.cup_data().ecdsa_signature().empty()) {
     LOG(ERROR) << "Signature not provided for CUP RPC response";
     Metrics::RecordCupRpcVerificationEvent(
         Metrics::CupRpcVerificationEvent::EMPTY_SIGNATURE);
     return absl::nullopt;
   }
 
-  std::string serialized_response = actions_response.cup_data().response();
-  if (!query_signer_->ValidateResponse(
-          serialized_response, actions_response.cup_data().ecdsa_signature())) {
+  std::string serialized_response = response.cup_data().response();
+  if (!query_signer_->ValidateResponse(serialized_response,
+                                       response.cup_data().ecdsa_signature())) {
     LOG(ERROR) << "CUP RPC response verification failed";
     Metrics::RecordCupRpcVerificationEvent(
         Metrics::CupRpcVerificationEvent::VERIFICATION_FAILED);
diff --git a/components/autofill_assistant/browser/service/cup_impl.h b/components/autofill_assistant/browser/service/cup_impl.h
index a755f14..d136823 100644
--- a/components/autofill_assistant/browser/service/cup_impl.h
+++ b/components/autofill_assistant/browser/service/cup_impl.h
@@ -50,11 +50,17 @@
   client_update_protocol::Ecdsa& GetQuerySigner();
 
  private:
-  std::string PackGetActionsRequest(const std::string& original_request);
-
-  absl::optional<std::string> UnpackGetActionsResponse(
+  // ResponseProtoType can be any proto containing a CUPResponseData message
+  // called |cup_data|
+  template <class ResponseProtoType>
+  absl::optional<std::string> InternalUnpackResponse(
       const std::string& original_response);
 
+  // RequestProtoType can be any proto containing a CUPRequestData message
+  // called |cup_data|
+  template <class RequestProtoType>
+  std::string InternalPackAndSignRequest(const std::string& original_request);
+
   std::unique_ptr<client_update_protocol::Ecdsa> query_signer_;
   RpcType rpc_type_;
 };
diff --git a/components/autofill_assistant/browser/service/cup_impl_unittest.cc b/components/autofill_assistant/browser/service/cup_impl_unittest.cc
index e4b49bec..0821df5 100644
--- a/components/autofill_assistant/browser/service/cup_impl_unittest.cc
+++ b/components/autofill_assistant/browser/service/cup_impl_unittest.cc
@@ -63,7 +63,31 @@
   EXPECT_FALSE(actual_user_request.has_cup_data());
 }
 
-TEST(CUPImplTest, IgnoresNonGetActionsRequest) {
+TEST(CUPImplTest, PacksAndSignsGetNoRoundTripByHashRequest) {
+  cup::CUPImpl cup{cup::CUPImpl::CreateQuerySigner(),
+                   RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX};
+  GetNoRoundTripScriptsByHashPrefixRequestProto user_request;
+  user_request.mutable_client_context()->set_experiment_ids("test");
+  std::string user_request_str;
+  user_request.SerializeToString(&user_request_str);
+
+  auto packed_request_str = cup.PackAndSignRequest(user_request_str);
+
+  GetNoRoundTripScriptsByHashPrefixRequestProto packed_request;
+  EXPECT_TRUE(packed_request.ParseFromString(packed_request_str));
+  EXPECT_TRUE(packed_request.client_context().experiment_ids().empty());
+  EXPECT_FALSE(packed_request.cup_data().request().empty());
+  EXPECT_FALSE(packed_request.cup_data().query_cup2key().empty());
+  EXPECT_FALSE(packed_request.cup_data().hash_hex().empty());
+
+  GetNoRoundTripScriptsByHashPrefixRequestProto actual_user_request;
+  EXPECT_TRUE(
+      actual_user_request.ParseFromString(packed_request.cup_data().request()));
+  EXPECT_EQ(actual_user_request.client_context().experiment_ids(), "test");
+  EXPECT_FALSE(actual_user_request.has_cup_data());
+}
+
+TEST(CUPImplTest, IgnoresUnsupportedRequest) {
   cup::CUPImpl cup{cup::CUPImpl::CreateQuerySigner(),
                    RpcType::GET_TRIGGER_SCRIPTS};
 
@@ -116,6 +140,64 @@
       Metrics::CupRpcVerificationEvent::VERIFICATION_SUCCEEDED, 1);
 }
 
+TEST(CUPImplTest, VerifiesTrustedGetNoRoundTripScriptsByHashResponse) {
+  base::HistogramTester histogram_tester;
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kAutofillAssistantCupPublicKeyBase64, kPublicKeyBase64);
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kAutofillAssistantCupKeyVersion, kPublicKeyVersion);
+
+  // Valid server etag generated from the server for the autofill_assistant key
+  // for the example request, response and nonce in this test.
+  const base::StringPiece server_etag =
+      "3044"
+      "0220409f3dcc50f9e5a1708c845dd062fe657c636cb63f14f0b68385413f0cbc"
+      "4208022046586b13463d8171e87fb1c6f7fbf26ad0eb7ab7fe9139063523e48476203c27"
+      ":976b91e914e68d5c8907b1e9752b814ff6c1986276cec6e0d0c92d90eb02838f";
+  // Sign the request and override the nonce so that result is deterministic.
+  cup::CUPImpl cup(cup::CUPImpl::CreateQuerySigner(),
+                   RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX);
+
+  // Base64 encoded version of
+  //   GetNoRoundTripByHashResponseProto {
+  //    hash_prefix: 64,
+  //    hash_prefix_length: 15
+  //   }`
+  const std::string request_base64 = "EEAIDw==";
+  std::string request_bytes;
+  ASSERT_TRUE(base::Base64Decode(request_base64, &request_bytes));
+  cup.PackAndSignRequest(request_bytes);
+  cup.GetQuerySigner().OverrideNonceForTesting(kPublicKeyVersionInt,
+                                               kExampleNonce);
+
+  // Construct server response as it would have been received by the client.
+  GetNoRoundTripScriptsByHashPrefixResponseProto packed_response;
+  packed_response.mutable_cup_data()->set_ecdsa_signature(
+      std::string(server_etag));
+
+  // Base64 encoded version of
+  //   GetNoRoundTripByHashResponseProto {
+  //    warnings: "foo",
+  //   }`
+  const std::string response_base64 = "GgNmb28=";
+  std::string serialized_response_bytes;
+  ASSERT_TRUE(base::Base64Decode(response_base64, &serialized_response_bytes));
+  packed_response.mutable_cup_data()->set_response(serialized_response_bytes);
+  std::string serialized_packed_response;
+  packed_response.SerializeToString(&serialized_packed_response);
+
+  // Expect that unpacking gives as a result the cup_data.response field of
+  // the packed response proto.
+  EXPECT_EQ(cup.UnpackResponse(serialized_packed_response),
+            serialized_response_bytes);
+  histogram_tester.ExpectBucketCount(
+      "Android.AutofillAssistant.CupRpcVerificationEvent",
+      Metrics::CupRpcVerificationEvent::VERIFICATION_FAILED, 0);
+  histogram_tester.ExpectBucketCount(
+      "Android.AutofillAssistant.CupRpcVerificationEvent",
+      Metrics::CupRpcVerificationEvent::VERIFICATION_SUCCEEDED, 1);
+}
+
 TEST(CUPImplTest, FailsToVerifySignatureFromDifferentKey) {
   base::HistogramTester histogram_tester;
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
@@ -236,7 +318,7 @@
       Metrics::CupRpcVerificationEvent::PARSING_FAILED, 1);
 }
 
-TEST(CUPImplTest, IgnoresNonGetActionsResponse) {
+TEST(CUPImplTest, IgnoresUnsupportedResponse) {
   cup::CUPImpl cup{cup::CUPImpl::CreateQuerySigner(),
                    RpcType::GET_TRIGGER_SCRIPTS};
 
diff --git a/components/autofill_assistant/browser/service/cup_unittest.cc b/components/autofill_assistant/browser/service/cup_unittest.cc
index 2cd8599..42e6b87 100644
--- a/components/autofill_assistant/browser/service/cup_unittest.cc
+++ b/components/autofill_assistant/browser/service/cup_unittest.cc
@@ -28,17 +28,27 @@
     if (enableSigning) {
       enabled_features.push_back(
           features::kAutofillAssistantSignGetActionsRequests);
+      enabled_features.push_back(
+          features::kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests);
     } else {
       disabled_features.push_back(
           features::kAutofillAssistantSignGetActionsRequests);
+      disabled_features.push_back(
+          features::kAutofillAssistantSignGetNoRoundTripScriptsByHashRequests);
     }
 
     if (enableVerifying) {
       enabled_features.push_back(
           features::kAutofillAssistantVerifyGetActionsResponses);
+      enabled_features.push_back(
+          features::
+              kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses);
     } else {
       disabled_features.push_back(
           features::kAutofillAssistantVerifyGetActionsResponses);
+      disabled_features.push_back(
+          features::
+              kAutofillAssistantVerifyGetNoRoundTripScriptsByHashResponses);
     }
 
     scoped_feature_list_.Reset();
@@ -61,6 +71,14 @@
       {false, false, RpcType::GET_ACTIONS, false, false},
       {false, false, RpcType::GET_TRIGGER_SCRIPTS, false, false},
       {true, true, RpcType::GET_TRIGGER_SCRIPTS, false, false},
+      {true, true, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX, true,
+       true},
+      {true, false, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX, true,
+       false},
+      {false, true, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX, false,
+       false},
+      {false, false, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX, false,
+       false},
   };
 
   RpcType unsupported_rpc_types[] = {
diff --git a/components/autofill_assistant/browser/service/local_script_store.cc b/components/autofill_assistant/browser/service/local_script_store.cc
new file mode 100644
index 0000000..f82bc15a
--- /dev/null
+++ b/components/autofill_assistant/browser/service/local_script_store.cc
@@ -0,0 +1,59 @@
+// 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/autofill_assistant/browser/service/local_script_store.h"
+
+#include <memory>
+#include <numeric>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "components/autofill_assistant/browser/protocol_utils.h"
+#include "components/autofill_assistant/browser/public/autofill_assistant.h"
+#include "components/autofill_assistant/browser/script_parameters.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/service/api_key_fetcher.h"
+#include "components/autofill_assistant/browser/service/service_request_sender_impl.h"
+#include "components/autofill_assistant/browser/switches.h"
+#include "components/version_info/version_info.h"
+#include "net/http/http_status_code.h"
+#include "url/origin.h"
+
+namespace autofill_assistant {
+
+LocalScriptStore::LocalScriptStore(
+    std::vector<GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::
+                    RoutineScript> routines,
+    std::string domain,
+    SupportsScriptResponseProto supports_site_response)
+    : routines_(routines),
+      domain_(domain),
+      supports_site_response_(supports_site_response) {}
+
+LocalScriptStore::~LocalScriptStore() = default;
+
+const std::vector<
+    GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+LocalScriptStore::GetRoutines() const {
+  return routines_;
+}
+
+const std::string LocalScriptStore::GetDomain() const {
+  return domain_;
+}
+
+const SupportsScriptResponseProto LocalScriptStore::GetSupportsSiteResponse()
+    const {
+  return supports_site_response_;
+}
+
+bool LocalScriptStore::empty() const {
+  return routines_.empty() || domain_.empty();
+}
+
+size_t LocalScriptStore::size() const {
+  return domain_.empty() ? 0 : routines_.size();
+}
+
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/local_script_store.h b/components/autofill_assistant/browser/service/local_script_store.h
new file mode 100644
index 0000000..30d00e4
--- /dev/null
+++ b/components/autofill_assistant/browser/service/local_script_store.h
@@ -0,0 +1,64 @@
+// 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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_LOCAL_SCRIPT_STORE_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_LOCAL_SCRIPT_STORE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/client.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/service/server_url_fetcher.h"
+#include "components/autofill_assistant/browser/trigger_context.h"
+#include "content/public/browser/browser_context.h"
+
+namespace autofill_assistant {
+
+class LocalScriptStore {
+ public:
+  ~LocalScriptStore();
+  LocalScriptStore(const LocalScriptStore&);
+  LocalScriptStore(LocalScriptStore&&);
+
+  LocalScriptStore(std::vector<GetNoRoundTripScriptsByHashPrefixResponseProto::
+                                   MatchInfo::RoutineScript> routines,
+                   std::string domain,
+                   SupportsScriptResponseProto supports_site_response);
+
+  // Returns routines aka pairs of [script_path, ClientActionsResponseProto].
+  [[nodiscard]] const std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+  GetRoutines() const;
+
+  // Returns the domain that this LocalScriptStore is valid for.
+  [[nodiscard]] const std::string GetDomain() const;
+
+  // Returns the results of SupportsScript for this domain/Intent match.
+  [[nodiscard]] const SupportsScriptResponseProto GetSupportsSiteResponse()
+      const;
+
+  // Returns if the store is empty (checks if the domains and routines are set).
+  bool empty() const;
+
+  // Returns the number of scripts in the store.
+  size_t size() const;
+
+ private:
+  // Contains pairs of [script_path, ClientActionsResponseProto].
+  std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+      routines_;
+
+  // The domain that this LocalScriptStore is valid for.
+  std::string domain_;
+
+  // The results of SupportsScript for this domain/Intent match.
+  SupportsScriptResponseProto supports_site_response_;
+};
+
+}  // namespace autofill_assistant
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_LOCAL_SCRIPT_STORE_H_
diff --git a/components/autofill_assistant/browser/service/local_script_store_unittest.cc b/components/autofill_assistant/browser/service/local_script_store_unittest.cc
new file mode 100644
index 0000000..45ae68a
--- /dev/null
+++ b/components/autofill_assistant/browser/service/local_script_store_unittest.cc
@@ -0,0 +1,85 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/service/local_script_store.h"
+
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
+#include "components/autofill_assistant/browser/mock_client.h"
+#include "components/autofill_assistant/browser/protocol_utils.h"
+#include "components/autofill_assistant/browser/public/autofill_assistant.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/service/mock_service_request_sender.h"
+#include "components/version_info/version_info.h"
+#include "net/http/http_status_code.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+class LocalScriptStoreTest : public testing::Test {
+ public:
+  std::unique_ptr<LocalScriptStore> GetStore() {
+    return std::make_unique<LocalScriptStore>(routines_, domain_,
+                                              supports_site_response_);
+  }
+
+ protected:
+  SupportsScriptResponseProto supports_site_response_;
+  std::string domain_;
+  std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+      routines_;
+};
+
+TEST_F(LocalScriptStoreTest, IsEmptyWithoutRoutines) {
+  domain_ = "test";
+  EXPECT_TRUE(GetStore()->empty());
+  EXPECT_EQ(GetStore()->size(), 0ul);
+}
+
+TEST_F(LocalScriptStoreTest, IsEmptyWithoutDomain) {
+  routines_.emplace_back();
+  EXPECT_TRUE(GetStore()->empty());
+  EXPECT_EQ(GetStore()->size(), 0ul);
+}
+
+TEST_F(LocalScriptStoreTest, IsNotEmptyWithRoutinesAndDomain) {
+  routines_.emplace_back();
+  domain_ = "test";
+  EXPECT_FALSE(GetStore()->empty());
+  EXPECT_EQ(GetStore()->size(), 1ul);
+}
+
+TEST_F(LocalScriptStoreTest, GetRoutinesRetrievesRoutines) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript
+      routine;
+  routine.set_script_path("test");
+  routines_.push_back(routine);
+  ASSERT_EQ(GetStore()->GetRoutines().size(), 1ul);
+  EXPECT_EQ(GetStore()->GetRoutines()[0].script_path(), "test");
+}
+
+TEST_F(LocalScriptStoreTest, GetDomainRetrievesDomain) {
+  domain_ = "test";
+  EXPECT_EQ(GetStore()->GetDomain(), domain_);
+}
+
+TEST_F(LocalScriptStoreTest, GetSupportsSiteRetrievesSupportsSiteResponse) {
+  supports_site_response_.add_scripts()->set_path("test");
+  ASSERT_EQ(GetStore()->GetSupportsSiteResponse().scripts_size(), 1);
+  EXPECT_EQ(GetStore()->GetSupportsSiteResponse().scripts()[0].path(), "test");
+}
+
+TEST_F(LocalScriptStoreTest, GetEmptyRoutinesByDefault) {
+  EXPECT_TRUE(GetStore()->GetRoutines().empty());
+}
+
+TEST_F(LocalScriptStoreTest, GetEmptyDomainByDefault) {
+  EXPECT_EQ(GetStore()->GetDomain(), "");
+}
+
+TEST_F(LocalScriptStoreTest, GetEmptySupportsSiteResponseByDefault) {
+  ASSERT_EQ(GetStore()->GetSupportsSiteResponse().scripts_size(), 0);
+}
+
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/no_round_trip_service.cc b/components/autofill_assistant/browser/service/no_round_trip_service.cc
index 34afe053..723979e 100644
--- a/components/autofill_assistant/browser/service/no_round_trip_service.cc
+++ b/components/autofill_assistant/browser/service/no_round_trip_service.cc
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -9,34 +9,127 @@
 #include <utility>
 #include <vector>
 
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/strings/string_util.h"
+#include "components/autofill_assistant/browser/protocol_utils.h"
+#include "components/autofill_assistant/browser/public/autofill_assistant.h"
+#include "components/autofill_assistant/browser/script_parameters.h"
 #include "components/autofill_assistant/browser/service.pb.h"
-#include "components/autofill_assistant/browser/trigger_context.h"
+#include "components/autofill_assistant/browser/service/api_key_fetcher.h"
+#include "components/autofill_assistant/browser/service/local_script_store.h"
+#include "components/autofill_assistant/browser/service/service_request_sender_impl.h"
+#include "components/autofill_assistant/browser/switches.h"
+#include "components/autofill_assistant/browser/url_utils.h"
+#include "components/version_info/version_info.h"
 #include "net/http/http_status_code.h"
+#include "url/origin.h"
 
 namespace autofill_assistant {
+using ::autofill_assistant::SupportsScriptResponseProto;
 
-LocalScriptStore::LocalScriptStore(
-    std::vector<GetNoRoundtripScriptsByHashPrefixResponseProto::MatchInfo::
-                    RoutineScript> routines,
-    std::string domain,
-    SupportsScriptResponseProto supports_site_response)
-    : routines(routines),
-      domain(domain),
-      supports_site_response(supports_site_response) {}
-LocalScriptStore::LocalScriptStore(const LocalScriptStore&) = default;
-LocalScriptStore::LocalScriptStore(LocalScriptStore&&) = default;
-LocalScriptStore::~LocalScriptStore() = default;
+namespace {
+constexpr uint32_t kHashPrefixLength = 15;
+
+ClientContextProto GetClientContext() {
+  // Should the ClientContext come from somewhere?
+  ClientContextProto client_context;
+  client_context.mutable_chrome()->set_chrome_version(
+      version_info::GetProductNameAndVersionForUserAgent());
+  return client_context;
+}
+
+bool AuthEnabled() {
+  return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+             switches::kAutofillAssistantAuth) == "true";
+}
+
+ServiceRequestSender::AuthMode GetDefaultAuthMode() {
+  return AuthEnabled()
+             ? ServiceRequestSender::AuthMode::OAUTH_WITH_API_KEY_FALLBACK
+             : ServiceRequestSender::AuthMode::API_KEY;
+}
+
+std::vector<
+    GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+CreateRoutines(
+    const autofill_assistant::
+        GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo& match) {
+  std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+      routines;
+  routines.reserve(match.routine_scripts_size());
+  for (const auto& routine_script : match.routine_scripts()) {
+    routines.push_back(routine_script);
+  }
+  return routines;
+}
+
+std::unique_ptr<LocalScriptStore> CreateStoreFromMatch(
+    const autofill_assistant::
+        GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo& match) {
+  const std::string domain = match.domain();
+  const std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+      routines = CreateRoutines(match);
+  const SupportsScriptResponseProto supports_site_response =
+      match.supports_site_response();
+  return std::make_unique<LocalScriptStore>(routines, domain,
+                                            supports_site_response);
+}
+
+}  // namespace
+
+NoRoundTripService::NoRoundTripService(
+    std::unique_ptr<ServiceRequestSender> request_sender,
+    const GURL& get_scripts_endpoint,
+    Client* client)
+    : get_scripts_endpoint_(get_scripts_endpoint),
+      client_(client),
+      request_sender_(std::move(request_sender)) {}
+
+NoRoundTripService::~NoRoundTripService() = default;
+
+// static
+std::string NoRoundTripService::CreateGetNoRoundtripRequest(
+    const GURL& url,
+    const ScriptParameters& script_parameters) {
+  DCHECK(!url.is_empty());
+
+  const auto hash_prefix = AutofillAssistant::GetHashPrefix(
+      kHashPrefixLength, url::Origin::Create(url));
+  const std::string request =
+      ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+          kHashPrefixLength, hash_prefix, GetClientContext(),
+          script_parameters);
+
+  return request;
+}
 
 // static
 std::unique_ptr<NoRoundTripService> NoRoundTripService::Create(
-    const LocalScriptStore& script_store) {
-  return std::make_unique<NoRoundTripService>(script_store);
+    content::BrowserContext* browser_context,
+    Client* client) {
+  return NoRoundTripService::Create(
+      browser_context, client,
+      ServerUrlFetcher(ServerUrlFetcher::GetDefaultServerUrl()));
 }
 
-NoRoundTripService::NoRoundTripService(const LocalScriptStore& script_store)
-    : script_store_(script_store) {}
+// static
+std::unique_ptr<NoRoundTripService> NoRoundTripService::Create(
+    content::BrowserContext* browser_context,
+    Client* client,
+    const ServerUrlFetcher& url_fetcher) {
+  auto request_sender = std::make_unique<ServiceRequestSenderImpl>(
+      browser_context, client->GetAccessTokenFetcher(),
+      std::make_unique<cup::CUPImplFactory>(),
+      std::make_unique<NativeURLLoaderFactory>(),
+      ApiKeyFetcher().GetAPIKey(client->GetChannel()));
 
-NoRoundTripService::~NoRoundTripService() = default;
+  return std::make_unique<NoRoundTripService>(
+      std::move(request_sender),
+      url_fetcher.GetNoRoundTripScriptsByHashEndpoint(), client);
+}
 
 void NoRoundTripService::SetScriptStoreConfig(
     const ScriptStoreConfig& script_store_config) {
@@ -47,17 +140,14 @@
     const GURL& url,
     const TriggerContext& trigger_context,
     ServiceRequestSender::ResponseCallback callback) {
-  const std::string supports_site_response_str =
-      script_store_.supports_site_response.SerializeAsString();
+  const std::string request =
+      CreateGetNoRoundtripRequest(url, trigger_context.GetScriptParameters());
 
-  const auto response_info = ServiceRequestSender::ResponseInfo(
-      {.encoded_body_length = static_cast<int64_t>(
-           script_store_.supports_site_response.ByteSizeLong())});
-
-  const int status =
-      url.DomainIs(script_store_.domain) ? net::HTTP_OK : net::HTTP_BAD_REQUEST;
-
-  std::move(callback).Run(status, supports_site_response_str, response_info);
+  request_sender_->SendRequest(
+      get_scripts_endpoint_, request, GetDefaultAuthMode(),
+      base::BindOnce(&NoRoundTripService::OnNoRountripByHashPrefixResponse,
+                     weak_ptr_factory_.GetWeakPtr(), url, std::move(callback)),
+      RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX);
 }
 
 void NoRoundTripService::GetActions(
@@ -68,24 +158,31 @@
     const std::string& script_payload,
     ServiceRequestSender::ResponseCallback callback) {
   DCHECK(!script_path.empty());
+  if (!script_store_) {
+    LOG(ERROR) << __func__ << " called on an empty script store.";
+    std::move(callback).Run(net::HTTP_BAD_REQUEST, "", {});
+    return;
+  }
 
   ServiceRequestSender::ResponseInfo response_info;
   response_info.encoded_body_length = 0;
 
-  for (const auto& routine : script_store_.routines) {
-    if (routine.routine().path() != script_path) {
+  for (const auto& routine : script_store_->GetRoutines()) {
+    if (!routine.has_script_path() || routine.script_path() != script_path) {
       continue;
     }
 
-    std::string get_actions_response;
-    routine.autobot_response().SerializeToString(&get_actions_response);
-    response_info.encoded_body_length =
-        static_cast<int64_t>(routine.autobot_response().ByteSizeLong());
+    const std::string get_actions_response =
+        routine.autobot_response().SerializeAsString();
+    const ServiceRequestSender::ResponseInfo response_info{
+        .encoded_body_length =
+            static_cast<int64_t>(routine.autobot_response().ByteSizeLong())};
+
     std::move(callback).Run(net::HTTP_OK, get_actions_response, response_info);
     return;
   }
 
-  std::move(callback).Run(net::HTTP_BAD_REQUEST, "", response_info);
+  std::move(callback).Run(net::HTTP_BAD_REQUEST, "", {});
 }
 
 void NoRoundTripService::GetNextActions(
@@ -96,7 +193,14 @@
     const RoundtripTimingStats& timing_stats,
     const RoundtripNetworkStats& network_stats,
     ServiceRequestSender::ResponseCallback callback) {
-  VLOG(1) << __func__ << "called in NoRoundTripService, returning empty list";
+  if (!script_store_) {
+    LOG(ERROR) << __func__ << " called on an empty script store.";
+    std::move(callback).Run(net::HTTP_BAD_REQUEST, "", {});
+    return;
+  }
+
+  LOG(WARNING) << __func__
+               << "called in NoRoundTripService, returning empty list";
   std::move(callback).Run(net::HTTP_OK, "",
                           ServiceRequestSender::ResponseInfo());
 }
@@ -129,4 +233,59 @@
     const std::string& payload,
     ServiceRequestSender::ResponseCallback callback) {}
 
+void NoRoundTripService::OnNoRountripByHashPrefixResponse(
+    const GURL& url,
+    ServiceRequestSender::ResponseCallback callback,
+    int http_status,
+    const std::string& response,
+    const ServiceRequestSender::ResponseInfo& response_info) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  if (http_status != net::HTTP_OK) {
+    LOG(ERROR) << " Failed to get scripts."
+               << ", http-status=" << http_status;
+    std::move(callback).Run(http_status, "", {});
+    return;
+  }
+
+  if (!resp.ParseFromString(response)) {
+    LOG(ERROR) << __func__ << " returned unparsable response";
+    std::move(callback).Run(net::HTTP_INTERNAL_SERVER_ERROR, "", {});
+    return;
+  }
+
+  std::vector<std::string> extra_urls;
+  for (const GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo& match :
+       resp.match_infos()) {
+    VLOG(3) << "Parsing " << match.domain();
+    if (url.host() != GURL(match.domain()).host()) {
+      continue;
+    }
+    script_store_ = CreateStoreFromMatch(match);
+    std::move(callback).Run(
+        net::HTTP_OK,
+        script_store_->GetSupportsSiteResponse().SerializeAsString(),
+        {.encoded_body_length = static_cast<int64_t>(
+             script_store_->GetSupportsSiteResponse().ByteSizeLong())});
+    return;
+  }
+
+  LOG(ERROR) << __func__ << " could not find a matching url.";
+#if DEBUG
+  for (const auto& match : resp.match_infos()) {
+    extra_urls.push_back(match.domain());
+  }
+  LOG(ERROR) << __func__ << "Looking for " << url.HostNoBrackets()
+             << ", found: " << base::JoinString(extra_urls, " ");
+#endif
+  std::move(callback).Run(net::HTTP_BAD_REQUEST, "", {});
+}
+
+NoRoundTripService::NoRoundTripService(
+    std::unique_ptr<LocalScriptStore> script_store)
+    : script_store_(std::move(script_store)) {}
+
+const LocalScriptStore* NoRoundTripService::GetStore() const {
+  return script_store_.get();
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/no_round_trip_service.h b/components/autofill_assistant/browser/service/no_round_trip_service.h
index c17b1d5..69d8422 100644
--- a/components/autofill_assistant/browser/service/no_round_trip_service.h
+++ b/components/autofill_assistant/browser/service/no_round_trip_service.h
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -9,59 +9,54 @@
 #include <string>
 #include <vector>
 
+#include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/client.h"
 #include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/service/local_script_store.h"
+#include "components/autofill_assistant/browser/service/server_url_fetcher.h"
 #include "components/autofill_assistant/browser/service/service.h"
 #include "components/autofill_assistant/browser/service/service_request_sender.h"
+#include "components/autofill_assistant/browser/trigger_context.h"
 #include "components/autofill_assistant/browser/user_data.h"
+#include "content/public/browser/browser_context.h"
 #include "url/gurl.h"
 
 namespace autofill_assistant {
 
-struct LocalScriptStore {
-  // Temporary boilerplate, this struct becomes a proper class in the child CL
-  ~LocalScriptStore();
-  LocalScriptStore(const LocalScriptStore&);
-  LocalScriptStore(LocalScriptStore&&);
-  LocalScriptStore& operator=(const LocalScriptStore&) = default;
-  LocalScriptStore& operator=(LocalScriptStore&&) = default;
-  LocalScriptStore(std::vector<GetNoRoundtripScriptsByHashPrefixResponseProto::
-                                   MatchInfo::RoutineScript> routines,
-                   std::string domain,
-                   SupportsScriptResponseProto supports_site_response);
-
-  // Contains pairs of [AutobotResponses, SupportedRoutine].
-  // TODO change SupportedRoutine to simply script_path
-  std::vector<
-      GetNoRoundtripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
-      routines;
-
-  // The domain that this LocalScriptStore is valid for
-  std::string domain;
-
-  // The results of SupportsScript for this domain/intent match
-  SupportsScriptResponseProto supports_site_response;
-};
-
 // An offline version of the service that fetches all actions at once and then
 // serves scripts without roundtrips.
 class NoRoundTripService : public Service {
  public:
-  // Convenience method for creating an offline service.
-  static std::unique_ptr<NoRoundTripService> Create(
-      const LocalScriptStore& script_store);
+  // Constructs a NoRoundTripService, does not make any call to the server, the
+  // calls are instead made in the first call to GetScripts.
+  NoRoundTripService(std::unique_ptr<ServiceRequestSender> request_sender,
+                     const GURL& get_scripts_endpoint,
+                     Client* client);
 
-  explicit NoRoundTripService(const LocalScriptStore& script_store);
   NoRoundTripService(const NoRoundTripService&) = delete;
   NoRoundTripService& operator=(const NoRoundTripService&) = delete;
   ~NoRoundTripService() override;
 
-  // Return the SupportsSite response from the local script store.
+  // Factory methods to create a NoRoundTrip service, all endpoint are
+  // initialised, but no RPC is made.
+  [[nodiscard]] static std::unique_ptr<NoRoundTripService> Create(
+      content::BrowserContext* context,
+      Client* client);
+  [[nodiscard]] static std::unique_ptr<NoRoundTripService> Create(
+      content::BrowserContext* context,
+      Client* client,
+      const ServerUrlFetcher& url_fetcher);
+
+  // Runs an RPC to GetNoRoundTripScriptsByHash, stores the results in the local
+  // store and finally calls the callback with a fabricated GetActionsResponse
+  // created from the local script store.
   void GetScriptsForUrl(
       const GURL& url,
       const TriggerContext& trigger_context,
       ServiceRequestSender::ResponseCallback callback) override;
 
-  // Return the action given a script_path from the local script store.
+  // Calls the callback with a fabricated GetActionsResponse created given a
+  // script_path from the local script store.
   void GetActions(const std::string& script_path,
                   const GURL& url,
                   const TriggerContext& trigger_context,
@@ -69,7 +64,7 @@
                   const std::string& script_payload,
                   ServiceRequestSender::ResponseCallback callback) override;
 
-  // This call will not work with the local script store.
+  // This call will always call the callback with an empty response.
   void GetNextActions(
       const TriggerContext& trigger_context,
       const std::string& previous_global_payload,
@@ -79,7 +74,6 @@
       const RoundtripNetworkStats& network_stats,
       ServiceRequestSender::ResponseCallback callback) override;
 
-  // This call will return the script store config from the local script store.
   void SetScriptStoreConfig(
       const ScriptStoreConfig& script_store_config) override;
 
@@ -104,9 +98,40 @@
                       const std::string& payload,
                       ServiceRequestSender::ResponseCallback callback) override;
 
+  // Retrieves the script store, used for testing.
+  const LocalScriptStore* GetStore() const;
+
+  // Initializes a NoRoundTripService, only used for testing purposes.
+  // Does not initializes RPC endpoints and the client.
+  explicit NoRoundTripService(std::unique_ptr<LocalScriptStore> script_store);
+
  private:
+  // Callback to run on receiving a response from
+  // OnNoRoundTripByHashPrefixRequest
+  void OnNoRountripByHashPrefixResponse(
+      const GURL& url,
+      ServiceRequestSender::ResponseCallback callback,
+      int http_status,
+      const std::string& response,
+      const ServiceRequestSender::ResponseInfo& response_info);
+
+  // Create a GetNoRoundtrip request given the url and the script parameters.
+  [[nodiscard]] static std::string CreateGetNoRoundtripRequest(
+      const GURL& url,
+      const ScriptParameters& script_parameters);
+
+  // RPC endpoint
+  GURL get_scripts_endpoint_;
+
+  raw_ptr<Client> client_;
+
   ScriptStoreConfig script_store_config_;
-  const LocalScriptStore script_store_;
+
+  std::unique_ptr<LocalScriptStore> script_store_;
+
+  std::unique_ptr<ServiceRequestSender> request_sender_;
+
+  base::WeakPtrFactory<NoRoundTripService> weak_ptr_factory_{this};
 };
 }  // namespace autofill_assistant
 #endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_NO_ROUND_TRIP_SERVICE_H_
diff --git a/components/autofill_assistant/browser/service/no_round_trip_service_unittest.cc b/components/autofill_assistant/browser/service/no_round_trip_service_unittest.cc
new file mode 100644
index 0000000..139d3b8
--- /dev/null
+++ b/components/autofill_assistant/browser/service/no_round_trip_service_unittest.cc
@@ -0,0 +1,346 @@
+// 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/autofill_assistant/browser/service/no_round_trip_service.h"
+
+#include <memory>
+
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
+#include "components/autofill_assistant/browser/mock_client.h"
+#include "components/autofill_assistant/browser/protocol_utils.h"
+#include "components/autofill_assistant/browser/public/autofill_assistant.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/service/mock_service_request_sender.h"
+#include "components/version_info/version_info.h"
+#include "net/http/http_status_code.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+
+using ::base::test::RunOnceCallback;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::IsEmpty;
+using ::testing::IsNull;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::SaveArg;
+
+namespace {
+const char kEndpointRPC[] = "https://www.fake.backend.com/no_roundtrip";
+const char kFakeUrl[] = "https://www.example.com";
+constexpr uint32_t kHashPrefixLength = 15;
+
+GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo CreateExampleMatch(
+    const std::string& domain,
+    const std::string& path,
+    int action_delay) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo match;
+  auto* supports_site_response = match.mutable_supports_site_response();
+  auto* script = supports_site_response->add_scripts();
+  script->set_path(path);
+  match.set_domain(domain);
+  auto* routine_script = match.add_routine_scripts();
+  auto* autobot_response = routine_script->mutable_autobot_response();
+  routine_script->set_script_path(path);
+  autobot_response->add_actions()->set_action_delay_ms(action_delay);
+
+  return match;
+}
+
+class NoRoundTripServiceTest : public testing::Test {
+ protected:
+  NoRoundTripServiceTest() {
+    client_context_.mutable_chrome()->set_chrome_version(
+        version_info::GetProductNameAndVersionForUserAgent());
+    mock_request_sender_ =
+        std::make_unique<NiceMock<MockServiceRequestSender>>();
+  }
+
+  ~NoRoundTripServiceTest() override = default;
+  NiceMock<MockClient> mock_client_;
+  ClientContextProto client_context_;
+  std::unique_ptr<NiceMock<MockServiceRequestSender>> mock_request_sender_;
+
+  base::MockCallback<ServiceRequestSender::ResponseCallback>
+      mock_response_callback_;
+
+  SupportsScriptResponseProto supports_site_response_;
+  std::string domain_;
+  std::vector<
+      GetNoRoundTripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
+      routines_;
+
+  NoRoundTripService GetService() {
+    return NoRoundTripService(std::make_unique<LocalScriptStore>(
+        routines_, domain_, supports_site_response_));
+  }
+
+  NoRoundTripService GetCompleteService() {
+    return NoRoundTripService(std::move(mock_request_sender_),
+                              GURL(kEndpointRPC), &mock_client_);
+  }
+
+  uint64_t GetHashPrefix() {
+    return AutofillAssistant::GetHashPrefix(
+        kHashPrefixLength, url::Origin::Create(GURL(kFakeUrl)));
+  }
+};
+
+TEST_F(NoRoundTripServiceTest, CallsEndpointAndPopulatesStore) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  const std::string path = "test_path_1";
+  *resp.add_match_infos() = CreateExampleMatch(kFakeUrl, path, 37);
+  const std::string resp_string = resp.SerializeAsString();
+
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, resp_string,
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  const SupportsScriptResponseProto& supports_script =
+      resp.match_infos()[0].supports_site_response();
+
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_OK, supports_script.SerializeAsString(), _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  const LocalScriptStore* local_script_store = service.GetStore();
+
+  ASSERT_THAT(local_script_store, Not(IsNull()));
+  EXPECT_EQ(local_script_store->GetDomain(), kFakeUrl);
+  ASSERT_EQ(local_script_store->GetRoutines().size(), 1ul);
+  auto routine_script = local_script_store->GetRoutines()[0];
+  auto autobot_response = routine_script.autobot_response();
+  ASSERT_EQ(autobot_response.actions().size(), 1);
+  auto action = autobot_response.actions()[0];
+  EXPECT_EQ(action.action_delay_ms(), 37);
+  EXPECT_EQ(routine_script.script_path(), path);
+  ASSERT_EQ(local_script_store->GetSupportsSiteResponse().scripts().size(), 1);
+  EXPECT_EQ(local_script_store->GetSupportsSiteResponse().scripts()[0].path(),
+            path);
+}
+
+TEST_F(NoRoundTripServiceTest, DoesNotPopulateStoreOnRPCError) {
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(
+          RunOnceCallback<2>(500, "", ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_INTERNAL_SERVER_ERROR, "", _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  EXPECT_THAT(service.GetStore(), IsNull());
+}
+
+TEST_F(NoRoundTripServiceTest, SelectsRightMatchWhenMultipleAreReturned) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  std::string script_path = "test_path_2";
+  *resp.add_match_infos() =
+      CreateExampleMatch("www.bad.com", "not_relevant_for_test", 0);
+  GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo* good_match =
+      resp.add_match_infos();
+  *good_match = CreateExampleMatch(kFakeUrl, script_path, 42);
+  const std::string resp_string = resp.SerializeAsString();
+
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, resp_string,
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  const SupportsScriptResponseProto& supports_script =
+      good_match->supports_site_response();
+
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_OK, supports_script.SerializeAsString(), _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  const LocalScriptStore* local_script_store = service.GetStore();
+
+  ASSERT_THAT(local_script_store, Not(IsNull()));
+  EXPECT_EQ(local_script_store->GetDomain(), kFakeUrl);
+  ASSERT_THAT(local_script_store->GetRoutines(), Not(IsEmpty()));
+  auto routine_script = local_script_store->GetRoutines()[0];
+  auto autobot_response = routine_script.autobot_response();
+  ASSERT_THAT(autobot_response.actions(), Not(IsEmpty()));
+  auto action = autobot_response.actions()[0];
+  EXPECT_EQ(action.action_delay_ms(), 42);
+  EXPECT_EQ(routine_script.script_path(), script_path);
+  ASSERT_THAT(local_script_store->GetSupportsSiteResponse().scripts(),
+              Not(IsEmpty()));
+  EXPECT_EQ(local_script_store->GetSupportsSiteResponse().scripts()[0].path(),
+            script_path);
+}
+
+TEST_F(NoRoundTripServiceTest, ReturnsEmptyStoreWhenNoUrlMatches) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  *resp.add_match_infos() =
+      CreateExampleMatch("bad.com", "not_relevant_for_test", 0);
+  *resp.add_match_infos() =
+      CreateExampleMatch("worse.com", "not_relevant_for_test", 0);
+  const std::string resp_string = resp.SerializeAsString();
+
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, resp_string,
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  ASSERT_THAT(service.GetStore(), IsNull());
+}
+
+TEST_F(NoRoundTripServiceTest, GetActionsReturnsBadRequestWithEmptyStore) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  *resp.add_match_infos() =
+      CreateExampleMatch("bad.com", "not_relevant_for_test", 0);
+  const std::string resp_string = resp.SerializeAsString();
+
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, resp_string,
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  const LocalScriptStore* local_script_store = service.GetStore();
+
+  ASSERT_THAT(local_script_store, IsNull());
+
+  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
+  service.GetActions("not_relevant_for_the_test",
+                     GURL("not_relevant_for_the_test"), TriggerContext(), "",
+                     "", mock_response_callback_.Get());
+}
+
+TEST_F(NoRoundTripServiceTest,
+       GetNextActionsReturnsInternalServerErrorWithEmptyStore) {
+  GetNoRoundTripScriptsByHashPrefixResponseProto resp;
+  *resp.add_match_infos() =
+      CreateExampleMatch("bad.com", "not_relevant_for_test", 0);
+  const std::string resp_string = resp.SerializeAsString();
+
+  EXPECT_CALL(
+      *mock_request_sender_.get(),
+      OnSendRequest(GURL(kEndpointRPC),
+                    ProtocolUtils::CreateGetNoRoundTripScriptsByHashRequest(
+                        kHashPrefixLength, GetHashPrefix(), client_context_,
+                        ScriptParameters()),
+                    _, RpcType::GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX))
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, resp_string,
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
+
+  NoRoundTripService service = GetCompleteService();
+  service.GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
+                           mock_response_callback_.Get());
+
+  const LocalScriptStore* local_script_store = service.GetStore();
+
+  ASSERT_THAT(local_script_store, IsNull());
+
+  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
+  service.GetNextActions(TriggerContext(), "", "",
+                         std::vector<ProcessedActionProto>(),
+                         RoundtripTimingStats(), RoundtripNetworkStats(),
+                         mock_response_callback_.Get());
+}
+
+TEST_F(NoRoundTripServiceTest, WithExistingPathGetActionsSucceeds) {
+  domain_ = "example.com";
+  GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo_RoutineScript
+      routine;
+  routine.set_script_path("script_path");
+  routine.mutable_autobot_response()->set_run_id(0);
+  routines_.push_back(routine);
+
+  EXPECT_CALL(
+      mock_response_callback_,
+      Run(net::HTTP_OK, routine.autobot_response().SerializeAsString(), _));
+
+  GetService().GetActions("script_path", GURL(kFakeUrl), TriggerContext(), "",
+                          "", mock_response_callback_.Get());
+}
+
+TEST_F(NoRoundTripServiceTest, GetActionsFailsGivenWrongPath) {
+  domain_ = "example.com";
+  GetNoRoundTripScriptsByHashPrefixResponseProto_MatchInfo_RoutineScript
+      routine;
+  routine.set_script_path("not_relevant_for_test");
+  routine.mutable_autobot_response()->set_run_id(0);
+  routines_.push_back(routine);
+
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_BAD_REQUEST, /* response= */ "", _));
+
+  GetService().GetActions("non_existing_path", GURL(kFakeUrl), TriggerContext(),
+                          "", "", mock_response_callback_.Get());
+}
+
+TEST_F(NoRoundTripServiceTest, GetNextActionsReturnsEmptyResponse) {
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_OK, /* response= */ "", _));
+
+  const std::vector<ProcessedActionProto> processed_actions;
+
+  GetService().GetNextActions(TriggerContext(), "", "", processed_actions,
+                              RoundtripTimingStats(), RoundtripNetworkStats(),
+                              mock_response_callback_.Get());
+}
+
+TEST_F(NoRoundTripServiceTest, GetUserDataFails) {
+  EXPECT_CALL(mock_response_callback_,
+              Run(net::HTTP_METHOD_NOT_ALLOWED, /* response= */ "", _));
+  const UserData user_data;
+  GetService().GetUserData(CollectUserDataOptions(), 0, &user_data,
+                           mock_response_callback_.Get());
+}
+
+}  // namespace
+
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/no_round_trip_service_unittests.cc b/components/autofill_assistant/browser/service/no_round_trip_service_unittests.cc
deleted file mode 100644
index fe360f1..0000000
--- a/components/autofill_assistant/browser/service/no_round_trip_service_unittests.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2020 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/autofill_assistant/browser/service/no_round_trip_service.h"
-
-#include <memory>
-#include "components/autofill_assistant/browser/service/no_round_trip_service.h"
-
-#include "base/test/gmock_callback_support.h"
-#include "base/test/mock_callback.h"
-#include "components/autofill_assistant/browser/service.pb.h"
-#include "net/http/http_status_code.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace autofill_assistant {
-
-using ::base::test::RunOnceCallback;
-using ::testing::_;
-using ::testing::DoAll;
-using ::testing::NiceMock;
-using ::testing::Return;
-using ::testing::SaveArg;
-
-namespace {
-const char kFakeUrl[] = "https://www.example.com";
-
-class NoRoundTripServiceTest : public testing::Test {
- protected:
-  ~NoRoundTripServiceTest() override = default;
-
-  base::MockCallback<ServiceRequestSender::ResponseCallback>
-      mock_response_callback_;
-
-  SupportsScriptResponseProto supports_site_response_;
-  std::string domain_;
-  std::vector<
-      GetNoRoundtripScriptsByHashPrefixResponseProto::MatchInfo::RoutineScript>
-      routines_;
-
-  NoRoundTripService GetService() {
-    return NoRoundTripService(
-        LocalScriptStore(routines_, domain_, supports_site_response_));
-  }
-};
-
-TEST_F(NoRoundTripServiceTest, WithRightUrlGetScriptsSucceeds) {
-  domain_ = "example.com";
-  supports_site_response_.add_scripts()->set_path("test_path");
-
-  EXPECT_CALL(
-      mock_response_callback_,
-      Run(net::HTTP_OK, supports_site_response_.SerializeAsString(), _));
-
-  GetService().GetScriptsForUrl(GURL(kFakeUrl), TriggerContext(),
-                                mock_response_callback_.Get());
-}
-
-TEST_F(NoRoundTripServiceTest, WithWrongUrlGetScriptsFails) {
-  domain_ = "example.com";
-  supports_site_response_.add_scripts()->set_path("test_path");
-
-  EXPECT_CALL(mock_response_callback_,
-              Run(net::HTTP_BAD_REQUEST,
-                  std::string(supports_site_response_.SerializeAsString()), _));
-
-  GetService().GetScriptsForUrl(GURL("https://www.wrong.com"), TriggerContext(),
-                                mock_response_callback_.Get());
-}
-
-TEST_F(NoRoundTripServiceTest, WithExistingPathGetActionsSucceeds) {
-  domain_ = "example.com";
-  routines_.resize(1);
-  routines_[0].mutable_routine()->set_path("script_path");
-  routines_[0].mutable_autobot_response()->set_run_id(0);
-
-  EXPECT_CALL(
-      mock_response_callback_,
-      Run(net::HTTP_OK,
-          std::string(routines_.at(0).autobot_response().SerializeAsString()),
-          _));
-
-  GetService().GetActions("script_path", GURL(kFakeUrl), TriggerContext(), "",
-                          "", mock_response_callback_.Get());
-}
-
-TEST_F(NoRoundTripServiceTest, GetActionsFailsGivenWrongPath) {
-  domain_ = "example.com";
-  routines_.resize(1);
-  routines_[0].mutable_routine()->set_path("script_path");
-  routines_[0].mutable_autobot_response()->set_run_id(0);
-
-  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_BAD_REQUEST, "", _));
-
-  GetService().GetActions("non_existing_path", GURL(kFakeUrl), TriggerContext(),
-                          "", "", mock_response_callback_.Get());
-}
-
-TEST_F(NoRoundTripServiceTest, GetNextActionsReturnsEmptyResponse) {
-  EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, "", _));
-
-  const std::vector<ProcessedActionProto> processed_actions;
-
-  GetService().GetNextActions(TriggerContext(), "", "", processed_actions,
-                              RoundtripTimingStats(), RoundtripNetworkStats(),
-                              mock_response_callback_.Get());
-}
-
-TEST_F(NoRoundTripServiceTest, GetUserDataFails) {
-  EXPECT_CALL(mock_response_callback_,
-              Run(net::HTTP_METHOD_NOT_ALLOWED, "", _));
-  const UserData user_data;
-  GetService().GetUserData(CollectUserDataOptions(), 0, &user_data,
-                           mock_response_callback_.Get());
-}
-
-}  // namespace
-
-}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/rpc_type.h b/components/autofill_assistant/browser/service/rpc_type.h
index dc72135..b7eb6cc 100644
--- a/components/autofill_assistant/browser/service/rpc_type.h
+++ b/components/autofill_assistant/browser/service/rpc_type.h
@@ -16,6 +16,7 @@
   GET_TRIGGER_SCRIPTS_BY_HASH_PREFIX,
   GET_USER_DATA,
   REPORT_PROGRESS,
+  GET_NO_ROUNDTRIP_SCRIPTS_BY_HASH_PREFIX,
 };
 }  // namespace autofill_assistant
 
diff --git a/components/autofill_assistant/browser/service/server_url_fetcher.cc b/components/autofill_assistant/browser/service/server_url_fetcher.cc
index 260c047..13ff5e95 100644
--- a/components/autofill_assistant/browser/service/server_url_fetcher.cc
+++ b/components/autofill_assistant/browser/service/server_url_fetcher.cc
@@ -19,6 +19,8 @@
 const char kCapabilitiesByHashEndpoint[] = "/v1/capabilitiesByHashPrefix2";
 const char kUserDataEndpoint[] = "/v1/userData";
 const char kProgressEndpoint[] = "/v1/reportProgress";
+const char kSelfContainedByHashEndpoint[] =
+    "/v1/noRoundTripScriptsByHashPrefix";
 }  // namespace
 
 namespace autofill_assistant {
@@ -78,4 +80,10 @@
   return server_url_.ReplaceComponents(trigger_replacements);
 }
 
+GURL ServerUrlFetcher::GetNoRoundTripScriptsByHashEndpoint() const {
+  GURL::Replacements no_roundtrip_hash_replacements;
+  no_roundtrip_hash_replacements.SetPathStr(kSelfContainedByHashEndpoint);
+  return server_url_.ReplaceComponents(no_roundtrip_hash_replacements);
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/server_url_fetcher.h b/components/autofill_assistant/browser/service/server_url_fetcher.h
index cb6cf109..4db8f9e 100644
--- a/components/autofill_assistant/browser/service/server_url_fetcher.h
+++ b/components/autofill_assistant/browser/service/server_url_fetcher.h
@@ -31,6 +31,8 @@
   virtual GURL GetCapabilitiesByHashEndpoint() const;
   // Returns the endpoint to send the GetUserData RPC to.
   virtual GURL GetUserDataEndpoint() const;
+  // Returns the endpoint to send the GetNoroundtripScriptsByHash RPC to.
+  virtual GURL GetNoRoundTripScriptsByHashEndpoint() const;
   // Returns the endpoint to send the ReportProgress RPC to.
   virtual GURL GetReportProgressEndpoint() const;
 
diff --git a/components/autofill_assistant/browser/trigger_context.cc b/components/autofill_assistant/browser/trigger_context.cc
index 5b74196..5b7ae43 100644
--- a/components/autofill_assistant/browser/trigger_context.cc
+++ b/components/autofill_assistant/browser/trigger_context.cc
@@ -157,7 +157,8 @@
 }
 
 bool TriggerContext::GetSkipAutofillAssistantOnboarding() const {
-  return skip_autofill_assistant_onboarding_;
+  return skip_autofill_assistant_onboarding_ ||
+         script_parameters_->GetIsNoRoundtrip().value_or(false);
 }
 
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/trigger_context_unittest.cc b/components/autofill_assistant/browser/trigger_context_unittest.cc
index 38d9ae7..af10358 100644
--- a/components/autofill_assistant/browser/trigger_context_unittest.cc
+++ b/components/autofill_assistant/browser/trigger_context_unittest.cc
@@ -58,6 +58,21 @@
             TriggerScriptProto::SHOPPING_CART_FIRST_TIME_USER);
 }
 
+TEST(TriggerContextTest, SkipOnboardingForNoRoundtripScripts) {
+  TriggerContext context = {std::make_unique<ScriptParameters>(
+                                base::flat_map<std::string, std::string>{
+                                    {"IS_NO_ROUND_TRIP", "true"}}),
+                            "exps",
+                            /* is_cct = */ true,
+                            /* onboarding_shown = */ true,
+                            /* is_direct_action = */ true,
+                            /* initial_url = */ "https://www.example.com",
+                            /* is_in_chrome_triggered = */ true,
+                            /* is_externally_triggered = */ true,
+                            /* skip_autofill_assistant_onboarding = */ false};
+  EXPECT_TRUE(context.GetSkipAutofillAssistantOnboarding());
+}
+
 TEST(TriggerContextTest, MergeEmpty) {
   TriggerContext empty;
   TriggerContext merged = {{&empty, &empty}};
diff --git a/components/autofill_assistant/browser/web/selector_observer.cc b/components/autofill_assistant/browser/web/selector_observer.cc
index f011c843..092fa4cb 100644
--- a/components/autofill_assistant/browser/web/selector_observer.cc
+++ b/components/autofill_assistant/browser/web/selector_observer.cc
@@ -183,16 +183,16 @@
     DomObjectFrameStack element_dom_object;
     element_dom_object.object_data.object_id = element_object_id_entry->second;
     element_dom_object.object_data.node_frame_id = dom_root.frame_id();
-    const auto entry = frame_ids_.find(dom_root);
-    if (entry != frame_ids_.end()) {
+    if (const auto entry = frame_ids_.find(dom_root);
+        entry != frame_ids_.end()) {
       element_dom_object.render_frame_id = entry->second.global_frame_id;
     }
     size_t depth = 1;
     std::string prev_frame_id = "";
     auto it = dom_roots_.find(std::make_pair(element.selector_id, depth++));
     while (it != dom_roots_.end() && it->second != dom_root) {
-      const auto entry = frame_ids_.find(it->second);
-      if (entry != frame_ids_.end()) {
+      if (const auto entry = frame_ids_.find(it->second);
+          entry != frame_ids_.end()) {
         JsObjectIdentifier frame;
         frame.object_id = entry->second.devtools_id;
         frame.node_frame_id = prev_frame_id;
diff --git a/components/breadcrumbs/core/application_breadcrumbs_logger.cc b/components/breadcrumbs/core/application_breadcrumbs_logger.cc
index 577fe8fe..8335db24 100644
--- a/components/breadcrumbs/core/application_breadcrumbs_logger.cc
+++ b/components/breadcrumbs/core/application_breadcrumbs_logger.cc
@@ -56,7 +56,7 @@
 }
 
 std::list<std::string> ApplicationBreadcrumbsLogger::GetEventsForTesting() {
-  return breadcrumb_manager_.GetEvents(/*event_count_limit=*/0);
+  return breadcrumb_manager_.GetEvents();
 }
 
 void ApplicationBreadcrumbsLogger::AddEvent(const std::string& event) {
diff --git a/components/breadcrumbs/core/breadcrumb_manager.cc b/components/breadcrumbs/core/breadcrumb_manager.cc
index fcdc872..fd96d42 100644
--- a/components/breadcrumbs/core/breadcrumb_manager.cc
+++ b/components/breadcrumbs/core/breadcrumb_manager.cc
@@ -37,17 +37,13 @@
 
 BreadcrumbManager::~BreadcrumbManager() = default;
 
-const std::list<std::string> BreadcrumbManager::GetEvents(
-    size_t event_count_limit) {
+const std::list<std::string> BreadcrumbManager::GetEvents() {
   DropOldEvents();
 
   std::list<std::string> events;
   for (const EventBucket& event_bucket : base::Reversed(event_buckets_)) {
     for (const std::string& event : base::Reversed(event_bucket.events)) {
       events.push_front(event);
-      if (event_count_limit > 0 && events.size() >= event_count_limit) {
-        return events;
-      }
     }
   }
   return events;
diff --git a/components/breadcrumbs/core/breadcrumb_manager.h b/components/breadcrumbs/core/breadcrumb_manager.h
index ca1e0d56..a10a0b6 100644
--- a/components/breadcrumbs/core/breadcrumb_manager.h
+++ b/components/breadcrumbs/core/breadcrumb_manager.h
@@ -30,13 +30,12 @@
   BreadcrumbManager& operator=(const BreadcrumbManager&) = delete;
   ~BreadcrumbManager();
 
-  // Returns a list of the collected breadcrumb events which are still relevant
-  // up to |event_count_limit|. Passing zero for |event_count_limit| signifies
-  // no limit. Events returned will have a timestamp prepended to the original
-  // |event| string representing when |AddEvent| was called.
+  // Returns a list of the collected breadcrumb events which are still relevant.
+  // Events returned will have a timestamp prepended to the original `event`
+  // string representing when `AddEvent` was called.
   // Note: This method may drop old events so the returned events can change
   // even if no new events have been added, but time has passed.
-  const std::list<std::string> GetEvents(size_t event_count_limit);
+  const std::list<std::string> GetEvents();
 
   // Logs a breadcrumb event with message data |event|.
   // NOTE: |event| must not include newline characters as newlines are used by
diff --git a/components/breadcrumbs/core/breadcrumb_manager_keyed_service.cc b/components/breadcrumbs/core/breadcrumb_manager_keyed_service.cc
index de95108..94fce71 100644
--- a/components/breadcrumbs/core/breadcrumb_manager_keyed_service.cc
+++ b/components/breadcrumbs/core/breadcrumb_manager_keyed_service.cc
@@ -27,9 +27,8 @@
   breadcrumb_manager_->RemoveObserver(observer);
 }
 
-const std::list<std::string> BreadcrumbManagerKeyedService::GetEvents(
-    size_t event_count_limit) const {
-  return breadcrumb_manager_->GetEvents(event_count_limit);
+const std::list<std::string> BreadcrumbManagerKeyedService::GetEvents() const {
+  return breadcrumb_manager_->GetEvents();
 }
 
 void BreadcrumbManagerKeyedService::StartPersisting(
diff --git a/components/breadcrumbs/core/breadcrumb_manager_keyed_service.h b/components/breadcrumbs/core/breadcrumb_manager_keyed_service.h
index 1c2828f2..4de1f7e 100644
--- a/components/breadcrumbs/core/breadcrumb_manager_keyed_service.h
+++ b/components/breadcrumbs/core/breadcrumb_manager_keyed_service.h
@@ -37,10 +37,9 @@
   void AddObserver(BreadcrumbManagerObserver* observer);
   void RemoveObserver(BreadcrumbManagerObserver* observer);
 
-  // Returns up to |event_count_limit| events from the underlying
-  // |breadcrumb_manager|. See |BreadcrumbManager::GetEvents| for returned event
-  // details.
-  const std::list<std::string> GetEvents(size_t event_count_limit) const;
+  // Returns events from the underlying `breadcrumb_manager_`. See
+  // `BreadcrumbManager::GetEvents` for returned event details.
+  const std::list<std::string> GetEvents() const;
 
   // Persists all events logged to |breadcrumb_manager_| to
   // |persistent_storage_manager|. If StartPersisting has already been called,
diff --git a/components/breadcrumbs/core/breadcrumb_manager_keyed_service_unittest.cc b/components/breadcrumbs/core/breadcrumb_manager_keyed_service_unittest.cc
index 4dab001d..a5cdcc7 100644
--- a/components/breadcrumbs/core/breadcrumb_manager_keyed_service_unittest.cc
+++ b/components/breadcrumbs/core/breadcrumb_manager_keyed_service_unittest.cc
@@ -20,7 +20,7 @@
           /*is_off_the_record=*/false);
   breadcrumb_manager_service->AddEvent("event");
 
-  const std::string event = breadcrumb_manager_service->GetEvents(0).front();
+  const std::string event = breadcrumb_manager_service->GetEvents().front();
 
   std::unique_ptr<BreadcrumbManagerKeyedService>
       otr_breadcrumb_manager_service =
@@ -29,7 +29,7 @@
   otr_breadcrumb_manager_service->AddEvent("event");
 
   const std::string off_the_record_event =
-      otr_breadcrumb_manager_service->GetEvents(0).front();
+      otr_breadcrumb_manager_service->GetEvents().front();
   // Event should indicate it was logged from an off-the-record "Incognito"
   // browser state.
   EXPECT_NE(std::string::npos, off_the_record_event.find(" I "));
diff --git a/components/breadcrumbs/core/breadcrumb_manager_unittest.cc b/components/breadcrumbs/core/breadcrumb_manager_unittest.cc
index dcaf173..98c3390 100644
--- a/components/breadcrumbs/core/breadcrumb_manager_unittest.cc
+++ b/components/breadcrumbs/core/breadcrumb_manager_unittest.cc
@@ -34,27 +34,12 @@
 TEST_F(BreadcrumbManagerTest, AddEvent) {
   const std::string event_message = "event";
   breadcrumb_manager_.AddEvent(event_message);
-  const std::list<std::string>& events = breadcrumb_manager_.GetEvents(0);
+  const std::list<std::string>& events = breadcrumb_manager_.GetEvents();
   ASSERT_EQ(1ul, events.size());
   // Events returned from |GetEvents| will have a timestamp prepended.
   EXPECT_NE(std::string::npos, events.front().find(event_message));
 }
 
-// Tests that returned events returned by |GetEvents| are limited by the
-// |event_count_limit| parameter.
-TEST_F(BreadcrumbManagerTest, EventCountLimited) {
-  breadcrumb_manager_.AddEvent("event1");
-  breadcrumb_manager_.AddEvent("event2");
-  breadcrumb_manager_.AddEvent("event3");
-  breadcrumb_manager_.AddEvent("event4");
-
-  std::list<std::string> events = breadcrumb_manager_.GetEvents(2);
-  ASSERT_EQ(2ul, events.size());
-  EXPECT_EQ("0:00:00 event3", events.front());
-  events.pop_front();
-  EXPECT_EQ("0:00:00 event4", events.front());
-}
-
 // Tests that old event buckets are dropped.
 TEST_F(BreadcrumbManagerTest, OldEventsDropped) {
   // Log an event from one and two hours ago.
@@ -72,7 +57,7 @@
   task_env_.FastForwardBy(base::Minutes(3));
   breadcrumb_manager_.AddEvent("event5");
 
-  std::list<std::string> events = breadcrumb_manager_.GetEvents(0);
+  std::list<std::string> events = breadcrumb_manager_.GetEvents();
   ASSERT_EQ(3ul, events.size());
   // Validate the three most recent events are the ones which were returned.
   EXPECT_EQ("2:00:00 event3", events.front());
@@ -91,23 +76,22 @@
   task_env_.FastForwardBy(base::Hours(1));
   breadcrumb_manager_.AddEvent("event3");
 
-  const std::list<std::string>& events = breadcrumb_manager_.GetEvents(0);
-  EXPECT_EQ(2ul, events.size());
+  EXPECT_EQ(2ul, breadcrumb_manager_.GetEvents().size());
 }
 
 // Tests that event timestamps are formatted as expected.
 TEST_F(BreadcrumbManagerTest, EventTimestampsFormatted) {
   breadcrumb_manager_.AddEvent("event1");
-  EXPECT_EQ("0:00:00 event1", breadcrumb_manager_.GetEvents(0).back());
+  EXPECT_EQ("0:00:00 event1", breadcrumb_manager_.GetEvents().back());
   task_env_.FastForwardBy(base::Seconds(100));
   breadcrumb_manager_.AddEvent("event2");
-  EXPECT_EQ("0:01:40 event2", breadcrumb_manager_.GetEvents(0).back());
+  EXPECT_EQ("0:01:40 event2", breadcrumb_manager_.GetEvents().back());
   task_env_.FastForwardBy(base::Hours(100));
   breadcrumb_manager_.AddEvent("event3");
-  EXPECT_EQ("100:01:40 event3", breadcrumb_manager_.GetEvents(0).back());
+  EXPECT_EQ("100:01:40 event3", breadcrumb_manager_.GetEvents().back());
   task_env_.FastForwardBy(base::Minutes(100));
   breadcrumb_manager_.AddEvent("event4");
-  EXPECT_EQ("101:41:40 event4", breadcrumb_manager_.GetEvents(0).back());
+  EXPECT_EQ("101:41:40 event4", breadcrumb_manager_.GetEvents().back());
 }
 
 }  // namespace breadcrumbs
diff --git a/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java b/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java
index 7520d63..c7becf0 100644
--- a/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java
+++ b/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java
@@ -18,6 +18,7 @@
 import android.widget.FrameLayout;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
 
 import org.chromium.base.MathUtils;
 import org.chromium.content_public.browser.GestureListenerManager;
@@ -58,7 +59,8 @@
     private static final long ANIMATION_DURATION_MS = 250;
 
     /** Detects when the user is dragging the WebContents. */
-    private final GestureStateListenerWithScroll mGestureStateListener;
+    @Nullable
+    protected final GestureStateListenerWithScroll mGestureStateListener;
 
     /** Listens for changes in the layout. */
     private final View.OnLayoutChangeListener mLayoutChangeListener;
@@ -93,8 +95,19 @@
      * @param attrs Attributes from the XML layout inflation.
      */
     public SwipableOverlayView(Context context, AttributeSet attrs) {
+        this(context, attrs, true);
+    }
+
+    /**
+     * Creates a SwipableOverlayView.
+     * @param context Context for acquiring resources.
+     * @param attrs Attributes from the XML layout inflation.
+     * @param hideOnScroll Whether this view should observe user's gesture and then auto-hide when
+     *                     page is scrolled down.
+     */
+    public SwipableOverlayView(Context context, AttributeSet attrs, boolean hideOnScroll) {
         super(context, attrs);
-        mGestureStateListener = createGestureStateListener();
+        mGestureStateListener = hideOnScroll ? createGestureStateListener() : null;
         mGestureState = Gesture.NONE;
         mLayoutChangeListener = createLayoutChangeListener();
         mInterpolator = new DecelerateInterpolator(1.0f);
@@ -123,6 +136,10 @@
         return mWebContents;
     }
 
+    protected int getTotalHeight() {
+        return mTotalHeight;
+    }
+
     protected void addToParentView(ViewGroup parentView) {
         if (parentView == null) return;
         if (getParent() == null) {
@@ -202,7 +219,7 @@
 
         // Adding a listener to GestureListenerManager results in extra IPCs on every frame, which
         // is very costly. Only attach the listener if needed.
-        if (mWebContents != null) {
+        if (mWebContents != null && mGestureStateListener != null) {
             if (mTotalHeight > 0) {
                 GestureListenerManager.fromWebContents(mWebContents)
                         .addListener(mGestureStateListener);
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
index 09c0344d4..8a9d93d3 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
@@ -760,7 +760,7 @@
 
         mAllowedSiteCount = 0;
 
-        if (websites.size() == 0) {
+        if (websites.size() == 0 || !shouldAddExceptionsForCategory()) {
             updateBlockedHeader(0);
             updateAllowedHeader(0, true);
             updateManagedHeader(0);
@@ -1234,6 +1234,21 @@
     }
 
     /**
+     * Always returns true unless a category uses custom logic to show/hide exceptions on the
+     * category settings page.
+     * @return Whether exceptions should be added for the category.
+     */
+    private boolean shouldAddExceptionsForCategory() {
+        if (mCategory.getType() == SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE
+                && !ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS)
+                && SiteSettingsFeatureList.isEnabled(
+                        SiteSettingsFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS_DOWNGRADE)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * Performs a set of tasks when the user updates the desktop site content setting.
      * 1. Records the desktop site content setting change.
      * 2. Updates the Shared Preference USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY.
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
index e41ed88b..aeca389 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -36,6 +36,7 @@
 import org.chromium.components.content_settings.ContentSettingsType;
 import org.chromium.components.embedder_support.util.Origin;
 import org.chromium.content_public.browser.BrowserContextHandle;
+import org.chromium.content_public.browser.ContentFeatureList;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -498,6 +499,8 @@
                 setUpLocationPreference(preference);
             } else if (type == ContentSettingsType.NOTIFICATIONS) {
                 setUpNotificationsPreference(preference, mSite.isEmbargoed(type));
+            } else if (type == ContentSettingsType.REQUEST_DESKTOP_SITE) {
+                setUpDesktopSitePreference(preference);
             } else {
                 setupContentSettingsPreference(preference,
                         mSite.getContentSetting(
@@ -1037,6 +1040,19 @@
         setupContentSettingsPreference(preference, permission, false /* isEmbargoed */);
     }
 
+    private void setUpDesktopSitePreference(Preference preference) {
+        // Skip adding the desktop site preference if RDS exceptions support is removed.
+        if (!ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS)
+                && SiteSettingsFeatureList.isEnabled(
+                        SiteSettingsFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS_DOWNGRADE)) {
+            return;
+        }
+        setupContentSettingsPreference(preference,
+                mSite.getContentSetting(getSiteSettingsDelegate().getBrowserContextHandle(),
+                        ContentSettingsType.REQUEST_DESKTOP_SITE),
+                mSite.isEmbargoed(ContentSettingsType.REQUEST_DESKTOP_SITE));
+    }
+
     private String getDSECategorySummary(@ContentSettingValues int value) {
         return value == ContentSettingValues.ALLOW
                 ? getString(R.string.website_settings_permissions_allowed_dse)
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb
index 1e58997..838b60e 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_af.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Vra voordat jy werwe toelaat om beskermde inhoud te speel (aanbeveel)</translation>
 <translation id="2146738493024040262">Maak kitsprogram oop</translation>
 <translation id="2148716181193084225">Vandag</translation>
+<translation id="2155988908301433309">Bekyk altyd mobiele werf</translation>
 <translation id="2182457891543959921">Vra voordat werwe toegelaat word om 'n 3D-kaart van jou omgewing te skep of kameraposisie na te spoor (aanbeveel)</translation>
 <translation id="2212565012507486665">Laat webkoekies toe</translation>
 <translation id="2228071138934252756">Om <ph name="APP_NAME" /> toegang tot jou kamera te gee, moet jy kamera ook in <ph name="BEGIN_LINK" />Android-instellings<ph name="END_LINK" /> aanskakel.</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">Werwe kan nie vra om kennisgewings te stuur nie</translation>
 <translation id="5516455585884385570">Maak kennisgewinginstellings oop</translation>
 <translation id="5527111080432883924">Vra voordat werwe toegelaat word om teks en prente van die knipbord af te lees (aanbeveel)</translation>
+<translation id="5553273073880784901">Bekyk altyd rekenaarwerf</translation>
 <translation id="5553374991681107062">Jongste</translation>
 <translation id="5556459405103347317">Herlaai</translation>
 <translation id="5596627076506792578">Meer opsies</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb
index afea09b..5d8089c 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_am.xtb
@@ -80,6 +80,7 @@
 <translation id="2653659639078652383">አስገባ</translation>
 <translation id="2677748264148917807">ለቅቀህ ውጣ</translation>
 <translation id="2687403674020088961">ሁሉንም ኩኪዎች አግድ (አይመከርም)</translation>
+<translation id="2692299144678073135">ተዛማጅ ጣቢያዎች በመላው ጣቢያዎች ላይ እርስዎን እንዲያስታውሱ ይፍቀዱላቸው</translation>
 <translation id="2704606927547763573">ተቀድቷል</translation>
 <translation id="2713106313042589954">ካሜራ አጥፋ</translation>
 <translation id="2717722538473713889">ኢሜይል አድራሻዎች</translation>
@@ -140,6 +141,7 @@
 <translation id="4002066346123236978">ርዕስ</translation>
 <translation id="4008040567710660924">የተወሰነ ጣቢያ ኩኪዎችን ፍቀድ።</translation>
 <translation id="4046123991198612571">ቀጣይ ትራክ</translation>
+<translation id="4048876521107516222">ተዛማጅ ጣቢያዎች እንደ እርስዎን በመለያ ገብተው እንደማቆየት ያሉ ነገሮች ላይ እገዛ ለማድረግ ኩኪዎችን ይጠቀማሉ</translation>
 <translation id="4149994727733219643">ለድረ-ገጾች የተቃለለ እይታ</translation>
 <translation id="4165986682804962316">የጣቢያ ቅንብሮች</translation>
 <translation id="4169549551965910670">ከዩኤስቢ መሣሪያ ጋር ተገናኝቷል</translation>
@@ -222,6 +224,7 @@
 <translation id="5887687176710214216">ለመጨረሻ ጊዜ የተጎበኘው ትላንትና</translation>
 <translation id="5916664084637901428">በርቷል</translation>
 <translation id="5922853908706496913">ማያ ገጽዎን በማጋራት ላይ</translation>
+<translation id="5922967540311291836">የሶስተኛ ወገን ኩኪዎችን ያግዱ፦</translation>
 <translation id="5939518447894949180">ዳግም አስጀምር</translation>
 <translation id="5975083100439434680">አሳንስ</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" />፣ <ph name="WARNING_MESSAGE" /></translation>
@@ -312,6 +315,7 @@
 <translation id="7846076177841592234">ምርጫ ሰርዝ</translation>
 <translation id="7846621471902887024">ከሁሉም ጣቢያዎች ዘግተው እንዲወጡ ይደረጋሉ።</translation>
 <translation id="7882806643839505685">ለተወሰነ ጣቢያ ድምጽ ፍቀድ።</translation>
+<translation id="789180354981963912">ማንነትን በማያሳውቅ ላይ የሶስተኛ ወገን ኩኪዎችን ያግዱ፦</translation>
 <translation id="7940722705963108451">አስታውሰኝ</translation>
 <translation id="7986741934819883144">አንድ እውቂያ ይምረጡ</translation>
 <translation id="7999064672810608036">እርግጠኛ ነዎት ለዚህ ጣቢያ ኩኪዎችንም ጨምሮ ሁሉንም አካባቢያዊ ውሂብ ማጽዳት እና ሁሉም ፍቃዶችን ዳግም ማስጀመር ይፈልጋሉ?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb
index de4b893..1ac8a200 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">السؤال أولاً قبل السماح للمواقع الإلكترونية بتشغيل المحتوى المَحمي (موصى به)</translation>
 <translation id="2146738493024040262">فتح تطبيق فوري</translation>
 <translation id="2148716181193084225">اليوم</translation>
+<translation id="2155988908301433309">عرض الموقع الإلكتروني المتوافق مع الأجهزة الجوّالة دائمًا</translation>
 <translation id="2182457891543959921">طلب الإذن قبل السماح لموقع إلكتروني بإنشاء خريطة ثلاثية الأبعاد للبيئة المحيطة بك أو تتبُّع موضع الكاميرا (مقترَح)</translation>
 <translation id="2212565012507486665">السماح بملفات تعريف الارتباط</translation>
 <translation id="2228071138934252756">‏للسماح لتطبيق <ph name="APP_NAME" /> بالوصول إلى الكاميرا، يُرجى أيضًا تفعيل الكاميرا في <ph name="BEGIN_LINK" />إعدادات Android<ph name="END_LINK" />.</translation>
@@ -204,6 +205,7 @@
 <translation id="5505264765875738116">منع المواقع الإلكترونية من طلب إرسال إشعارات</translation>
 <translation id="5516455585884385570">فتح إعدادات الإشعارات</translation>
 <translation id="5527111080432883924">السؤال أولاً قبل السماح للمواقع الإلكترونية بقراءة النصوص والصور من الحافظة (موصى به)</translation>
+<translation id="5553273073880784901">عرض الموقع الإلكتروني المتوافق مع أجهزة الكمبيوتر المكتبي دائمًا</translation>
 <translation id="5553374991681107062">الأحدث</translation>
 <translation id="5556459405103347317">إعادة التحميل</translation>
 <translation id="5596627076506792578">خيارات إضافية</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb
index be143d1..e616044a 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_az.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Saytlar qorunan kontenti oxutmazdan əvvəl icazə tələb edilsin (tövsiyyə edilir)</translation>
 <translation id="2146738493024040262">Ani tətbiqi açın</translation>
 <translation id="2148716181193084225">Bu gün</translation>
+<translation id="2155988908301433309">Həmişə mobil sayta baxın</translation>
 <translation id="2182457891543959921">Saytların ətrafınızdakı sahələrin 3D xəritəsini yaratmasına və ya kamera mövqeyini izləməsinə icazə verməzdən əvvəl icazə tələb edin (tövsiyə edilir)</translation>
 <translation id="2212565012507486665">Kukilərə icazə verin</translation>
 <translation id="2228071138934252756"><ph name="APP_NAME" /> tətbiqinə kameranıza giriş icazəsi vermək üçün <ph name="BEGIN_LINK" />Android Ayarlarında<ph name="END_LINK" /> kameranı da aktiv edin.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Təqdim edin</translation>
 <translation id="2677748264148917807">Tərk edin</translation>
 <translation id="2687403674020088961">Bütün kukiləri bloklayın (tövsiyə edilmir)</translation>
+<translation id="2692299144678073135">Əlaqəli saytların sizi yadda saxlamasına icazə verin</translation>
 <translation id="2704606927547763573">Kopyalandı</translation>
 <translation id="2713106313042589954">Kameranı deaktiv edin</translation>
 <translation id="2717722538473713889">E-poçt ünvanları</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Başlıq</translation>
 <translation id="4008040567710660924">Xüsusi sayt üçün kukilərə icazə verin.</translation>
 <translation id="4046123991198612571">Növbəti trek</translation>
+<translation id="4048876521107516222">Əlaqəli saytlar hesabdan çıxmadan qalmaq kimi işlərdə kömək etmək üçün kukilərdən istifadə edir</translation>
 <translation id="4149994727733219643">İnternet səhifələr üçün sadələşdirilmiş görünüş</translation>
 <translation id="4165986682804962316">Sayt ayarları</translation>
 <translation id="4169549551965910670">USB cihazına qoşulub</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Saytlar bildiriş göndərilməsini tələb edə bilməz</translation>
 <translation id="5516455585884385570">Bildiriş ayarlarını açın</translation>
 <translation id="5527111080432883924">Saytların buferdəki mətn və şəkillərə girişinə icazə vermədən öncə soruşun (məsləhətlidir)</translation>
+<translation id="5553273073880784901">Həmişə masaüstü saytına baxın</translation>
 <translation id="5553374991681107062">Ən son</translation>
 <translation id="5556459405103347317">Yenidən yükləyin</translation>
 <translation id="5596627076506792578">Əlavə seçimlər</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Son ziyarət dünən olub</translation>
 <translation id="5916664084637901428">Aktiv</translation>
 <translation id="5922853908706496913">Ekranınız paylaşılır</translation>
+<translation id="5922967540311291836">Üçüncü tərəf kukiləri bloklayın:</translation>
 <translation id="5939518447894949180">Sıfırlayın</translation>
 <translation id="5975083100439434680">Kiçildin</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" />-<ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Seçimi ləğv edin</translation>
 <translation id="7846621471902887024">Bütün saytlardan çıxacaqsınız.</translation>
 <translation id="7882806643839505685">Xüsusi sayt üçün səsə icazə verin.</translation>
+<translation id="789180354981963912">Anonim rejimdə üçüncü tərəf kukilərini bloklayın:</translation>
 <translation id="7940722705963108451">Mənə xatırladın</translation>
 <translation id="7986741934819883144">Kontakt seçin</translation>
 <translation id="7999064672810608036">Bütün lokal datanı silmək və bu sayt üçün bütün icazələri sıfırlamaq istəyirsiniz?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb
index 0118704..6b05c69 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_bg.xtb
@@ -79,6 +79,7 @@
 <translation id="2653659639078652383">Изпращане</translation>
 <translation id="2677748264148917807">Излизане</translation>
 <translation id="2687403674020088961">Блокиране на всички „бисквитки“ (не се препоръчва)</translation>
+<translation id="2692299144678073135">Разрешаване на сродните сайтове да ви помнят, когато превключвате между тях</translation>
 <translation id="2704606927547763573">Копирано</translation>
 <translation id="2713106313042589954">Изключване на камерата</translation>
 <translation id="2717722538473713889">Имейл адреси</translation>
@@ -139,6 +140,7 @@
 <translation id="4002066346123236978">Заглавие</translation>
 <translation id="4008040567710660924">Разрешаване на „бисквитките“ за конкретен сайт.</translation>
 <translation id="4046123991198612571">Следващ запис</translation>
+<translation id="4048876521107516222">Свързаните сайтове използват „бисквитки“, за да ви помагат с различни неща, като например да останете в профила си</translation>
 <translation id="4149994727733219643">Опростен изглед на уеб страниците</translation>
 <translation id="4165986682804962316">Настройки за сайта</translation>
 <translation id="4169549551965910670">Установена е връзка с USB устройство</translation>
@@ -220,6 +222,7 @@
 <translation id="5887687176710214216">Последно посещение: вчера</translation>
 <translation id="5916664084637901428">Включено</translation>
 <translation id="5922853908706496913">Екранът ви се споделя</translation>
+<translation id="5922967540311291836">Блокиране на „бисквитките“ на трети страни:</translation>
 <translation id="5939518447894949180">Нулиране</translation>
 <translation id="5975083100439434680">Намаляване на мащаба</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +313,7 @@
 <translation id="7846076177841592234">Анулиране на избора</translation>
 <translation id="7846621471902887024">Ще излезете от профила си във всички сайтове.</translation>
 <translation id="7882806643839505685">Разрешаване на звука за конкретен сайт.</translation>
+<translation id="789180354981963912">Блокиране на „бисквитките“ на трети страни в режим „инкогнито“:</translation>
 <translation id="7940722705963108451">Напомняне</translation>
 <translation id="7986741934819883144">Изберете контакт</translation>
 <translation id="7999064672810608036">Наистина ли искате да изчистите всички локални данни, включително „бисквитките“, и да нулирате всички разрешения за този уебсайт?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb
index 3a5f9f8..045cfb27 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb
@@ -79,6 +79,7 @@
 <translation id="2653659639078652383">Envia</translation>
 <translation id="2677748264148917807">Surt</translation>
 <translation id="2687403674020088961">Bloqueja totes les galetes (opció no recomanada)</translation>
+<translation id="2692299144678073135">Permet que els llocs web relacionats et recordin en diversos llocs web</translation>
 <translation id="2704606927547763573">Copiada</translation>
 <translation id="2713106313042589954">Desactiva la càmera</translation>
 <translation id="2717722538473713889">Adreces electròniques</translation>
@@ -139,6 +140,7 @@
 <translation id="4002066346123236978">Títol</translation>
 <translation id="4008040567710660924">Permet les galetes d'un lloc web concret.</translation>
 <translation id="4046123991198612571">Pista següent</translation>
+<translation id="4048876521107516222">Els llocs web relacionats utilitzen galetes per ajudar-te amb coses com ara mantenir la sessió iniciada</translation>
 <translation id="4149994727733219643">Visualització simplificada de pàgines web</translation>
 <translation id="4165986682804962316">Configuració del lloc web</translation>
 <translation id="4169549551965910670">Connectat a un dispositiu USB</translation>
@@ -220,6 +222,7 @@
 <translation id="5887687176710214216">Darrera visita: ahir</translation>
 <translation id="5916664084637901428">Activat</translation>
 <translation id="5922853908706496913">S'està compartint la pantalla</translation>
+<translation id="5922967540311291836">Bloqueja les galetes de tercers:</translation>
 <translation id="5939518447894949180">Restableix</translation>
 <translation id="5975083100439434680">Redueix</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +313,7 @@
 <translation id="7846076177841592234">Cancel·la la selecció</translation>
 <translation id="7846621471902887024">Se't tancarà la sessió de tots els llocs web.</translation>
 <translation id="7882806643839505685">Permet el so d'un lloc web concret.</translation>
+<translation id="789180354981963912">Bloqueja les galetes de tercers en mode d'incògnit:</translation>
 <translation id="7940722705963108451">Recorda-m'ho</translation>
 <translation id="7986741934819883144">Selecciona un contacte</translation>
 <translation id="7999064672810608036">Confirmes que vols esborrar d'aquest lloc web totes les dades locals, incloses les galetes, i restablir-ne tots els permisos?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_cy.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_cy.xtb
index 78336a3..8016714 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_cy.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_cy.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Gofyn cyn caniatáu i wefannau chwarae cynnwys gwarchodedig (argymhellir)</translation>
 <translation id="2146738493024040262">Agor Ap Sydyn</translation>
 <translation id="2148716181193084225">Heddiw</translation>
+<translation id="2155988908301433309">Gweld gwefan symudol bob amser</translation>
 <translation id="2182457891543959921">Gofyn cyn caniatáu i wefannau greu map 3D o'ch amgylchoedd neu olrhain safle eich camera (argymhellir)</translation>
 <translation id="2212565012507486665">Caniatáu cwcis</translation>
 <translation id="2228071138934252756">I adael i <ph name="APP_NAME" /> gael mynediad at eich camera, trowch y camera ymlaen yn <ph name="BEGIN_LINK" />Gosodiadau Android<ph name="END_LINK" /> hefyd.</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">Ni all gwefannau ofyn am anfon hysbysiadau</translation>
 <translation id="5516455585884385570">Agor y gosodiadau hysbysu</translation>
 <translation id="5527111080432883924">Gofyn cyn caniatáu i wefannau ddarllen testun a lluniau o'r clipfwrdd (argymhellir)</translation>
+<translation id="5553273073880784901">Gweld gwefan bwrdd gwaith bob amser</translation>
 <translation id="5553374991681107062">Diweddaraf</translation>
 <translation id="5556459405103347317">Ail-lwytho</translation>
 <translation id="5596627076506792578">Rhagor o ddewisiadau</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb
index 3e49f192..e29d65fd 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_da.xtb
@@ -80,6 +80,7 @@
 <translation id="2653659639078652383">Send</translation>
 <translation id="2677748264148917807">Forlad</translation>
 <translation id="2687403674020088961">Bloker alle cookies (anbefales ikke)</translation>
+<translation id="2692299144678073135">Tillad, at relaterede websites husker dig på forskellige websites</translation>
 <translation id="2704606927547763573">Kopieret</translation>
 <translation id="2713106313042589954">Slå kamera fra</translation>
 <translation id="2717722538473713889">Mailadresser</translation>
@@ -140,6 +141,7 @@
 <translation id="4002066346123236978">Titel</translation>
 <translation id="4008040567710660924">Tillad cookies for et bestemt website.</translation>
 <translation id="4046123991198612571">Næste nummer</translation>
+<translation id="4048876521107516222">Relaterede websites anvender cookies som en hjælp til f.eks. at sørge for, at du kan forblive logget ind</translation>
 <translation id="4149994727733219643">Enkel visning af websider</translation>
 <translation id="4165986682804962316">Websiteindstillinger</translation>
 <translation id="4169549551965910670">Forbundet til en USB-enhed</translation>
@@ -222,6 +224,7 @@
 <translation id="5887687176710214216">Senest besøgt i går</translation>
 <translation id="5916664084637901428">Til</translation>
 <translation id="5922853908706496913">Deling af din skærm</translation>
+<translation id="5922967540311291836">Bloker tredjepartscookies:</translation>
 <translation id="5939518447894949180">Nulstil</translation>
 <translation id="5975083100439434680">Zoom ud</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -312,6 +315,7 @@
 <translation id="7846076177841592234">Annuller valg</translation>
 <translation id="7846621471902887024">Du bliver logget ud af alle websites.</translation>
 <translation id="7882806643839505685">Tillad, at et bestemt website afspiller lyd.</translation>
+<translation id="789180354981963912">Bloker tredjepartscookies i inkognitotilstand:</translation>
 <translation id="7940722705963108451">Påmind mig</translation>
 <translation id="7986741934819883144">Vælg en kontakt</translation>
 <translation id="7999064672810608036">Er du sikker på, at du vil slette alle lokale data, herunder cookies, og nulstille alle tilladelser for dette website?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb
index 7f9a9915..b6b8164 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_es-419.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Preguntar antes de permitir que los sitios reproduzcan contenido protegido (recomendado)</translation>
 <translation id="2146738493024040262">Abrir app instantánea</translation>
 <translation id="2148716181193084225">Hoy</translation>
+<translation id="2155988908301433309">Ver siempre el sitio móvil</translation>
 <translation id="2182457891543959921">Preguntar antes de permitir que los sitios creen un mapa 3D de tu entorno o hagan un seguimiento de la posición de la cámara (recomendado)</translation>
 <translation id="2212565012507486665">Permitir cookies</translation>
 <translation id="2228071138934252756">Para permitir que <ph name="APP_NAME" /> acceda a tu cámara, actívala también en la <ph name="BEGIN_LINK" />Configuración de Android<ph name="END_LINK" />.</translation>
@@ -204,6 +205,7 @@
 <translation id="5505264765875738116">Los sitios no podrán preguntarte si quieres recibir notificaciones</translation>
 <translation id="5516455585884385570">Abrir la configuración de notificaciones</translation>
 <translation id="5527111080432883924">Preguntar antes de permitir que los sitios lean el texto y las imágenes del portapapeles (recomendado)</translation>
+<translation id="5553273073880784901">Ver siempre el sitio para computadoras</translation>
 <translation id="5553374991681107062">Recientes</translation>
 <translation id="5556459405103347317">Volver a cargar</translation>
 <translation id="5596627076506792578">Más opciones</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb
index 6f8e5d3..4744efb 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">قبل از اجازه به سایت‌ها برای پخش محتوای محافظت‌شده سؤال شود (توصیه می‌شود)</translation>
 <translation id="2146738493024040262">برنامه فوری را باز کنید</translation>
 <translation id="2148716181193084225">امروز</translation>
+<translation id="2155988908301433309">همیشه سایت ویژه تلفن همراه مشاهده شود</translation>
 <translation id="2182457891543959921">قبل از اینکه به سایت‌ها اجازه داده شود نقشه سه‌بعدی از محیط ایجاد کنند یا موقعیت دوربین را ردیابی کنند سؤال شود (توصیه می‌شود)</translation>
 <translation id="2212565012507486665">مجاز کردن کوکی ها</translation>
 <translation id="2228071138934252756">‏برای اینکه به <ph name="APP_NAME" /> اجازه دهید به دوربین دسترسی پیدا کند، دوربین را در <ph name="BEGIN_LINK" />تنظیمات Android<ph name="END_LINK" /> نیز روشن کنید.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">ارسال</translation>
 <translation id="2677748264148917807">خروج</translation>
 <translation id="2687403674020088961">مسدود کردن همه کوکی‌ها (توصیه نمی‌شود)</translation>
+<translation id="2692299144678073135">اجازه دادن به سایت‌های مربوطه برای به‌خاطر آوردن شما در سایت‌ها</translation>
 <translation id="2704606927547763573">کپی شد</translation>
 <translation id="2713106313042589954">خاموش کردن دوربین</translation>
 <translation id="2717722538473713889">آدرس‌های ایمیل</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">عنوان</translation>
 <translation id="4008040567710660924">کوکی‌ها را برای سایت خاصی مجاز کنید.</translation>
 <translation id="4046123991198612571">آهنگ بعدی</translation>
+<translation id="4048876521107516222">سایت‌های مربوطه از کوکی استفاده می‌کنند تا در مواردی مثل ورود به سیستم به شما کمک کنند</translation>
 <translation id="4149994727733219643">نمای ساده‌شده برای صفحه‌های وب</translation>
 <translation id="4165986682804962316">تنظیمات سایت</translation>
 <translation id="4169549551965910670">‏به دستگاه USB متصل است</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">سایت‌ها نمی‌توانند برای ارسال اعلان درخواست دهند</translation>
 <translation id="5516455585884385570">باز کردن تنظیمات اعلان</translation>
 <translation id="5527111080432883924">قبل از اینکه به سایت‌ها اجازه داده شود به نوشتار و تصاویر بریده‌دان دسترسی پیدا کنند سؤال شود (توصیه می‌شود)</translation>
+<translation id="5553273073880784901">همیشه سایت ویژه رایانه مشاهده شود</translation>
 <translation id="5553374991681107062">جدیدترین</translation>
 <translation id="5556459405103347317">تازه‌سازی</translation>
 <translation id="5596627076506792578">گزینه‌های بیشتر</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">آخرین بازدید: دیروز</translation>
 <translation id="5916664084637901428">روشن</translation>
 <translation id="5922853908706496913">درحال هم‌رسانی صفحه‌نمایش</translation>
+<translation id="5922967540311291836">مسدود کردن کوکی‌های شخص ثالث:</translation>
 <translation id="5939518447894949180">بازنشانی</translation>
 <translation id="5975083100439434680">دورنمایی کردن</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">لغو انتخاب</translation>
 <translation id="7846621471902887024">از سیستم همه سایت‌ها خارج خواهید شد.</translation>
 <translation id="7882806643839505685">پخش صدا برای سایت خاصی مجاز شود.</translation>
+<translation id="789180354981963912">مسدود کردن کوکی‌های شخص ثالث در «حالت ناشناس»:</translation>
 <translation id="7940722705963108451">به من یادآوری شود</translation>
 <translation id="7986741934819883144">مخاطبی انتخاب کنید</translation>
 <translation id="7999064672810608036">مطمئنید که می‌خواهید تمام داده‌های محلی، شامل کوکی‌ها را حذف کنید و تمام مجوزهای این وب‌سایت را بازنشانی کنید؟</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb
index 8208c60..ed9bfe75e0 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb
@@ -80,6 +80,7 @@
 <translation id="2653659639078652383">Isumite</translation>
 <translation id="2677748264148917807">Umalis</translation>
 <translation id="2687403674020088961">I-block ang lahat ng cookies (hindi inirerekomenda)</translation>
+<translation id="2692299144678073135">Payagan ang mga nauugnay na site na tandaan ka sa mga site</translation>
 <translation id="2704606927547763573">Kinopya</translation>
 <translation id="2713106313042589954">I-off ang camera</translation>
 <translation id="2717722538473713889">Mga email address</translation>
@@ -140,6 +141,7 @@
 <translation id="4002066346123236978">Pamagat</translation>
 <translation id="4008040567710660924">Payagan ang cookies para sa isang partikular na site.</translation>
 <translation id="4046123991198612571">Susunod na track</translation>
+<translation id="4048876521107516222">Gumagamit ng cookies ang mga nauugnay na site para makatulong sa mga bagay gaya ng pagpapanatili sa iyong naka-sign in</translation>
 <translation id="4149994727733219643">Pinasimpleng view para sa mga web page</translation>
 <translation id="4165986682804962316">Mga setting ng site</translation>
 <translation id="4169549551965910670">Nakakonekta sa USB device</translation>
@@ -222,6 +224,7 @@
 <translation id="5887687176710214216">Huling binisita kahapon</translation>
 <translation id="5916664084637901428">Naka-on</translation>
 <translation id="5922853908706496913">Ibinabahagi ang iyong screen</translation>
+<translation id="5922967540311291836">I-block ang third-party na cookies:</translation>
 <translation id="5939518447894949180">I-reset</translation>
 <translation id="5975083100439434680">Mag-zoom out</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -312,6 +315,7 @@
 <translation id="7846076177841592234">Kanselahin ang pinili</translation>
 <translation id="7846621471902887024">Masa-sign out ka sa lahat ng site.</translation>
 <translation id="7882806643839505685">Payagan ang tunog para sa isang partikular na site.</translation>
+<translation id="789180354981963912">I-block ang third-party na cookies sa Incognito:</translation>
 <translation id="7940722705963108451">Ipaalala sa akin</translation>
 <translation id="7986741934819883144">Pumili ng contact</translation>
 <translation id="7999064672810608036">Sigurado ka bang gusto mong i-clear ang lahat ng lokal na data, kasama ang cookies, at i-reset ang lahat ng pahintulot para sa website na ito?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
index 68a2771..54d51d9f 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
@@ -80,6 +80,7 @@
 <translation id="2653659639078652383">Pošalji</translation>
 <translation id="2677748264148917807">Napusti</translation>
 <translation id="2687403674020088961">Blokiranje svih kolačića (ne preporučuje se)</translation>
+<translation id="2692299144678073135">Dopustite povezanim web-lokacijama da vas zapamte na više web-lokacija</translation>
 <translation id="2704606927547763573">Kopirano</translation>
 <translation id="2713106313042589954">Isključi kameru</translation>
 <translation id="2717722538473713889">E-adrese</translation>
@@ -140,6 +141,7 @@
 <translation id="4002066346123236978">Naslov</translation>
 <translation id="4008040567710660924">Dopusti kolačiće za određenu web-lokaciju.</translation>
 <translation id="4046123991198612571">Sljedeća pjesma</translation>
+<translation id="4048876521107516222">Povezane web-lokacije upotrebljavaju kolačiće kako bi vam pomogle da npr. ostanete prijavljeni</translation>
 <translation id="4149994727733219643">Pojednostavljeni prikaz za web-stranice</translation>
 <translation id="4165986682804962316">Postavke web-lokacije</translation>
 <translation id="4169549551965910670">Povezano s USB uređajem</translation>
@@ -222,6 +224,7 @@
 <translation id="5887687176710214216">Posljednji posjet bio je jučer</translation>
 <translation id="5916664084637901428">Uključi</translation>
 <translation id="5922853908706496913">Dijeljenje zaslona</translation>
+<translation id="5922967540311291836">Blokiraj kolačiće trećih strana:</translation>
 <translation id="5939518447894949180">Ponovno postavi</translation>
 <translation id="5975083100439434680">Smanji</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -312,6 +315,7 @@
 <translation id="7846076177841592234">Poništi odabir</translation>
 <translation id="7846621471902887024">Odjavit ćete se sa svih web-lokacija.</translation>
 <translation id="7882806643839505685">Dopuštanje zvuka za određenu web-lokaciju.</translation>
+<translation id="789180354981963912">Blokiraj kolačiće trećih strana u anonimnom načinu:</translation>
 <translation id="7940722705963108451">Podsjeti me</translation>
 <translation id="7986741934819883144">Odaberite kontakt</translation>
 <translation id="7999064672810608036">Jeste li sigurni da želite izbrisati sve lokalne podatke, uključujući kolačiće, i poništiti sva dopuštenja za ovu web-lokaciju?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb
index cf2d503..5a6c7522 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_id.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Tanyakan sebelum mengizinkan situs memutar konten yang dilindungi (direkomendasikan)</translation>
 <translation id="2146738493024040262">Buka Aplikasi Instan</translation>
 <translation id="2148716181193084225">Hari ini</translation>
+<translation id="2155988908301433309">Selalu tampilkan situs seluler</translation>
 <translation id="2182457891543959921">Tanyakan sebelum mengizinkan situs membuat peta 3D untuk area di sekeliling Anda atau melacak posisi kamera (direkomendasikan)</translation>
 <translation id="2212565012507486665">Izinkan cookie</translation>
 <translation id="2228071138934252756">Untuk mengizinkan <ph name="APP_NAME" /> mengakses kamera Anda, aktifkan juga kamera di <ph name="BEGIN_LINK" />Setelan Android<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Kirim</translation>
 <translation id="2677748264148917807">Keluar</translation>
 <translation id="2687403674020088961">Blokir semua cookie (tidak direkomendasikan)</translation>
+<translation id="2692299144678073135">Izinkan situs terkait mengingat Anda di seluruh situs</translation>
 <translation id="2704606927547763573">Disalin</translation>
 <translation id="2713106313042589954">Nonaktifkan kamera</translation>
 <translation id="2717722538473713889">Alamat email</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Judul</translation>
 <translation id="4008040567710660924">Izinkan cookie untuk situs tertentu.</translation>
 <translation id="4046123991198612571">Lagu berikutnya</translation>
+<translation id="4048876521107516222">Situs terkait menggunakan cookie untuk membantu berbagai hal seperti membuat Anda tetap login</translation>
 <translation id="4149994727733219643">Tampilan sederhana untuk halaman web</translation>
 <translation id="4165986682804962316">Setelan situs</translation>
 <translation id="4169549551965910670">Terhubung ke perangkat USB</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Situs tidak dapat meminta izin mengirimkan notifikasi</translation>
 <translation id="5516455585884385570">Buka setelan notifikasi</translation>
 <translation id="5527111080432883924">Tanya sebelum mengizinkan situs membaca teks dan gambar dari papan klip (disarankan)</translation>
+<translation id="5553273073880784901">Selalu tampilkan situs desktop</translation>
 <translation id="5553374991681107062">Terbaru</translation>
 <translation id="5556459405103347317">Muat ulang</translation>
 <translation id="5596627076506792578">Opsi lainnya</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Terakhir dibuka kemarin</translation>
 <translation id="5916664084637901428">Aktif</translation>
 <translation id="5922853908706496913">Membagikan layar Anda</translation>
+<translation id="5922967540311291836">Blokir cookie pihak ketiga:</translation>
 <translation id="5939518447894949180">Reset</translation>
 <translation id="5975083100439434680">Perkecil</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Batalkan pilihan</translation>
 <translation id="7846621471902887024">Anda akan logout dari semua situs.</translation>
 <translation id="7882806643839505685">Izinkan suara untuk situs tertentu.</translation>
+<translation id="789180354981963912">Blokir cookie pihak ketiga dalam mode Samaran:</translation>
 <translation id="7940722705963108451">Ingatkan saya</translation>
 <translation id="7986741934819883144">Pilih kontak</translation>
 <translation id="7999064672810608036">Yakin ingin menghapus semua data lokal, termasuk cookie, dan menyetel ulang semua izin untuk situs web ini?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb
index bd8744d..29bc97b 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_is.xtb
@@ -79,6 +79,7 @@
 <translation id="2653659639078652383">Senda</translation>
 <translation id="2677748264148917807">Yfirgefa</translation>
 <translation id="2687403674020088961">Loka á öll fótspor (ekki mælt með)</translation>
+<translation id="2692299144678073135">Leyfa tengdum vefsvæðum að muna eftir þér á milli vefsvæða</translation>
 <translation id="2704606927547763573">Afritað</translation>
 <translation id="2713106313042589954">Slökkva á myndavél</translation>
 <translation id="2717722538473713889">Netföng</translation>
@@ -139,6 +140,7 @@
 <translation id="4002066346123236978">Heiti</translation>
 <translation id="4008040567710660924">Leyfa fótspor fyrir tiltekið vefsvæði.</translation>
 <translation id="4046123991198612571">Næsta lag</translation>
+<translation id="4048876521107516222">Tengd vefsvæði nota fótspor í tilgangi á borð við að viðhalda innskráningu</translation>
 <translation id="4149994727733219643">Einfaldað yfirlit fyrir vefsíður</translation>
 <translation id="4165986682804962316">Vefsvæðastillingar</translation>
 <translation id="4169549551965910670">Tengt við USB-tæki</translation>
@@ -220,6 +222,7 @@
 <translation id="5887687176710214216">Síðast opnað í gær</translation>
 <translation id="5916664084637901428">Kveikt</translation>
 <translation id="5922853908706496913">Deiling skjásins þíns</translation>
+<translation id="5922967540311291836">Loka á fótspor þriðju aðila:</translation>
 <translation id="5939518447894949180">Endurstilla</translation>
 <translation id="5975083100439434680">Minnka aðdrátt</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +313,7 @@
 <translation id="7846076177841592234">Hætta við val</translation>
 <translation id="7846621471902887024">Þú verður skráð(ur) út af öllum vefsvæðum.</translation>
 <translation id="7882806643839505685">Leyfa hljóð á tilteknu vefsvæði.</translation>
+<translation id="789180354981963912">Loka á fótspor þriðju aðila í huliðsstillingu:</translation>
 <translation id="7940722705963108451">Minna mig á</translation>
 <translation id="7986741934819883144">Velja tengilið</translation>
 <translation id="7999064672810608036">Ertu viss um að þú viljir hreinsa öll staðbundin gögn fyrir þetta vefsvæði, þar á meðal fótspor, og endurstilla allar heimildir þess?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb
index 875bdfc..765f1310 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_it.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Chiedi prima di consentire ai siti di riprodurre contenuti protetti (opzione consigliata)</translation>
 <translation id="2146738493024040262">Apri l'app istantanea</translation>
 <translation id="2148716181193084225">Oggi</translation>
+<translation id="2155988908301433309">Visualizza sempre il sito mobile</translation>
 <translation id="2182457891543959921">Chiedi conferma prima di consentire ai siti di creare una mappa 3D dell'ambiente circostante o di monitorare la posizione della fotocamera (opzione consigliata)</translation>
 <translation id="2212565012507486665">Consenti cookie</translation>
 <translation id="2228071138934252756">Per consentire all'app <ph name="APP_NAME" /> di accedere alla fotocamera, attiva la fotocamera anche nelle <ph name="BEGIN_LINK" />Impostazioni Android<ph name="END_LINK" />.</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">I siti non possono chiedere di inviare notifiche</translation>
 <translation id="5516455585884385570">Apri le impostazioni di notifica</translation>
 <translation id="5527111080432883924">Chiedi conferma prima di consentire ai siti di leggere testo e immagini negli appunti (opzione consigliata)</translation>
+<translation id="5553273073880784901">Visualizza sempre il sito desktop</translation>
 <translation id="5553374991681107062">Più recenti</translation>
 <translation id="5556459405103347317">Ricarica</translation>
 <translation id="5596627076506792578">Altre opzioni</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb
index 2265834..218a5e6 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">יש לבקש ממני אישור לפני מתן הרשאה לאתרים להציג תוכן מוגן (מומלץ)</translation>
 <translation id="2146738493024040262">פתיחת אפליקציה ללא התקנה</translation>
 <translation id="2148716181193084225">היום</translation>
+<translation id="2155988908301433309">תמיד יוצג האתר לנייד</translation>
 <translation id="2182457891543959921">תוצג שאלה לפני מתן הרשאה לאתרים ליצור מפה בתלת ממד של הסביבה שלך או לעקוב אחר מיקום המצלמה (מומלץ)</translation>
 <translation id="2212565012507486665">‏אישור קובצי cookie</translation>
 <translation id="2228071138934252756">‏כדי לאפשר ל-<ph name="APP_NAME" /> לגשת אל המצלמה, צריך להפעיל אותה גם ב<ph name="BEGIN_LINK" />הגדרות Android<ph name="END_LINK" />.</translation>
@@ -204,6 +205,7 @@
 <translation id="5505264765875738116">אתרים לא יכולים לבקש לשלוח התראות</translation>
 <translation id="5516455585884385570">פתיחה של הגדרות ההתראות</translation>
 <translation id="5527111080432883924">יש לבקש הרשאה לפני מתן גישה לאתרים אל טקסט ותמונות מלוח העריכה (מומלץ)</translation>
+<translation id="5553273073880784901">תמיד יוצג האתר שמותאם למחשב</translation>
 <translation id="5553374991681107062">האחרון</translation>
 <translation id="5556459405103347317">טעינה מחדש</translation>
 <translation id="5596627076506792578">אפשרויות נוספות</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb
index e361135a..fd8e85f5 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">사이트에서 보호된 콘텐츠를 재생하도록 허용하기 전에 확인(권장)</translation>
 <translation id="2146738493024040262">인스턴트 앱 열기</translation>
 <translation id="2148716181193084225">오늘</translation>
+<translation id="2155988908301433309">항상 모바일 사이트 보기</translation>
 <translation id="2182457891543959921">사이트에서 주변 환경의 3D 지도를 생성하거나 카메라 위치를 추적하도록 허용하기 전에 확인(권장)</translation>
 <translation id="2212565012507486665">쿠키 허용</translation>
 <translation id="2228071138934252756"><ph name="APP_NAME" />에서 카메라에 액세스하도록 허용하려면 <ph name="BEGIN_LINK" />Android 설정<ph name="END_LINK" />에서도 카메라를 사용 설정하세요.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">제출</translation>
 <translation id="2677748264148917807">나가기</translation>
 <translation id="2687403674020088961">모든 쿠키 차단(권장되지 않음)</translation>
+<translation id="2692299144678073135">관련 사이트에서 나를 기억하도록 허용</translation>
 <translation id="2704606927547763573">복사됨</translation>
 <translation id="2713106313042589954">카메라 끄기</translation>
 <translation id="2717722538473713889">이메일 주소</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">제목</translation>
 <translation id="4008040567710660924">특정 사이트의 쿠키를 허용합니다.</translation>
 <translation id="4046123991198612571">다음 트랙</translation>
+<translation id="4048876521107516222">관련 사이트에서 로그인 유지 등을 목적으로 쿠키를 사용합니다.</translation>
 <translation id="4149994727733219643">웹페이지 간단히 보기</translation>
 <translation id="4165986682804962316">사이트 설정</translation>
 <translation id="4169549551965910670">USB 기기에 연결되었습니다.</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">사이트에서 알림 전송 허용을 요청할 수 없음</translation>
 <translation id="5516455585884385570">알림 설정 열기</translation>
 <translation id="5527111080432883924">사이트에서 클립보드의 텍스트 및 이미지에 액세스하도록 허용하기 전에 확인(권장)</translation>
+<translation id="5553273073880784901">항상 데스크톱 사이트 보기</translation>
 <translation id="5553374991681107062">최신</translation>
 <translation id="5556459405103347317">새로고침</translation>
 <translation id="5596627076506792578">옵션 더보기</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">최근 방문: 어제</translation>
 <translation id="5916664084637901428">사용</translation>
 <translation id="5922853908706496913">화면 공유</translation>
+<translation id="5922967540311291836">서드 파티 쿠키 차단:</translation>
 <translation id="5939518447894949180">초기화</translation>
 <translation id="5975083100439434680">축소</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">선택 취소</translation>
 <translation id="7846621471902887024">모든 사이트에서 로그아웃됩니다.</translation>
 <translation id="7882806643839505685">특정 사이트에서 소리를 재생하도록 허용합니다.</translation>
+<translation id="789180354981963912">시크릿 모드에서 서드 파티 쿠키 차단:</translation>
 <translation id="7940722705963108451">알림</translation>
 <translation id="7986741934819883144">연락처 선택</translation>
 <translation id="7999064672810608036">쿠키를 포함하여 이 웹사이트의 모든 로컬 데이터를 삭제하고 모든 권한을 재설정하시겠습니까?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb
index 4336731..8ce8c17a4 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ky.xtb
@@ -80,6 +80,7 @@
 <translation id="2653659639078652383">Тапшыруу</translation>
 <translation id="2677748264148917807">Чыгуу</translation>
 <translation id="2687403674020088961">Бардык cookie файлдарды бөгөттөө (сунушталбайт)</translation>
+<translation id="2692299144678073135">Окшош сайттарга башка сайттарда сизди эстеп калууга уруксат берүү</translation>
 <translation id="2704606927547763573">Көчүрүлдү</translation>
 <translation id="2713106313042589954">Камераны өчүрүү</translation>
 <translation id="2717722538473713889">Электрондук почта даректери</translation>
@@ -140,6 +141,7 @@
 <translation id="4002066346123236978">Аталышы</translation>
 <translation id="4008040567710660924">Белгилүү бир сайттын cookie файлдарына уруксат берүү.</translation>
 <translation id="4046123991198612571">Кийинки трек</translation>
+<translation id="4048876521107516222">Окшош сайттар сизге жардам берүү, мисалы, тутумдан чыгарбай туруу үчүн cookie файлдарын колдонот</translation>
 <translation id="4149994727733219643">Веб барактар үчүн жөнөкөйлөштүрүлгөн көрүнүш</translation>
 <translation id="4165986682804962316">Сайт жөндөөлөрү</translation>
 <translation id="4169549551965910670">USB түзмөгүнө туташты</translation>
@@ -222,6 +224,7 @@
 <translation id="5887687176710214216">Кечээ акыркы жолу кирген</translation>
 <translation id="5916664084637901428">Күйүк</translation>
 <translation id="5922853908706496913">Экраныңыз бөлүшүлүүдө</translation>
+<translation id="5922967540311291836">Үчүнчү тараптын cookie файлдарын бөгөттөө:</translation>
 <translation id="5939518447894949180">Кайра коюу</translation>
 <translation id="5975083100439434680">Кичирейтүү</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" />, <ph name="WARNING_MESSAGE" /></translation>
@@ -312,6 +315,7 @@
 <translation id="7846076177841592234">Тандоону жокко чыгаруу</translation>
 <translation id="7846621471902887024">Бардык сайттардан чыгарыласыз.</translation>
 <translation id="7882806643839505685">Белгилүү бир сайтка добуш чыгарууга уруксат берүү.</translation>
+<translation id="789180354981963912">Жашыруун режимде үчүнчү тараптын cookie файлдарын бөгөттөө:</translation>
 <translation id="7940722705963108451">Эскертилсин</translation>
 <translation id="7986741934819883144">Байланышты тандоо</translation>
 <translation id="7999064672810608036">Чын эле жергиликтүү дайындарын баарын тазалап, анын ичинде кукилерди, жана бул вебсайттын уруксаттарынын баарын баштапкы абалга келтиргиңиз келеби?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb
index 33c4e4d..73ae072 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_lo.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">ຖາມກ່ອນທີ່ຈະອະນຸຍາດໃຫ້ເວັບໄຊຫຼິ້ນເນື້ອຫາທີ່ມີການປົກປ້ອງ (ແນະນຳ)</translation>
 <translation id="2146738493024040262">ເປີດແອັບພ້ອມໃຊ້</translation>
 <translation id="2148716181193084225">ມື້​ນີ້</translation>
+<translation id="2155988908301433309">ສະແດງເວັບໄຊມືຖືເທົ່ານັ້ນ</translation>
 <translation id="2182457891543959921">ຖາມກ່ອນທີ່ຈະອະນຸຍາດໃຫ້ເວັບໄຊສ້າງແຜນທີ່ 3 ມິຕິຂອງສິ່ງທີ່ຢູ່ອ້ອມຂ້າງຕົວທ່ານ ຫຼື ຕາມຕຳແໜ່ງກ້ອງ (ແນະນຳ)</translation>
 <translation id="2212565012507486665">ອະນຸຍາດຄຸກກີ້</translation>
 <translation id="2228071138934252756">ເພື່ອອະນຸຍາດໃຫ້ <ph name="APP_NAME" /> ເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງທ່ານ, ກະລຸນາເປີດກ້ອງຖ່າຍຮູບໃນ <ph name="BEGIN_LINK" />ການຕັ້ງຄ່າ Android<ph name="END_LINK" /> ນຳ.</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">ເວັບໄຊບໍ່ສາມາດຂໍໃຫ້ສົ່ງການແຈ້ງເຕືອນໄດ້</translation>
 <translation id="5516455585884385570">ເປີດການຕັ້ງຄ່າການແຈ້ງເຕືອນ</translation>
 <translation id="5527111080432883924">ຖາມກ່ອນອະນຸຍາດໃຫ້ເວັບໄຊອ່ານຂໍ້ຄວາມ ແລະ ຮູບພາບຈາກຄລິບບອດ (ແນະນຳ)</translation>
+<translation id="5553273073880784901">ສະແດງເວັບໄຊເດັສທັອບເທົ່ານັ້ນ</translation>
 <translation id="5553374991681107062">ຫຼ້າສຸດ</translation>
 <translation id="5556459405103347317">ໂຫຼດຄືນໃໝ່</translation>
 <translation id="5596627076506792578">ໂຕ​ເລືອກ​ເພີ່ມ​ເຕີມ</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb
index 56918d6..8faa74f 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Paklausti prieš leidžiant svetainėms leisti saugomą turinį (rekomenduojama)</translation>
 <translation id="2146738493024040262">Atidaryti akimirksniu įkeliamą programėlę</translation>
 <translation id="2148716181193084225">Šiandien</translation>
+<translation id="2155988908301433309">Visada peržiūrėti svetainę mobiliesiems</translation>
 <translation id="2182457891543959921">Klausti, ar svetainėms leidžiama kurti jūsų aplinkos 3D žemėlapį ir stebėti kameros padėtį (rekomenduojama)</translation>
 <translation id="2212565012507486665">Leisti slapukus</translation>
 <translation id="2228071138934252756">Norėdami leisti „<ph name="APP_NAME" />“ pasiekti jūsų kamerą, taip pat įjunkite ją <ph name="BEGIN_LINK" />„Android“ nustatymuose<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Pateikti</translation>
 <translation id="2677748264148917807">Išeiti</translation>
 <translation id="2687403674020088961">Blokuoti visus slapukus (nerekomenduojama)</translation>
+<translation id="2692299144678073135">Leisti susijusioms svetainėms prisiminti jus svetainėse</translation>
 <translation id="2704606927547763573">Nukopij.</translation>
 <translation id="2713106313042589954">Išjungti fotoaparatą</translation>
 <translation id="2717722538473713889">El. pašto adresai</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Pavadinimas</translation>
 <translation id="4008040567710660924">Leisti konkrečios svetainės slapukus.</translation>
 <translation id="4046123991198612571">Kitas takelis</translation>
+<translation id="4048876521107516222">Susijusios svetainės naudoja slapukus, kad padėtų, pvz., likti jums prisijungus</translation>
 <translation id="4149994727733219643">Supaprastinta tinklalapių peržiūra</translation>
 <translation id="4165986682804962316">Svetainės nustatymai</translation>
 <translation id="4169549551965910670">Prisijungta prie USB įrenginio</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Svetainės negali prašyti siųsti pranešimus</translation>
 <translation id="5516455585884385570">Atidaryti pranešimų nustatymus</translation>
 <translation id="5527111080432883924">Klausti, prieš leidžiant svetainėms skaityti tekstą ir vaizdus iš iškarpinės (rekomenduojama)</translation>
+<translation id="5553273073880784901">Visada peržiūrėti svetainę kompiuteriams</translation>
 <translation id="5553374991681107062">Naujausi</translation>
 <translation id="5556459405103347317">Įkelti iš naujo</translation>
 <translation id="5596627076506792578">Daugiau parinkčių</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Paskutinį kartą lankytasi vakar</translation>
 <translation id="5916664084637901428">Įjungta</translation>
 <translation id="5922853908706496913">Bendrinamas ekranas</translation>
+<translation id="5922967540311291836">Blokuoti trečiųjų šalių slapukus:</translation>
 <translation id="5939518447894949180">Nustatyti iš naujo</translation>
 <translation id="5975083100439434680">Tolinti</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Atšaukti pasirinkimą</translation>
 <translation id="7846621471902887024">Būsite atjungti nuo visų svetainių.</translation>
 <translation id="7882806643839505685">Konkrečios svetainės garso leidimas.</translation>
+<translation id="789180354981963912">Blokuoti trečiųjų šalių slapukus inkognito režimu:</translation>
 <translation id="7940722705963108451">Priminti</translation>
 <translation id="7986741934819883144">Pasirinkite kontaktą</translation>
 <translation id="7999064672810608036">Ar tikrai norite išvalyti visus šios svetainės vietinius duomenis, įskaitant slapukus, ir iš naujo nustatyti visus leidimus?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
index a755ea6f..11e45537 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Tanya sebelum membenarkan tapak memainkan kandungan yang dilindungi (disyorkan)</translation>
 <translation id="2146738493024040262">Buka Apl Segera</translation>
 <translation id="2148716181193084225">Hari ini</translation>
+<translation id="2155988908301433309">Sentiasa lihat laman mudah alih</translation>
 <translation id="2182457891543959921">Tanya sebelum membenarkan tapak membuat peta 3D bagi persekitaran anda atau menjejaki kedudukan kamera (disyorkan)</translation>
 <translation id="2212565012507486665">Benarkan kuki</translation>
 <translation id="2228071138934252756">Untuk membolehkan <ph name="APP_NAME" /> mengakses kamera anda, hidupkan juga kamera dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Serah</translation>
 <translation id="2677748264148917807">Tinggalkan</translation>
 <translation id="2687403674020088961">Sekat semua kuki (tidak disyorkan)</translation>
+<translation id="2692299144678073135">Benarkan laman berkaitan mengingati anda di seluruh laman</translation>
 <translation id="2704606927547763573">Disalin</translation>
 <translation id="2713106313042589954">Matikan kamera</translation>
 <translation id="2717722538473713889">Alamat e-mel</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Tajuk</translation>
 <translation id="4008040567710660924">Benarkan kuki untuk tapak tertentu.</translation>
 <translation id="4046123991198612571">Lagu seterusnya</translation>
+<translation id="4048876521107516222">Laman berkaitan menggunakan kuki untuk membantu melakukan perkara seperti memastikan anda kekal log masuk</translation>
 <translation id="4149994727733219643">Paparan ringkas bagi halaman web</translation>
 <translation id="4165986682804962316">Tetapan tapak</translation>
 <translation id="4169549551965910670">Disambungkan kepada peranti USB</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Tapak tidak boleh membuat permintaan untuk menghantar pemberitahuan</translation>
 <translation id="5516455585884385570">Buka tetapan pemberitahuan</translation>
 <translation id="5527111080432883924">Tanya sebelum membenarkan tapak membaca teks dan imej daripada papan keratan (disyorkan)</translation>
+<translation id="5553273073880784901">Sentiasa lihat laman desktop</translation>
 <translation id="5553374991681107062">Terbaharu</translation>
 <translation id="5556459405103347317">Muat Semula</translation>
 <translation id="5596627076506792578">Lagi pilihan</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Terakhir dilawati semalam</translation>
 <translation id="5916664084637901428">Hidupkan</translation>
 <translation id="5922853908706496913">Berkongsi skrin anda</translation>
+<translation id="5922967540311291836">Sekat kuki pihak ketiga:</translation>
 <translation id="5939518447894949180">Tetapkan semula</translation>
 <translation id="5975083100439434680">Zum keluar</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Batalkan pilihan</translation>
 <translation id="7846621471902887024">Anda akan dilog keluar daripada semua tapak.</translation>
 <translation id="7882806643839505685">Benarkan bunyi untuk tapak tertentu.</translation>
+<translation id="789180354981963912">Sekat kuki pihak ketiga dalam Inkognito:</translation>
 <translation id="7940722705963108451">Ingatkan saya</translation>
 <translation id="7986741934819883144">Pilih kenalan</translation>
 <translation id="7999064672810608036">Anda pasti ingin mengosongkan semua data setempat, termasuk kuki dan menetapkan semula semua kebenaran untuk laman web ini?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb
index 3fbcd70..c298649 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_my.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">ကာကွယ်ထားသော အကြောင်းအရာကို ဖွင့်ရန် ဝဘ်ဆိုက်များကို ခွင့်မပြုမီ ခွင့်တောင်းပါ (အကြံပြုထားသည်)</translation>
 <translation id="2146738493024040262">ချက်ခြင်းသုံးအက်ပ်ကို ဖွင့်ရန်</translation>
 <translation id="2148716181193084225">ယနေ့</translation>
+<translation id="2155988908301433309">မိုဘိုင်းဝဘ်ဆိုက် အမြဲကြည့်ရန်</translation>
 <translation id="2182457891543959921">သင့်ပတ်ဝန်းကျင်၏ 3D မြေပုံဆွဲခြင်း သို့မဟုတ် ကင်မရာအနေအထား ခြေရာခံခြင်းတို့အတွက် ဝဘ်ဆိုက်များကို ခွင့်မပြုမီ မေးမြန်းရန် (အကြံပြုထားသည်)</translation>
 <translation id="2212565012507486665">ကွတ်ကီးများ ခွင့်ပြုရန်</translation>
 <translation id="2228071138934252756"><ph name="APP_NAME" /> က သင့်ကင်မရာကို သုံးနိုင်ရန် <ph name="BEGIN_LINK" />Android ဆက်တင်များ<ph name="END_LINK" /> တွင်လည်း ကင်မရာကို ဖွင့်ပါ။</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">ပေးပို့ရန်</translation>
 <translation id="2677748264148917807">ထွက်ခွာရန်</translation>
 <translation id="2687403674020088961">ကွတ်ကီးများအားလုံးကို ပိတ်ရန် (အကြံမပြုပါ)</translation>
+<translation id="2692299144678073135">ဝဘ်ဆိုက်များကြားတွင် သင့်ကိုမှတ်မိရန်အတွက် သက်ဆိုင်ရာဝဘ်ဆိုက်များကို ခွင့်ပြုရန်</translation>
 <translation id="2704606927547763573">ကူးယူပြီးပါပြီ</translation>
 <translation id="2713106313042589954">ကင်မရာပိတ်ရန်</translation>
 <translation id="2717722538473713889">အီးမေးလ်လိပ်စာများ</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">ခေါင်းစဉ်</translation>
 <translation id="4008040567710660924">အချို့ဝဘ်ဆိုက်များအတွက် ကွတ်ကီးများ ခွင့်ပြုသည်။</translation>
 <translation id="4046123991198612571">နောက်တစ်ပုဒ်</translation>
+<translation id="4048876521107516222">သင့်ကို လက်မှတ်ထိုးဝင်ပြီးသားဖြစ်စေရန် ကဲ့သို့သောအရာများအတွက် သက်ဆိုင်ရာဝဘ်ဆိုက်များက ကွတ်ကီးများ သုံးပါသည်</translation>
 <translation id="4149994727733219643">ဝဘ်စာမျက်နှာများအတွက် ရိုးရှင်းသည့်မြင်ကွင်း</translation>
 <translation id="4165986682804962316">ဝက်ဆိုက် ဆက်တင်များ</translation>
 <translation id="4169549551965910670">USB ကိရိယာသို့ ချိတ်ဆက်ပြီး</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">ဝဘ်ဆိုက်များက အကြောင်းကြားချက်များပို့ရန် တောင်းဆို၍မရပါ</translation>
 <translation id="5516455585884385570">အကြောင်းကြားချက် ဆက်တင်များကို ဖွင့်ရန်</translation>
 <translation id="5527111080432883924">ကလစ်ဘုတ်ရှိ စာနှင့် ပုံများကို ဝဘ်ဆိုက်များအား ကြည့်ရှုခွင့်မပြုမီ မေးမြန်းပါ (အကြံပြုထားသည်)</translation>
+<translation id="5553273073880784901">ဒက်စ်တော့ဝဘ်ဆိုက် အမြဲကြည့်ရန်</translation>
 <translation id="5553374991681107062">နောက်ဆုံး</translation>
 <translation id="5556459405103347317">ပြန်တင်ရန်</translation>
 <translation id="5596627076506792578">ပိုမို ရွေးချယ်စရာများ</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">မနေ့က နောက်ဆုံး ဝင်ကြည့်ထားသည်</translation>
 <translation id="5916664084637901428">ဖွင့်ရန်</translation>
 <translation id="5922853908706496913">သင့်ဖန်သားပြင်ကို မျှဝေနေသည်</translation>
+<translation id="5922967540311291836">ပြင်ပကုမ္ပဏီ၏ကွတ်ကီးများကို ပိတ်ထားခြင်း-</translation>
 <translation id="5939518447894949180">ပြန်ညှိ</translation>
 <translation id="5975083100439434680">ဇူးမ်ဖြုတ်ရန်</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">ရွေးချယ်ထားသောဖိုင်များကို ပြန်ဖျက်ပါ</translation>
 <translation id="7846621471902887024">ဝဘ်ဆိုက်အားလုံးမှ သင် ထွက်သွားပါမည်။</translation>
 <translation id="7882806643839505685">ဝဘ်ဆိုက်တစ်ခုအတွက် အသံဖွင့်ခွင့်ပြုသည်။</translation>
+<translation id="789180354981963912">‘ရုပ်ဖျက်မုဒ်’ တွင် ပြင်ပကုမ္ပဏီ၏ကွတ်ကီးများကို ပိတ်ထားခြင်း-</translation>
 <translation id="7940722705963108451">သတိပေးရန်</translation>
 <translation id="7986741934819883144">အဆက်အသွယ်တစ်ခုကို ရွေးပါ</translation>
 <translation id="7999064672810608036">ကွက်ကီးများအပါအဝင်၊ အတွင်းရှိ ဒေတာများအားလုံး ရှင်းလင်းကာ၊ ဤဝဘ်ဆိုက်အတွက် ခွင့်ပြုချက်များအားလုံးအား ပြန်လည်သတ်မှတ်လိုသည်မှာ သေချာပါသလား?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
index aa485c7..6a90a914 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Vragen voordat sites beschermde content mogen afspelen (aanbevolen)</translation>
 <translation id="2146738493024040262">Instant-app openen</translation>
 <translation id="2148716181193084225">Vandaag</translation>
+<translation id="2155988908301433309">Altijd mobiele site bekijken</translation>
 <translation id="2182457891543959921">Vragen voordat sites een 3D-kaart van je omgeving mogen maken of de camerapositie mogen volgen (aanbevolen)</translation>
 <translation id="2212565012507486665">Cookies toestaan</translation>
 <translation id="2228071138934252756">Als je <ph name="APP_NAME" /> toegang wilt geven tot je camera, moet je de camera ook aanzetten via de <ph name="BEGIN_LINK" />Android-instellingen<ph name="END_LINK" />.</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">Sites kunnen niet vragen of ze je meldingen mogen sturen</translation>
 <translation id="5516455585884385570">Instellingen voor meldingen openen</translation>
 <translation id="5527111080432883924">Vragen voordat sites toestemming krijgen om tekst en afbeeldingen vanaf het klembord te lezen (aanbevolen)</translation>
+<translation id="5553273073880784901">Altijd desktopsite bekijken</translation>
 <translation id="5553374991681107062">Nieuwste</translation>
 <translation id="5556459405103347317">Opnieuw laden</translation>
 <translation id="5596627076506792578">Meer opties</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb
index e52819a..98e7e0f4 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_or.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">ସୁରକ୍ଷିତ ବିଷୟବସ୍ତୁକୁ(ସୁପାରିସ୍ କରାଯାଇଥିବା) ଚଲାଇବା ପାଇଁ ସାଇଟ୍‌ଗୁଡ଼ିକୁ ଅନୁମତି ଦେବା ପୂର୍ବରୁ, ପଚାରନ୍ତୁ</translation>
 <translation id="2146738493024040262">ଇନ୍‌ଷ୍ଟାଣ୍ଟ ଆପ୍ ଖୋଲନ୍ତୁ</translation>
 <translation id="2148716181193084225">ଆଜି</translation>
+<translation id="2155988908301433309">ସର୍ବଦା ମୋବାଇଲ ସାଇଟ ଦେଖନ୍ତୁ</translation>
 <translation id="2182457891543959921">ଆପଣଙ୍କ ପରିପାର୍ଶ୍ୱର ଏକ 3D ମ୍ୟାପ୍ ତିଆରି କରିବା ଏବଂ କ୍ୟାମେରା ସ୍ଥିତି ଟ୍ରାକ୍ କରିବାକୁ ସାଇଟଗୁଡ଼ିକୁ ଅନୁମତି ଦେବା ପୂର୍ବରୁ ପଚାରନ୍ତୁ (ସୁପାରିଶ କରାଯାଇଛି)</translation>
 <translation id="2212565012507486665">କୁକୀଗୁଡ଼ିକୁ ଅନୁମତି ଦିଅନ୍ତୁ</translation>
 <translation id="2228071138934252756"><ph name="APP_NAME" />କୁ ଆପଣଙ୍କ କ୍ୟାମେରା ଆକ୍ସେସ୍ ଦେବା ପାଇଁ, <ph name="BEGIN_LINK" />Android ସେଟିଂସ<ph name="END_LINK" />ରେ କ୍ୟାମେରା ମଧ୍ୟ ଚାଲୁ କରନ୍ତୁ।</translation>
@@ -206,6 +207,7 @@
 <translation id="5505264765875738116">ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପଠାଇବାକୁ ସାଇଟ୍‌ଗୁଡ଼ିକ ପଚାରିପାରିବେ ନାହିଁ</translation>
 <translation id="5516455585884385570">ବିଜ୍ଞପ୍ତି ସେଟିଂସ୍ ଖୋଲନ୍ତୁ</translation>
 <translation id="5527111080432883924">କ୍ଲିପ୍‌ବୋର୍ଡ (ସୁପାରିସ୍‌ କରାଯାଇଥିବା)ରୁ ଟେକ୍ସଟ୍‍ ଏବଂ ଛବି ପଢ଼ିବାକୁ ସାଇଟ୍‌ଗୁଡ଼ିକୁ ଅନୁମତି ଦେବା ପୂର୍ବରୁ, ପଚାରନ୍ତୁ</translation>
+<translation id="5553273073880784901">ସର୍ବଦା ଡେସ୍କଟପ ସାଇଟ ଦେଖନ୍ତୁ</translation>
 <translation id="5553374991681107062">ନବୀନତମ</translation>
 <translation id="5556459405103347317">ପୁନଃ ଲୋଡ୍ କରନ୍ତୁ</translation>
 <translation id="5596627076506792578">ଅଧିକ ବିକଳ୍ପ</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb
index a609b897..0d3acd9 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Pytaj, zanim pozwolisz stronom na odtwarzanie treści chronionej (zalecane)</translation>
 <translation id="2146738493024040262">Otwórz aplikację błyskawiczną</translation>
 <translation id="2148716181193084225">Dzisiaj</translation>
+<translation id="2155988908301433309">Zawsze wyświetlaj stronę mobilną</translation>
 <translation id="2182457891543959921">Pytaj, zanim zezwolisz stronom na tworzenie mapy 3D Twojego otoczenia lub śledzenie pozycji kamery (zalecane)</translation>
 <translation id="2212565012507486665">Zezwalaj na pliki cookie</translation>
 <translation id="2228071138934252756">Aby zezwolić aplikacji <ph name="APP_NAME" /> na dostęp do aparatu, musisz go też włączyć w <ph name="BEGIN_LINK" />Ustawieniach Androida<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Prześlij</translation>
 <translation id="2677748264148917807">Wyjdź</translation>
 <translation id="2687403674020088961">Blokuj wszystkie pliki cookie (niezalecane)</translation>
+<translation id="2692299144678073135">Zezwalaj powiązanym witrynom na zapamiętywanie Cię na różnych stronach</translation>
 <translation id="2704606927547763573">Skopiowane</translation>
 <translation id="2713106313042589954">Wyłącz kamerę</translation>
 <translation id="2717722538473713889">Adresy e-mail</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Tytuł</translation>
 <translation id="4008040567710660924">Zezwalaj na pliki cookie z określonej strony internetowej.</translation>
 <translation id="4046123991198612571">Następny utwór</translation>
+<translation id="4048876521107516222">Powiązane witryny używają plików cookie, m.in. aby Cię nie wylogowywać</translation>
 <translation id="4149994727733219643">Uproszczony widok stron internetowych</translation>
 <translation id="4165986682804962316">Ustawienia witryn</translation>
 <translation id="4169549551965910670">Połączona z urządzeniem USB</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Strony nie mogą prosić o zgodę na wysyłanie powiadomień</translation>
 <translation id="5516455585884385570">Otwórz ustawienia powiadomień</translation>
 <translation id="5527111080432883924">Pytaj, czy zezwolić stronom na odczytywanie tekstu i obrazów ze schowka (zalecane)</translation>
+<translation id="5553273073880784901">Zawsze wyświetlaj stronę na komputery</translation>
 <translation id="5553374991681107062">Najnowsze</translation>
 <translation id="5556459405103347317">Odśwież</translation>
 <translation id="5596627076506792578">Więcej opcji</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Ostatnio używana wczoraj</translation>
 <translation id="5916664084637901428">Włączone</translation>
 <translation id="5922853908706496913">Udostępnianie ekranu</translation>
+<translation id="5922967540311291836">Blokuj pliki cookie innych firm:</translation>
 <translation id="5939518447894949180">Resetuj</translation>
 <translation id="5975083100439434680">Pomniejsz</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Anuluj wybór</translation>
 <translation id="7846621471902887024">Wylogujemy Cię ze wszystkich stron.</translation>
 <translation id="7882806643839505685">Zezwalaj na dźwięk na określonej stronie.</translation>
+<translation id="789180354981963912">Blokuj pliki cookie innych firm w trybie incognito:</translation>
 <translation id="7940722705963108451">Przypomnij mi</translation>
 <translation id="7986741934819883144">Wybierz kontakt</translation>
 <translation id="7999064672810608036">Na pewno chcesz usunąć wszystkie dane lokalne (w tym pliki cookie) i zresetować uprawnienia tej witryny?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb
index 2de0c9df..f3db7ca 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Запрашивать разрешение на воспроизведение защищенного контента (рекомендуется)</translation>
 <translation id="2146738493024040262">Открыть приложение с мгновенным запуском</translation>
 <translation id="2148716181193084225">Сегодня</translation>
+<translation id="2155988908301433309">Всегда показывать мобильную версию сайта.</translation>
 <translation id="2182457891543959921">Запрашивать для сайтов разрешение на создание 3D-карты места, в котором вы находитесь, и отслеживание положения камеры (рекомендуется)</translation>
 <translation id="2212565012507486665">Разрешить файлы cookie</translation>
 <translation id="2228071138934252756">Чтобы у приложения "<ph name="APP_NAME" />" был доступ к камере, включите ее в <ph name="BEGIN_LINK" />настройках Android<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Отправить</translation>
 <translation id="2677748264148917807">Закрыть</translation>
 <translation id="2687403674020088961">Заблокировать все файлы cookie (не рекомендуется)</translation>
+<translation id="2692299144678073135">Разрешать связанным сайтам запоминать ваши данные на сайтах</translation>
 <translation id="2704606927547763573">Скопировано</translation>
 <translation id="2713106313042589954">Выключить камеру</translation>
 <translation id="2717722538473713889">Адреса электронной почты</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Название</translation>
 <translation id="4008040567710660924">Разрешить определенному сайту сохранять файлы cookie</translation>
 <translation id="4046123991198612571">Следующий трек</translation>
+<translation id="4048876521107516222">Связанные сайты используют файлы cookie, чтобы предоставлять пользователю дополнительные возможности, например запоминать, что выполнен вход в аккаунт</translation>
 <translation id="4149994727733219643">Упрощенный просмотр веб-страниц</translation>
 <translation id="4165986682804962316">Настройки сайтов</translation>
 <translation id="4169549551965910670">Выполнено подключение к USB-устройству</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Сайты не могут запрашивать разрешения на отправку уведомлений</translation>
 <translation id="5516455585884385570">Перейти в настройки уведомлений</translation>
 <translation id="5527111080432883924">Запрашивать мое разрешение на доступ сайтов к тексту и изображениям, скопированным в буфер обмена (рекомендуется)</translation>
+<translation id="5553273073880784901">Всегда показывать полную версию сайта.</translation>
 <translation id="5553374991681107062">По дате</translation>
 <translation id="5556459405103347317">Перезагрузить</translation>
 <translation id="5596627076506792578">Ещё</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Последнее посещение: вчера</translation>
 <translation id="5916664084637901428">ВКЛ</translation>
 <translation id="5922853908706496913">Предоставлен доступ к вашему экрану</translation>
+<translation id="5922967540311291836">Блокировать сторонние файлы cookie</translation>
 <translation id="5939518447894949180">Сбросить</translation>
 <translation id="5975083100439434680">Уменьшить</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Отменить выбор</translation>
 <translation id="7846621471902887024">Вы выйдете из аккаунта на всех сайтах.</translation>
 <translation id="7882806643839505685">Включить звуки на определенном сайте</translation>
+<translation id="789180354981963912">Блокировать сторонние файлы cookie в режиме инкогнито</translation>
 <translation id="7940722705963108451">Напомнить</translation>
 <translation id="7986741934819883144">Выберите контакт</translation>
 <translation id="7999064672810608036">Вы уверены, что хотите удалить все данные этого веб-сайта, включая файлы cookie, и сбросить заданные разрешения?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
index 3b56d45..eb3ccf3 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">වෙබ් අඩවිවලට ආරක්‍ෂිත අන්තර්ගත ධාවන කිරීමට ඉඩ දීමට පෙර විමසන්න (නිර්දේශිතයි)</translation>
 <translation id="2146738493024040262">ක්ෂණික යෙදුම විවෘත කරන්න</translation>
 <translation id="2148716181193084225">අද</translation>
+<translation id="2155988908301433309">සෑම විටම ජංගම අඩවිය බලන්න</translation>
 <translation id="2182457891543959921">වෙබ් අඩවිවලට ඔබේ වටපිටාවේ ත්‍රිමාන සිතියමක් සෑදීමට හෝ කැමරා ස්ථානය හඹා යෑමට ඉඩ දීමට පෙර අසන්න (නිර්දේශිතයි)</translation>
 <translation id="2212565012507486665">කුකීවලට ඉඩ දෙන්න</translation>
 <translation id="2228071138934252756"><ph name="APP_NAME" /> හට ඔබේ කැමරාවට ප්‍රවේශ වීමට ඉඩ දීමට, <ph name="BEGIN_LINK" />Android සැකසීම්<ph name="END_LINK" /> තුළද කැමරාව ක්‍රියාත්මක කරන්න.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">ඉදිරිපත් කරන්න</translation>
 <translation id="2677748264148917807">හැර යන්න</translation>
 <translation id="2687403674020088961">සියලුම කුකී අවහිර කරන්න (නිර්දේශ නොකෙරේ)</translation>
+<translation id="2692299144678073135">අඩවි හරහා ඔබව මතක තබා ගැනීමට අදාළ අඩවිවලට ඉඩ දෙන්න</translation>
 <translation id="2704606927547763573">පිටපත් කරන ලදි</translation>
 <translation id="2713106313042589954">කැමරාව ක්‍රියාවිරහිත කරන්න</translation>
 <translation id="2717722538473713889">ඉ-තැපැල් ලිපින</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">සිරස්තලය</translation>
 <translation id="4008040567710660924">නිශ්චිත අඩවියක් සඳහා කුකීවලට ඉඩ දෙන්න.</translation>
 <translation id="4046123991198612571">ඊළඟ ඛණ්ඩය</translation>
+<translation id="4048876521107516222">අදාළ අඩවි ඔබව පුරනය වී තබා ගැනීම වැනි දේවල් සඳහා උදවු කිරීමට කුකීස් භාවිතා කරයි</translation>
 <translation id="4149994727733219643">වෙබ් පිටු සඳහා සරල දසුනක්</translation>
 <translation id="4165986682804962316">අඩවි සැකසුම්</translation>
 <translation id="4169549551965910670">USB උපාංගයකට සම්බන්ධ කර ඇත</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">වෙබ් අඩවිවලට දැනුම්දීම් යැවීමට ඉල්ලිය නොහැක</translation>
 <translation id="5516455585884385570">දැනුම්දීම් සැකසීම් විවෘත කරන්න</translation>
 <translation id="5527111080432883924">අඩවිවලට පසුරු පුවරුවෙන් පෙළ සහ රූප කියවීමට ඉඩ දීමට පෙර විමසන්න (නිර්දේශිතයි)</translation>
+<translation id="5553273073880784901">සෑම විටම ඩෙස්ක්ටොප් අඩවිය බලන්න</translation>
 <translation id="5553374991681107062">නවතම</translation>
 <translation id="5556459405103347317">නැවත</translation>
 <translation id="5596627076506792578">තවත් විකල්ප</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">අවසන් වරට ඊයේ පිවිසි</translation>
 <translation id="5916664084637901428">ක්‍රියාත්මකයි</translation>
 <translation id="5922853908706496913">ඔබේ තිරය බෙදා ගැනීම</translation>
+<translation id="5922967540311291836">තෙවන පාර්ශ්ව කුකී අවහිර කරන්න:</translation>
 <translation id="5939518447894949180">නැවත සකසන්න</translation>
 <translation id="5975083100439434680">විශාලනය අඩු කරන්න</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">තේරීම අවලංගු කරන්න</translation>
 <translation id="7846621471902887024">ඔබ සියලුම වෙබ් අඩවිවලින් වරනු ලැබේ.</translation>
 <translation id="7882806643839505685">නිශ්චිත අඩවියක් සඳහා ශබ්දයට ඉඩ දෙන්න.</translation>
+<translation id="789180354981963912">අප්‍රසිද්ධ තුළ තෙවන පාර්ශ්ව කුකී අවහිර කරන්න:</translation>
 <translation id="7940722705963108451">මට සිහිකැඳවන්න</translation>
 <translation id="7986741934819883144">සම්බන්ධතාවක් තෝරාගන්න</translation>
 <translation id="7999064672810608036">කුකීස් ඇතුළු සියලු පෙදෙසි දත්ත හිස් කිරීමට අවශ්‍ය යැයි සහ මෙම වෙබ් අඩවිය සඳහා සියලු අවසර නැවත සැකසිය යුතු යැයි ඔබට විශ්වාස ද?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb
index 6175e9f..243d58a3 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_sk.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">Pýtať sa, či chcete povoliť webu prehrávať chránený obsah (odporúčané)</translation>
 <translation id="2146738493024040262">Otvoriť okamžitú aplikáciu</translation>
 <translation id="2148716181193084225">Dnes</translation>
+<translation id="2155988908301433309">Vždy zobrazovať mobilný web</translation>
 <translation id="2182457891543959921">Pýtať sa, či chcete povoliť webu vytvárať priestorovú mapu okolia alebo sledovať pozíciu kamery (odporúčané)</translation>
 <translation id="2212565012507486665">Povoliť súbory cookie</translation>
 <translation id="2228071138934252756">Ak chcete povoliť aplikácii <ph name="APP_NAME" /> používať váš fotoaparát, zapnite ho aj v <ph name="BEGIN_LINK" />nastaveniach Androidu<ph name="END_LINK" />.</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">Odoslať</translation>
 <translation id="2677748264148917807">Odísť</translation>
 <translation id="2687403674020088961">Blokovať všetky súbory cookie (neodporúča sa)</translation>
+<translation id="2692299144678073135">Povoliť súvisiacim webom, aby si vás pamätali na rôznych weboch</translation>
 <translation id="2704606927547763573">Skopírované</translation>
 <translation id="2713106313042589954">Vypnúť kameru</translation>
 <translation id="2717722538473713889">E‑mailové adresy</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">Názov</translation>
 <translation id="4008040567710660924">Povoliť súbory cookie na konkrétnom webe.</translation>
 <translation id="4046123991198612571">Ďalšia skladba</translation>
+<translation id="4048876521107516222">Súvisiace weby vám prostredníctvom súborov cookie pomáhajú uchovať si aktívne prihlásenie</translation>
 <translation id="4149994727733219643">Jednoduché zobrazenie webových stránok</translation>
 <translation id="4165986682804962316">Nastavenia webu</translation>
 <translation id="4169549551965910670">Pripojené k zariadeniu USB</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">Weby nemôžu žiadať o odosielanie upozornení</translation>
 <translation id="5516455585884385570">Otvoriť nastavenia upozornení</translation>
 <translation id="5527111080432883924">Pýtať sa, či chcete povoliť webu prístup k textom a obrázkom v schránke (odporúčané)</translation>
+<translation id="5553273073880784901">Vždy zobrazovať web pre počítače</translation>
 <translation id="5553374991681107062">Najnovšie</translation>
 <translation id="5556459405103347317">Znova načítať</translation>
 <translation id="5596627076506792578">Ďalšie možnosti</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">Naposledy navštívený včera</translation>
 <translation id="5916664084637901428">Zapnuté</translation>
 <translation id="5922853908706496913">Zdieľate obrazovku</translation>
+<translation id="5922967540311291836">Blokovať súbory cookie tretích strán:</translation>
 <translation id="5939518447894949180">Resetovať</translation>
 <translation id="5975083100439434680">Oddialiť</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> – <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">Zrušiť výber</translation>
 <translation id="7846621471902887024">Systém vás odhlási zo všetkých webov.</translation>
 <translation id="7882806643839505685">Povoliť zvuk na konkrétnom webe.</translation>
+<translation id="789180354981963912">Blokovať súbory cookie tretích strán v režime inkognito:</translation>
 <translation id="7940722705963108451">Pripomenúť mi</translation>
 <translation id="7986741934819883144">Výber kontaktu</translation>
 <translation id="7999064672810608036">Naozaj chcete vymazať všetky miestne dáta tohto webu, vrátane súborov cookie, a resetovať všetky jeho povolenia?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb
index c8d1589..0995bae2 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-CN.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">需先询问,得到许可后才允许网站播放受保护的内容 (推荐)</translation>
 <translation id="2146738493024040262">打开免安装应用</translation>
 <translation id="2148716181193084225">今天</translation>
+<translation id="2155988908301433309">始终查看移动网站</translation>
 <translation id="2182457891543959921">需先询问,得到许可后才允许网站为您的周边环境创建 3D 地图或跟踪摄像头位置(推荐)</translation>
 <translation id="2212565012507486665">允许使用 Cookie</translation>
 <translation id="2228071138934252756">若要允许 <ph name="APP_NAME" /> 使用您的摄像头,您还需在 <ph name="BEGIN_LINK" />Android 设置<ph name="END_LINK" />中开启摄像头。</translation>
@@ -204,6 +205,7 @@
 <translation id="5505264765875738116">网站无法询问能否向您发送通知</translation>
 <translation id="5516455585884385570">打开通知设置</translation>
 <translation id="5527111080432883924">需先询问,得到许可后才允许网站读取剪贴板中的文字和图片(推荐)</translation>
+<translation id="5553273073880784901">始终查看桌面版网站</translation>
 <translation id="5553374991681107062">最新</translation>
 <translation id="5556459405103347317">重新加载</translation>
 <translation id="5596627076506792578">更多选项</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb
index e88ad9a..b155dd5 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">網站播放受保護內容前先詢問您 (建議)</translation>
 <translation id="2146738493024040262">開啟免安裝應用程式</translation>
 <translation id="2148716181193084225">今天</translation>
+<translation id="2155988908301433309">一律查看行動版網站</translation>
 <translation id="2182457891543959921">在允許網站建立您身處環境的 3D 地圖或追蹤攝錄機位置前先詢問您 (建議)</translation>
 <translation id="2212565012507486665">允許 Cookie</translation>
 <translation id="2228071138934252756">如要讓 <ph name="APP_NAME" /> 存取您的相機,請一併在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中開啟相機。</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">提交</translation>
 <translation id="2677748264148917807">離開</translation>
 <translation id="2687403674020088961">封鎖所有 Cookie (不建議)</translation>
+<translation id="2692299144678073135">允許相關網站記住你在不同網站上的身分</translation>
 <translation id="2704606927547763573">已複製</translation>
 <translation id="2713106313042589954">關閉攝錄機</translation>
 <translation id="2717722538473713889">電郵地址</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">標題</translation>
 <translation id="4008040567710660924">允許特定網站存取 Cookie。</translation>
 <translation id="4046123991198612571">下一首曲目</translation>
+<translation id="4048876521107516222">相關網站會使用 Cookie 為你提供多項協助,例如保持登入狀態</translation>
 <translation id="4149994727733219643">使用簡化檢視模式查看網頁</translation>
 <translation id="4165986682804962316">網站設定</translation>
 <translation id="4169549551965910670">已連線至 USB 裝置</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">網站將無法要求向您傳送通知</translation>
 <translation id="5516455585884385570">開通知設定</translation>
 <translation id="5527111080432883924">允許網站讀取剪貼簿的文字和圖片前詢問您 (建議)</translation>
+<translation id="5553273073880784901">一律查看電腦版網站</translation>
 <translation id="5553374991681107062">最新</translation>
 <translation id="5556459405103347317">重新載入</translation>
 <translation id="5596627076506792578">更多選項</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">上次瀏覽日期:昨天</translation>
 <translation id="5916664084637901428">開啟</translation>
 <translation id="5922853908706496913">正在分享螢幕畫面</translation>
+<translation id="5922967540311291836">封鎖第三方 Cookie:</translation>
 <translation id="5939518447894949180">重設</translation>
 <translation id="5975083100439434680">縮小</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">取消選取</translation>
 <translation id="7846621471902887024">您將會從所有網站登出。</translation>
 <translation id="7882806643839505685">允許特定網站播放音效。</translation>
+<translation id="789180354981963912">在無痕模式中封鎖第三方 Cookie:</translation>
 <translation id="7940722705963108451">提醒我</translation>
 <translation id="7986741934819883144">選取聯絡人</translation>
 <translation id="7999064672810608036">您確定要清除這個網站的所有本機資料 (包括 Cookie),然後重設其所有權限嗎?</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb
index f39f6d7..90a8ba4f 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb
@@ -48,6 +48,7 @@
 <translation id="2107397443965016585">允許網站播放受保護的內容前,必須先詢問你 (建議)</translation>
 <translation id="2146738493024040262">開啟免安裝應用程式</translation>
 <translation id="2148716181193084225">今天</translation>
+<translation id="2155988908301433309">一律查看行動版網站</translation>
 <translation id="2182457891543959921">網站必須先詢問你,才能根據你的周遭環境建立 3D 地圖或追蹤攝影機位置 (建議)</translation>
 <translation id="2212565012507486665">允許 Cookie</translation>
 <translation id="2228071138934252756">如要允許 <ph name="APP_NAME" /> 存取裝置的相機,請一併在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中開啟相機。</translation>
@@ -79,6 +80,7 @@
 <translation id="2653659639078652383">提交</translation>
 <translation id="2677748264148917807">離開</translation>
 <translation id="2687403674020088961">封鎖所有 Cookie (不建議)</translation>
+<translation id="2692299144678073135">允許相關網站記住你在不同網站上的身分</translation>
 <translation id="2704606927547763573">已複製</translation>
 <translation id="2713106313042589954">關閉攝影機</translation>
 <translation id="2717722538473713889">電子郵件地址</translation>
@@ -139,6 +141,7 @@
 <translation id="4002066346123236978">標題</translation>
 <translation id="4008040567710660924">允許特定網站的 Cookie。</translation>
 <translation id="4046123991198612571">下一首曲目</translation>
+<translation id="4048876521107516222">相關網站會使用 Cookie 為你提供多項協助,例如保持登入狀態</translation>
 <translation id="4149994727733219643">使用簡易檢視模式查看網頁</translation>
 <translation id="4165986682804962316">網站設定</translation>
 <translation id="4169549551965910670">已連接至 USB 裝置</translation>
@@ -204,6 +207,7 @@
 <translation id="5505264765875738116">網站無法要求傳送通知給你</translation>
 <translation id="5516455585884385570">開啟通知設定</translation>
 <translation id="5527111080432883924">允許網站讀取剪貼簿中的文字和圖片前,必須先詢問你 (建議)</translation>
+<translation id="5553273073880784901">一律查看電腦版網站</translation>
 <translation id="5553374991681107062">最新</translation>
 <translation id="5556459405103347317">重新載入</translation>
 <translation id="5596627076506792578">更多選項</translation>
@@ -220,6 +224,7 @@
 <translation id="5887687176710214216">上次造訪日期:昨天</translation>
 <translation id="5916664084637901428">開啟</translation>
 <translation id="5922853908706496913">正在分享你的螢幕畫面</translation>
+<translation id="5922967540311291836">封鎖第三方 Cookie:</translation>
 <translation id="5939518447894949180">重設</translation>
 <translation id="5975083100439434680">縮小</translation>
 <translation id="5976059395673079613"><ph name="PERMISSION" /> - <ph name="WARNING_MESSAGE" /></translation>
@@ -310,6 +315,7 @@
 <translation id="7846076177841592234">全部取消選取</translation>
 <translation id="7846621471902887024">系統會將你登出所有網站。</translation>
 <translation id="7882806643839505685">允許特定網站播放音訊。</translation>
+<translation id="789180354981963912">在無痕模式中封鎖第三方 Cookie:</translation>
 <translation id="7940722705963108451">提醒我</translation>
 <translation id="7986741934819883144">選取聯絡人</translation>
 <translation id="7999064672810608036">確定要刪除這個網站儲存的所有本機資料 (包括 Cookie 在內),並重設這個網站的所有權限嗎?</translation>
diff --git a/components/commerce_strings.grdp b/components/commerce_strings.grdp
index e050764..778453e 100644
--- a/components/commerce_strings.grdp
+++ b/components/commerce_strings.grdp
@@ -131,15 +131,60 @@
     <message name="IDS_PRICE_TRACKING_SETTINGS_POPUP_DESCRIPTION" desc="Text shown in chrome settings indicating that the price drop notifications will be sent via chrome popups. User can turn on or off the toggle next to this setting item to manage whether they want to receive such notifications.">
       Price drop alerts show up as popup notifications on your desktop
     </message>
+  </if>
 
-    <message name="IDS_PRICE_DROP_POPUP_CONTENT_TITLE" desc="Text shown on the price drop popup notification. It tells users how much price drop on the corresponding product.">
-      <ph name="PRICE_DROP">%1$s<ex>$100</ex></ph> price drop on <ph name="PRODUCT_NAME">%2$s<ex>Chromebook</ex></ph>
+  <!-- Android only -->
+  <if expr="is_android">
+    <!-- For Android Price Tracking -->
+    <message name="IDS_PRICE_ANNOTATIONS_SETTINGS_TITLE" desc="The title text for price annotations settings in Google services. User can turn on or off the toggle next to this item to manage whether they want to see price drops on their open tabs.">
+      Show price drops on tabs
     </message>
-    <message name="IDS_PRICE_DROP_POPUP_CONTENT_TEXT" desc="Text shown on the price drop popup notification below the content title. It tells users the current price of the product and the source website.">
-      Now <ph name="CURRENT_PRICE">%1$s<ex>$799</ex></ph> on <ph name="SOURCE_WEBSITE">%2$s<ex>amazon.com</ex></ph>
+    <message name="IDS_PRICE_ANNOTATIONS_SETTINGS_DESCRIPTION" desc="The description text for price annotations settings in Google services. User can turn on or off the toggle next to this item to manage whether they want to see price drops on their open tabs.">
+      Price drop alerts will show up on your open tabs
     </message>
-    <message name="IDS_PRICE_DROP_POPUP_ACTION_BUTTON" desc="Text shown on the price drop popup notification below the content text. When users click this button, we send them to the source website.">
-      Visit site
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_TITLE" desc="The title text for price notifications settings in Google services. User can click into this item to view the detailed settings.">
+      Get price tracking notifications
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_DESCRIPTION" desc="The description text for price notifications settings in Google services. User can click into this item to view the detailed settings.">
+      Manage mobile and email notifications
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_TITLE" desc="The title text for the detailed page settings of price notifications in Google services.">
+      Price tracking notifications
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_DESCRIPTION" desc="The description text for the detailed page settings of price notifications in Google services.">
+      Manage how you receive price drop alerts for products you track
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_TITLE" desc="The title text for managing mobile price drop popup notifications shown on the detailed page settings in Google services.">
+      Mobile
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_ON" desc="The description text for managing mobile price drop popup notifications when the notification is currently enabled. Shown on the detailed page settings in Google services. It tells users that they can disable the popup notification in the Chrome notification settings.">
+      Price drop alerts are on. You can change this in <ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph>
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_OFF" desc="The description text for managing mobile price drop popup notifications when the notification is currently disabled. Shown on the detailed page settings in Google services. It tells users that they can enable the popup notification in the Chrome notification settings.">
+      Chrome notifications must be on. You can turn them on in <ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph>
+    </message>
+    <message name="IDS_CHROME_NOTIFICATION_SETTINGS_FOR_PRICE_TRACKING" desc="The button text within the description for managing mobile price drop popup notifications. When user clicks this button, we send them to the Chrome notification settings.">
+      settings
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_TITLE" desc="The title text for managing price drop email notifications shown on the detailed page settings in Google services. User can turn on or off the toggle next to this item to manage whether they want to receive price drop emails.">
+      Email
+    </message>
+    <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_DESCRIPTION" desc="The description text for managing price drop email notifications shown on the detailed page settings in Google services. User can turn on or off the toggle next to this item to manage whether they want to receive price drop emails.">
+      Send to <ph name="EMAIL_ADDRESS">%1$s<ex>example@google.com</ex></ph>
     </message>
   </if>
+
+  <!-- For Price Tracking on all platforms -->
+  <message name="IDS_PRICE_DROP_POPUP_CONTENT_TITLE" desc="Text shown on the price drop popup notification. It tells users how much price drop on the corresponding product.">
+    <ph name="PRICE_DROP">%1$s<ex>$100</ex></ph> price drop on <ph name="PRODUCT_NAME">%2$s<ex>Chromebook</ex></ph>
+  </message>
+  <message name="IDS_PRICE_DROP_POPUP_CONTENT_TEXT" desc="Text shown on the price drop popup notification below the content title. It tells users the current price of the product and the source website.">
+    Now <ph name="CURRENT_PRICE">%1$s<ex>$799</ex></ph> on <ph name="SOURCE_WEBSITE">%2$s<ex>amazon.com</ex></ph>
+  </message>
+  <message name="IDS_PRICE_DROP_POPUP_ACTION_BUTTON" desc="Text shown on the price drop popup notification below the content text. When users click this button, we send them to the source website.">
+    Visit site
+  </message>
+  <message name="IDS_PRICE_DROP_POPUP_UNTRACK_BUTTON" desc="Text shown on the price drop popup notification below the content text. When users click this button, we untrack this product and will no longer send its price drop to users.">
+    Untrack price
+  </message>
 </grit-part>
diff --git a/components/commerce_strings_grdp/IDS_CHROME_NOTIFICATION_SETTINGS_FOR_PRICE_TRACKING.png.sha1 b/components/commerce_strings_grdp/IDS_CHROME_NOTIFICATION_SETTINGS_FOR_PRICE_TRACKING.png.sha1
new file mode 100644
index 0000000..3020def
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_CHROME_NOTIFICATION_SETTINGS_FOR_PRICE_TRACKING.png.sha1
@@ -0,0 +1 @@
+1f5b6433a28f1089d14aece815f77bab1cf47f2c
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_DESCRIPTION.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..a703025
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+7325a57704296b244b63a21db049f288594edbcb
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_TITLE.png.sha1
new file mode 100644
index 0000000..a703025
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_ANNOTATIONS_SETTINGS_TITLE.png.sha1
@@ -0,0 +1 @@
+7325a57704296b244b63a21db049f288594edbcb
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_DROP_POPUP_UNTRACK_BUTTON.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_DROP_POPUP_UNTRACK_BUTTON.png.sha1
new file mode 100644
index 0000000..4cdf8d7
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_DROP_POPUP_UNTRACK_BUTTON.png.sha1
@@ -0,0 +1 @@
+1d994677233c0416a40c4c7b8eabbf8ba42df302
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DESCRIPTION.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..a703025
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+7325a57704296b244b63a21db049f288594edbcb
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_DESCRIPTION.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_TITLE.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_DETAILED_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_DESCRIPTION.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_TITLE.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_EMAIL_TITLE.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_OFF.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_OFF.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_OFF.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_ON.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_ON.png.sha1
new file mode 100644
index 0000000..3020def
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_ON.png.sha1
@@ -0,0 +1 @@
+1f5b6433a28f1089d14aece815f77bab1cf47f2c
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_TITLE.png.sha1
new file mode 100644
index 0000000..3da635a
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_TITLE.png.sha1
@@ -0,0 +1 @@
+63d0e328c380acfb7e60a339d7739a032948976a
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_TITLE.png.sha1
new file mode 100644
index 0000000..a703025
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_NOTIFICATIONS_SETTINGS_TITLE.png.sha1
@@ -0,0 +1 @@
+7325a57704296b244b63a21db049f288594edbcb
\ No newline at end of file
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn
index 4a4c539..03dd46a 100644
--- a/components/crash/android/BUILD.gn
+++ b/components/crash/android/BUILD.gn
@@ -32,6 +32,7 @@
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   srcjar_deps = [ ":java_enums_srcjar" ]
   sources = [
+    "java/src/org/chromium/components/crash/CustomAssertionHandler.java",
     "java/src/org/chromium/components/crash/LogcatCrashExtractor.java",
     "java/src/org/chromium/components/crash/MinidumpLogcatPrepender.java",
     "java/src/org/chromium/components/crash/PureJavaExceptionReporter.java",
diff --git a/components/crash/android/java/src/org/chromium/components/crash/CustomAssertionHandler.java b/components/crash/android/java/src/org/chromium/components/crash/CustomAssertionHandler.java
new file mode 100644
index 0000000..6a581ad1
--- /dev/null
+++ b/components/crash/android/java/src/org/chromium/components/crash/CustomAssertionHandler.java
@@ -0,0 +1,38 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.crash;
+
+/**
+ * Assertion handler to report assertions to crash.
+ *
+ * R8 has a --force-assertions-handler flag which we use to make this class, and specifically the
+ * {@link assertionHandler} method, handle every assertion failure.
+ */
+public class CustomAssertionHandler {
+    private CustomAssertionHandler() {}
+
+    private static PureJavaExceptionHandler.JavaExceptionReporterFactory sReporterFactory;
+
+    /**
+     * The handler that we tell R8 to forward assertions to via --force-assertions-hander.
+     *
+     * The R8 docs say that this function must be a static method, taking one argument, of type
+     * java.lang.Throwable.
+     */
+    public static void assertionHandler(Throwable exception) {
+        // We've gotten an assertion report before we were ready to report. We drop these assertions
+        // until we are ready to report them.
+        if (sReporterFactory != null) {
+            PureJavaExceptionHandler.JavaExceptionReporter reporter =
+                    sReporterFactory.createJavaExceptionReporter();
+            reporter.postCreateAndUploadReport(exception);
+        }
+    }
+
+    public static void installHandler(
+            PureJavaExceptionHandler.JavaExceptionReporterFactory factory) {
+        sReporterFactory = factory;
+    }
+}
diff --git a/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java
index 2aa7eb98..5e9b3a96 100644
--- a/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java
+++ b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionHandler.java
@@ -23,6 +23,7 @@
     /** Interface to allow uploading reports. */
     public interface JavaExceptionReporter {
         void createAndUploadReport(Throwable e);
+        void postCreateAndUploadReport(Throwable e);
     }
 
     /** A factory interface to allow creating custom reporters. */
diff --git a/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionReporter.java b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionReporter.java
index 89ca5c3..4c2d031 100644
--- a/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionReporter.java
+++ b/components/crash/android/java/src/org/chromium/components/crash/PureJavaExceptionReporter.java
@@ -15,6 +15,8 @@
 import org.chromium.base.PiiElider;
 import org.chromium.base.StrictModeContext;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.task.PostTask;
+import org.chromium.base.task.TaskTraits;
 import org.chromium.components.minidump_uploader.CrashFileManager;
 import org.chromium.components.version_info.VersionInfo;
 
@@ -65,12 +67,9 @@
     private final String mLocalId = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
     private final String mBoundary = "------------" + UUID.randomUUID() + RN;
 
-    // The top level directory where all crash related files are stored.
-    protected final File mCrashFilesDirectory;
     private boolean mAttachLogcat;
 
-    public PureJavaExceptionReporter(File crashFilesDirectory, boolean attachLogcat) {
-        mCrashFilesDirectory = crashFilesDirectory;
+    public PureJavaExceptionReporter(boolean attachLogcat) {
         mAttachLogcat = attachLogcat;
     }
 
@@ -84,6 +83,17 @@
         }
     }
 
+    /**
+     * Report an exception on a background thread.
+     *
+     * This is used for silent exception reporting.
+     */
+    @Override
+    public void postCreateAndUploadReport(Throwable javaException) {
+        PostTask.postTask(
+                TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> createAndUploadReport(javaException));
+    }
+
     private void addPairedString(String messageType, String messageData) {
         addString(mBoundary);
         addString(FORM_DATA_MESSAGE + messageType + "\"");
@@ -102,7 +112,7 @@
     private void createReport(Throwable javaException) {
         try {
             String minidumpFileName = getMinidumpPrefix() + mLocalId + FILE_SUFFIX;
-            File minidumpDir = new File(mCrashFilesDirectory, CrashFileManager.CRASH_DUMP_DIR);
+            File minidumpDir = new File(getCrashFilesDirectory(), CrashFileManager.CRASH_DUMP_DIR);
             // Tests disable minidump uploading by not creating the minidump directory.
             mUpload = minidumpDir.exists();
             String overrideMinidumpDirPath =
@@ -190,7 +200,7 @@
         if (mAttachLogcat) {
             LogcatCrashExtractor logcatExtractor = new LogcatCrashExtractor();
             mMinidumpFile = logcatExtractor.attachLogcatToMinidump(
-                    mMinidumpFile, new CrashFileManager(mCrashFilesDirectory));
+                    mMinidumpFile, new CrashFileManager(getCrashFilesDirectory()));
         }
         uploadMinidump(mMinidumpFile);
     }
@@ -211,4 +221,9 @@
      * @return prefix to be added before the minidump file name.
      */
     protected abstract String getMinidumpPrefix();
+
+    /**
+     * @return The top level directory where all crash related files are stored.
+     */
+    protected abstract File getCrashFilesDirectory();
 }
diff --git a/components/crash/android/junit/src/org/chromium/components/crash/PureJavaExceptionReporterTest.java b/components/crash/android/junit/src/org/chromium/components/crash/PureJavaExceptionReporterTest.java
index 30c5349..c516250f 100644
--- a/components/crash/android/junit/src/org/chromium/components/crash/PureJavaExceptionReporterTest.java
+++ b/components/crash/android/junit/src/org/chromium/components/crash/PureJavaExceptionReporterTest.java
@@ -35,7 +35,12 @@
         private File mMinidump;
 
         public TestPureJavaExceptionReporter() {
-            super(mTestRule.getCacheDir(), /*attachLogcat=*/true);
+            super(/*attachLogcat=*/true);
+        }
+
+        @Override
+        protected File getCrashFilesDirectory() {
+            return mTestRule.getCacheDir();
         }
 
         @Override
diff --git a/components/crash/android/silent_java_assert_reporting.gni b/components/crash/android/silent_java_assert_reporting.gni
new file mode 100644
index 0000000..d767d7c0
--- /dev/null
+++ b/components/crash/android/silent_java_assert_reporting.gni
@@ -0,0 +1,16 @@
+# 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("//build/config/android/config.gni")
+declare_args() {
+  # Whether java assertions should be silently reported to Crash, instead of
+  # being removed or fully enabled. This overrides any value set for
+  # enable_java_asserts.
+  enable_silent_java_assert_reporting = android_channel == "canary"
+}
+
+if (enable_silent_java_assert_reporting) {
+  crash_reporting_assertion_handler =
+      "org.chromium.components.crash.CustomAssertionHandler.assertionHandler"
+}
diff --git a/components/cronet/OWNERS b/components/cronet/OWNERS
index 8015f9c5..ccadf09 100644
--- a/components/cronet/OWNERS
+++ b/components/cronet/OWNERS
@@ -1,4 +1,3 @@
-cleborgne@google.com
 danstahr@google.com
 sporeba@google.com
 stefanoduo@google.com
diff --git a/components/desks_storage/core/desk_model.cc b/components/desks_storage/core/desk_model.cc
index 2516756..6a0ad31 100644
--- a/components/desks_storage/core/desk_model.cc
+++ b/components/desks_storage/core/desk_model.cc
@@ -60,7 +60,7 @@
   observers_.RemoveObserver(observer);
 }
 
-void DeskModel::GetTemplateJson(const std::string& uuid,
+void DeskModel::GetTemplateJson(const base::GUID& uuid,
                                 apps::AppRegistryCache* app_cache,
                                 GetTemplateJsonCallback callback) {
   auto result = GetEntryByUUID(uuid);
@@ -99,9 +99,7 @@
 }
 
 std::unique_ptr<ash::DeskTemplate> DeskModel::GetAdminDeskTemplateByUUID(
-    const std::string& uuid_str) const {
-  const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str);
-
+    const base::GUID& uuid) const {
   for (const std::unique_ptr<ash::DeskTemplate>& policy_entry :
        policy_entries_) {
     if (policy_entry->uuid() == uuid)
diff --git a/components/desks_storage/core/desk_model.h b/components/desks_storage/core/desk_model.h
index 603350c0..dd43f31be 100644
--- a/components/desks_storage/core/desk_model.h
+++ b/components/desks_storage/core/desk_model.h
@@ -114,7 +114,7 @@
   // but could not be loaded/parsed, `callback` will be called with `kFailure`
   // and a nullptr. An asynchronous `callback` is used here to accommodate
   // storage backend that need to perform asynchronous I/O.
-  virtual GetEntryByUuidResult GetEntryByUUID(const std::string& uuid) = 0;
+  virtual GetEntryByUuidResult GetEntryByUUID(const base::GUID& uuid) = 0;
 
   using AddOrUpdateEntryCallback =
       base::OnceCallback<void(AddOrUpdateEntryStatus status)>;
@@ -133,7 +133,7 @@
                               const std::string& json_representation)>;
   // Retrieves a template based on its `uuid`, if found returns a std::string
   // containing the json representation of the template queried.
-  virtual void GetTemplateJson(const std::string& uuid,
+  virtual void GetTemplateJson(const base::GUID& uuid,
                                apps::AppRegistryCache* app_cache,
                                GetTemplateJsonCallback callback);
 
@@ -205,7 +205,7 @@
   // Finds the admin desk template with the given `uuid`. Returns `nullptr`
   // if none is found.
   std::unique_ptr<ash::DeskTemplate> GetAdminDeskTemplateByUUID(
-      const std::string& uuid) const;
+      const base::GUID& uuid) const;
 
   // The observers.
   base::ObserverList<DeskModelObserver>::Unchecked observers_;
diff --git a/components/desks_storage/core/desk_model_wrapper.cc b/components/desks_storage/core/desk_model_wrapper.cc
index d1101ba7..d9ddb79 100644
--- a/components/desks_storage/core/desk_model_wrapper.cc
+++ b/components/desks_storage/core/desk_model_wrapper.cc
@@ -51,7 +51,7 @@
 }
 
 DeskModel::GetEntryByUuidResult DeskModelWrapper::GetEntryByUUID(
-    const std::string& uuid) {
+    const base::GUID& uuid) {
   // Check if this is an admin template uuid first.
   std::unique_ptr<ash::DeskTemplate> policy_entry =
       GetAdminDeskTemplateByUUID(uuid);
@@ -83,7 +83,7 @@
 void DeskModelWrapper::DeleteEntry(const base::GUID& uuid,
                                    DeskModel::DeleteEntryCallback callback) {
   auto status = std::make_unique<DeskModel::DeleteEntryStatus>();
-  if (GetDeskTemplateModel()->HasUuid(uuid.AsLowercaseString())) {
+  if (GetDeskTemplateModel()->HasUuid(uuid)) {
     GetDeskTemplateModel()->DeleteEntry(uuid, std::move(callback));
   } else {
     save_and_recall_desks_model_->DeleteEntry(uuid, std::move(callback));
diff --git a/components/desks_storage/core/desk_model_wrapper.h b/components/desks_storage/core/desk_model_wrapper.h
index 24e475c..d666376 100644
--- a/components/desks_storage/core/desk_model_wrapper.h
+++ b/components/desks_storage/core/desk_model_wrapper.h
@@ -36,7 +36,7 @@
   // DeskModel:
   DeskModel::GetAllEntriesResult GetAllEntries() override;
   DeskModel::GetEntryByUuidResult GetEntryByUUID(
-      const std::string& uuid) override;
+      const base::GUID& uuid) override;
   void AddOrUpdateEntry(std::unique_ptr<ash::DeskTemplate> new_entry,
                         AddOrUpdateEntryCallback callback) override;
   void DeleteEntry(const base::GUID& uuid,
diff --git a/components/desks_storage/core/desk_model_wrapper_unittests.cc b/components/desks_storage/core/desk_model_wrapper_unittests.cc
index 53ed1e4..9ebb596 100644
--- a/components/desks_storage/core/desk_model_wrapper_unittests.cc
+++ b/components/desks_storage/core/desk_model_wrapper_unittests.cc
@@ -510,7 +510,8 @@
   task_environment_.RunUntilIdle();
 
   // Find the desk template by its uuid.
-  auto result1 = model_wrapper_->GetEntryByUUID(kTestUuid1);
+  auto result1 = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid1));
   EXPECT_EQ(result1.status, DeskModel::GetEntryByUuidStatus::kOk);
 
   EXPECT_EQ(result1.entry->uuid(),
@@ -518,7 +519,8 @@
   EXPECT_EQ(base::UTF16ToUTF8(result1.entry->template_name()), "desk_01");
 
   // Find the save and recall desk by its uuid.
-  auto result3 = model_wrapper_->GetEntryByUUID(kTestUuid3);
+  auto result3 = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid3));
 
   EXPECT_EQ(result3.status, DeskModel::GetEntryByUuidStatus::kOk);
 
@@ -539,7 +541,8 @@
   // Check that the admin template is included as an entry.
   EXPECT_EQ(model_wrapper_->GetAllEntryUuids().size(), 2ul);
 
-  auto result = model_wrapper_->GetEntryByUUID(kTestUuid5);
+  auto result = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid5));
   EXPECT_EQ(result.status, DeskModel::GetEntryByUuidStatus::kOk);
   EXPECT_EQ(result.entry->uuid(), base::GUID::ParseCaseInsensitive(kTestUuid5));
   EXPECT_EQ(result.entry->source(), ash::DeskTemplateSource::kPolicy);
@@ -550,7 +553,8 @@
 TEST_F(DeskModelWrapperTest, GetEntryByUuidReturnsNotFoundIfEntryDoesNotExist) {
   InitializeBridge();
 
-  auto result = model_wrapper_->GetEntryByUUID(kTestUuid1);
+  auto result = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid1));
   EXPECT_EQ(result.status, DeskModel::GetEntryByUuidStatus::kNotFound);
 }
 
@@ -578,14 +582,16 @@
   task_environment_.RunUntilIdle();
 
   // Check that the entries are updated.
-  auto result1 = model_wrapper_->GetEntryByUUID(kTestUuid1);
+  auto result1 = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid1));
   EXPECT_EQ(result1.status, DeskModel::GetEntryByUuidStatus::kOk);
   EXPECT_EQ(result1.entry->uuid(),
             base::GUID::ParseCaseInsensitive(kTestUuid1));
   EXPECT_EQ(result1.entry->template_name(),
             base::UTF8ToUTF16(std::string("desk_01_mod")));
 
-  auto result3 = model_wrapper_->GetEntryByUUID(kTestUuid3);
+  auto result3 = model_wrapper_->GetEntryByUUID(
+      base::GUID::ParseCaseInsensitive(kTestUuid3));
   EXPECT_EQ(result3.status, DeskModel::GetEntryByUuidStatus::kOk);
   EXPECT_EQ(result3.entry->uuid(),
             base::GUID::ParseCaseInsensitive(kTestUuid3));
diff --git a/components/desks_storage/core/desk_sync_bridge.cc b/components/desks_storage/core/desk_sync_bridge.cc
index 51dbbd4..d6df940b 100644
--- a/components/desks_storage/core/desk_sync_bridge.cc
+++ b/components/desks_storage/core/desk_sync_bridge.cc
@@ -1077,12 +1077,11 @@
 }
 
 DeskModel::GetEntryByUuidResult DeskSyncBridge::GetEntryByUUID(
-    const std::string& uuid_str) {
+    const base::GUID& uuid) {
   if (!IsReady()) {
     return GetEntryByUuidResult(GetEntryByUuidStatus::kFailure, nullptr);
   }
 
-  const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str);
   if (!uuid.is_valid()) {
     return GetEntryByUuidResult(GetEntryByUuidStatus::kInvalidUuid, nullptr);
   }
@@ -1090,7 +1089,7 @@
   auto it = desk_template_entries_.find(uuid);
   if (it == desk_template_entries_.end()) {
     std::unique_ptr<DeskTemplate> policy_entry =
-        GetAdminDeskTemplateByUUID(uuid_str);
+        GetAdminDeskTemplateByUUID(uuid);
 
     if (policy_entry) {
       return GetEntryByUuidResult(GetEntryByUuidStatus::kOk,
@@ -1429,11 +1428,8 @@
              }) != desk_template_entries_.end();
 }
 
-bool DeskSyncBridge::HasUuid(const std::string& uuid_str) const {
-  const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str);
-  if (!uuid.is_valid())
-    return false;
-  return base::Contains(desk_template_entries_, uuid);
+bool DeskSyncBridge::HasUuid(const base::GUID& uuid) const {
+  return uuid.is_valid() && base::Contains(desk_template_entries_, uuid);
 }
 
 }  // namespace desks_storage
diff --git a/components/desks_storage/core/desk_sync_bridge.h b/components/desks_storage/core/desk_sync_bridge.h
index 09f6cb4b..a95c2083 100644
--- a/components/desks_storage/core/desk_sync_bridge.h
+++ b/components/desks_storage/core/desk_sync_bridge.h
@@ -67,7 +67,7 @@
   // DeskModel overrides.
   DeskModel::GetAllEntriesResult GetAllEntries() override;
   DeskModel::GetEntryByUuidResult GetEntryByUUID(
-      const std::string& uuid) override;
+      const base::GUID& uuid) override;
 
   void AddOrUpdateEntry(std::unique_ptr<ash::DeskTemplate> new_entry,
                         AddOrUpdateEntryCallback callback) override;
@@ -98,7 +98,7 @@
   sync_pb::WorkspaceDeskSpecifics ToSyncProto(
       const ash::DeskTemplate* desk_template);
 
-  bool HasUuid(const std::string& uuid_str) const;
+  bool HasUuid(const base::GUID& uuid) const;
 
   const ash::DeskTemplate* GetUserEntryByUUID(const base::GUID& uuid) const;
 
diff --git a/components/desks_storage/core/desk_sync_bridge_unittest.cc b/components/desks_storage/core/desk_sync_bridge_unittest.cc
index 1a19bd38..b38f646 100644
--- a/components/desks_storage/core/desk_sync_bridge_unittest.cc
+++ b/components/desks_storage/core/desk_sync_bridge_unittest.cc
@@ -1303,7 +1303,7 @@
 
   EXPECT_EQ(2ul, bridge()->GetAllEntryUuids().size());
 
-  auto result = bridge()->GetEntryByUUID(kTestUuid1.AsLowercaseString());
+  auto result = bridge()->GetEntryByUUID(kTestUuid1);
   EXPECT_EQ(result.status, DeskModel::GetEntryByUuidStatus::kOk);
   EXPECT_TRUE(result.entry);
 }
@@ -1315,7 +1315,7 @@
 
   AddTwoTemplates();
 
-  auto result = bridge()->GetEntryByUUID(kTestUuid1.AsLowercaseString());
+  auto result = bridge()->GetEntryByUUID(kTestUuid1);
   EXPECT_EQ(result.status, DeskModel::GetEntryByUuidStatus::kOk);
   EXPECT_TRUE(result.entry);
   for (const auto& [app_id, launch_list] :
@@ -1337,8 +1337,7 @@
   EXPECT_EQ(3ul, bridge()->GetAllEntryUuids().size());
 
   base::RunLoop loop;
-  auto result =
-      bridge()->GetEntryByUUID(kTestAdminTemplateUuid1.AsLowercaseString());
+  auto result = bridge()->GetEntryByUUID(kTestAdminTemplateUuid1);
   EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
   EXPECT_TRUE(result.entry);
 }
@@ -1350,7 +1349,8 @@
 
   EXPECT_EQ(2ul, bridge()->GetAllEntryUuids().size());
 
-  const std::string nonExistingUuid = base::StringPrintf(kUuidFormat, 5);
+  const base::GUID nonExistingUuid =
+      base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 5));
 
   base::RunLoop loop;
   auto result = bridge()->GetEntryByUUID(nonExistingUuid);
@@ -1361,8 +1361,7 @@
 TEST_F(DeskSyncBridgeTest, GetEntryByUUIDShouldFailWhenUuidIsInvalid) {
   InitializeBridge();
 
-  base::RunLoop loop;
-  auto result = bridge()->GetEntryByUUID("invalid uuid");
+  auto result = bridge()->GetEntryByUUID(base::GUID());
   EXPECT_EQ(result.status, DeskModel::GetEntryByUuidStatus::kInvalidUuid);
   EXPECT_FALSE(result.entry);
 }
@@ -1658,7 +1657,7 @@
 
   base::RunLoop loop;
   bridge()->GetTemplateJson(
-      kTestUuid1.AsLowercaseString(), app_cache(),
+      kTestUuid1, app_cache(),
       base::BindLambdaForTesting([&](DeskModel::GetTemplateJsonStatus status,
                                      const std::string& templates_json) {
         EXPECT_EQ(DeskModel::GetTemplateJsonStatus::kOk, status);
diff --git a/components/desks_storage/core/desk_template_conversion.cc b/components/desks_storage/core/desk_template_conversion.cc
index b0c811f..f312de1 100644
--- a/components/desks_storage/core/desk_template_conversion.cc
+++ b/components/desks_storage/core/desk_template_conversion.cc
@@ -4,11 +4,13 @@
 
 #include "components/desks_storage/core/desk_template_conversion.h"
 
+#include "base/containers/fixed_flat_set.h"
 #include "base/guid.h"
 #include "base/json/json_reader.h"
 #include "base/json/values_util.h"
 #include "base/notreached.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "components/app_constants/constants.h"
@@ -112,37 +114,33 @@
 constexpr char kZIndex[] = "z_index";
 
 // Valid value sets.
-const std::set<std::string> kValidDeskTypes = {kDeskTypeTemplate,
-                                               kDeskTypeSaveAndRecall};
-const std::set<std::string> kValidLaunchContainers = {
-    kLaunchContainerWindow, kLaunchContainerPanelDeprecated,
-    kLaunchContainerTab, kLaunchContainerNone, kLaunchContainerUnspecified};
-const std::set<std::string> kValidWindowOpenDispositions = {
-    kWindowOpenDispositionUnknown,
-    kWindowOpenDispositionCurrentTab,
-    kWindowOpenDispositionSingletonTab,
-    kWindowOpenDispositionNewForegroundTab,
-    kWindowOpenDispositionNewBackgroundTab,
-    kWindowOpenDispositionNewPopup,
-    kWindowOpenDispositionNewWindow,
-    kWindowOpenDispositionSaveToDisk,
-    kWindowOpenDispositionOffTheRecord,
-    kWindowOpenDispositionIgnoreAction,
-    kWindowOpenDispositionSwitchToTab,
-    kWindowOpenDispositionNewPictureInPicture};
-const std::set<std::string> kValidWindowStates = {kWindowStateNormal,
-                                                  kWindowStateMinimized,
-                                                  kWindowStateMaximized,
-                                                  kWindowStateFullscreen,
-                                                  kWindowStatePrimarySnapped,
-                                                  kWindowStateSecondarySnapped,
-                                                  kZIndex};
-const std::set<std::string> kValidTabGroupColors = {
-    app_restore::kTabGroupColorUnknown, app_restore::kTabGroupColorGrey,
-    app_restore::kTabGroupColorBlue,    app_restore::kTabGroupColorRed,
-    app_restore::kTabGroupColorYellow,  app_restore::kTabGroupColorGreen,
-    app_restore::kTabGroupColorPink,    app_restore::kTabGroupColorPurple,
-    app_restore::kTabGroupColorCyan,    app_restore::kTabGroupColorOrange};
+constexpr auto kValidDeskTypes = base::MakeFixedFlatSet<base::StringPiece>(
+    {kDeskTypeTemplate, kDeskTypeSaveAndRecall});
+constexpr auto kValidLaunchContainers =
+    base::MakeFixedFlatSet<base::StringPiece>(
+        {kLaunchContainerWindow, kLaunchContainerPanelDeprecated,
+         kLaunchContainerTab, kLaunchContainerNone,
+         kLaunchContainerUnspecified});
+constexpr auto kValidWindowOpenDispositions =
+    base::MakeFixedFlatSet<base::StringPiece>(
+        {kWindowOpenDispositionUnknown, kWindowOpenDispositionCurrentTab,
+         kWindowOpenDispositionSingletonTab,
+         kWindowOpenDispositionNewForegroundTab,
+         kWindowOpenDispositionNewBackgroundTab, kWindowOpenDispositionNewPopup,
+         kWindowOpenDispositionNewWindow, kWindowOpenDispositionSaveToDisk,
+         kWindowOpenDispositionOffTheRecord, kWindowOpenDispositionIgnoreAction,
+         kWindowOpenDispositionSwitchToTab,
+         kWindowOpenDispositionNewPictureInPicture});
+constexpr auto kValidWindowStates = base::MakeFixedFlatSet<base::StringPiece>(
+    {kWindowStateNormal, kWindowStateMinimized, kWindowStateMaximized,
+     kWindowStateFullscreen, kWindowStatePrimarySnapped,
+     kWindowStateSecondarySnapped, kZIndex});
+constexpr auto kValidTabGroupColors = base::MakeFixedFlatSet<base::StringPiece>(
+    {app_restore::kTabGroupColorUnknown, app_restore::kTabGroupColorGrey,
+     app_restore::kTabGroupColorBlue, app_restore::kTabGroupColorRed,
+     app_restore::kTabGroupColorYellow, app_restore::kTabGroupColorGreen,
+     app_restore::kTabGroupColorPink, app_restore::kTabGroupColorPurple,
+     app_restore::kTabGroupColorCyan, app_restore::kTabGroupColorOrange});
 
 // Version number.
 constexpr int kVersionNum = 1;
diff --git a/components/desks_storage/core/local_desk_data_manager.cc b/components/desks_storage/core/local_desk_data_manager.cc
index ac2f0bd..518d6ec 100644
--- a/components/desks_storage/core/local_desk_data_manager.cc
+++ b/components/desks_storage/core/local_desk_data_manager.cc
@@ -8,6 +8,7 @@
 
 #include "ash/public/cpp/desk_template.h"
 #include "base/containers/contains.h"
+#include "base/containers/fixed_flat_set.h"
 #include "base/files/dir_reader_posix.h"
 #include "base/files/file_util.h"
 #include "base/guid.h"
@@ -55,8 +56,8 @@
 constexpr size_t kMaxSaveAndRecallDeskCount = 6u;
 
 // Set of valid desk types.
-const std::set<ash::DeskTemplateType> kDeskTypes = {
-    ash::DeskTemplateType::kTemplate, ash::DeskTemplateType::kSaveAndRecall};
+constexpr auto kDeskTypes = base::MakeFixedFlatSet<ash::DeskTemplateType>(
+    {ash::DeskTemplateType::kTemplate, ash::DeskTemplateType::kSaveAndRecall});
 
 // Reads a file at `fully_qualified_path` into a
 // std::unique_ptr<ash::DeskTemplate> This function returns a `nullptr` if the
@@ -188,13 +189,12 @@
 }
 
 DeskModel::GetEntryByUuidResult LocalDeskDataManager::GetEntryByUUID(
-    const std::string& uuid_str) {
+    const base::GUID& uuid) {
   if (cache_status_ != LocalDeskDataManager::CacheStatus::kOk) {
     return DeskModel::GetEntryByUuidResult(
         DeskModel::GetEntryByUuidStatus::kFailure, nullptr);
   }
 
-  const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str);
   if (!uuid.is_valid()) {
     return DeskModel::GetEntryByUuidResult(
         DeskModel::GetEntryByUuidStatus::kInvalidUuid, nullptr);
@@ -206,7 +206,7 @@
 
   if (cache_entry == saved_desks_list_[desk_type].end()) {
     std::unique_ptr<ash::DeskTemplate> policy_entry =
-        GetAdminDeskTemplateByUUID(uuid_str);
+        GetAdminDeskTemplateByUUID(uuid);
 
     if (policy_entry) {
       return DeskModel::GetEntryByUuidResult(
diff --git a/components/desks_storage/core/local_desk_data_manager.h b/components/desks_storage/core/local_desk_data_manager.h
index f2e6c04..1adfd9e 100644
--- a/components/desks_storage/core/local_desk_data_manager.h
+++ b/components/desks_storage/core/local_desk_data_manager.h
@@ -57,7 +57,7 @@
   // DeskModel:
   DeskModel::GetAllEntriesResult GetAllEntries() override;
   DeskModel::GetEntryByUuidResult GetEntryByUUID(
-      const std::string& uuid) override;
+      const base::GUID& uuid) override;
   void AddOrUpdateEntry(std::unique_ptr<ash::DeskTemplate> new_entry,
                         AddOrUpdateEntryCallback callback) override;
   void DeleteEntry(const base::GUID& uuid,
diff --git a/components/desks_storage/core/local_desk_data_manager_unittests.cc b/components/desks_storage/core/local_desk_data_manager_unittests.cc
index 2b98e9f..e4c998e 100644
--- a/components/desks_storage/core/local_desk_data_manager_unittests.cc
+++ b/components/desks_storage/core/local_desk_data_manager_unittests.cc
@@ -41,27 +41,37 @@
 constexpr uint32_t kThreadSafeIterations = 1000;
 
 const base::FilePath kInvalidFilePath = base::FilePath("?");
-const std::string kTestUuid1 = base::StringPrintf(kUuidFormat, 1);
-const std::string kTestUuid2 = base::StringPrintf(kUuidFormat, 2);
-const std::string kTestUuid3 = base::StringPrintf(kUuidFormat, 3);
-const std::string kTestUuid4 = base::StringPrintf(kUuidFormat, 4);
-const std::string kTestUuid5 = base::StringPrintf(kUuidFormat, 5);
-const std::string kTestUuid6 = base::StringPrintf(kUuidFormat, 6);
-const std::string kTestUuid7 = base::StringPrintf(kUuidFormat, 7);
-const std::string kTestUuid8 = base::StringPrintf(kUuidFormat, 8);
-const std::string kTestUuid9 = base::StringPrintf(kUuidFormat, 9);
-const std::string kTestSaveAndRecallDeskUuid1 =
-    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 10);
-const std::string kTestSaveAndRecallDeskUuid2 =
-    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 11);
-const std::string kTestSaveAndRecallDeskUuid3 =
-    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 12);
+const base::GUID kTestUuid1 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 1));
+const base::GUID kTestUuid2 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 2));
+const base::GUID kTestUuid3 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 3));
+const base::GUID kTestUuid4 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 4));
+const base::GUID kTestUuid5 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 5));
+const base::GUID kTestUuid6 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 6));
+const base::GUID kTestUuid7 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 7));
+const base::GUID kTestUuid8 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 8));
+const base::GUID kTestUuid9 =
+    base::GUID::ParseCaseInsensitive(base::StringPrintf(kUuidFormat, 9));
+const base::GUID kTestSaveAndRecallDeskUuid1 = base::GUID::ParseCaseInsensitive(
+    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 10));
+const base::GUID kTestSaveAndRecallDeskUuid2 = base::GUID::ParseCaseInsensitive(
+    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 11));
+const base::GUID kTestSaveAndRecallDeskUuid3 = base::GUID::ParseCaseInsensitive(
+    base::StringPrintf(kSaveAndRecallDeskUuidFormat, 12));
 
 const base::Time kTestTime1 = base::Time();
 const std::string kTestFileName1 =
-    base::StringPrintf(kTemplateFileNameFormat, kTestUuid1.c_str());
+    base::StringPrintf(kTemplateFileNameFormat,
+                       kTestUuid1.AsLowercaseString().c_str());
 const std::string kPolicyWithOneTemplate =
-    "[{\"version\":1,\"uuid\":\"" + kTestUuid9 +
+    "[{\"version\":1,\"uuid\":\"" + kTestUuid9.AsLowercaseString() +
     "\",\"name\":\""
     "Admin Template 1"
     "\",\"created_time_usec\":\"1633535632\",\"updated_time_usec\": "
@@ -76,13 +86,10 @@
 // Search `entry_list` for `entry_query` as a uuid and returns true if
 // found, false if not.
 bool FindUuidInUuidList(
-    const std::string& uuid_query,
+    const base::GUID& uuid,
     const std::vector<const ash::DeskTemplate*>& entry_list) {
-  base::GUID guid = base::GUID::ParseCaseInsensitive(uuid_query);
-  DCHECK(guid.is_valid());
-
   for (auto* entry : entry_list) {
-    if (entry->uuid() == guid)
+    if (entry->uuid() == uuid)
       return true;
   }
 
@@ -137,25 +144,24 @@
 
 // Make test template with default restore data.
 std::unique_ptr<ash::DeskTemplate> MakeTestDeskTemplate(
-    const std::string& uuid,
+    const base::GUID& uuid,
     ash::DeskTemplateSource source,
     const std::string& name,
     const base::Time created_time) {
   auto entry = std::make_unique<ash::DeskTemplate>(
-      base::GUID::ParseCaseInsensitive(uuid), source, name, created_time,
-      ash::DeskTemplateType::kTemplate);
+      uuid, source, name, created_time, ash::DeskTemplateType::kTemplate);
   entry->set_desk_restore_data(std::make_unique<app_restore::RestoreData>());
   return entry;
 }
 
 // Make test save and recall desk with default restore data.
 std::unique_ptr<ash::DeskTemplate> MakeTestSaveAndRecallDesk(
-    const std::string& uuid,
+    const base::GUID& uuid,
     const std::string& name,
     const base::Time created_time) {
   auto entry = std::make_unique<ash::DeskTemplate>(
-      base::GUID::ParseCaseInsensitive(uuid), ash::DeskTemplateSource::kUser,
-      name, created_time, ash::DeskTemplateType::kSaveAndRecall);
+      uuid, ash::DeskTemplateSource::kUser, name, created_time,
+      ash::DeskTemplateType::kSaveAndRecall);
   entry->set_desk_restore_data(std::make_unique<app_restore::RestoreData>());
   return entry;
 }
@@ -433,8 +439,7 @@
 
   EXPECT_TRUE(data_manager_->FindOtherEntryWithName(
       base::UTF8ToUTF16(std::string("desk_01")),
-      ash::DeskTemplateType::kTemplate,
-      base::GUID::ParseCaseInsensitive(kTestUuid1)));
+      ash::DeskTemplateType::kTemplate, kTestUuid1));
   task_environment_.RunUntilIdle();
 }
 
@@ -446,8 +451,7 @@
 
   EXPECT_FALSE(data_manager_->FindOtherEntryWithName(
       base::UTF8ToUTF16(std::string("desk_01")),
-      ash::DeskTemplateType::kTemplate,
-      base::GUID::ParseCaseInsensitive(kTestUuid1)));
+      ash::DeskTemplateType::kTemplate, kTestUuid1));
   task_environment_.RunUntilIdle();
 }
 
@@ -459,7 +463,7 @@
 
   auto result = data_manager_->GetEntryByUUID(kTestUuid1);
   EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
-  EXPECT_EQ(base::GUID::ParseCaseInsensitive(kTestUuid1), result.entry->uuid());
+  EXPECT_EQ(kTestUuid1, result.entry->uuid());
   EXPECT_EQ(base::UTF8ToUTF16(std::string("desk_01")),
             result.entry->template_name());
   EXPECT_EQ(kTestTime1, result.entry->created_time());
@@ -476,7 +480,7 @@
 
   auto result = data_manager_->GetEntryByUUID(kTestUuid9);
   EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
-  EXPECT_EQ(base::GUID::ParseCaseInsensitive(kTestUuid9), result.entry->uuid());
+  EXPECT_EQ(kTestUuid9, result.entry->uuid());
   EXPECT_EQ(ash::DeskTemplateSource::kPolicy, result.entry->source());
   EXPECT_EQ(base::UTF8ToUTF16(std::string("Admin Template 1")),
             result.entry->template_name());
@@ -518,7 +522,7 @@
 
   auto result = data_manager_->GetEntryByUUID(kTestUuid1);
   EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
-  EXPECT_EQ(base::GUID::ParseCaseInsensitive(kTestUuid1), result.entry->uuid());
+  EXPECT_EQ(kTestUuid1, result.entry->uuid());
   EXPECT_EQ(base::UTF8ToUTF16(std::string("desk_01_mod")),
             result.entry->template_name());
   EXPECT_EQ(kTestTime1, result.entry->created_time());
@@ -529,7 +533,7 @@
                                   base::BindOnce(&VerifyEntryAddedCorrectly));
 
   data_manager_->DeleteEntry(
-      base::GUID::ParseCaseInsensitive(kTestUuid1),
+      kTestUuid1,
       base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
         EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
       }));
@@ -626,8 +630,7 @@
 
   auto result = data_manager_->GetEntryByUUID(kTestSaveAndRecallDeskUuid1);
   EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
-  EXPECT_EQ(base::GUID::ParseCaseInsensitive(kTestSaveAndRecallDeskUuid1),
-            result.entry->uuid());
+  EXPECT_EQ(kTestSaveAndRecallDeskUuid1, result.entry->uuid());
   EXPECT_EQ(u"save_and_recall_desk_01", result.entry->template_name());
   EXPECT_EQ(kTestTime1, result.entry->created_time());
 }
@@ -639,7 +642,7 @@
   VerifyAllEntries(1ul, "Added one save and recall desk");
   EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 1ul);
   data_manager_->DeleteEntry(
-      base::GUID::ParseCaseInsensitive(kTestSaveAndRecallDeskUuid1),
+      kTestSaveAndRecallDeskUuid1,
       base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
         EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
       }));
@@ -797,7 +800,7 @@
   base::SetPosixFilePermissions(temp_dir_.GetPath(),
                                 base::FILE_PERMISSION_READ_BY_USER);
   data_manager_->DeleteEntry(
-      base::GUID::ParseCaseInsensitive(kTestUuid1),
+      kTestUuid1,
       base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
         EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kFailure);
       }));
diff --git a/components/download/internal/common/download_response_handler.cc b/components/download/internal/common/download_response_handler.cc
index ee44dabe..245c0b3 100644
--- a/components/download/internal/common/download_response_handler.cc
+++ b/components/download/internal/common/download_response_handler.cc
@@ -101,7 +101,8 @@
 
 void DownloadResponseHandler::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   create_info_ = CreateDownloadCreateInfo(*head);
   cert_status_ = head->cert_status;
 
@@ -231,9 +232,6 @@
   std::move(callback).Run();
 }
 
-void DownloadResponseHandler::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {}
-
 void DownloadResponseHandler::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {}
 
diff --git a/components/download/internal/common/resource_downloader.cc b/components/download/internal/common/resource_downloader.cc
index 565ea4e5..285a8d6 100644
--- a/components/download/internal/common/resource_downloader.cc
+++ b/components/download/internal/common/resource_downloader.cc
@@ -31,14 +31,15 @@
   ~URLLoaderStatusMonitor() override = default;
 
   // network::mojom::URLLoaderClient
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {}
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {}
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override {}
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override {}
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
@@ -216,8 +217,8 @@
 
   // Simulate on the new URLLoaderClient calls that happened on the old client.
   response_head->cert_status = cert_status;
-  url_loader_client_->OnReceiveResponse(std::move(response_head),
-                                        std::move(response_body));
+  url_loader_client_->OnReceiveResponse(
+      std::move(response_head), std::move(response_body), absl::nullopt);
 
   // Bind the new client.
   url_loader_client_receiver_ =
diff --git a/components/download/public/common/download_response_handler.h b/components/download/public/common/download_response_handler.h
index 47e816d..57d72d5 100644
--- a/components/download/public/common/download_response_handler.h
+++ b/components/download/public/common/download_response_handler.h
@@ -66,14 +66,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/components/embedder_support/android/util/android_stream_reader_url_loader.cc b/components/embedder_support/android/util/android_stream_reader_url_loader.cc
index 3c34a33..1053b86 100644
--- a/components/embedder_support/android/util/android_stream_reader_url_loader.cc
+++ b/components/embedder_support/android/util/android_stream_reader_url_loader.cc
@@ -351,7 +351,7 @@
   cache_response_ =
       response_delegate_->ShouldCacheResponse(response_head_.get());
   client_->OnReceiveResponse(std::move(response_head_),
-                             std::move(consumer_handle_));
+                             std::move(consumer_handle_), absl::nullopt);
 }
 
 void AndroidStreamReaderURLLoader::ReadMore() {
diff --git a/components/history_clusters/core/history_clusters_debug_jsons.cc b/components/history_clusters/core/history_clusters_debug_jsons.cc
index aa1edad..1388fd73 100644
--- a/components/history_clusters/core/history_clusters_debug_jsons.cc
+++ b/components/history_clusters/core/history_clusters_debug_jsons.cc
@@ -9,6 +9,7 @@
 #include "base/json/json_writer.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "components/history_clusters/core/history_clusters_util.h"
 
 namespace history_clusters {
 
@@ -38,6 +39,11 @@
         "openerVisitId",
         static_cast<int>(visit.opener_visit_of_redirect_chain_start));
     debug_visit.Set("searchTerms", visit.content_annotations.search_terms);
+    debug_visit.Set(
+        "urlForDeduping",
+        visit.content_annotations.search_normalized_url.is_empty()
+            ? ComputeURLForDeduping(visit.url_row.url()).spec()
+            : visit.content_annotations.search_normalized_url.spec());
     debug_visits_list.Append(std::move(debug_visit));
   }
 
diff --git a/components/media_router/common/BUILD.gn b/components/media_router/common/BUILD.gn
index 5a57c31..7b3c9366 100644
--- a/components/media_router/common/BUILD.gn
+++ b/components/media_router/common/BUILD.gn
@@ -6,6 +6,7 @@
   public_deps = [
     "//base",
     "//base:i18n",
+    "//media",
     "//net",
     "//third_party/icu",
     "//url",
@@ -34,6 +35,7 @@
   deps = [
     "mojom:media_route_provider_id",
     "mojom:route_request_result_code",
+    "//third_party/blink/public:blink_headers",
   ]
 
   if (!is_android) {
diff --git a/components/media_router/common/DEPS b/components/media_router/common/DEPS
index e2da925..0be15b2 100644
--- a/components/media_router/common/DEPS
+++ b/components/media_router/common/DEPS
@@ -2,4 +2,6 @@
   "+url",
   "+mojo",
   "+third_party/openscreen/src/cast/common/public",
+  "+third_party/blink/public",
+  "+media",
 ]
diff --git a/components/media_router/common/media_source.cc b/components/media_router/common/media_source.cc
index 285388a..65603948 100644
--- a/components/media_router/common/media_source.cc
+++ b/components/media_router/common/media_source.cc
@@ -14,6 +14,9 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "components/media_router/common/media_source.h"
+#include "media/base/audio_codecs.h"
+#include "media/base/video_codecs.h"
+#include "third_party/blink/public/platform/modules/remoteplayback/remote_playback_source.h"
 #include "url/gurl.h"
 
 namespace media_router {
@@ -35,7 +38,8 @@
 // List of non-http(s) schemes that are allowed in a Presentation URL.
 constexpr std::array<const char* const, 5> kAllowedSchemes{
     {kCastPresentationUrlScheme, kCastDialPresentationUrlScheme,
-     kDialPresentationUrlScheme, kRemotePlaybackPresentationUrlScheme, "test"}};
+     kDialPresentationUrlScheme, blink::kRemotePlaybackPresentationUrlScheme,
+     "test"}};
 
 bool IsSchemeAllowed(const GURL& url) {
   return url.SchemeIsHTTPOrHTTPS() ||
@@ -93,6 +97,21 @@
 }
 
 // static
+MediaSource MediaSource::ForPresentationUrl(const GURL& presentation_url) {
+  return MediaSource(presentation_url);
+}
+
+// static
+MediaSource MediaSource::ForRemotePlayback(int tab_id,
+                                           media::VideoCodec video_codec,
+                                           media::AudioCodec audio_codec) {
+  return MediaSource(
+      base::StringPrintf(blink::kRemotePlaybackDesktopUrlFormat, tab_id,
+                         media::GetCodecName(video_codec).c_str(),
+                         media::GetCodecName(audio_codec).c_str()));
+}
+
+// static
 MediaSource MediaSource::ForDesktop(
     const std::string& registered_desktop_stream_id,
     bool with_audio) {
@@ -110,11 +129,6 @@
   return MediaSource(std::string(kUnchosenDesktopMediaUrn));
 }
 
-// static
-MediaSource MediaSource::ForPresentationUrl(const GURL& presentation_url) {
-  return MediaSource(presentation_url);
-}
-
 bool MediaSource::IsTabMirroringSource() const {
   return id() == kAnyTabMediaUrn || TabId() > 0;
 }
@@ -130,6 +144,10 @@
          IsLegacyCastPresentationUrl(url_);
 }
 
+bool MediaSource::IsRemotePlaybackSource() const {
+  return url_.SchemeIs(kRemotePlaybackPresentationUrlScheme);
+}
+
 int MediaSource::TabId() const {
   int tab_id = -1;
   sscanf(id_.c_str(), kTabMediaUrnFormat, &tab_id);
diff --git a/components/media_router/common/media_source.h b/components/media_router/common/media_source.h
index ea28353..c2e0fb1 100644
--- a/components/media_router/common/media_source.h
+++ b/components/media_router/common/media_source.h
@@ -12,6 +12,11 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
+namespace media {
+enum class AudioCodec;
+enum class VideoCodec;
+}  // namespace media
+
 namespace media_router {
 
 // URL schemes used by Presentation URLs for Cast and DIAL.
@@ -92,6 +97,9 @@
   static MediaSource ForAnyTab();
   static MediaSource ForTab(int tab_id);
   static MediaSource ForPresentationUrl(const GURL& presentation_url);
+  static MediaSource ForRemotePlayback(int tab_id,
+                                       media::VideoCodec video_codec,
+                                       media::AudioCodec audio_codec);
 
   // Creates a media source for a specific desktop.
   // |registered_desktop_stream_id| is the string returned by
@@ -116,6 +124,9 @@
   // Returns true if this is represents a Cast Presentation URL.
   bool IsCastPresentationUrl() const;
 
+  // Returns true if the source is a RemotePlayback source.
+  bool IsRemotePlaybackSource() const;
+
   // Parses the ID and returns the SessionTabHelper tab ID referencing a source
   // tab.  Don't rely on this method returning something useful without first
   // calling IsTabMirroringSource(); it will return 0 for for ForLocalFile()
diff --git a/components/media_router/common/media_source_unittest.cc b/components/media_router/common/media_source_unittest.cc
index 37a74f57..906f9c7 100644
--- a/components/media_router/common/media_source_unittest.cc
+++ b/components/media_router/common/media_source_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <string>
 
+#include "media/base/audio_codecs.h"
+#include "media/base/video_codecs.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media_router {
@@ -26,6 +28,7 @@
   EXPECT_TRUE(IsValidPresentationUrl(GURL("https://google.com")));
   EXPECT_TRUE(IsValidPresentationUrl(GURL("cast://foo")));
   EXPECT_TRUE(IsValidPresentationUrl(GURL("cast:foo")));
+  EXPECT_TRUE(IsValidPresentationUrl(GURL("remote-playback:foo")));
 }
 
 TEST(MediaSourceTest, IsAutoJoinPresentationId) {
@@ -62,6 +65,7 @@
   EXPECT_TRUE(source.IsTabMirroringSource());
   EXPECT_FALSE(source.IsCastPresentationUrl());
   EXPECT_FALSE(source.IsDialSource());
+  EXPECT_FALSE(source.IsRemotePlaybackSource());
 }
 
 TEST(MediaSourceTest, ForTab) {
@@ -72,6 +76,7 @@
   EXPECT_TRUE(source.IsTabMirroringSource());
   EXPECT_FALSE(source.IsCastPresentationUrl());
   EXPECT_FALSE(source.IsDialSource());
+  EXPECT_FALSE(source.IsRemotePlaybackSource());
 }
 
 TEST(MediaSourceTest, ForDesktopWithoutAudio) {
@@ -84,6 +89,7 @@
   EXPECT_FALSE(source.IsTabMirroringSource());
   EXPECT_FALSE(source.IsCastPresentationUrl());
   EXPECT_FALSE(source.IsDialSource());
+  EXPECT_FALSE(source.IsRemotePlaybackSource());
 }
 
 TEST(MediaSourceTest, ForDesktopWithAudio) {
@@ -98,6 +104,7 @@
   EXPECT_FALSE(source.IsTabMirroringSource());
   EXPECT_FALSE(source.IsCastPresentationUrl());
   EXPECT_FALSE(source.IsDialSource());
+  EXPECT_FALSE(source.IsRemotePlaybackSource());
 }
 
 TEST(MediaSourceTest, ForPresentationUrl) {
@@ -109,6 +116,20 @@
   EXPECT_FALSE(source.IsTabMirroringSource());
   EXPECT_FALSE(source.IsCastPresentationUrl());
   EXPECT_FALSE(source.IsDialSource());
+  EXPECT_FALSE(source.IsRemotePlaybackSource());
+}
+
+TEST(MediaSourceTest, ForRemotePlayback) {
+  constexpr char kRemotePlaybackUrl[] =
+      "remote-playback:media-session?tab_id=1&video_codec=vp8&audio_codec=aac";
+  auto source = MediaSource::ForRemotePlayback(1, media::VideoCodec::kVP8,
+                                               media::AudioCodec::kAAC);
+  EXPECT_EQ(kRemotePlaybackUrl, source.id());
+  EXPECT_FALSE(source.IsDesktopMirroringSource());
+  EXPECT_FALSE(source.IsTabMirroringSource());
+  EXPECT_FALSE(source.IsCastPresentationUrl());
+  EXPECT_FALSE(source.IsDialSource());
+  EXPECT_TRUE(source.IsRemotePlaybackSource());
 }
 
 TEST(MediaSourceTest, IsCastPresentationUrl) {
diff --git a/components/media_router/common/providers/cast/cast_media_source.cc b/components/media_router/common/providers/cast/cast_media_source.cc
index 76338a3..63dab4af 100644
--- a/components/media_router/common/providers/cast/cast_media_source.cc
+++ b/components/media_router/common/providers/cast/cast_media_source.cc
@@ -225,6 +225,11 @@
                                            std::vector<CastAppInfo>({info}));
 }
 
+std::unique_ptr<CastMediaSource> CastMediaSourceForRemotePlayback(
+    const MediaSource& source) {
+  return CastMediaSourceForTabMirroring(source.id());
+}
+
 // The logic shared by ParseCastUrl() and ParseLegacyCastUrl().
 std::unique_ptr<CastMediaSource> CreateFromURLParams(
     const MediaSource::Id& source_id,
@@ -429,6 +434,9 @@
   if (source.IsDesktopMirroringSource())
     return CastMediaSourceForDesktopMirroring(source);
 
+  if (source.IsRemotePlaybackSource())
+    return CastMediaSourceForRemotePlayback(source);
+
   const GURL& url = source.url();
 
   if (!url.is_valid() || url.spec().length() > kMaxCastPresentationUrlLength)
diff --git a/components/media_router/common/providers/cast/cast_media_source_unittest.cc b/components/media_router/common/providers/cast/cast_media_source_unittest.cc
index 64c1085fd..7b7ced3 100644
--- a/components/media_router/common/providers/cast/cast_media_source_unittest.cc
+++ b/components/media_router/common/providers/cast/cast_media_source_unittest.cc
@@ -14,6 +14,17 @@
 
 namespace media_router {
 
+namespace {
+void AssertDefaultCastMediaSource(CastMediaSource* source) {
+  EXPECT_TRUE(source->client_id().empty());
+  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
+  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
+  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
+            source->default_action_policy());
+  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
+}
+}  // namespace
+
 TEST(CastMediaSourceTest, FromCastURLWithDefaults) {
   MediaSource::Id source_id("cast:ABCDEFAB");
   std::unique_ptr<CastMediaSource> source =
@@ -26,16 +37,11 @@
   EXPECT_TRUE(app_info.required_capabilities.empty());
   const auto& broadcast_request = source->broadcast_request();
   EXPECT_FALSE(broadcast_request);
-  EXPECT_EQ("", source->client_id());
-  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
-  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
-  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
-            source->default_action_policy());
-  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
   EXPECT_EQ(absl::nullopt, source->target_playout_delay());
   EXPECT_EQ(true, source->site_requested_audio_capture());
   EXPECT_EQ(cast_channel::VirtualConnectionType::kStrong,
             source->connection_type());
+  AssertDefaultCastMediaSource(source.get());
 }
 
 TEST(CastMediaSourceTest, FromCastURL) {
@@ -123,12 +129,21 @@
             source->app_infos()[0].app_id);
   EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
             source->app_infos()[1].app_id);
-  EXPECT_TRUE(source->client_id().empty());
-  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
-  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
-  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
-            source->default_action_policy());
-  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
+  AssertDefaultCastMediaSource(source.get());
+}
+
+TEST(CastMediaSourceTest, FromRemotePlaybackURL) {
+  MediaSource::Id source_id(
+      "remote-playback:media-session?tab_id=1&video_codec=vc&audio_codec=ac");
+  std::unique_ptr<CastMediaSource> source =
+      CastMediaSource::FromMediaSourceId(source_id);
+  ASSERT_TRUE(source);
+  EXPECT_EQ(source_id, source->source_id());
+  ASSERT_EQ(2u, source->app_infos().size());
+  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
+            source->app_infos()[0].app_id);
+  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
+            source->app_infos()[1].app_id);
 }
 
 TEST(CastMediaSourceTest, FromMirroringURN) {
@@ -142,12 +157,7 @@
             source->app_infos()[0].app_id);
   EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
             source->app_infos()[1].app_id);
-  EXPECT_TRUE(source->client_id().empty());
-  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
-  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
-  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
-            source->default_action_policy());
-  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
+  AssertDefaultCastMediaSource(source.get());
 }
 
 TEST(CastMediaSourceTest, FromDesktopUrn) {
@@ -159,12 +169,7 @@
   ASSERT_EQ(1u, source->app_infos().size());
   EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
             source->app_infos()[0].app_id);
-  EXPECT_TRUE(source->client_id().empty());
-  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
-  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
-  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
-            source->default_action_policy());
-  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
+  AssertDefaultCastMediaSource(source.get());
 }
 
 TEST(CastMediaSourceTest, FromInvalidSource) {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinator.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinator.java
index 0488402bb..abe5db8 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinator.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinator.java
@@ -23,6 +23,7 @@
      * including situations in which the message is already dismissed and hide animation is running.
      */
     private MessageState mCurrentDisplayedMessage;
+    private List<MessageState> mCurrentDisplayedMessages;
     private MessageState mLastShownMessage;
     private MessageQueueDelegate mMessageQueueDelegate;
 
@@ -70,4 +71,9 @@
     MessageState getCurrentDisplayedMessage() {
         return mCurrentDisplayedMessage;
     }
+
+    // Return a list of two messages which should be displayed when stacking animation is enabled.
+    List<MessageState> getCurrentDisplayedMessages() {
+        return mCurrentDisplayedMessages;
+    }
 }
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java
index 9872f0d0..48b66fc 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManager.java
@@ -5,6 +5,7 @@
 package org.chromium.components.messages;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
@@ -12,9 +13,11 @@
 import org.chromium.ui.util.TokenHolder;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * A class managing the queue of messages. Its primary role is to decide when to show/hide current
@@ -202,33 +205,56 @@
     }
 
     /**
-     * Iterate the queues of each scope to get the next messages. If multiple messages meet the
+     * Iterate the queues of each scope to get the next message. If multiple messages meet the
      * requirements, which can show in the given scope, then the message queued earliest will be
      * returned.
      */
     @VisibleForTesting
     MessageState getNextMessage() {
-        if (isQueueSuspended()) return null;
-        MessageState nextMessage = null;
-        for (List<MessageState> queue : mMessageQueues.values()) {
+        var nextMessages = getNextMessages();
+        assert nextMessages.size() == 2;
+        return nextMessages.get(0);
+    }
+
+    /**
+     * Return the next two messages which should be displayed. The first element stands for the
+     * front message while the other one stands for the back message. Null represents no view should
+     * be displayed at that position.
+     */
+    @VisibleForTesting
+    List<MessageState> getNextMessages() {
+        if (isQueueSuspended()) {
+            return Arrays.asList(null, null);
+        }
+        MessageState a = null;
+        MessageState b = null;
+        for (var queue : mMessageQueues.values()) {
             if (queue.isEmpty()) continue;
             Boolean isActive = mScopeStates.get(queue.get(0).scopeKey);
-            if (isActive == null || !isActive) continue;
-            for (MessageState candidate : queue) {
+            if (!Objects.equals(isActive, true)) continue;
+            for (var candidate : queue) {
                 boolean shouldShow = candidate.handler.shouldShow();
                 Log.w(TAG,
                         "MessageStateHandler#shouldShow for message with ID %s and key %s in "
                                 + "MessageQueueManager#getNextMessage returned %s.",
                         candidate.handler.getMessageIdentifier(), candidate.messageKey, shouldShow);
-                if (shouldShow
-                        && (nextMessage == null
-                                || (candidate.highPriority && !nextMessage.highPriority)
-                                || candidate.id < nextMessage.id)) {
-                    nextMessage = candidate;
+                if (!shouldShow) continue;
+                if (isLowerPriority(a, candidate)) {
+                    b = a;
+                    a = candidate;
+                } else if (isLowerPriority(b, candidate)) {
+                    b = candidate;
                 }
             }
         }
-        return nextMessage;
+        return Arrays.asList(a, b);
+    }
+
+    // Return true if |a| is lower priority than |b|.
+    private boolean isLowerPriority(@Nullable MessageState a, @NonNull MessageState b) {
+        if (a == null) return true;
+        if (!a.highPriority && b.highPriority) return true;
+        return a.id > b.id;
     }
 
     static class MessageState {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java
index c30345e..0dd0f56 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageQueueManagerTest.java
@@ -643,6 +643,36 @@
         verify(m1, times(2)).show();
     }
 
+    /**
+     * Test that {@link MessageQueueManager#getNextMessages()} returns correct list.
+     */
+    @Test
+    @SmallTest
+    public void testGetNextTwoMessages() {
+        MessageQueueManager queueManager = new MessageQueueManager();
+        queueManager.setDelegate(mEmptyDelegate);
+        var messages = queueManager.getNextMessages();
+        Assert.assertArrayEquals(new MessageState[] {null, null}, messages.toArray());
+        MessageStateHandler m1 = Mockito.spy(new EmptyMessageStateHandler());
+        MessageStateHandler m2 = Mockito.spy(new EmptyMessageStateHandler());
+
+        queueManager.enqueueMessage(m1, m1, SCOPE_INSTANCE_ID, false);
+        messages = queueManager.getNextMessages();
+        Assert.assertEquals(m1, messages.get(0).handler);
+        Assert.assertNull(messages.get(1));
+
+        queueManager.enqueueMessage(m2, m2, SCOPE_INSTANCE_ID, false);
+        messages = queueManager.getNextMessages();
+        Assert.assertEquals(m1, messages.get(0).handler);
+        Assert.assertEquals(m2, messages.get(1).handler);
+
+        MessageStateHandler m3 = Mockito.spy(new EmptyMessageStateHandler());
+        queueManager.enqueueMessage(m3, m3, SCOPE_INSTANCE_ID, true);
+        messages = queueManager.getNextMessages();
+        Assert.assertEquals(m3, messages.get(0).handler);
+        Assert.assertEquals(m1, messages.get(1).handler);
+    }
+
     static int getEnqueuedMessageCountForTesting(@MessageIdentifier int messageIdentifier) {
         return RecordHistogram.getHistogramValueCountForTesting(
                 MessagesMetrics.getEnqueuedHistogramNameForTesting(), messageIdentifier);
diff --git a/components/mirroring/service/BUILD.gn b/components/mirroring/service/BUILD.gn
index 04991ebb..d6c24e10 100644
--- a/components/mirroring/service/BUILD.gn
+++ b/components/mirroring/service/BUILD.gn
@@ -25,6 +25,9 @@
     "receiver_setup_querier.h",
     "remoting_sender.cc",
     "remoting_sender.h",
+    "rpc_dispatcher.h",
+    "rpc_dispatcher_impl.cc",
+    "rpc_dispatcher_impl.h",
     "rtp_stream.cc",
     "rtp_stream.h",
     "session.cc",
diff --git a/components/mirroring/service/DEPS b/components/mirroring/service/DEPS
index 300fc73d..32f6333 100644
--- a/components/mirroring/service/DEPS
+++ b/components/mirroring/service/DEPS
@@ -2,6 +2,7 @@
   "-components",
   "+components/mirroring/mojom",
   "+components/mirroring/service",
+  "+components/openscreen_platform",
   "+components/version_info",
   "+crypto",
   "+gpu/config",
@@ -14,5 +15,8 @@
   "+services/viz/public",
   "+third_party/libaom",
   "+third_party/openscreen/src/cast/streaming",
+  "+third_party/openscreen/src/cast/common/public",
+  "+third_party/openscreen/src/platform/api",
+  "+third_party/openscreen/src/platform/base",
   "+ui/base",
 ]
diff --git a/components/mirroring/service/media_remoter.cc b/components/mirroring/service/media_remoter.cc
index 10b1f7c2..f04162ac 100644
--- a/components/mirroring/service/media_remoter.cc
+++ b/components/mirroring/service/media_remoter.cc
@@ -4,15 +4,10 @@
 
 #include "components/mirroring/service/media_remoter.h"
 
-#include "base/base64.h"
 #include "base/bind.h"
-#include "base/callback.h"
-#include "base/json/json_writer.h"
 #include "base/logging.h"
-#include "base/strings/string_piece.h"
-#include "base/values.h"
-#include "components/mirroring/service/message_dispatcher.h"
 #include "components/mirroring/service/remoting_sender.h"
+#include "components/mirroring/service/rpc_dispatcher.h"
 #include "media/cast/net/cast_transport.h"
 
 using media::cast::Codec;
@@ -21,18 +16,15 @@
 namespace mirroring {
 
 MediaRemoter::MediaRemoter(
-    Client* client,
+    Client& client,
     const media::mojom::RemotingSinkMetadata& sink_metadata,
-    MessageDispatcher* message_dispatcher)
+    RpcDispatcher& rpc_dispatcher)
     : client_(client),
       sink_metadata_(sink_metadata),
-      message_dispatcher_(message_dispatcher),
+      rpc_dispatcher_(rpc_dispatcher),
       cast_environment_(nullptr),
       transport_(nullptr),
       state_(MIRRORING) {
-  DCHECK(client_);
-  DCHECK(message_dispatcher_);
-
   client_->ConnectToRemotingSource(
       receiver_.BindNewPipeAndPassRemote(),
       remoting_source_.BindNewPipeAndPassReceiver());
@@ -46,10 +38,8 @@
   Stop(media::mojom::RemotingStopReason::ROUTE_TERMINATED);
 }
 
-void MediaRemoter::OnMessageFromSink(const ReceiverResponse& response) {
-  DCHECK_EQ(ResponseType::RPC, response.type());
-  remoting_source_->OnMessageFromSink(
-      std::vector<uint8_t>(response.rpc().begin(), response.rpc().end()));
+void MediaRemoter::OnMessageFromSink(const std::vector<uint8_t>& response) {
+  remoting_source_->OnMessageFromSink(response);
 }
 
 void MediaRemoter::StartRpcMessaging(
@@ -72,9 +62,8 @@
   transport_ = transport;
   audio_config_ = audio_config;
   video_config_ = video_config;
-  message_dispatcher_->Subscribe(
-      ResponseType::RPC, base::BindRepeating(&MediaRemoter::OnMessageFromSink,
-                                             weak_factory_.GetWeakPtr()));
+  rpc_dispatcher_->Subscribe(base::BindRepeating(
+      &MediaRemoter::OnMessageFromSink, weak_factory_.GetWeakPtr()));
   state_ = REMOTING_STARTED;
   remoting_source_->OnStarted();
 }
@@ -104,7 +93,7 @@
   if (state_ != STARTING_REMOTING && state_ != REMOTING_STARTED)
     return;
   if (state_ == REMOTING_STARTED) {
-    message_dispatcher_->Unsubscribe(ResponseType::RPC);
+    rpc_dispatcher_->Unsubscribe();
     audio_sender_.reset();
     video_sender_.reset();
     cast_environment_ = nullptr;
@@ -161,20 +150,7 @@
 void MediaRemoter::SendMessageToSink(const std::vector<uint8_t>& message) {
   if (state_ != REMOTING_STARTED)
     return;
-  std::string encoded_rpc;
-  base::Base64Encode(
-      base::StringPiece(reinterpret_cast<const char*>(message.data()),
-                        message.size()),
-      &encoded_rpc);
-  base::Value::Dict rpc;
-  rpc.Set("type", "RPC");
-  rpc.Set("rpc", std::move(encoded_rpc));
-  mojom::CastMessagePtr rpc_message = mojom::CastMessage::New();
-  rpc_message->message_namespace = mojom::kRemotingNamespace;
-  const bool did_serialize_rpc =
-      base::JSONWriter::Write(rpc, &rpc_message->json_format_data);
-  DCHECK(did_serialize_rpc);
-  message_dispatcher_->SendOutboundMessage(std::move(rpc_message));
+  rpc_dispatcher_->SendOutboundMessage(message);
 }
 
 void MediaRemoter::EstimateTransmissionCapacity(
diff --git a/components/mirroring/service/media_remoter.h b/components/mirroring/service/media_remoter.h
index b7e6a42..6f3deec 100644
--- a/components/mirroring/service/media_remoter.h
+++ b/components/mirroring/service/media_remoter.h
@@ -22,8 +22,7 @@
 
 namespace mirroring {
 
-class MessageDispatcher;
-class ReceiverResponse;
+class RpcDispatcher;
 class RemotingSender;
 
 // MediaRemoter remotes media content directly to a Cast Receiver. When
@@ -61,9 +60,9 @@
     virtual void RestartMirroringStreaming() = 0;
   };
 
-  MediaRemoter(Client* client,
+  MediaRemoter(Client& client,
                const media::mojom::RemotingSinkMetadata& sink_metadata,
-               MessageDispatcher* message_dispatcher);
+               RpcDispatcher& message_dispatcher);
 
   MediaRemoter(const MediaRemoter&) = delete;
   MediaRemoter& operator=(const MediaRemoter&) = delete;
@@ -71,7 +70,7 @@
   ~MediaRemoter() override;
 
   // Callback from |message_dispatcher_| for received RPC messages.
-  void OnMessageFromSink(const ReceiverResponse& response);
+  void OnMessageFromSink(const std::vector<uint8_t>& response);
 
   // Called when OFFER/ANSWER exchange for a remoting session succeeds.
   void StartRpcMessaging(
@@ -111,15 +110,15 @@
   // session and fallback to mirroring.
   void OnRemotingDataStreamError();
 
-  const raw_ptr<Client> client_;  // Outlives this class.
+  raw_ref<Client> client_;
   const media::mojom::RemotingSinkMetadata sink_metadata_;
-  const raw_ptr<MessageDispatcher> message_dispatcher_;  // Outlives this class.
+  raw_ref<RpcDispatcher> rpc_dispatcher_;
   mojo::Receiver<media::mojom::Remoter> receiver_{this};
   mojo::Remote<media::mojom::RemotingSource> remoting_source_;
   scoped_refptr<media::cast::CastEnvironment> cast_environment_;
   std::unique_ptr<RemotingSender> audio_sender_;
   std::unique_ptr<RemotingSender> video_sender_;
-  raw_ptr<media::cast::CastTransport> transport_;  // Outlives this class;
+  raw_ptr<media::cast::CastTransport> transport_;
   media::cast::FrameSenderConfig audio_config_;
   media::cast::FrameSenderConfig video_config_;
 
diff --git a/components/mirroring/service/media_remoter_unittest.cc b/components/mirroring/service/media_remoter_unittest.cc
index 345713bf..e7a97db 100644
--- a/components/mirroring/service/media_remoter_unittest.cc
+++ b/components/mirroring/service/media_remoter_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/time/default_tick_clock.h"
 #include "components/mirroring/service/message_dispatcher.h"
 #include "components/mirroring/service/mirror_settings.h"
+#include "components/mirroring/service/rpc_dispatcher_impl.h"
 #include "media/cast/cast_environment.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -73,6 +74,7 @@
       : message_dispatcher_(receiver_.BindNewPipeAndPassRemote(),
                             inbound_channel_.BindNewPipeAndPassReceiver(),
                             error_callback_.Get()),
+        rpc_dispatcher_(message_dispatcher_),
         sink_metadata_(DefaultSinkMetadata()) {}
   MediaRemoterTest(const MediaRemoterTest&) = delete;
   MediaRemoterTest& operator=(const MediaRemoterTest&) = delete;
@@ -98,8 +100,8 @@
     EXPECT_FALSE(media_remoter_);
     EXPECT_CALL(*this, OnConnectToRemotingSource()).Times(1);
     EXPECT_CALL(remoting_source_, OnSinkAvailable(_)).Times(1);
-    media_remoter_ = std::make_unique<MediaRemoter>(this, sink_metadata_,
-                                                    &message_dispatcher_);
+    media_remoter_ =
+        std::make_unique<MediaRemoter>(*this, sink_metadata_, rpc_dispatcher_);
     task_environment_.RunUntilIdle();
     Mock::VerifyAndClear(this);
     Mock::VerifyAndClear(&remoting_source_);
@@ -171,6 +173,7 @@
   base::MockCallback<MessageDispatcher::ErrorCallback> error_callback_;
   mojo::Remote<mojom::CastMessageChannel> inbound_channel_;
   MessageDispatcher message_dispatcher_;
+  RpcDispatcherImpl rpc_dispatcher_;
   const media::mojom::RemotingSinkMetadata sink_metadata_;
   MockRemotingSource remoting_source_;
   mojo::Remote<media::mojom::Remoter> remoter_;
diff --git a/components/mirroring/service/rpc_dispatcher.h b/components/mirroring/service/rpc_dispatcher.h
new file mode 100644
index 0000000..bd90abb
--- /dev/null
+++ b/components/mirroring/service/rpc_dispatcher.h
@@ -0,0 +1,44 @@
+// 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_MIRRORING_SERVICE_RPC_DISPATCHER_H_
+#define COMPONENTS_MIRRORING_SERVICE_RPC_DISPATCHER_H_
+
+#include <stdint.h>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "base/containers/span.h"
+
+namespace mirroring {
+
+// Abstract interface for dispatching inbound and outbound RPC messages.
+class COMPONENT_EXPORT(MIRRORING_SERVICE) RpcDispatcher {
+ public:
+  RpcDispatcher() = default;
+  RpcDispatcher(const RpcDispatcher&) = delete;
+  RpcDispatcher(RpcDispatcher&&) = delete;
+  RpcDispatcher& operator=(const RpcDispatcher&) = delete;
+  RpcDispatcher& operator=(RpcDispatcher&&) = delete;
+  virtual ~RpcDispatcher() = default;
+
+  using ResponseCallback =
+      base::RepeatingCallback<void(const std::vector<uint8_t>& response)>;
+
+  // Handles registration for RPC messages. Currently only one callback that
+  // receives all RPC messages is allowed. Multiple calls to `Subscribe` will
+  // overwrite the currently set callback.
+  virtual void Subscribe(ResponseCallback callback) = 0;
+  virtual void Unsubscribe() = 0;
+
+  // Requests to send outbound `message` to the remoting implementation on the
+  // receiver. The message is routed based on the already encoded RPC message
+  // `handle`.
+  virtual void SendOutboundMessage(base::span<const uint8_t> message) = 0;
+};
+
+}  // namespace mirroring
+
+#endif  // COMPONENTS_MIRRORING_SERVICE_RPC_DISPATCHER_H_
diff --git a/components/mirroring/service/rpc_dispatcher_impl.cc b/components/mirroring/service/rpc_dispatcher_impl.cc
new file mode 100644
index 0000000..02b65ef
--- /dev/null
+++ b/components/mirroring/service/rpc_dispatcher_impl.cc
@@ -0,0 +1,69 @@
+// 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/mirroring/service/rpc_dispatcher_impl.h"
+
+#include "base/base64.h"
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "base/json/json_writer.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "components/mirroring/mojom/cast_message_channel.mojom.h"
+#include "components/mirroring/service/message_dispatcher.h"
+#include "components/mirroring/service/receiver_response.h"
+#include "components/mirroring/service/rpc_dispatcher.h"
+
+namespace mirroring {
+
+RpcDispatcherImpl::RpcDispatcherImpl(MessageDispatcher& message_dispatcher)
+    : message_dispatcher_(message_dispatcher) {}
+
+RpcDispatcherImpl::~RpcDispatcherImpl() {
+  if (is_subscribed_) {
+    Unsubscribe();
+  }
+}
+
+void RpcDispatcherImpl::Subscribe(RpcDispatcher::ResponseCallback callback) {
+  // NOTE: use of `base::Unretained` is safe because we unsubscribe from the
+  // `message_dispatcher_` in the destructor of this class.
+  message_dispatcher_->Subscribe(
+      ResponseType::RPC,
+      base::BindRepeating(&RpcDispatcherImpl::ProcessResponse,
+                          base::Unretained(this), std::move(callback)));
+  is_subscribed_ = true;
+}
+
+void RpcDispatcherImpl::ProcessResponse(
+    RpcDispatcher::ResponseCallback callback,
+    const ReceiverResponse& response) {
+  DCHECK_EQ(ResponseType::RPC, response.type());
+  callback.Run(
+      std::vector<uint8_t>(response.rpc().begin(), response.rpc().end()));
+}
+
+void RpcDispatcherImpl::Unsubscribe() {
+  message_dispatcher_->Unsubscribe(ResponseType::RPC);
+  is_subscribed_ = false;
+}
+
+void RpcDispatcherImpl::SendOutboundMessage(base::span<const uint8_t> message) {
+  std::string encoded_rpc;
+  base::Base64Encode(
+      base::StringPiece(reinterpret_cast<const char*>(message.data()),
+                        message.size()),
+      &encoded_rpc);
+  base::Value::Dict rpc;
+  rpc.Set("type", "RPC");
+  rpc.Set("rpc", std::move(encoded_rpc));
+  mojom::CastMessagePtr rpc_message = mojom::CastMessage::New();
+  rpc_message->message_namespace = mojom::kRemotingNamespace;
+  const bool did_serialize_rpc =
+      base::JSONWriter::Write(rpc, &rpc_message->json_format_data);
+  DCHECK(did_serialize_rpc);
+  message_dispatcher_->SendOutboundMessage(std::move(rpc_message));
+}
+
+}  // namespace mirroring
diff --git a/components/mirroring/service/rpc_dispatcher_impl.h b/components/mirroring/service/rpc_dispatcher_impl.h
new file mode 100644
index 0000000..504cbb3
--- /dev/null
+++ b/components/mirroring/service/rpc_dispatcher_impl.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 COMPONENTS_MIRRORING_SERVICE_RPC_DISPATCHER_IMPL_H_
+#define COMPONENTS_MIRRORING_SERVICE_RPC_DISPATCHER_IMPL_H_
+
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "components/mirroring/service/message_dispatcher.h"
+#include "components/mirroring/service/receiver_response.h"
+#include "components/mirroring/service/rpc_dispatcher.h"
+
+namespace mirroring {
+
+// Implementation of the RpcDispatcher API using a MessageDispatcher as the
+// backing implementation.
+class COMPONENT_EXPORT(MIRRORING_SERVICE) RpcDispatcherImpl final
+    : public RpcDispatcher {
+ public:
+  explicit RpcDispatcherImpl(MessageDispatcher& message_dispatcher);
+  RpcDispatcherImpl(RpcDispatcherImpl&&) = delete;
+  RpcDispatcherImpl(const RpcDispatcherImpl&) = delete;
+  RpcDispatcherImpl& operator=(RpcDispatcherImpl&&) = delete;
+  RpcDispatcherImpl& operator=(const RpcDispatcherImpl&) = delete;
+  ~RpcDispatcherImpl() final;
+
+  // RpcDispatcher overrides.
+  void Subscribe(RpcDispatcher::ResponseCallback callback) override;
+  void Unsubscribe() override;
+  void SendOutboundMessage(base::span<const uint8_t> message) override;
+
+ private:
+  void ProcessResponse(RpcDispatcher::ResponseCallback callback,
+                       const ReceiverResponse& response);
+
+  raw_ref<MessageDispatcher> message_dispatcher_;
+  bool is_subscribed_ = false;
+};
+
+}  // namespace mirroring
+
+#endif  // COMPONENTS_MIRRORING_SERVICE_RPC_DISPATCHER_IMPL_H_
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc
index 64571ea..f954671 100644
--- a/components/mirroring/service/session.cc
+++ b/components/mirroring/service/session.cc
@@ -481,6 +481,7 @@
   // provider.
   media_remoter_.reset();
   message_dispatcher_.reset();
+  rpc_dispatcher_.reset();
   setup_querier_.reset();
   weak_factory_.InvalidateWeakPtrs();
   audio_encode_thread_ = nullptr;
@@ -1025,11 +1026,13 @@
     build_version = setup_querier_->build_version();
     friendly_name = setup_querier_->friendly_name();
   }
+
+  rpc_dispatcher_ = std::make_unique<RpcDispatcherImpl>(*message_dispatcher_);
   media_remoter_ = std::make_unique<MediaRemoter>(
-      this,
+      *this,
       ToRemotingSinkMetadata(caps, friendly_name, session_params_,
                              build_version),
-      message_dispatcher_.get());
+      *rpc_dispatcher_);
 }
 
 }  // namespace mirroring
diff --git a/components/mirroring/service/session.h b/components/mirroring/service/session.h
index fceb835fa..24da610 100644
--- a/components/mirroring/service/session.h
+++ b/components/mirroring/service/session.h
@@ -16,6 +16,7 @@
 #include "components/mirroring/service/message_dispatcher.h"
 #include "components/mirroring/service/mirror_settings.h"
 #include "components/mirroring/service/receiver_setup_querier.h"
+#include "components/mirroring/service/rpc_dispatcher_impl.h"
 #include "components/mirroring/service/rtp_stream.h"
 #include "gpu/config/gpu_info.h"
 #include "media/capture/video/video_capture_feedback.h"
@@ -175,7 +176,7 @@
   MirrorSettings mirror_settings_;
 
   std::unique_ptr<MessageDispatcher> message_dispatcher_;
-
+  std::unique_ptr<RpcDispatcherImpl> rpc_dispatcher_;
   mojo::Remote<network::mojom::NetworkContext> network_context_;
 
   std::unique_ptr<ReceiverSetupQuerier> setup_querier_;
diff --git a/components/network_hints/browser/simple_network_hints_handler_impl.cc b/components/network_hints/browser/simple_network_hints_handler_impl.cc
index e695a38..24672c7 100644
--- a/components/network_hints/browser/simple_network_hints_handler_impl.cc
+++ b/components/network_hints/browser/simple_network_hints_handler_impl.cc
@@ -82,10 +82,13 @@
     // separating it from real navigations in the observer's callback.
     resolve_host_parameters->is_speculative = true;
     // TODO(https://crbug.com/997049): Pass in a non-empty NetworkIsolationKey.
+    // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger
+    // HTTPS DNS resource record query.
     render_frame_host->GetProcess()
         ->GetStoragePartition()
         ->GetNetworkContext()
-        ->ResolveHost(host_port_pair,
+        ->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                          std::move(host_port_pair)),
                       GetPendingNetworkIsolationKey(render_frame_host),
                       std::move(resolve_host_parameters),
                       receiver_.BindNewPipeAndPassRemote());
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 3d67830..c92c079 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -767,6 +767,13 @@
 
 // Local history zero-prefix (aka zero-suggest) and prefix suggestions:
 
+// The maximum number of entries stored by the in-memory zero-suggest cache at
+// at any given time (LRU eviction policy is used to enforce this limit).
+const base::FeatureParam<int> kZeroSuggestCacheMaxSize(
+    &omnibox::kZeroSuggestInMemoryCaching,
+    "ZeroSuggestCacheMaxSize",
+    10);
+
 // The relevance score for remote zero-suggest ranges from 550-1400. A default
 // value of 500 places local history zero-suggest below the remote zero-suggest.
 const base::FeatureParam<int> kLocalHistoryZeroSuggestRelevanceScore(
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 87b9ab8f..293323c7 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -512,6 +512,9 @@
 
 // Local history zero-prefix (aka zero-suggest) and prefix suggestions.
 
+// Determines the maximum number of entries stored by the in-memory ZPS cache.
+extern const base::FeatureParam<int> kZeroSuggestCacheMaxSize;
+
 // Determines the relevance score for the local history zero-prefix suggestions.
 extern const base::FeatureParam<int> kLocalHistoryZeroSuggestRelevanceScore;
 
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc
index 536a8b2..23946d86 100644
--- a/components/omnibox/browser/zero_suggest_provider_unittest.cc
+++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -1680,20 +1680,20 @@
   base::test::ScopedFeatureList features;
   features.InitAndEnableFeature(omnibox::kClobberTriggersSRPZeroSuggest);
 
-  // Set up the pref to cache the response from the previous run.
-  std::string json_response(
-      R"(["",["search1", "search2", "search3"],)"
-      R"([],[],{"google:suggestrelevance":[602, 601, 600],)"
-      R"("google:verbatimrelevance":1300}])");
   PrefService* prefs = client_->GetPrefs();
-  AutocompleteInput input = PrefetchingInputForSRP();
-  omnibox::SetUserPreferenceForZeroSuggestCachedResponse(
-      prefs, input.current_url().spec(), json_response);
 
   {
     base::HistogramTester histogram_tester;
 
     // Start a prefetch request.
+    AutocompleteInput input = PrefetchingInputForSRP();
+    // Set up the pref to cache the response from the previous run.
+    std::string json_response(
+        R"(["",["search1", "search2", "search3"],)"
+        R"([],[],{"google:suggestrelevance":[602, 601, 600],)"
+        R"("google:verbatimrelevance":1300}])");
+    omnibox::SetUserPreferenceForZeroSuggestCachedResponse(
+        prefs, input.current_url().spec(), json_response);
     provider_->StartPrefetch(input);
     EXPECT_TRUE(provider_->done());
 
@@ -1824,20 +1824,20 @@
   features.InitAndEnableFeature(
       omnibox::kClobberTriggersContextualWebZeroSuggest);
 
-  // Set up the pref to cache the response from the previous run.
-  std::string json_response(
-      R"(["",["search1", "search2", "search3"],)"
-      R"([],[],{"google:suggestrelevance":[602, 601, 600],)"
-      R"("google:verbatimrelevance":1300}])");
   PrefService* prefs = client_->GetPrefs();
-  AutocompleteInput input = PrefetchingInputForWeb();
-  omnibox::SetUserPreferenceForZeroSuggestCachedResponse(
-      prefs, input.current_url().spec(), json_response);
 
   {
     base::HistogramTester histogram_tester;
 
     // Start a prefetch request.
+    AutocompleteInput input = PrefetchingInputForWeb();
+    // Set up the pref to cache the response from the previous run.
+    std::string json_response(
+        R"(["",["search1", "search2", "search3"],)"
+        R"([],[],{"google:suggestrelevance":[602, 601, 600],)"
+        R"("google:verbatimrelevance":1300}])");
+    omnibox::SetUserPreferenceForZeroSuggestCachedResponse(
+        prefs, input.current_url().spec(), json_response);
     provider_->StartPrefetch(input);
     EXPECT_TRUE(provider_->done());
 
diff --git a/components/page_load_metrics/OWNERS b/components/page_load_metrics/OWNERS
index 6b50b55..1703764 100644
--- a/components/page_load_metrics/OWNERS
+++ b/components/page_load_metrics/OWNERS
@@ -6,4 +6,4 @@
 ryansturm@chromium.org
 johnidel@chromium.org
 toyoshim@chromium.org
-
+kenoss@chromium.org
diff --git a/components/pdf/browser/mock_url_loader_client.h b/components/pdf/browser/mock_url_loader_client.h
index c379953..7d56169b 100644
--- a/components/pdf/browser/mock_url_loader_client.h
+++ b/components/pdf/browser/mock_url_loader_client.h
@@ -26,7 +26,8 @@
   MOCK_METHOD(void,
               OnReceiveResponse,
               (network::mojom::URLResponseHeadPtr head,
-               mojo::ScopedDataPipeConsumerHandle body),
+               mojo::ScopedDataPipeConsumerHandle body,
+               absl::optional<mojo_base::BigBuffer> cached_metadata),
               (override));
   MOCK_METHOD(void,
               OnReceiveRedirect,
@@ -40,10 +41,6 @@
                OnUploadProgressCallback ack_callback),
               (override));
   MOCK_METHOD(void,
-              OnReceiveCachedMetadata,
-              (mojo_base::BigBuffer data),
-              (override));
-  MOCK_METHOD(void,
               OnTransferSizeUpdated,
               (int32_t transfer_size_diff),
               (override));
diff --git a/components/pdf/browser/plugin_response_writer.cc b/components/pdf/browser/plugin_response_writer.cc
index 8c4af89..92749e5 100644
--- a/components/pdf/browser/plugin_response_writer.cc
+++ b/components/pdf/browser/plugin_response_writer.cc
@@ -110,7 +110,8 @@
     return;
   }
 
-  client_->OnReceiveResponse(std::move(response), std::move(consumer));
+  client_->OnReceiveResponse(std::move(response), std::move(consumer),
+                             absl::nullopt);
 
   producer_ = std::make_unique<mojo::DataPipeProducer>(std::move(producer));
 
diff --git a/components/pdf/browser/plugin_response_writer_unittest.cc b/components/pdf/browser/plugin_response_writer_unittest.cc
index 6cc52a9..86a70a6 100644
--- a/components/pdf/browser/plugin_response_writer_unittest.cc
+++ b/components/pdf/browser/plugin_response_writer_unittest.cc
@@ -80,10 +80,12 @@
  protected:
   PluginResponseWriterTest() {
     ON_CALL(mock_client_, OnReceiveResponse)
-        .WillByDefault([this](network::mojom::URLResponseHeadPtr head,
-                              mojo::ScopedDataPipeConsumerHandle body) {
-          body_drainer_ = std::make_unique<BodyDrainer>(std::move(body));
-        });
+        .WillByDefault(
+            [this](network::mojom::URLResponseHeadPtr head,
+                   mojo::ScopedDataPipeConsumerHandle body,
+                   absl::optional<mojo_base::BigBuffer> cached_metadata) {
+              body_drainer_ = std::make_unique<BodyDrainer>(std::move(body));
+            });
   }
 
   std::unique_ptr<PluginResponseWriter> NewPluginResponseWriter(
@@ -141,7 +143,8 @@
 
     EXPECT_CALL(mock_client_, OnReceiveResponse)
         .WillOnce([this](network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) {
+                         mojo::ScopedDataPipeConsumerHandle body,
+                         absl::optional<mojo_base::BigBuffer> cached_metadata) {
           EXPECT_EQ(200, head->headers->response_code());
           EXPECT_EQ("text/html", head->mime_type);
           body_drainer_ = std::make_unique<BodyDrainer>(std::move(body));
diff --git a/components/policy/ENTERPRISE_POLICY_OWNERS b/components/policy/ENTERPRISE_POLICY_OWNERS
index 7220ed56..b4d97511 100644
--- a/components/policy/ENTERPRISE_POLICY_OWNERS
+++ b/components/policy/ENTERPRISE_POLICY_OWNERS
@@ -11,5 +11,5 @@
 pastarmovj@chromium.org
 pmarko@chromium.org
 poromov@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 zmin@chromium.org
diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb
index 57b9e4b..efd12c0 100644
--- a/components/policy/resources/policy_templates_es-419.xtb
+++ b/components/policy/resources/policy_templates_es-419.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">Establece la configuración regional que se aplica en la pantalla de acceso de <ph name="PRODUCT_OS_NAME" />.
 
       Si se establece esta política, la pantalla de acceso mostrará siempre la configuración regional que indica su primer valor (la política se define como una lista para otras futuras configuraciones). Si no se establece esta política o se establece una lista vacía, la pantalla de acceso mostrará la configuración regional de la última sesión de usuario. Si el valor de esta política no corresponde a una configuración regional válida, la pantalla de acceso mostrará una configuración de resguardo (la actual es en-US).</translation>
+<translation id="1050158007881386475">Inhabilitar los informes de estado de la placa del dispositivo</translation>
 <translation id="1052499923181221200">Esta política no tendrá efecto, a menos que SamlInSessionPasswordChangeEnabled sea verdadera.
       Si esta política es verdadera y se establece como, por ejemplo, 14, los usuarios de SAML recibirán una notificación sobre el vencimiento de su contraseña 14 días antes de la fecha de caducidad.
       Los usuarios podrán ocuparse de inmediato y cambiar la contraseña en la sesión, antes de que caduque.
@@ -330,6 +331,7 @@
       Si la fuerzas (2), el usuario no podrá suprimir el selector de perfiles. Se mostrará el selector de perfiles incluso si hay solo un perfil disponible.</translation>
 <translation id="1339174690935954950">No permitir que los usuarios envíen comentarios</translation>
 <translation id="1342918903685430097">Configurar la versión mínima permitida de <ph name="PRODUCT_OS_NAME" /> para el dispositivo.</translation>
+<translation id="1343128241903870688">Inhabilitar los informes de apps del dispositivo</translation>
 <translation id="1347198119056266798">Esta política es obsoleta; usa las políticas <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> y <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> en su lugar. Se ignorará esta política si se configuran las políticas <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> o <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> (obsoleta).
 
       Esta configuración aplica el uso de la función SafeSearch para las consultas en Búsqueda web de Google y evita que los usuarios puedan cambiarla. Además, aplica el modo restringido moderado en YouTube.
@@ -369,6 +371,7 @@
 <translation id="1393485621820363363">Impresoras empresariales habilitadas asociadas a dispositivos</translation>
 <translation id="1395505489889158859">Permitir el envío de nombres de usuario y nombres de archivo a impresoras nativas</translation>
 <translation id="1397855852561539316">Dirección URL sugerida para el proveedor de búsqueda predeterminado</translation>
+<translation id="1402227992519954892">Habilitar los informes de apps del dispositivo</translation>
 <translation id="141279920573530952">Si estableces la política, podrás crear una lista de los sitios que reciben automáticamente permiso para acceder a todos los puertos en serie disponibles.
 
       Las URLs deben ser válidas; de lo contrario, se ignorará la política. Solo se considera el origen (esquema, host y puerto) de la URL.
@@ -614,6 +617,7 @@
 <translation id="1616280227447957376">Permite continuar desde la página de advertencia de SSL en orígenes específicos</translation>
 <translation id="1617235075406854669">Habilita la eliminación del historial de descargas y del navegador.</translation>
 <translation id="1620510694547887537">Cámara</translation>
+<translation id="162162247775156979">Inhabilitar los informes de estado del almacenamiento del dispositivo</translation>
 <translation id="1626379196197114720">Permite que se utilice la memoria caché atrás/adelante</translation>
 <translation id="1628974048137236820">La página Nueva pestaña no mostrará tarjetas</translation>
 <translation id="1630263002012156148">Si habilitas la política, se establecerá la página Nueva pestaña como la página principal del usuario y se ignorarán las demás URL de página principal. Si inhabilitas la política, la página principal no será la página Nueva pestaña, a menos que se establezca chrome://newtab como la URL de la página principal del usuario.
@@ -1706,8 +1710,12 @@
 <translation id="2665422249821137126">Habilita el cursor grande en la pantalla de acceso</translation>
 <translation id="2667894101494585925">Habilitar la recuperación de la guía de optimización</translation>
 <translation id="2672012807430078509">Controlar el uso de NTLM como protocolo de autenticación para las activaciones de archivos compartidos SMB</translation>
+<translation id="2673363037046384711">El usuario final puede habilitar o inhabilitar el modo de alta eficiencia</translation>
 <translation id="2678503605767349615">Certificados de cliente obligatorios en todo el dispositivo</translation>
 <translation id="268577405881275241">Habilitar la función del proxy de compresión de datos</translation>
+<translation id="268695908564263739">Esta política habilita o inhabilita la configuración del modo de alta eficiencia. Esta configuración hace que, a fin de recuperar memoria, se cierren las pestañas tras un período en segundo plano.
+      Si no estableces esta política, el usuario final podrá controlar esta configuración desde chrome://settings/performance.
+      </translation>
 <translation id="2691668238491124549">Si estableces esta política (como solo recomendadas), se moverán al principio de la lista las configuraciones regionales recomendadas para una sesión administrada, en el orden en el que aparecen en la política. De forma predeterminada, estará seleccionada la primera configuración regional recomendada.
 
       Si no estableces la política, se seleccionará de forma predeterminada la configuración regional actual de la IU.
@@ -2907,6 +2915,7 @@
 <translation id="3898345958122666461">Desactivar NTLMv2</translation>
 <translation id="3898795800259311780">Permite o rechaza la captura de pantalla</translation>
 <translation id="3903313632842363082">Inhabilitar los informes de los usuarios del dispositivo</translation>
+<translation id="3904304709151553598">Inhabilitar los informes de los ventiladores del dispositivo</translation>
 <translation id="3907683835264956726">Permite el acceso de usuarios en línea cuando están en una pantalla de bloqueo. Si estableces la política como verdadera, la reautenticación en línea en la pantalla de bloqueo se activará, por ejemplo, mediante la política <ph name="POLICY" />.
       Después de que se cumpla la condición, la reautenticación se aplicará de manera forzosa y de inmediato cuando un usuario esté en la pantalla de acceso o la próxima vez que bloquee la pantalla.
       Si estableces la política como falsa o no la estableces, los usuarios siempre podrán desbloquear la pantalla con sus credenciales locales.</translation>
@@ -2951,6 +2960,7 @@
 
           Si no la estableces, inicialmente las teclas especiales estarán inhabilitadas en la pantalla de acceso, pero el usuario podrá habilitarlas en cualquier momento.</translation>
 <translation id="3927291637826333102">Permitir que estos orígenes capturen pestañas, ventanas y escritorios</translation>
+<translation id="3928726028264020458">Habilitar los informes de los VPD del dispositivo</translation>
 <translation id="3943930334592166130">Esta política controla si se le solicita al usuario que seleccione un certificado de cliente cuando más de un certificado coincide con <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" />.
       Si habilitas esta política, se le solicitará al usuario que seleccione un certificado de cliente cada vez que la política de selección automática coincida con múltiples certificados.
       Si inhabilitas esta política o no la estableces, solo se le solicitará al usuario que haga una elección cuando ningún certificado coincida con la selección automática.</translation>
@@ -3040,6 +3050,7 @@
       En <ph name="MS_WIN_NAME" />, esta funcionalidad solo estará disponible en instancias que están vinculadas a un dominio de <ph name="MS_AD_NAME" />, están inscritas en <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> o se ejecutan en Windows 10 Pro. En <ph name="MAC_OS_NAME" />, esta funcionalidad solo está disponible en instancias administradas mediante MDM o vinculadas a un dominio a través de MCX.</translation>
 <translation id="4043796890723386527">Impedir que los usuarios creen o utilicen perfiles secundarios o usen el modo de invitado en el navegador <ph name="LACROS_NAME" /></translation>
 <translation id="4051723201852944592">Habilita la oclusión de ventanas</translation>
+<translation id="4052529125939620019">Cargar la extensión del componente CryptoToken al iniciar el navegador</translation>
 <translation id="4053157306171963473">Inhabilitar los informes de tiempo de actividad del dispositivo</translation>
 <translation id="4056910949759281379">Inhabilitar el protocolo SPDY</translation>
 <translation id="4061107397839125009">Si estableces la política, podrás especificar una lista de patrones de URL que indiquen los sitios que no pueden mostrar notificaciones.
@@ -3098,6 +3109,38 @@
 
       Si estableces la política, los usuarios no podrán cambiarla. Si no la estableces, el teclado en pantalla estará desactivado al principio, pero los usuarios podrán activarlo en cualquier momento.</translation>
 <translation id="412697421478384751">Permitir que los usuarios establezcan PIN no seguros para la pantalla bloqueada</translation>
+<translation id="4130565559631908067">Esta política proporciona una forma de anular la lista de conjuntos que el navegador utiliza para las funciones de los conjuntos propios.
+
+      Cada conjunto de la lista de conjuntos propios del navegador debe cumplir los requisitos de un conjunto propio.
+      Un conjunto propio debe contener un sitio propietario y uno o más sitios miembros.
+      Un conjunto también puede contener una lista de sitios de servicio de su propiedad, así como un mapa de un sitio a todas sus variantes de ccTLD.
+      Consulta https://github.com/WICG/first-party-sets para obtener más información sobre los conjuntos propios que usa <ph name="PRODUCT_NAME" />.
+
+      Todos los sitios de un conjunto propio deben ser un dominio registrable de HTTPS. Además, cada sitio en un conjunto propio debe ser único.
+      Esto quiere decir que un sitio no puede estar enumerado más de una vez en un conjunto propio.
+
+      Cuando se proporciona un diccionario vacío a la política, el navegador utiliza la lista pública de conjuntos propios.
+
+      Para todos los sitios de un conjunto propio de la lista <ph name="REPLACEMENTS" />, si el sitio también está
+      en un conjunto propio de la lista del navegador, ese sitio se quitará del conjunto propio del navegador.
+      Luego de esto, el conjunto propio de la política se agregará a la lista de conjuntos propios del navegador.
+
+      Para todos los sitios de un conjunto propio de la lista <ph name="ADDITIONS" />, si el sitio también está
+      en un conjunto propio de la lista del navegador, ese conjunto se actualizará para que
+      el nuevo conjunto propio pueda agregarse a la lista del navegador. Una vez que se actualice la lista del navegador,
+      el conjunto propio de la política se agregará a la lista de conjuntos propios del navegador.
+
+      La lista de conjuntos propios del navegador requiere que ningún sitio de la lista esté en
+      más de un conjunto. Este también es un requisito para las listas <ph name="REPLACEMENTS" />
+      y <ph name="ADDITIONS" />. De la misma manera, un sitio no puede estar al mismo tiempo en
+      las listas <ph name="REPLACEMENTS" /> y <ph name="ADDITIONS" />.
+
+      Los comodines (*) no se admiten como valor de la política, ni en ningún conjunto propio en estas listas.
+
+      Todos los conjuntos que brinda esta política deben ser conjuntos propios válidos. De lo contrario, se
+      producirá un error.
+
+      Esta política solo está disponible en instancias de Windows vinculadas a un dominio de <ph name="MS_AD_NAME" />, en instancias de Windows 10 Pro o Enterprise habilitadas para la administración de dispositivos, o en instancias de macOS administradas mediante MDM o vinculadas a un dominio a través de MCX.</translation>
 <translation id="4138655880188755661">Límite de tiempo</translation>
 <translation id="4147818922357566987">Habilitar solo variaciones relacionadas con correcciones críticas</translation>
 <translation id="4150201353443180367">Pantalla</translation>
@@ -3919,6 +3962,7 @@
 <translation id="5148753489738115745">Te permite especificar los parámetros adicionales que se utilizan cuando <ph name="PRODUCT_FRAME_NAME" /> inicia <ph name="PRODUCT_NAME" />.
 
           Si no se configura esta política, se utilizará la línea de comandos predeterminada.</translation>
+<translation id="5151099177901233471">Habilitar los informes de la zona horaria del dispositivo</translation>
 <translation id="5152393033264257734">Permite las revisiones de intercepción de DNS y las barras de información de "http://intranetsite/" para "quisiste decir".</translation>
 <translation id="5152787786897382519">Chromium y Google Chrome tienen algunos grupos de políticas que dependen unos de otros para controlar una función. Los siguientes grupos de políticas representan estos conjuntos. Como las políticas pueden tener diferentes fuentes, solo se aplicarán los valores que provengan de la fuente de mayor prioridad. Se ignorarán los valores que provengan de una fuente de menor prioridad perteneciente al mismo grupo. El orden de prioridad se define en <ph name="POLICY_PRIORITY_DOC_URL" />.</translation>
 <translation id="5153187201534281749">Ícono de experimentos del navegador de la barra de herramientas</translation>
@@ -4060,6 +4104,7 @@
       Aquí la "versión" puede ser exacta, como "61.0.3163.120", o el prefijo de una versión, como "61.0".  </translation>
 <translation id="5247973380763021389">Impedir que las políticas de nube destinadas a los usuarios anulen las políticas de nube de la máquina</translation>
 <translation id="5249453807420671499">Los usuarios pueden agregar cuentas de Kerberos</translation>
+<translation id="5249555581286638799">Habilitar el modo de alta eficiencia</translation>
 <translation id="5252210248395576403">Esta política le otorga permiso a Respuestas rápidas para acceder al contenido seleccionado y enviar información al servidor, a fin de obtener resultados de traducción.
 
       Si habilitas la política o no la estableces, se habilitará la traducción de Respuestas rápidas.
@@ -4068,6 +4113,7 @@
 
       Si estableces la política como falsa o no la estableces, se desactivará este modo y los usuarios no podrán activarlo.</translation>
 <translation id="5255162913209987122">Se puede recomendar</translation>
+<translation id="525543707238275321">Inhabilitar los informes de la CPU del dispositivo</translation>
 <translation id="5257395339965216304">Datos de apps alojadas</translation>
 <translation id="5262320080678421295">Inhabilitar la confianza en los certificados emitidos mediante la PKI heredada de Symantec Corporation</translation>
 <translation id="5266173014392157048">Esta política dejó de estar disponible. Usa la política "<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />" en su lugar.
@@ -4136,6 +4182,7 @@
       Si para ese momento no se configuró la política, <ph name="PRODUCT_NAME" /> usará la versión máxima predeterminada.
 
       De lo contrario, se podrá establecer como uno de los siguientes valores: "tls1.2" o "tls1.3". De esta manera, <ph name="PRODUCT_NAME" /> no usará versiones de SSL/TLS posteriores a la especificada. Se ignorarán los valores no reconocidos.</translation>
+<translation id="5329018127554115226">Se inhabilitará el modo de alta eficiencia</translation>
 <translation id="5330684698007383292">Permitir que <ph name="PRODUCT_FRAME_NAME" /> gestione los siguientes tipos de contenido</translation>
 <translation id="5331746669335642668">La política de nube de <ph name="PRODUCT_NAME" /> anula la política de la plataforma.</translation>
 <translation id="5346587320074666194">Bloquea el acceso a los sensores en estos sitios</translation>
@@ -4330,6 +4377,7 @@
       No se aplica esta política para los cambios de canales.</translation>
 <translation id="5519331583722582543">Función experimental booleana que indica si el teclado en pantalla puede proporcionar entradas mediante el reconocimiento de escritura a mano.</translation>
 <translation id="5519619299971727565">Inhabilitar los informes de uso de las apps de Linux</translation>
+<translation id="5521035900165046997">Habilitar los informes de Bluetooth del dispositivo</translation>
 <translation id="5521875416764302911">Impedir que los usuarios accedan a <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">Permitir las consultas a Quirks Server y los archivos de configuración específicos de hardware que se pueden descargar</translation>
 <translation id="5526701598901867718">Todos (inseguro)</translation>
@@ -4385,6 +4433,7 @@
 <translation id="5598417829613725146">Canvas (compatible a partir de la versión 90)</translation>
 <translation id="5599461642204007579">Configuración de la administración de <ph name="MS_AD_NAME" /></translation>
 <translation id="5601503069213153581">PIN</translation>
+<translation id="5607021831414604820">Habilitar los informes de estado del almacenamiento del dispositivo</translation>
 <translation id="5614865701790130558">Registra eventos para las instalaciones de extensiones basadas en políticas</translation>
 <translation id="5618398258385745432">La configuración asociada se usó antes de implementar la reautenticación para ver contraseñas. A partir de ese momento, la configuración y, por lo tanto, esta política no tienen efecto en el comportamiento de Chrome. El comportamiento actual de Chrome es como si la política se hubiera establecido para no ver las contraseñas en texto claro en las páginas de configuración del administrador de contraseñas. Esto significa que la página de configuración contiene solo un marcador de posición y Chrome mostrará la contraseña después de que el usuario haga clic en "Mostrar" (e implemente la reautenticación, si corresponde). A continuación, se muestra la descripción original de la política.
 
@@ -4494,6 +4543,7 @@
       Nota: Si reinicias el dispositivo y sales de la cuenta, se borrará la caché.</translation>
 <translation id="5717973246079053225">Inhabilitar los informes en la nube de navegadores administrados</translation>
 <translation id="572155275267014074">Configuración de Android</translation>
+<translation id="5722577409367087850">Cargar la extensión</translation>
 <translation id="5728154254076636808">Habilita la creación de las copias de itinerancia para los datos de perfil de <ph name="PRODUCT_NAME" /></translation>
 <translation id="5729308727912841256">Contraseña de Kerberos. La contraseña de acceso reemplaza al marcador de posición <ph name="PASSWORD_PLACEHOLDER" />.</translation>
 <translation id="5732972008943405952">Importar el formulario de Autocompletar del navegador predeterminado en la primera ejecución</translation>
@@ -4756,6 +4806,7 @@
       Si la inhabilitas, los usuarios no podrán canjear esas ofertas.</translation>
 <translation id="6046615715547751255">No permitir los controles de informes detallados</translation>
 <translation id="6048199181629830227">Habilita la administración de carga fuera del horario de mayor consumo</translation>
+<translation id="6049117606554031363">Habilitar los informes de estado de la placa del dispositivo</translation>
 <translation id="6053681087509103368">Permitir que WebRTC use versiones obsoletas del protocolo TLD/DTLS</translation>
 <translation id="6058879286588763839">A menos que especifiques <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" /> (que anula <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />), si estableces <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />, se especificará la política de administración de energía en el modo de carga de la batería (cuando lo admita el dispositivo). Para extender la duración de la batería, la política controlará de forma dinámica la carga de la batería y reducirá su desgaste debido al uso.
 
@@ -4788,6 +4839,7 @@
 <translation id="6099853574908182288">Modo predeterminado de impresión a color</translation>
 <translation id="6102342563050263313">Habilitar el desplazamiento al texto especificado en fragmentos de URL</translation>
 <translation id="6102449843040973938">No impide que se ejecute <ph name="BOREALIS_NAME" /> en un dispositivo</translation>
+<translation id="610892566190435199">Habilitar los informes de estado de energía del dispositivo</translation>
 <translation id="6111936128861357925">Permitir juego del huevo de pascua del dinosaurio</translation>
 <translation id="6112524153927257380">Si estableces la política, los usuarios no podrán omitir las decisiones de seguridad relacionadas con las descargas.
 
@@ -4935,6 +4987,7 @@
       Esta política permite que las empresas inhabiliten la zona de pruebas de audio si utilizan configuraciones de software de seguridad que interfieran con la zona de pruebas.</translation>
 <translation id="624818583115864448">puerto 554 (puede desbloquearse hasta el 15/10/2021)</translation>
 <translation id="6252773211180267325">No impide que se ejecute <ph name="BOREALIS_NAME" /> para un usuario</translation>
+<translation id="625580680776945310">Se habilitará el modo de alta eficiencia</translation>
 <translation id="6258658183356534534">Controlar la función de actualización de GREASE de optimización del cliente de usuario-cliente</translation>
 <translation id="6261643884958898336">Enviar la información de identificación de la máquina</translation>
 <translation id="6265892395051519509">Permite el acceso a los sensores en estos sitios</translation>
@@ -5106,6 +5159,7 @@
 <translation id="6368403635025849609">Permitir JavaScript en estos sitios</translation>
 <translation id="6371561334154580937">Mostrar el diálogo de salida cuando se cierra la última ventana</translation>
 <translation id="6372105930898423193">Permite volver a habilitar la función AppCache, incluso si se encuentra desactivada de forma predeterminada</translation>
+<translation id="6373299801585455337">Habilitar los informes de la CPU del dispositivo</translation>
 <translation id="6376540107659524656">Inhabilitar SSH en la app del sistema de la terminal</translation>
 <translation id="6376659517206731212">Puede ser obligatoria</translation>
 <translation id="6377031865393559909">Permitir que los usuarios utilicen plantillas de escritorio</translation>
@@ -5113,6 +5167,7 @@
 <translation id="6378393933102834628">Si estableces la política como verdadera, se mostrarán los accesos directos a aplicaciones. Si la estableces como falsa, no se mostrarán nunca los accesos directos.
 
       Si estableces la política, los usuarios no podrán cambiarla. Si no la estableces, los usuarios podrán ocultar o mostrar los accesos directos a aplicaciones desde el menú contextual de la barra de favoritos.</translation>
+<translation id="638003144128412430">Inhabilitar los informes de la zona horaria del dispositivo</translation>
 <translation id="6382351416269252693">Establece una lista de patrones de URL de sitios donde se indiquen los que rechazarán automáticamente el permiso de fuentes locales. Esto limitará la capacidad de los sitios para ver la información sobre las fuentes locales.j
 
       Para obtener información detallada sobre los patrones de URL de sitios válidos, consulta https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. Se permite el uso de caracteres comodín (<ph name="WILDCARD_VALUE" />). Esta política solo establece coincidencias basadas en el origen; por lo tanto, se ignoran todas las rutas de acceso que se incluyan en el patrón de URL.
@@ -5159,6 +5214,7 @@
 <translation id="6440051664870270040">Permitir la navegación y las ventanas emergentes en los sitios al mismo tiempo</translation>
 <translation id="6447948611083700881">Se inhabilitó la funcionalidad de copia de seguridad y restablecimiento</translation>
 <translation id="6449476513004303784">No permitir que los usuarios administren certificados</translation>
+<translation id="6452882999388592166">Si habilitas la política, la extensión del componente CryptoToken integrada se cargará al iniciar el navegador. Si la inhabilitas o no la estableces, CryptoToken no se cargará al iniciar el navegador. Esta política es una solución temporal para los sitios que se inhabilitaron porque "chrome.runtime" quedó indefinido como efecto secundario de la eliminación de CryptoToken en M106. Los sitios web no deben depender de la definición incondicional de "chrome.runtime".</translation>
 <translation id="6453641799812499182">Permite que <ph name="CORS" /> revise las mitigaciones en la nueva implementación de <ph name="CORS" /></translation>
 <translation id="645425387487868471">Permitir forzar el acceso para <ph name="PRODUCT_NAME" /></translation>
 <translation id="6455842857207956758">Permite la sincronización de contraseñas de SAML entre varios dispositivos Chrome mediante la supervisión del valor del token de sincronización de contraseñas y el envío del usuario a la reautenticación en línea si se actualizó la contraseña y debe sincronizarse.
@@ -5640,6 +5696,7 @@
 <translation id="6903814433019432303">Esta política solo se encuentra activa en el modo de venta.
 
       Permite determinar el conjunto de URL que se cargará cuando se inicie la sesión en el demo. Esta política anulará cualquier otro mecanismo para establecer la URL inicial y, por tanto, solo se puede aplicar a una sesión que no esté asociada a un usuario concreto.</translation>
+<translation id="6903818804346914108">Habilitar los informes de los ventiladores del dispositivo</translation>
 <translation id="6905405893096403868">Si estableces esta política como una lista de strings, se transferirá cada string al navegador alternativo como parámetro de la línea de comandos. En <ph name="MS_WIN_NAME" />, los parámetros están separados por espacios. En <ph name="MAC_OS_NAME" /> y <ph name="LINUX_OS_NAME" />, un parámetro puede contener espacios y tratarse como un único parámetro.
 
       Si un parámetro contiene <ph name="URL_PLACEHOLDER" />, se reemplazará <ph name="URL_PLACEHOLDER" /> por la URL de la página que se abrirá. Si ningún parámetro contiene <ph name="URL_PLACEHOLDER" />, se agregará la dirección URL al final de la línea de comandos.
@@ -5940,6 +5997,7 @@
 <translation id="718126088895133062">Esta política especifica el ID de usuario de la licencia de <ph name="PLUGIN_VM_NAME" /> para este dispositivo.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">Usar un servicio web de Google para ayudar a solucionar errores de ortografía</translation>
+<translation id="7187248416163189586">Inhabilitar los informes de la retroiluminación del dispositivo</translation>
 <translation id="718850220532931090">Esta política dejó de estar disponible; usa <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" /> en su lugar.
 
       Si estableces la política, se especificarán las extensiones que tienen permiso para usar la función <ph name="CHALLENGE_USER_KEY_FUNCTION" /> de <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> para la certificación remota. Para usar la API, las extensiones deben estar en esta lista.
@@ -5962,6 +6020,7 @@
 <translation id="7207095846245296855">Forzar Google SafeSearch</translation>
 <translation id="7211368186050418507">Nunca detectar de forma automática la zona horaria</translation>
 <translation id="7216442368414164495">Permitir que los usuarios acepten informes extendidos de navegación segura</translation>
+<translation id="721970071627370558">Inhabilitar los informes de estado de energía del dispositivo</translation>
 <translation id="7221574724100909818">Usar el ícono de bloqueo para conexiones seguras</translation>
 <translation id="7229365071755865554">Habilitar el guardado de contraseñas en el administrador de contraseñas</translation>
 <translation id="7229975860249300121">Contiene una expresión regular que se usa para determinar qué Cuentas de Google se pueden establecer como las principales del navegador en <ph name="PRODUCT_NAME" /> (es decir, la cuenta que se elige en el proceso de aceptación de la sincronización).
@@ -6319,6 +6378,7 @@
 <translation id="7587345076013230465">Notificar al usuario que debe seleccionar el certificado de cliente cada vez que la política de selección automática coincida con varios certificados en la pantalla de acceso</translation>
 <translation id="7587921466180902617">Habilitar la prueba interna de Screencast para los usuarios de Family Link</translation>
 <translation id="759957074386651883">Configuración de Navegación segura</translation>
+<translation id="7602621823177962064">Inhabilitar los informes de la memoria del dispositivo</translation>
 <translation id="7604169113182304895">Las apps de Android pueden respetar esta lista de forma voluntaria, pero no puedes forzarlas a que lo hagan.</translation>
 <translation id="7612157962821894603">Marcas que se deben aplicar al iniciar <ph name="PRODUCT_NAME" /> en todo el sistema</translation>
 <translation id="7613115815080726221">El período sin intervención del usuario después del cual se toma una acción de inactividad (en milisegundos).</translation>
@@ -6661,6 +6721,7 @@
 <translation id="7992613144342460685">Otorgar el permiso de Ubicación de ventanas a estos sitios</translation>
 <translation id="7995610550667275367">Análisis (compatible a partir de la versión 87)</translation>
 <translation id="7999023147219236247">Esta política solicita al usuario que otorgue permisos a las apps. PERMISSION_POLICY_UNSPECIFIED: La política no está especificada. Si no se especifican políticas para un permiso en ningún nivel, se usará el comportamiento "PROMPT" de forma predeterminada. PROMPT: Le solicita al usuario que otorgue un permiso. GRANT: Otorga un permiso de forma automática. DENY: Rechaza un permiso de forma automática.</translation>
+<translation id="7999336306414770162">Inhabilitar los informes de los VPD del dispositivo</translation>
 <translation id="7999818120028621358">Habilitar la generación de informes para los eventos de prevención de filtración de datos</translation>
 <translation id="8001701200415781021">Determinar qué Cuentas de Google se pueden establecer como las principales del navegador en <ph name="PRODUCT_NAME" /></translation>
 <translation id="800595420827930383">Usar el verificador de certificados heredado de la plataforma</translation>
@@ -6711,6 +6772,7 @@
 <translation id="8056273037819805106">Se usarán las credenciales de acceso de <ph name="PRODUCT_OS_NAME" /> para la autenticación de red en un proxy administrado.</translation>
 <translation id="8056800559672904373">Una cuenta administrada debe ser una cuenta principal sin cuentas secundarias asociadas y se pueden importar datos de navegación cuando crees el perfil</translation>
 <translation id="8059164285174960932">URL donde los clientes de acceso remoto deben obtener el token de autenticación</translation>
+<translation id="8059352177830050556">Habilitar los informes de la retroiluminación del dispositivo</translation>
 <translation id="8062375903420954294">Esta política permite restringir las direcciones IP y las interfaces que utiliza WebRTC al momento de intentar encontrar la mejor conexión disponible. Consulta el RFC 8828, sección 5.2 (https://tools.ietf.org/html/rfc8828.html#section-5.2). Si no estableces la política, de forma predeterminada se utilizarán todas las interfaces disponibles.</translation>
 <translation id="8062485064082966327">Usa un servicio anónimo de Google para obtener descripciones automáticas de las imágenes sin etiquetar</translation>
 <translation id="8071371098891664137">Si eliges <ph name="PRINTERS_BLOCKLIST" /> para <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" />, la configuración de <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> especificará las impresoras que no podrán utilizar los usuarios. El usuario podrá acceder a todas las impresoras, excepto aquellas con los ID mencionados en esta política. Los ID deben coincidir con los valores de los campos <ph name="ID_FIELD" /> o <ph name="GUID_FIELD" /> en el archivo que se especifica en <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />.</translation>
@@ -7043,6 +7105,7 @@
 <translation id="8367488518695804749">No permitir que ningún sitio muestre ventanas emergentes</translation>
 <translation id="8369602308428138533">Demora de pantalla apagada con alimentación de CA</translation>
 <translation id="8371178326720637170">Habilitar las extensiones administradas para usar la API de Enterprise Hardware Platform</translation>
+<translation id="8373176843640227330">Inhabilitar los informes de Bluetooth del dispositivo</translation>
 <translation id="8375817202037102567">Bloquea el acceso de escritura a archivos y directorios en estos sitios</translation>
 <translation id="8378266419596669629">Bloquear el permiso de fuentes locales para estos sitios</translation>
 <translation id="8379317372795444261">Se permite la autenticación <ph name="BASIC_AUTH" /> en las conexiones de HTTP</translation>
@@ -7091,6 +7154,7 @@
 
        En la versión 95 de <ph name="PRODUCT_NAME" />, se quitará esta política.</translation>
 <translation id="8427466947904008809">Permitir que CRD realice solicitudes a la API de WebAuthn que se envíen al proxy a través de un host remoto</translation>
+<translation id="8428295225823548121">Habilitar los informes de la memoria del dispositivo</translation>
 <translation id="8428635849021776523">Inhabilitar los informes de Android</translation>
 <translation id="8433186206711564395">Opciones de red</translation>
 <translation id="8433769814000220721">Habilita el contenido sugerido</translation>
@@ -7521,6 +7585,7 @@
 <translation id="8882255181490012651">No permitir el acceso de los usuarios que habilitaron Phone Hub a las fotos y los videos tomados recientemente del teléfono</translation>
 <translation id="8887709920496070892">El período sin intervención del usuario después del cual se muestra un diálogo de advertencia (en milisegundos).</translation>
 <translation id="8890438048579188548">Oculta las advertencias de baja de <ph name="CLOUD_PRINT_NAME" /></translation>
+<translation id="8891334958985336685">Inhabilitar los informes del sistema del dispositivo</translation>
 <translation id="8892286064305622118">Espacio libre en disco que se requiere para <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="8892783613915541293">Retrasos y acciones que se deben tomar cuando el dispositivo esté inactivo y funcionando con CA.</translation>
 <translation id="8897796778265450949">Limita el tiempo durante el cual puede acceder sin conexión un usuario que se autenticó mediante GAIA sin SAML</translation>
@@ -7591,6 +7656,7 @@
 <translation id="8977192934280677167">Permite realizar búsquedas con el proveedor de búsqueda predeterminado a través del menú contextual</translation>
 <translation id="8983537551095611459">Configurar la lista de excepciones de ID de extensiones para el procedimiento de limpieza de las sesiones de invitados administradas y restringidas</translation>
 <translation id="8983539044126123594">Habilitar el acceso con cuentas de Google adicionales</translation>
+<translation id="8985219286836584291">Habilitar los informes del sistema del dispositivo</translation>
 <translation id="8992176907758534924">No permitir que ningún sitio muestre imágenes.</translation>
 <translation id="8994954504552592260">Habilita la migración de los dispositivos administrados por <ph name="MS_AD_NAME" /> a la administración en la nube. Esta política permite el comienzo remoto de una migración sin contacto de varios dispositivos pertenecientes a una empresa. Además, la migración será lo más transparente posible para los usuarios finales.
 
@@ -7852,6 +7918,7 @@
       Si estableces esta política como falsa, solo los usuarios presentes en <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" /> podrán acceder.
 
       Si la estableces como verdadera o no la configuras, todos los usuarios podrán acceder.</translation>
+<translation id="966425658642788645">Aplicar el comportamiento predeterminado</translation>
 <translation id="971677226939413180">La opción Imprimir como imagen no está disponible para el usuario</translation>
 <translation id="974349541138387272">Especifica la plantilla de URI del agente de resolución de DNS sobre HTTPS</translation>
 <translation id="979467274961593903">No permitir el uso de la depuración remota</translation>
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb
index cd844ca1..8faedf7 100644
--- a/components/policy/resources/policy_templates_id.xtb
+++ b/components/policy/resources/policy_templates_id.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">Mengonfigurasi lokal yang diterapkan pada layar login <ph name="PRODUCT_OS_NAME" />.
 
       Jika kebijakan ini disetel, layar login akan selalu ditampilkan dalam lokal yang diberikan oleh nilai pertama dari kebijakan ini (kebijakan didefinisikan sebagai daftar untuk kompatibilitas yang diteruskan).  Jika kebijakan ini tidak disetel atau disetel ke daftar kosong, layar login akan ditampilkan dalam lokal sesi pengguna terakhir.  Jika kebijakan ini disetel ke nilai lokal yang tidak valid, layar login akan ditampilkan di lokal alternatif (saat ini, en-US).</translation>
+<translation id="1050158007881386475">Nonaktifkan pelaporan status board perangkat</translation>
 <translation id="1052499923181221200">Kebijakan ini tidak berpengaruh kecuali jika SamlInSessionPasswordChangeEnabled ditetapkan ke true.
       Jika kebijakan tersebut ditetapkan ke true, dan kebijakan ini ditetapkan ke (misalnya) 14, berarti pengguna SAML akan diberi tahu 14 hari sebelumnya bahwa sandi mereka akan habis masa berlakunya pada tanggal tertentu.
       Selanjutnya mereka dapat segera menangani hal tersebut dengan melakukan pengubahan sandi dalam-sesi dan memperbarui sandi sebelum habis masa berlakunya.
@@ -329,6 +330,7 @@
       Jika 'Forced' (2) dipilih, pemilih profil tidak dapat disembunyikan oleh pengguna. Pemilih profil akan ditampilkan meski hanya tersedia satu profil.</translation>
 <translation id="1339174690935954950">Cegah pengguna mengirim masukan</translation>
 <translation id="1342918903685430097">Mengonfigurasi versi minimum <ph name="PRODUCT_OS_NAME" /> yang diizinkan untuk perangkat.</translation>
+<translation id="1343128241903870688">Nonaktifkan pelaporan info aplikasi perangkat</translation>
 <translation id="1347198119056266798">Kebijakan ini tidak digunakan lagi. Sebagai gantinya, gunakan <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> dan <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />. Kebijakan ini diabaikan jika salah satu dari kebijakan <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> atau <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> (tidak digunakan lagi) ditetapkan.
 
       Memaksa kueri di Google Penelusuran Web untuk dijalankan dengan SafeSearch disetel ke aktif dan mencegah pengguna mengubah setelan ini. Setelan ini juga memaksa Mode Terbatas Menengah di YouTube.
@@ -368,6 +370,7 @@
 <translation id="1393485621820363363">Mengaktifkan printer perangkat perusahaan</translation>
 <translation id="1395505489889158859">Aktifkan pengiriman nama pengguna dan nama file ke printer native</translation>
 <translation id="1397855852561539316">URL saran penyedia penelusuran default</translation>
+<translation id="1402227992519954892">Aktifkan pelaporan info aplikasi perangkat</translation>
 <translation id="141279920573530952">Menyetel kebijakan memungkinkan Anda menetapkan daftar situs yang otomatis diizinkan untuk mengakses semua port serial yang tersedia.
 
       URL harus valid. Jika tidak, kebijakan akan diabaikan. Hanya asal (skema, host, dan port) URL yang dipertimbangkan.
@@ -613,6 +616,7 @@
 <translation id="1616280227447957376">Mengizinkan untuk melanjutkan dari halaman peringatan SSL di asal tertentu</translation>
 <translation id="1617235075406854669">Aktifkan penghapusan histori download atau browser</translation>
 <translation id="1620510694547887537">Kamera</translation>
+<translation id="162162247775156979">Nonaktifkan pelaporan status penyimpanan perangkat</translation>
 <translation id="1626379196197114720">Izinkan penggunaan back-forward cache</translation>
 <translation id="1628974048137236820">Halaman Tab Baru tidak akan menampilkan kartu</translation>
 <translation id="1630263002012156148">Jika kebijakan disetel ke Aktif, halaman beranda pengguna akan menjadi halaman Tab Baru dan lokasi URL halaman beranda lain akan diabaikan. Jika kebijakan disetel ke Nonaktif, halaman beranda pengguna tidak akan pernah menjadi halaman Tab Baru, kecuali jika URL halaman beranda pengguna disetel ke chrome://newtab.
@@ -1108,6 +1112,7 @@
 <translation id="2043770014371753404">Menonaktifkan printer perusahaan</translation>
 <translation id="2057317273526988987">Izinkan akses ke daftar URL</translation>
 <translation id="2058055310819710697">Aktifkan Mode Developer Aplikasi Terisolasi</translation>
+<translation id="205807990145127714">Data telemetri yang akan dilaporkan saat peristiwa perubahan kekuatan sinyal terjadi.</translation>
 <translation id="2061123930713023976">Mengizinkan debug untuk rekaman paket jaringan</translation>
 <translation id="2061810934846663491">Mengonfigurasi nama domain wajib untuk host akses jarak jauh</translation>
 <translation id="2062632109797189011">Mengaktifkan kembali window.webkitStorageInfo API yang sudah tidak digunakan lagi</translation>
@@ -1709,8 +1714,12 @@
 <translation id="2665422249821137126">Mengaktifkan kursor besar di layar login</translation>
 <translation id="2667894101494585925">Mengaktifkan Pengambilan Panduan Pengoptimalan</translation>
 <translation id="2672012807430078509">Kontrol yang mengaktifkan NTLM sebagai protokol autentikasi untuk pemasangan SMB</translation>
+<translation id="2673363037046384711">Pengguna akhir dapat mengaktifkan atau menonaktifkan Mode Efisiensi Tinggi.</translation>
 <translation id="2678503605767349615">Sertifikat Klien seluruh perangkat yang diperlukan</translation>
 <translation id="268577405881275241">Aktifkan fitur proxy kompresi data</translation>
+<translation id="268695908564263739">Kebijakan ini mengaktifkan atau menonaktifkan setelan Mode Efisiensi Tinggi. Setelan ini membuat tab ditutup setelah jangka waktu tertentu di latar belakang untuk mengklaim kembali memori.
+      Jika kebijakan ini tidak disetel, pengguna akhir dapat mengontrol setelan ini di chrome://settings/performance.
+      </translation>
 <translation id="2691668238491124549">Jika kebijakan ditetapkan (sebagai direkomendasikan saja), lokal yang direkomendasikan untuk sesi terkelola akan dipindahkan ke daftar atas, sesuai urutan kemunculannya dalam kebijakan. Lokal yang direkomendasikan pertama sudah otomatis dipilih.
 
       Jika tidak ditetapkan, lokal UI saat ini akan otomatis dipilih.
@@ -2914,6 +2923,7 @@
 <translation id="3898345958122666461">Nonaktifkan NTLMv2</translation>
 <translation id="3898795800259311780">Mengizinkan atau menolak tangkapan layar</translation>
 <translation id="3903313632842363082">Nonaktifkan pelaporan pengguna perangkat</translation>
+<translation id="3904304709151553598">Nonaktifkan pelaporan info kipas perangkat</translation>
 <translation id="3907683835264956726">Memungkinkan login pengguna online di layar kunci. Jika kebijakan disetel ke benar (true), autentikasi ulang online di layar kunci akan dipicu, misalnya oleh <ph name="POLICY" />.
       Autentikasi ulang diterapkan segera saat di layar kunci atau di waktu berikutnya pengguna mengunci layar, setelah kondisinya terpenuhi.
       Jika kebijakan disetel ke salah (false) atau tidak disetel, pengguna akan selalu dapat membuka kunci layar dengan kredensial lokal.</translation>
@@ -2958,6 +2968,7 @@
 
           Jika kebijakan ini tidak ditetapkan, tombol lekat mula-mula akan dinonaktifkan di layar login, tetapi dapat diaktifkan oleh pengguna kapan saja.</translation>
 <translation id="3927291637826333102">Mengizinkan tangkapan Desktop, Jendela, dan Tab berdasarkan asal berikut</translation>
+<translation id="3928726028264020458">Aktifkan pelaporan info VPD perangkat</translation>
 <translation id="3943930334592166130">Kebijakan ini mengontrol apakah pengguna akan diminta memilih sertifikat klien saat lebih dari satu sertifikat cocok dengan <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" />.
       Jika kebijakan ini disetel ke Aktif, pengguna akan diminta memilih sertifikat klien setiap kali kebijakan pemilihan otomatis cocok dengan beberapa sertifikat.
       Jika kebijakan ini disetel ke Nonaktif atau tidak disetel, pengguna mungkin hanya diminta saat tidak ada sertifikat yang cocok dengan pemilihan otomatis.</translation>
@@ -3047,6 +3058,7 @@
       Di <ph name="MS_WIN_NAME" />, fungsi ini hanya tersedia di instance yang dihubungkan ke domain <ph name="MS_AD_NAME" />, dijalankan di Windows 10 Pro, atau didaftarkan di <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />. Di <ph name="MAC_OS_NAME" />, fungsi ini hanya tersedia di instance yang dikelola melalui MDM, atau dihubungkan ke domain melalui MCX.</translation>
 <translation id="4043796890723386527">Cegah pengguna membuat dan menggunakan profil sekunder serta menggunakan mode tamu di browser <ph name="LACROS_NAME" /></translation>
 <translation id="4051723201852944592">Mengaktifkan Penghalangan Jendela</translation>
+<translation id="4052529125939620019">Memuat ekstensi komponen CryptoToken saat browser dimulai</translation>
 <translation id="4053157306171963473">Nonaktifkan pelaporan waktu aktivitas perangkat</translation>
 <translation id="4056910949759281379">Nonaktifkan protokol SPDY</translation>
 <translation id="4061107397839125009">Menyetel kebijakan memungkinkan Anda menetapkan daftar pola URL yang menentukan situs yang tidak dapat menampilkan notifikasi.
@@ -3105,6 +3117,38 @@
 
       Jika kebijakan disetel, pengguna tidak dapat mengubahnya. Jika kebijakan tidak disetel, keyboard virtual mula-mula akan dinonaktifkan, tetapi pengguna dapat mengaktifkannya kapan saja.</translation>
 <translation id="412697421478384751">Izinkan pengguna menyetel PIN lemah untuk PIN layar kunci</translation>
+<translation id="4130565559631908067">Kebijakan ini memberikan cara untuk mengganti daftar set yang digunakan browser untuk fitur Set Pihak Pertama.
+
+      Setiap set dalam daftar Set Pihak Pertama browser harus memenuhi persyaratan Set Pihak Pertama.
+      Set Pihak Pertama harus berisi situs pemilik dan satu atau beberapa situs anggota.
+      Set juga dapat berisi daftar situs layanan yang dimilikinya, serta peta dari situs ke semua varian ccTLD-nya.
+      Lihat https: //github.com/WICG/first-party-sets untuk mendapatkan informasi selengkapnya terkait Set Pihak Pertama yang digunakan oleh <ph name="PRODUCT_NAME" />.
+
+      Semua situs dalam Set Pihak Pertama harus berupa domain yang dapat didaftarkan yang disalurkan melalui HTTPS. Setiap situs dalam Set Pihak Pertama juga harus unik.
+      Artinya, situs tidak dapat tercantum lebih dari sekali dalam Set Pihak Pertama.
+
+      Jika kebijakan ini diberikan kamus kosong, browser akan menggunakan daftar Set Pihak Pertama publik.
+
+      Untuk semua situs dalam Set Pihak Pertama dari daftar <ph name="REPLACEMENTS" />, jika suatu situs juga ada
+      di Set Pihak Pertama dalam daftar browser, situs tersebut akan dihapus dari Set Pihak Pertama browser.
+      Setelahnya, Set Pihak Pertama kebijakan akan ditambahkan ke daftar Set Pihak Pertama browser.
+
+      Untuk semua situs dalam Set Pihak Pertama dari daftar <ph name="ADDITIONS" />, jika suatu situs juga ada
+      di Set Pihak Pertama dalam daftar browser, Set Pihak Pertama browser akan diperbarui agar
+      Set Pihak Pertama baru dapat ditambahkan ke daftar browser. Setelah daftar browser diperbarui,
+      Set Pihak Pertama kebijakan akan ditambahkan ke daftar Set Pihak Pertama browser.
+
+      Daftar Set Pihak Pertama browser mengharuskan semua situs dalam daftarnya tidak ada yang tercantum di
+      lebih dari satu set. Ketentuan ini juga berlaku untuk daftar <ph name="REPLACEMENTS" />
+      dan daftar <ph name="ADDITIONS" />. Situs juga tidak boleh ada dalam daftar
+      <ph name="REPLACEMENTS" /> dan daftar <ph name="ADDITIONS" />.
+
+      Karakter pengganti (*) tidak didukung sebagai nilai kebijakan, ataupun di Set Pihak Pertama dalam daftar ini.
+
+      Semua set yang disediakan oleh kebijakan harus berupa Set Pihak Pertama yang valid. Jika set tidak valid,
+      error yang sesuai akan ditampilkan.
+
+      Kebijakan ini hanya tersedia pada instance Windows yang dihubungkan ke domain <ph name="MS_AD_NAME" />, atau instance Windows 10 Pro atau Enterprise yang terdaftar untuk pengelolaan perangkat, dan instance macOS yang dikelola melalui MDM atau dihubungkan ke domain melalui MCX.</translation>
 <translation id="4138655880188755661">Batas Waktu</translation>
 <translation id="4147818922357566987">Aktifkan variasi terkait perbaikan penting saja</translation>
 <translation id="4150201353443180367">Tampilan</translation>
@@ -3706,6 +3750,7 @@
       Jika kebijakan disetel ke Nonaktif atau tidak disetel, <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> akan menjadi opsional dan proses peluncuran <ph name="PRODUCT_NAME" /> tidak akan diblokir jika gagal.
 
       Pendaftaran kebijakan cloud cakupan perangkat di desktop menggunakan kebijakan ini. Lihat https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744 untuk detailnya.</translation>
+<translation id="488996881569316769">Telemetri Jaringan</translation>
 <translation id="4890453377345554695">Menyetel kebijakan memungkinkan Anda menetapkan daftar pola URL yang menentukan situs mana yang dapat meminta akses tulis ke file atau direktori di sistem file pada sistem operasi host.
 
       Tidak menyetel kebijakan berarti <ph name="DEFAULT_FILE_SYSTEM_WRITE_GUARD_SETTING_POLICY_NAME" /> akan berlaku untuk semua situs, jika disetel. Jika tidak, setelan pribadi pengguna akan berlaku.
@@ -3929,6 +3974,7 @@
 <translation id="5148753489738115745">Memungkinkan Anda menentukan parameter tambahan yang digunakan saat <ph name="PRODUCT_FRAME_NAME" /> meluncurkan <ph name="PRODUCT_NAME" />.
 
           Jika kebijakan ini tidak disetel, baris perintah default akan digunakan.</translation>
+<translation id="5151099177901233471">Aktifkan pelaporan info zona waktu perangkat</translation>
 <translation id="5152393033264257734">Izinkan pemeriksaan intersepsi DNS dan infobar "Mungkin maksud Anda http://intranetsite/".</translation>
 <translation id="5152787786897382519">Chromium dan Google Chrome memiliki beberapa grup kebijakan yang saling bergantung satu sama lain untuk memberikan kontrol terhadap fitur. Kumpulan ini ditunjukkan oleh grup kebijakan berikut. Karena kebijakan dapat memiliki beberapa sumber, hanya nilai yang berasal dari sumber dengan prioritas tertinggi yang akan diterapkan. Nilai yang berasal dari sumber dengan prioritas lebih rendah di grup yang sama akan diabaikan. Urutan prioritas ditentukan di <ph name="POLICY_PRIORITY_DOC_URL" />.</translation>
 <translation id="5153187201534281749">Ikon eksperimen browser di toolbar</translation>
@@ -4039,6 +4085,7 @@
 
       Jika tidak disetel atau tidak valid, perilaku akan sama dengan "Tunggu saluran target juga mengalami downgrade saluran rilis".</translation>
 <translation id="5229339291699779956">Mengaktifkan tunneling PCIe untuk perangkat periferal Thunderbolt/USB4, perangkat periferal akan berfungsi pada kemampuan penuh</translation>
+<translation id="5230095739094490896">Mencetak template atribut IPP 'client-name'</translation>
 <translation id="5233239004553860036">Jika kebijakan ini disetel ke <ph name="POLICY_VALUE_ALL" /> atau tidak disetel, semua penggunaan akun terkelola akan diizinkan. Hal ini dapat menyebabkan akun terkelola menjadi akun sekunder, yang hanya akan menerima kebijakan jika akun tersebut login sebagai akun utama di Profil browser.
       Kebijakan yang disetel untuk akun tidak akan diterapkan dalam skenario berikut:
         -  Menjadi akun sekunder di tingkat OS (Setelan Akun)
@@ -4070,6 +4117,7 @@
       "Versi" di sini bisa merupakan versi yang tepat seperti '61.0.3163.120' atau awalan versi, seperti '61.0'  </translation>
 <translation id="5247973380763021389">Cegah kebijakan cloud pengguna mengabaikan kebijakan cloud perangkat.</translation>
 <translation id="5249453807420671499">Pengguna dapat menambahkan akun Kerberos</translation>
+<translation id="5249555581286638799">Mengaktifkan Mode Efisiensi Tinggi</translation>
 <translation id="5252210248395576403">Kebijakan ini memberikan izin kepada fitur Jawaban Instan untuk mengakses konten yang dipilih dan mengirimkan info ke server untuk mendapatkan hasil terjemahan.
 
       Jika kebijakan ini disetel ke aktif atau tidak disetel, terjemahan Jawaban Instan akan diaktifkan.
@@ -4078,6 +4126,7 @@
 
       Jika kebijakan ditetapkan ke Salah (False) atau tidak ditetapkan, Desktop Terpadu akan dinonaktifkan dan pengguna tidak dapat mengaktifkannya.</translation>
 <translation id="5255162913209987122">Dapat Direkomendasikan</translation>
+<translation id="525543707238275321">Nonaktifkan pelaporan info CPU perangkat</translation>
 <translation id="5257395339965216304">Data aplikasi yang dihosting</translation>
 <translation id="5262320080678421295">Nonaktifkan kepercayaan pada sertifikat yang dikeluarkan oleh IKP Lama Symantec Corporation</translation>
 <translation id="5266173014392157048">Kebijakan ini tidak digunakan lagi. Sebagai gantinya, gunakan kebijakan '<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />'.
@@ -4142,6 +4191,7 @@
       Jika kebijakan ini tidak dikonfigurasi, <ph name="PRODUCT_NAME" /> akan menggunakan versi maksimum default.
 
       Jika kebijakan ini dikonfigurasi, produk dapat ditetapkan ke salah satu nilai berikut: "tls1.2" atau "tls1.3". Setelah ditetapkan, <ph name="PRODUCT_NAME" /> tidak akan menggunakan versi SSL/TLS yang lebih baru daripada versi yang ditentukan. Nilai yang tidak dikenal akan diabaikan.</translation>
+<translation id="5329018127554115226">Mode Efisiensi Tinggi akan dinonaktifkan.</translation>
 <translation id="5330684698007383292">Izinkan <ph name="PRODUCT_FRAME_NAME" /> menangani jenis konten berikut</translation>
 <translation id="5331746669335642668">Kebijakan cloud <ph name="PRODUCT_NAME" /> menggantikan kebijakan Platform.</translation>
 <translation id="5346587320074666194">Memblokir akses ke sensor di situs ini</translation>
@@ -4337,6 +4387,7 @@
       Kebijakan ini tidak berlaku untuk peralihan channel.</translation>
 <translation id="5519331583722582543">Tanda boolean menunjukkan apakah keyboard virtual dapat memberikan input melalui pengenalan tulis tangan.</translation>
 <translation id="5519619299971727565">Nonaktifkan pelaporan penggunaan aplikasi Linux</translation>
+<translation id="5521035900165046997">Aktifkan pelaporan info Bluetooth perangkat</translation>
 <translation id="5521875416764302911">Cegah pengguna login ke <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">Izinkan kueri ke Server Quirk dan file konfigurasi khusus hardware yang mungkin didownload</translation>
 <translation id="5526701598901867718">Semua (tidak aman)</translation>
@@ -4392,6 +4443,7 @@
 <translation id="5598417829613725146">Canvas (didukung sejak versi 90)</translation>
 <translation id="5599461642204007579">Setelan pengelolaan <ph name="MS_AD_NAME" /></translation>
 <translation id="5601503069213153581">PIN</translation>
+<translation id="5607021831414604820">Aktifkan pelaporan status penyimpanan perangkat</translation>
 <translation id="5614865701790130558">Membuat log peristiwa penginstalan ekstensi berdasarkan kebijakan</translation>
 <translation id="5618398258385745432">Setelan terkait digunakan sebelum autentikasi ulang saat melihat sandi diperkenalkan. Sejak saat itu, setelan dan kebijakan ini tidak berpengaruh pada perilaku Chrome. Perilaku Chrome saat ini sama seperti saat kebijakan ini ditetapkan untuk tidak menampilkan sandi dalam teks jelas di halaman setelan pengelola sandi. Artinya, halaman setelan hanya memuat placeholder, dan Chrome hanya akan menampilkan sandi setelah pengguna mengklik "Tampilkan" (dan mengautentikasi ulang, jika berlaku). Deskripsi asli untuk kebijakan ini tercantum di bawah.
 
@@ -4501,6 +4553,7 @@
       Catatan: Memulai ulang dan logout akan menghapus cache.</translation>
 <translation id="5717973246079053225">Nonaktifkan pelaporan cloud profil terkelola</translation>
 <translation id="572155275267014074">Setelan Android</translation>
+<translation id="5722577409367087850">Muat ekstensi</translation>
 <translation id="5728154254076636808">Mengaktifkan pembuatan salinan roaming untuk data profil <ph name="PRODUCT_NAME" /></translation>
 <translation id="5729308727912841256">Sandi Kerberos. Placeholder <ph name="PASSWORD_PLACEHOLDER" /> diganti dengan sandi login.</translation>
 <translation id="5732972008943405952">Mengimpor data formulir isi-otomatis dari browser default saat pertama kali dijalankan</translation>
@@ -4763,6 +4816,7 @@
       Jika kebijakan disetel ke Nonaktif, pengguna tidak dapat menukarkan penawaran ini.</translation>
 <translation id="6046615715547751255">Jangan izinkan kontrol pelaporan terperinci</translation>
 <translation id="6048199181629830227">Mengaktifkan fitur manajemen pengaktifan daya baterai</translation>
+<translation id="6049117606554031363">Aktifkan pelaporan status board perangkat</translation>
 <translation id="6053681087509103368">Izinkan WebRTC menggunakan versi protokol TLS/DTLS yang usang</translation>
 <translation id="6058879286588763839">Menyetel <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> akan menentukan kebijakan pengelolaan daya mode pengisian daya baterai (jika didukung di perangkat), kecuali <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" /> yang menggantikan <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> ditentukan. Untuk memperpanjang masa pakai baterai, kebijakan secara dinamis mengontrol pengisian daya baterai dengan meminimalkan ketegangan dan keausan.
 
@@ -4795,6 +4849,7 @@
 <translation id="6099853574908182288">Mode warna pencetakan default</translation>
 <translation id="6102342563050263313">Mengaktifkan scroll ke teks yang ditentukan di fragmen URL</translation>
 <translation id="6102449843040973938">Jangan cegah <ph name="BOREALIS_NAME" /> berjalan di perangkat</translation>
+<translation id="610892566190435199">Aktifkan pelaporan status daya perangkat</translation>
 <translation id="6111936128861357925">Izinkan Game Dinosaur Easter Egg</translation>
 <translation id="6112524153927257380">Jika kebijakan ini disetel, pengguna tidak dapat mengabaikan keputusan keamanan download.
 
@@ -4942,6 +4997,7 @@
       Kebijakan ini ditujukan untuk memberikan fleksibilitas kepada perusahaan untuk menonaktifkan sandbox audio jika menggunakan penyiapan software keamanan yang mengganggu sandbox.</translation>
 <translation id="624818583115864448">port 554 (blokir dapat dibatalkan hingga 15/10/2021)</translation>
 <translation id="6252773211180267325">Jangan cegah <ph name="BOREALIS_NAME" /> berjalan untuk pengguna</translation>
+<translation id="625580680776945310">Mode Efisiensi Tinggi akan diaktifkan.</translation>
 <translation id="6258658183356534534">Mengontrol fitur Pembaruan GREASE Petunjuk Klien Agen Pengguna.</translation>
 <translation id="6261643884958898336">Laporkan informasi Identifikasi Mesin</translation>
 <translation id="6265892395051519509">Mengizinkan akses ke sensor di situs ini</translation>
@@ -5113,6 +5169,7 @@
 <translation id="6368403635025849609">Izinkan JavaScript di situs ini</translation>
 <translation id="6371561334154580937">Tampilkan dialog logout saat jendela terakhir ditutup.</translation>
 <translation id="6372105930898423193">Mengizinkan fitur AppCache untuk diaktifkan ulang meskipun dinonaktifkan secara default</translation>
+<translation id="6373299801585455337">Aktifkan pelaporan info CPU perangkat</translation>
 <translation id="6376540107659524656">Nonaktifkan SSH di Terminal System App</translation>
 <translation id="6376659517206731212">Bisa Jadi Wajib</translation>
 <translation id="6377031865393559909">Izinkan pengguna menggunakan template desktop</translation>
@@ -5120,6 +5177,7 @@
 <translation id="6378393933102834628">Jika kebijakan ditetapkan ke Benar (True), pintasan aplikasi akan ditampilkan. Jika kebijakan ditetapkan ke Salah (False), pintasan tidak akan pernah muncul.
 
       Jika Anda menetapkan kebijakan, pengguna tidak dapat mengubahnya. Jika tidak ditetapkan, pengguna perlu menentukan untuk menampilkan atau menyembunyikan pintasan aplikasi dari menu konteks kolom bookmark.</translation>
+<translation id="638003144128412430">Nonaktifkan pelaporan info zona waktu perangkat</translation>
 <translation id="6382351416269252693">Menetapkan daftar pola URL situs yang menentukan situs yang akan otomatis menolak izin font lokal. Hal ini akan membatasi kemampuan situs untuk melihat informasi tentang font lokal.
 
       Untuk informasi selengkapnya tentang pola URL situs yang valid, lihat https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. Karakter pengganti, <ph name="WILDCARD_VALUE" />, diizinkan. Kebijakan ini hanya mencocokkan berdasarkan asal, sehingga jalur apa pun di pola URL akan diabaikan.
@@ -5166,6 +5224,7 @@
 <translation id="6440051664870270040">Izinkan situs menavigasi dan membuka (jendela) pop-up sekaligus</translation>
 <translation id="6447948611083700881">Opsi pencadangan dan pemulihan dinonaktifkan</translation>
 <translation id="6449476513004303784">Jangan izinkan pengguna mengelola sertifikat</translation>
+<translation id="6452882999388592166">Jika disetel ke Aktif, ekstensi komponen CryptoToken bawaan akan dimuat saat browser dimulai. Jika disetel ke Nonaktif atau tidak disetel, CryptoToken tidak akan dimuat saat browser dimulai. Kebijakan ini dimaksudkan sebagai solusi sementara untuk situs yang rusak karena `chrome.runtime` tidak ditentukan sebagai efek samping penghapusan CryptoToken di M106. Situs tidak boleh bergantung pada `chrome.runtime` yang ditentukan tanpa syarat.</translation>
 <translation id="6453641799812499182">Mengaktifkan mitigasi pemeriksaan <ph name="CORS" /> dalam implementasi <ph name="CORS" /> yang baru</translation>
 <translation id="645425387487868471">Aktifkan login paksa untuk <ph name="PRODUCT_NAME" /></translation>
 <translation id="6455842857207956758">Mengaktifkan sinkronisasi sandi SAML antara beberapa perangkat Chrome dengan memantau nilai token sinkronisasi sandi dan mengirimkan autentikasi ulang kepada pengguna secara online jika sandi diperbarui dan perlu disinkronkan.
@@ -5240,6 +5299,7 @@
 <translation id="6506486086262398387">Menyetel kebijakan ke Aktif berarti fitur Berbagi File Jaringan untuk <ph name="PRODUCT_OS_NAME" /> akan menggunakan NTLM sebagai autentikasi untuk berbagi SMB jika perlu. Jika kebijakan disetel ke Nonaktif, autentikasi NTLM untuk berbagi SMB akan dinonaktifkan.
 
       Jika kebijakan tidak disetel, perilaku default akan dinonaktifkan bagi pengguna terkelola dan aktif bagi pengguna lainnya.</translation>
+<translation id="6513453889192806240">Latensi HTTPS</translation>
 <translation id="6515357889978918016">Gambar <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="6518102411616460786">Tunggu saluran target juga mengalami downgrade saluran rilis</translation>
 <translation id="6520802717075138474">Impor mesin telusur dari browser default saat pertama kali dijalankan</translation>
@@ -5509,6 +5569,12 @@
 
       Jika kebijakan ditetapkan ke salah (false) atau tidak ditetapkan, <ph name="PLUGIN_VM_NAME" /> tidak akan diaktifkan untuk pengguna tersebut.
       Jika ditetapkan ke benar (true), <ph name="PLUGIN_VM_NAME" /> akan diaktifkan untuk pengguna tersebut selama setelan lain mengizinkannya. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> dan <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" /> harus ditetapkan ke benar (true), dan <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> atau <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" /> harus ditetapkan agar <ph name="PLUGIN_VM_NAME" /> dapat berjalan.</translation>
+<translation id="6750902920405577210">Daftar data telemetri yang akan dilaporkan saat peristiwa perubahan kekuatan sinyal terjadi.
+
+      Setiap data telemetri yang ditentukan hanya akan dilaporkan jika data tersebut tidak dinonaktifkan oleh kebijakan kontrolnya.
+      Kebijakan kontrol untuk https_latency dan network_telemetry adalah ReportDeviceNetworkStatus.
+
+      Jika tidak disetel, tidak ada data telemetri tambahan yang akan dilaporkan saat peristiwa perubahan kekuatan sinyal terjadi.</translation>
 <translation id="6752711782954612641">Jika <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> aktif, menyetel <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> akan menentukan parameter saat menelusuri URL dengan POST. Kebijakan terdiri dari pasangan nama kunci yang dipisahkan koma. Jika nilai adalah parameter template seperti <ph name="SEARCH_TERM_MARKER" />, data istilah penelusuran nyata akan menggantikannya.
 
       Jika <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> tidak disetel, permintaan penelusuran akan dikirimkan menggunakan metode GET.</translation>
@@ -5647,6 +5713,7 @@
 <translation id="6903814433019432303">Kebijakan ini aktif dalam mode eceran saja.
 
       Menentukan kumpulan URL yang akan dimuat saat sesi demo dimulai. Kebijakan ini mengganti mekanisme lain untuk menyetel URL awal, sehingga hanya dapat diterapkan ke sesi yang tidak terkait dengan pengguna tertentu.</translation>
+<translation id="6903818804346914108">Aktifkan pelaporan info kipas perangkat</translation>
 <translation id="6905405893096403868">Menyetel kebijakan ke daftar string artinya setiap string akan diteruskan ke browser alternatif sebagai parameter command line yang berbeda. Pada <ph name="MS_WIN_NAME" />, parameter digabungkan dengan spasi. Pada <ph name="MAC_OS_NAME" /> dan <ph name="LINUX_OS_NAME" />, parameter dapat berisi spasi dan masih diperlakukan sebagai parameter tunggal.
 
       Jika parameter berisi <ph name="URL_PLACEHOLDER" />, <ph name="URL_PLACEHOLDER" /> akan diganti dengan URL halaman yang akan dibuka. Jika tidak ada parameter yang berisi <ph name="URL_PLACEHOLDER" />, URL akan ditambahkan di akhir command line.
@@ -5949,6 +6016,7 @@
 <translation id="718126088895133062">Kebijakan ini menetapkan ID pengguna lisensi <ph name="PLUGIN_VM_NAME" /> untuk perangkat ini.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">Gunakan layanan web Google untuk membantu mengatasi kesalahan ejaan</translation>
+<translation id="7187248416163189586">Nonaktifkan pelaporan info lampu latar perangkat</translation>
 <translation id="718850220532931090">Kebijakan ini tidak digunakan lagi. Sebagai gantinya, gunakan <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />.
 
       Menyetel kebijakan akan menentukan ekstensi yang diizinkan untuk menggunakan <ph name="CHALLENGE_USER_KEY_FUNCTION" /> fungsi <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> untuk pengesahan jarak jauh. Ekstensi harus ada dalam daftar ini agar dapat menggunakan API.
@@ -5971,6 +6039,7 @@
 <translation id="7207095846245296855">Paksa Google SafeSearch</translation>
 <translation id="7211368186050418507">Jangan pernah deteksi otomatis zona waktu</translation>
 <translation id="7216442368414164495">Memungkinkan pengguna ikut serta dalam pelaporan yang diperluas Safe Browsing</translation>
+<translation id="721970071627370558">Nonaktifkan pelaporan status daya perangkat</translation>
 <translation id="7221574724100909818">Gunakan ikon gembok untuk koneksi aman</translation>
 <translation id="7229365071755865554">Aktifkan penyimpanan sandi menggunakan pengelola sandi</translation>
 <translation id="7229975860249300121">Berisi ekspresi reguler yang digunakan untuk menentukan akun Google mana yang dapat disetel sebagai akun utama browser di <ph name="PRODUCT_NAME" /> (akun yang dipilih selama alur keikutsertaan Sinkronisasi).
@@ -6328,6 +6397,7 @@
 <translation id="7587345076013230465">Minta pengguna memilih sertifikat klien setiap kali kebijakan pemilihan otomatis cocok dengan beberapa sertifikat di layar login</translation>
 <translation id="7587921466180902617">Aktifkan dogfood Screencast untuk pengguna Family Link</translation>
 <translation id="759957074386651883">Setelan Safe Browsing</translation>
+<translation id="7602621823177962064">Nonaktifkan pelaporan info memori perangkat</translation>
 <translation id="7604169113182304895">Aplikasi Android dapat memilih untuk menerima daftar ini secara sukarela. Anda tidak dapat memaksa aplikasi untuk menerimanya.</translation>
 <translation id="7612157962821894603">Tanda di seluruh sistem yang akan diterapkan pada waktu mulai <ph name="PRODUCT_NAME" /></translation>
 <translation id="7613115815080726221">Durasi waktu tanpa input pengguna sebelum tindakan tidak ada aktivitas dilakukan, dalam milidetik.</translation>
@@ -6670,6 +6740,7 @@
 <translation id="7992613144342460685">Memberikan izin Penempatan Jendela di situs ini</translation>
 <translation id="7995610550667275367">Pemindaian (didukung sejak versi 87)</translation>
 <translation id="7999023147219236247">Kebijakan untuk memberikan izin permintaan ke aplikasi. PERMISSION_POLICY_UNSPECIFIED: Kebijakan tidak ditentukan. Jika tidak ada kebijakan yang ditentukan untuk izin di tingkat mana pun, perilaku `PROMPT` akan digunakan secara default. PROMPT: Meminta pengguna memberikan izin. GRANT: Otomatis memberikan izin. DENY: Otomatis menolak izin.</translation>
+<translation id="7999336306414770162">Nonaktifkan pelaporan info VPD perangkat</translation>
 <translation id="7999818120028621358">Aktifkan pelaporan peristiwa pencegahan kebocoran data</translation>
 <translation id="8001701200415781021">Batasi akun Google mana yang diizinkan untuk disetel sebagai akun utama browser di <ph name="PRODUCT_NAME" /></translation>
 <translation id="800595420827930383">Gunakan pemverifikasi sertifikat platform lama</translation>
@@ -6720,6 +6791,7 @@
 <translation id="8056273037819805106">Kredensial login <ph name="PRODUCT_OS_NAME" /> akan digunakan untuk autentikasi jaringan ke proxy terkelola.</translation>
 <translation id="8056800559672904373">Akun terkelola harus berupa akun utama yang tidak memiliki akun sekunder, dan pengguna dapat mengimpor data penjelajahan yang ada pada saat pembuatan profilnya</translation>
 <translation id="8059164285174960932">URL tempat klien akses jarak jauh seharusnya memperoleh token autentikasi mereka</translation>
+<translation id="8059352177830050556">Aktifkan pelaporan info lampu latar perangkat</translation>
 <translation id="8062375903420954294">Kebijakan ini memungkinkan pembatasan alamat IP dan antarmuka yang dapat digunakan oleh WebRTC saat mencoba menemukan koneksi terbaik yang tersedia. Lihat RFC 8828 bagian 5.2 (https://tools.ietf.org/html/rfc8828.html#section-5.2). Jika tidak disetel, semua antarmuka yang tersedia akan digunakan secara default.</translation>
 <translation id="8062485064082966327">Gunakan layanan Google anonim untuk memberikan deskripsi otomatis untuk gambar tanpa label</translation>
 <translation id="8071371098891664137">Jika <ph name="PRINTERS_BLOCKLIST" /> dipilih untuk <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" />, menyetel <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> akan menentukan printer yang tidak dapat digunakan oleh pengguna. Semua printer diberikan kepada pengguna kecuali ID yang tercantum dalam kebijakan ini. ID harus sesuai dengan kolom <ph name="ID_FIELD" /> atau <ph name="GUID_FIELD" /> dalam file yang ditentukan di <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />.</translation>
@@ -7042,6 +7114,7 @@
 <translation id="8367488518695804749">Jangan izinkan situs mana pun menampilkan pop-up</translation>
 <translation id="8369602308428138533">Penundaan mematikan layar saat menggunakan daya AC</translation>
 <translation id="8371178326720637170">Memungkinkan ekstensi terkelola untuk menggunakan Enterprise Hardware Platform API</translation>
+<translation id="8373176843640227330">Nonaktifkan pelaporan info Bluetooth perangkat</translation>
 <translation id="8375817202037102567">Blokir akses tulis ke file dan direktori di situs ini</translation>
 <translation id="8378266419596669629">Memblokir izin Font Lokal di situs ini</translation>
 <translation id="8379317372795444261">Autentikasi <ph name="BASIC_AUTH" /> diizinkan di koneksi HTTP</translation>
@@ -7090,6 +7163,7 @@
 
        Kebijakan ini akan dihapus dari <ph name="PRODUCT_NAME" /> versi 95.</translation>
 <translation id="8427466947904008809">Izinkan CRD mengeksekusi permintaan WebAuthn API yang di-proxy dari host jarak jauh.</translation>
+<translation id="8428295225823548121">Aktifkan pelaporan info memori perangkat</translation>
 <translation id="8428635849021776523">Nonaktifkan pelaporan Android</translation>
 <translation id="8433186206711564395">Setelan jaringan</translation>
 <translation id="8433769814000220721">Mengaktifkan Konten yang Disarankan</translation>
@@ -7282,6 +7356,18 @@
 
       Jika kebijakan ditetapkan ke false, tidak ada tab yang akan dibekukan.</translation>
 <translation id="8619748440665904084">Nonaktifkan impor data formulir isi otomatis saat browser pertama kali dijalankan</translation>
+<translation id="8620103780247748230">Kebijakan ini mengontrol nilai atribut IPP (Internet Printing Protocol) <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> dalam tugas pencetakan.
+
+      Menyetel kebijakan ke string akan mengakibatkan penambahan item <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> tambahan ke setiap tugas pencetakan. Anggota <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> dari item <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> yang ditambahkan akan disetel ke nilai kebijakan setelah substitusi variabel.
+
+      Variabel yang didukung adalah <ph name="DIRECTORY_ID_PLACEHOLDER" />, <ph name="SERIAL_NUMBER_PLACEHOLDER" />, <ph name="ASSET_ID_PLACEHOLDER" />, <ph name="ANNOTATED_LOCATION_PLACEHOLDER" />, <ph name="USER_EMAIL_PLACEHOLDER" />, <ph name="USER_EMAIL_NAME_PLACEHOLDER" />, <ph name="USER_EMAIL_DOMAIN" />. Variabel placeholder yang tidak didukung tidak akan diperluas.
+
+      Nilai yang dihasilkan setelah substitusi variabel dianggap valid jika hanya terdiri dari karakter <ph name="ASCII" /> yang dapat dicetak dan panjangnya tidak melebihi 255.
+
+      Perlu diketahui, karena alasan privasi, kebijakan ini hanya berlaku saat berkomunikasi dengan printer menggunakan protokol <ph name="IPPS_PROTOCOL" />, <ph name="HTTPS_PROTOCOL" />, <ph name="USB_PROTOCOL" />, atau <ph name="IPP_USB_PROTOCOL" />. Perlu diketahui juga bahwa kebijakan ini hanya berlaku untuk printer yang mendukung <ph name="CLIENT_NAME_IPP_ATTRIBUTE" />.
+
+      Jika kebijakan ini disetel ke nilai kosong atau yang tidak valid atau tidak disetel, <ph name="CLIENT_INFO_PLACEHOLDER" /> tambahan tidak akan ditambahkan ke permintaan tugas pencetakan.
+      </translation>
 <translation id="8623672932476443039">Jika kebijakan disetel ke Aktif, pengguna akan dapat mengakses Mode Developer untuk Aplikasi Terisolasi.
       Jika kebijakan disetel ke Nonaktif, pengguna tidak dapat mengakses kemampuan tersebut.
       Jika kebijakan ini tidak disetel, secara default pengguna yang dikelola perusahaan tidak akan diizinkan di ChromeOS dan semua pengguna serta OS lainnya akan diizinkan.</translation>
@@ -7508,6 +7594,7 @@
 <translation id="8882255181490012651">Melarang pengguna yang telah mengizinkan Phone Hub mengakses foto dan video yang terakhir diambil di ponselnya</translation>
 <translation id="8887709920496070892">Durasi waktu tanpa input pengguna sebelum dialog peringatan ditampilkan, dalam milidetik.</translation>
 <translation id="8890438048579188548">Sembunyikan peringatan <ph name="CLOUD_PRINT_NAME" /> tidak digunakan lagi</translation>
+<translation id="8891334958985336685">Nonaktifkan pelaporan info sistem perangkat</translation>
 <translation id="8892286064305622118">Perlu ruang disk kosong untuk <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="8892783613915541293">Penundaan dan tindakan yang harus diambil saat perangkat tidak beraktivitas dan menggunakan daya AC.</translation>
 <translation id="8897796778265450949">Membatasi waktu bagi pengguna yang diautentikasi melalui GAIA tanpa SAML untuk dapat login secara offline</translation>
@@ -7578,6 +7665,7 @@
 <translation id="8977192934280677167">Mengizinkan akses menu konteks penyedia penelusuran default</translation>
 <translation id="8983537551095611459">Mengonfigurasi daftar ID ekstensi yang dikecualikan dari prosedur pembersihan sesi tamu terkelola yang dibatasi.</translation>
 <translation id="8983539044126123594">Aktifkan login dengan Akun Google tambahan</translation>
+<translation id="8985219286836584291">Aktifkan pelaporan info sistem perangkat</translation>
 <translation id="8992176907758534924">Jangan izinkan situs apa pun menampilkan gambar</translation>
 <translation id="8994954504552592260">Mengaktifkan migrasi perangkat yang dikelola <ph name="MS_AD_NAME" /> ke pengelolaan cloud. Kebijakan ini memungkinkan migrasi nirsentuh beberapa perangkat di perusahaan untuk dimulai dari jarak jauh. Selain itu, proses migrasi akan dibuat setransparan mungkin bagi pengguna akhir.
 
@@ -7838,6 +7926,7 @@
       Jika kebijakan ini disetel ke salah (false), hanya pengguna yang ada di <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" /> yang dapat login.
 
       Jika kebijakan ini disetel ke benar (true) atau tidak dikonfigurasi, semua pengguna akan dapat login.</translation>
+<translation id="966425658642788645">Terapkan perilaku default</translation>
 <translation id="971677226939413180">Opsi Cetak sebagai gambar tidak tersedia bagi pilihan pengguna.</translation>
 <translation id="974349541138387272">Menentukan template URI pada resolver DNS-over-HTTPS yang diinginkan</translation>
 <translation id="979467274961593903">Jangan izinkan penggunaan proses debug jarak jauh</translation>
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb
index bf7dfc26..df9965d 100644
--- a/components/policy/resources/policy_templates_it.xtb
+++ b/components/policy/resources/policy_templates_it.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">Consente di configurare la lingua da utilizzare per la schermata di accesso di <ph name="PRODUCT_OS_NAME" />.
 
       Se questa norma viene impostata, la schermata di accesso verrà sempre visualizzata nella lingua stabilita dal primo valore di questa norma (la norma viene definita come elenco per la compatibilità con le versioni successive). Se la norma non viene impostata o se viene impostato un elenco vuoto, la schermata di accesso verrà visualizzata nella lingua dell'ultima sessione utente. Se la norma viene impostata su un valore non corrispondente a una lingua valida, la schermata di accesso verrà visualizzata in una lingua di riserva (attualmente en-US).</translation>
+<translation id="1050158007881386475">Disattiva i report sullo stato della scheda del dispositivo</translation>
 <translation id="1052499923181221200">Questo criterio non ha effetti a meno che SamlInSessionPasswordChangeEnabled sia impostato su true.
       Se quel criterio è impostato su true e questo criterio è impostato su (ad esempio) 14, significa che gli utenti SAML riceveranno una notifica che li informa con 14 giorni di anticipo che la password scadrà in una determinata data.
       Quindi, gli utenti possono organizzarsi immediatamente, modificare la password all'interno della sessione e aggiornarla prima della scadenza.
@@ -330,6 +331,7 @@
       Se è selezionata l'opzione "Forzato" (2), il selettore profilo non può essere eliminato dall'utente. Il selettore profilo sarà mostrato anche se c'è un solo profilo disponibile.</translation>
 <translation id="1339174690935954950">Impedisci agli utenti di inviare feedback</translation>
 <translation id="1342918903685430097">Configura la versione minima di <ph name="PRODUCT_OS_NAME" /> consentita per il dispositivo.</translation>
+<translation id="1343128241903870688">Disattiva i report sulle informazioni relative alle app del dispositivo</translation>
 <translation id="1347198119056266798">Questa norma è obsoleta, al suo posto usa <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> e <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />. Questa norma viene ignorata se sono impostate le norme <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> o la norma (obsoleta) <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" />.
 
       Forza l'esecuzione delle query in Ricerca Google con l'opzione SafeSearch attiva e impedisce agli utenti di modificare questa impostazione. Questa impostazione forza anche il livello medio della Modalità con restrizioni su YouTube.
@@ -369,6 +371,7 @@
 <translation id="1393485621820363363">Stampanti aziendali associate ai dispositivi attive</translation>
 <translation id="1395505489889158859">Viene attivato l'invio di nome utente e nome file alle stampanti native</translation>
 <translation id="1397855852561539316">URL di suggerimento del provider di ricerca predefinito</translation>
+<translation id="1402227992519954892">Attiva i report sulle informazioni relative alle app del dispositivo</translation>
 <translation id="141279920573530952">La configurazione del criterio consente di elencare i siti a cui viene concessa automaticamente l'autorizzazione ad accedere a tutte le porte seriali disponibili.
 
       Se gli URL non sono validi, il criterio viene ignorato. Viene considerata soltanto l'origine (schema, host e porta) dell'URL.
@@ -614,6 +617,7 @@
 <translation id="1616280227447957376">Consenti di proseguire dalla pagina di avviso SSL su origini specifiche</translation>
 <translation id="1617235075406854669">Attiva eliminazione cronologia del browser e dei download</translation>
 <translation id="1620510694547887537">Fotocamera</translation>
+<translation id="162162247775156979">Disattiva i report sullo stato dello spazio di archiviazione del dispositivo</translation>
 <translation id="1626379196197114720">Consenti uso della cache back-forward</translation>
 <translation id="1628974048137236820">La pagina Nuova scheda non mostra schede</translation>
 <translation id="1630263002012156148">Se il criterio viene impostato su Attivato, la pagina Nuova scheda viene impostata come pagina iniziale dell'utente e l'eventuale URL della pagina iniziale specificato viene ignorato. Se viene impostato su Disattivato, la pagina iniziale dell'utente non sarà mai la pagina Nuova scheda, a meno che chrome://newtab venga impostato come URL della pagina iniziale dell'utente.
@@ -1705,8 +1709,12 @@
 <translation id="2665422249821137126">Attiva il puntatore grande nella schermata di accesso</translation>
 <translation id="2667894101494585925">Attiva il recupero della guida all'ottimizzazione</translation>
 <translation id="2672012807430078509">Controlla l'attivazione del protocollo di autenticazione NTLM per i montaggi SMB</translation>
+<translation id="2673363037046384711">L'utente finale può attivare o disattivare la modalità ad alta efficienza.</translation>
 <translation id="2678503605767349615">Certificati client a livello di dispositivo richiesti</translation>
 <translation id="268577405881275241">Attiva la funzione proxy di compressione dei dati</translation>
+<translation id="268695908564263739">Questo criterio attiva o disattiva l'impostazione della modalità ad alta efficienza. Questa impostazione fa sì che le schede vengano chiuse dopo un certo periodo di tempo in background per recuperare memoria.
+      Se questo criterio non è impostato, l'utente finale può controllare questa impostazione all'indirizzo chrome://settings/performance.
+      </translation>
 <translation id="2691668238491124549">Se questo criterio viene impostato (come consigliato), le lingue consigliate per una sessione gestita vengono spostate in cima all'elenco, nell'ordine di visualizzazione nel criterio. La prima lingua consigliata è preselezionata.
 
       Se il criterio non viene impostato, viene preselezionata la lingua attuale dell'interfaccia utente.
@@ -2906,6 +2914,7 @@
 <translation id="3898345958122666461">Disattiva NTLMv2</translation>
 <translation id="3898795800259311780">Consenti o nega acquisizione schermo</translation>
 <translation id="3903313632842363082">Disattiva i report sugli utenti del dispositivo</translation>
+<translation id="3904304709151553598">Disattiva i report sulle informazioni relative alla ventola del dispositivo</translation>
 <translation id="3907683835264956726">Consente l'accesso online degli utenti in una schermata di blocco. Se il criterio viene impostato su true, la riautenticazione online nella schermata di blocco viene attivata, ad esempio, tramite il criterio <ph name="POLICY" />.
       La riautenticazione viene applicata subito quando è visualizzata la schermata di blocco o la volta successiva che l'utente blocca lo schermo dopo che viene soddisfatta la condizione.
       Se il criterio viene impostato su false o non viene impostato, gli utenti possono sbloccare in qualsiasi momento lo schermo con le proprie credenziali locali.</translation>
@@ -2949,6 +2958,7 @@
 
           Se questo criterio non viene impostato, inizialmente i tasti permanenti sono disattivati nella schermata di accesso, ma l'utente può attivarli in qualsiasi momento.</translation>
 <translation id="3927291637826333102">Consenti acquisizione schermate desktop, schede e finestre in base a queste origini</translation>
+<translation id="3928726028264020458">Attiva i report sulle informazioni VPD del dispositivo</translation>
 <translation id="3943930334592166130">Questo criterio controlla se all'utente viene richiesto di selezionare un certificato client quando più certificati corrispondono a <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" />.
       Se il criterio viene impostato su Attivato, all'utente viene richiesto di selezionare un certificato client quando il criterio di selezione automatica corrisponde a più certificati.
       Se viene impostato su Disattivato o se non viene configurato, all'utente può essere richiesta la selezione solo quando nessun certificato corrisponde alla selezione automatica.</translation>
@@ -3038,6 +3048,7 @@
       Su <ph name="MS_WIN_NAME" />, questa funzionalità è disponibile soltanto sulle istanze che fanno parte di un dominio <ph name="MS_AD_NAME" />, sono in esecuzione su Windows 10 Pro o sono registrate in <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />. Su <ph name="MAC_OS_NAME" />, questa funzionalità è disponibile soltanto nelle istanze gestite tramite MDM o aggiunte a un dominio tramite MCX.</translation>
 <translation id="4043796890723386527">Impedisci agli utenti di creare e usare profili secondari e di utilizzare la modalità ospite nel browser <ph name="LACROS_NAME" /></translation>
 <translation id="4051723201852944592">Attiva Copertura finestra</translation>
+<translation id="4052529125939620019">Carica l'estensione del componente CryptoToken all'avvio</translation>
 <translation id="4053157306171963473">Disattiva i report sul tempo di attività del dispositivo</translation>
 <translation id="4056910949759281379">Disabilita protocollo SPDY</translation>
 <translation id="4061107397839125009">La configurazione del criterio consente di impostare un elenco di pattern URL che specificano i siti che non possono mostrare notifiche.
@@ -3096,6 +3107,38 @@
 
       Se il criterio viene configurato, gli utenti non possono modificarlo. Se non viene configurato, la tastiera sullo schermo è disattivata all'inizio, ma gli utenti possono attivarla in qualsiasi momento.</translation>
 <translation id="412697421478384751">Consenti agli utenti di impostare PIN non sicuri per la schermata di blocco</translation>
+<translation id="4130565559631908067">Questo criterio fornisce un modo per eseguire l'override dell'elenco di insiemi che il browser utilizza per le funzionalità degli insiemi proprietari.
+
+      Ogni insieme nell'elenco di insiemi proprietari del browser deve soddisfare i requisiti di un insieme proprietario.
+      Un insieme proprietario deve contenere un sito proprietario e uno o più siti membri.
+      Un insieme può anche contenere un elenco di siti di servizi di sua proprietà, nonché una mappa di un sito a tutte le sue varianti ccTLD.
+      Consulta la pagina https: //github.com/WICG/first-party-sets per maggiori informazioni sugli insiemi proprietari che vengono utilizzati da <ph name="PRODUCT_NAME" />.
+
+      Tutti i siti di un insieme proprietario devono avere un dominio registrabile pubblicato su HTTPS. Ciascun sito di un insieme proprietario deve anche essere univoco,
+      ovvero non può essere elencato più di una volta in un insieme proprietario.
+
+      Quando a questo criterio viene dato un dizionario vuoto, il browser utilizza l'elenco pubblico di insiemi proprietari.
+
+      Per tutti i siti in un insieme proprietario dell'elenco <ph name="REPLACEMENTS" />, se un sito è presente anche
+      in un insieme proprietario nell'elenco del browser, quel sito verrà rimosso dall'insieme proprietario del browser.
+      Dopodiché, l'insieme proprietario del criterio verrà aggiunto all'elenco di insiemi proprietari del browser.
+
+      Per tutti i siti in un insieme proprietario dell'elenco <ph name="ADDITIONS" />, se un sito è presente anche
+      in un insieme proprietario nell'elenco del browser, l'insieme proprietario del browser verrà aggiornato in modo che il
+      nuovo insieme proprietario possa essere aggiunto all'elenco del browser. Una volta aggiornato l'elenco del browser,
+      l'insieme proprietario del criterio verrà aggiunto all'elenco di insiemi proprietari del browser.
+
+      L'elenco di insiemi proprietari del browser richiede che nessuno dei siti al suo interno
+      sia presente in più di un insieme. Questo requisito è valido anche per gli elenchi <ph name="REPLACEMENTS" />
+      e <ph name="ADDITIONS" />. In modo simile, un sito non può essere presente in entrambi gli elenchi
+      <ph name="REPLACEMENTS" /> e <ph name="ADDITIONS" />.
+
+      I caratteri jolly (*) non sono supportati come valore del criterio, neppure all'interno di un insieme proprietario in questi elenchi.
+
+      Tutti gli insiemi forniti da questo criterio devono essere insiemi proprietario validi. Qualora non lo fossero, verrà segnalato
+      un errore adeguato.
+
+      Questo criterio è disponibile esclusivamente per le istanze di Windows aggiunte a un dominio <ph name="MS_AD_NAME" />, per le istanze di Windows 10 Pro o Enterprise registrate per la gestione dei dispositivi e per le istanze di macOS gestite tramite MDM o aggiunte a un dominio tramite MCX.</translation>
 <translation id="4138655880188755661">Limite di tempo</translation>
 <translation id="4147818922357566987">Attiva solo le varianti relative alle correzioni critiche</translation>
 <translation id="4150201353443180367">Display</translation>
@@ -3909,6 +3952,7 @@
 <translation id="5148753489738115745">Consente di specificare dei parametri aggiuntivi da utilizzare quando <ph name="PRODUCT_FRAME_NAME" /> avvia <ph name="PRODUCT_NAME" />.
 
 Se questa norma non viene impostata viene utilizzata la riga di comando predefinita.</translation>
+<translation id="5151099177901233471">Attiva i report sulle informazioni relative al fuso orario del dispositivo</translation>
 <translation id="5152393033264257734">Consenti controlli dell'intercettazione DNS e barre di informazioni "http://intranetsite/" alternative</translation>
 <translation id="5152787786897382519">Chromium e Google Chrome hanno alcuni gruppi di criteri che dipendono gli uni dagli altri per fornire il controllo di una funzionalità. Questi insiemi sono rappresentati dai seguenti gruppi di criteri. Dato che i criteri possono avere diverse origini, vengono applicati soltanto i valori provenienti dall'origine con la priorità massima. I valori dello stesso gruppo provenienti da un'origine con priorità inferiore vengono ignorati. L'ordine di priorità è definito in <ph name="POLICY_PRIORITY_DOC_URL" />.</translation>
 <translation id="5153187201534281749">Icona degli esperimenti del browser nella barra degli strumenti</translation>
@@ -4051,6 +4095,7 @@
       Per "versione" si intende sia una versione esatta, ad esempio "61.0.3163.120", sia un prefisso di versione, ad esempio "61.0".  </translation>
 <translation id="5247973380763021389">Impedisci ai criteri relativi al cloud degli utenti di eseguire l'override dei criteri relativi al cloud delle macchine.</translation>
 <translation id="5249453807420671499">Gli utenti possono aggiungere account Kerberos</translation>
+<translation id="5249555581286638799">Attiva la modalità ad alta efficienza</translation>
 <translation id="5252210248395576403">Questo criterio consente di autorizzare Risposte rapide ad accedere ai contenuti selezionati e a inviare le informazioni al server per ricevere i risultati della traduzione.
 
       Se il criterio è attivato o non impostato, la funzionalità di traduzione di Risposte rapide sarà attiva.
@@ -4059,6 +4104,7 @@
 
       Se il criterio viene impostato su False o non viene impostato, la modalità Desktop unificato viene disattivata e gli utenti non possono attivarla.</translation>
 <translation id="5255162913209987122">Può essere consigliata</translation>
+<translation id="525543707238275321">Disattiva i report sulle informazioni relative alla CPU del dispositivo</translation>
 <translation id="5257395339965216304">Dati app ospitate</translation>
 <translation id="5262320080678421295">Disattiva attendibilità nei certificati emessi dall'Infrastruttura a chiave pubblica precedente di Symantec Corporation</translation>
 <translation id="5266173014392157048">Questo criterio è deprecato. Utilizza il criterio "<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />".
@@ -4123,6 +4169,7 @@
       Se questa norma non viene configurata, <ph name="PRODUCT_NAME" /> utilizza la versione massima predefinita.
 
       . In caso contrario, potrebbe essere impostato uno dei seguenti valori: "tls1.2" o "tls1.3". Se questa norma viene impostata, <ph name="PRODUCT_NAME" /> non utilizzerà versioni SSL/TLS successive a quella specificata. I valori non riconosciuti verranno ignorati.</translation>
+<translation id="5329018127554115226">La modalità ad alta efficienza verrà disattivata.</translation>
 <translation id="5330684698007383292">Consenti a <ph name="PRODUCT_FRAME_NAME" /> di gestire i seguenti tipi di contenuti</translation>
 <translation id="5331746669335642668">La norma relativa al cloud <ph name="PRODUCT_NAME" /> esegue l'override della norma relativa alla piattaforma.</translation>
 <translation id="5346587320074666194">Blocca l'accesso ai sensori su questi siti</translation>
@@ -4318,6 +4365,7 @@
       Questo criterio non viene applicato agli switch del canale.</translation>
 <translation id="5519331583722582543">Un flag booleano che indica se la tastiera sullo schermo può offrire la funzionalità di inserimento tramite riconoscimento della scrittura a mano libera.</translation>
 <translation id="5519619299971727565">Disattiva la generazione di report sull'utilizzo delle app Linux</translation>
+<translation id="5521035900165046997">Attiva i report sulle informazioni Bluetooth del dispositivo</translation>
 <translation id="5521875416764302911">Impedisci agli utenti di accedere a <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">Consenti le query a Quirks Server e il download di file di configurazione specifici per l'hardware</translation>
 <translation id="5526701598901867718">Tutto (non sicuro)</translation>
@@ -4373,6 +4421,7 @@
 <translation id="5598417829613725146">Canvas (supportata dalla versione 90)</translation>
 <translation id="5599461642204007579">Impostazioni di gestione di <ph name="MS_AD_NAME" /></translation>
 <translation id="5601503069213153581">PIN</translation>
+<translation id="5607021831414604820">Attiva i report sullo stato di archiviazione del dispositivo</translation>
 <translation id="5614865701790130558">Registra eventi per le installazioni di estensioni basate sul criterio</translation>
 <translation id="5618398258385745432">L'impostazione associata veniva utilizzata prima dell'introduzione della riautenticazione per la visualizzazione delle password. Dopodiché l'impostazione e quindi la norma non hanno più inciso sul comportamento di Chrome. Ora Chrome funziona come se la norma fosse impostata in modo da disattivare la visualizzazione delle password in testo non criptato nella pagina delle impostazioni di Gestione password. Ciò significa che la pagina delle impostazioni contiene soltanto un segnaposto e che Chrome mostra la password soltanto se l'utente fa clic su "Mostra" (ed esegue la riautenticazione, se possibile). Di seguito è riportata la descrizione originale della norma.
 
@@ -4481,6 +4530,7 @@
       Nota: se il dispositivo viene riavviato o se l'utente esce, la cache viene svuotata.</translation>
 <translation id="5717973246079053225">Disattiva reporting su cloud tramite profilo gestito</translation>
 <translation id="572155275267014074">Impostazioni di Android</translation>
+<translation id="5722577409367087850">Carica l'estensione</translation>
 <translation id="5728154254076636808">Consente la creazione di copie di roaming per i dati dei profili <ph name="PRODUCT_NAME" /></translation>
 <translation id="5729308727912841256">La password Kerberos. Il segnaposto <ph name="PASSWORD_PLACEHOLDER" /> viene sostituito dalla password di accesso.</translation>
 <translation id="5732972008943405952">Importa i dati della compilazione automatica dei moduli dal browser predefinito alla prima esecuzione</translation>
@@ -4732,6 +4782,7 @@
       Se viene impostato su Disattivato, gli utenti non possono riscattare tali offerte.</translation>
 <translation id="6046615715547751255">Non consentire i controlli di reporting granulare</translation>
 <translation id="6048199181629830227">Attiva la gestione della variazione dei picchi energetici</translation>
+<translation id="6049117606554031363">Attiva i report sullo stato della scheda del dispositivo</translation>
 <translation id="6053681087509103368">Consenti a WebRTC di usare versioni obsolete del protocollo TLS/DTLS</translation>
 <translation id="6058879286588763839">A meno che <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" /> non venga specificato, sovrascrivendo <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />, la configurazione di <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> consente di specificare il criterio di gestione della modalità di ricarica della batteria (se supportato dal dispositivo). Per estendere la durata della batteria, il criterio controlla dinamicamente la ricarica della batteria riducendo al minimo l'usura e preservandone l'efficienza.
 
@@ -4764,6 +4815,7 @@
 <translation id="6099853574908182288">Modalità di stampa a colori predefinita</translation>
 <translation id="6102342563050263313">Attiva scorrimento al testo specificato in frammenti di URL</translation>
 <translation id="6102449843040973938">È consentita l'esecuzione di <ph name="BOREALIS_NAME" /> su un dispositivo</translation>
+<translation id="610892566190435199">Attiva i report sullo stato di alimentazione del dispositivo</translation>
 <translation id="6111936128861357925">Attiva il gioco del dinosauro</translation>
 <translation id="6112524153927257380">Se il criterio viene impostato, gli utenti non potranno aggirare le decisioni relative alla sicurezza dei download.
 
@@ -4911,6 +4963,7 @@
       Lo scopo di questo criterio è fornire alle imprese la flessibilità di disattivare la sandbox dell'audio qualora interferisca con le configurazioni software di sicurezza utilizzate.</translation>
 <translation id="624818583115864448">porta 554 (può essere sbloccata fino al 15/10/2021)</translation>
 <translation id="6252773211180267325">È consentita l'esecuzione di <ph name="BOREALIS_NAME" /> per un utente</translation>
+<translation id="625580680776945310">La modalità ad alta efficienza verrà attivata.</translation>
 <translation id="6258658183356534534">Controlla la funzionalità di aggiornamento User-Agent Client Hints GREASE.</translation>
 <translation id="6261643884958898336">Segnala informazioni di identificazione dei computer</translation>
 <translation id="6265892395051519509">Consenti l'accesso ai sensori su questi siti</translation>
@@ -5070,6 +5123,7 @@
 <translation id="6368403635025849609">Consenti JavaScript su questi siti</translation>
 <translation id="6371561334154580937">Mostra finestra di dialogo di disconnessione nell'ultima finestra chiusa.</translation>
 <translation id="6372105930898423193">Consente di riattivare la funzionalità AppCache anche se è disattivata per impostazione predefinita.</translation>
+<translation id="6373299801585455337">Attiva i report sulle informazioni relative alla CPU del dispositivo</translation>
 <translation id="6376540107659524656">Disattiva SSH in Terminal System App</translation>
 <translation id="6376659517206731212">Può essere obbligatorio</translation>
 <translation id="6377031865393559909">Gli utenti possono usare i modelli di scrivanie</translation>
@@ -5077,6 +5131,7 @@
 <translation id="6378393933102834628">Se il criterio è impostato su True, la scorciatoia per le app viene visualizzata. Se il criterio è impostato su False, tale scorciatoia non viene mai visualizzata.
 
       Se il criterio è configurato, gli utenti non possono apportare modifiche. Se non è configurato, gli utenti possono decidere se mostrare o nascondere la scorciatoia per le app dal menu contestuale della barra dei Preferiti.</translation>
+<translation id="638003144128412430">Disattiva i report sulle informazioni relative al fuso orario del dispositivo</translation>
 <translation id="6382351416269252693">Consente di impostare un elenco di pattern URL per i siti che specifica i siti a cui viene negata automaticamente l'autorizzazione per i caratteri locali. Ciò limiterà la capacità dei siti di vedere le informazioni sui caratteri locali.
 
       Per informazioni dettagliate sui pattern URL di siti validi, visita la pagina https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. I caratteri jolly (<ph name="WILDCARD_VALUE" />) sono consentiti. Questo criterio ha corrispondenze basate soltanto sull'origine, pertanto qualsiasi percorso nel pattern URL viene ignorato.
@@ -5124,6 +5179,7 @@
 <translation id="6447948611083700881">Backup e ripristino disabilitati</translation>
 <translation id="6449476513004303784">Non consentire agli utenti di gestire i certificati
 </translation>
+<translation id="6452882999388592166">Se impostato su Attivato, l'estensione del componente CryptoToken integrata viene caricata all'avvio. Se impostato su Disattivato o se non viene configurato, CryptoToken non viene caricato all'avvio del browser. Questo criterio è inteso come soluzione alternativa temporanea per i siti non funzionanti perché "chrome.runtime" non è definito come effetto collaterale della rimozione di CryptoToken nella versione M106. I siti web non devono dipendere dalla definizione senza condizioni di "chrome.runtime".</translation>
 <translation id="6453641799812499182">Attiva le mitigazioni dei controlli <ph name="CORS" /> nella nuova implementazione <ph name="CORS" /></translation>
 <translation id="645425387487868471">Attiva l'accesso forzato per <ph name="PRODUCT_NAME" /></translation>
 <translation id="6455842857207956758">Consente di attivare la sincronizzazione delle password SAML tra più dispositivi Chrome monitorando il valore del token di sincronizzazione delle password e facendo svolgere all'utente la procedura di riautenticazione online se la password è stata aggiornata e deve essere sincronizzata.
@@ -5612,6 +5668,7 @@
 <translation id="6903814433019432303">Questa norma è attiva soltanto in modalità retail.
 
       Consente di stabilire l'insieme di URL da caricare all'avvio della sessione demo. Questa norma sostituirà qualsiasi altro meccanismo di impostazione dell'URL iniziale ed è quindi possibile applicarla soltanto a una sessione non associata a un determinato utente.</translation>
+<translation id="6903818804346914108">Attiva i report sulle informazioni relative alla ventola del dispositivo</translation>
 <translation id="6905405893096403868">Se per il criterio viene impostato un elenco di stringhe, ogni stringa viene passata al browser alternativo sotto forma di parametri della riga di comando separati. Su <ph name="MS_WIN_NAME" />, i parametri vengono uniti usando degli spazi. Su <ph name="MAC_OS_NAME" /> e <ph name="LINUX_OS_NAME" />, un parametro può contenere degli spazi ed essere comunque gestito come un singolo parametro.
 
       Se un parametro contiene <ph name="URL_PLACEHOLDER" />, il valore <ph name="URL_PLACEHOLDER" /> viene sostituito con l'URL della pagina da aprire. Se nessun parametro contiene <ph name="URL_PLACEHOLDER" />, l'URL viene aggiunto alla fine della riga di comando.
@@ -5914,6 +5971,7 @@
 <translation id="718126088895133062">Questo criterio consente di specificare l'ID utente della licenza <ph name="PLUGIN_VM_NAME" /> di questo dispositivo.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">Usa un servizio web di Google per correggere gli errori ortografici</translation>
+<translation id="7187248416163189586">Disattiva i report sulle informazioni relative alla retroilluminazione del dispositivo</translation>
 <translation id="718850220532931090">Questo criterio è deprecato. Utilizza il criterio <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />.
 
       La configurazione del criterio consente di specificare le estensioni consentite per utilizzare la funzione <ph name="CHALLENGE_USER_KEY_FUNCTION" /> di <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> per l'attestazione da remoto. Per utilizzare l'API, le estensioni devono essere presenti in questo elenco.
@@ -5937,6 +5995,7 @@
 <translation id="7207095846245296855">Forza il filtro SafeSearch di Google</translation>
 <translation id="7211368186050418507">Non rilevare mai automaticamente il fuso orario</translation>
 <translation id="7216442368414164495">Consenti agli utenti di attivare i rapporti estesi di Navigazione sicura</translation>
+<translation id="721970071627370558">Disattiva i report sullo stato di alimentazione del dispositivo</translation>
 <translation id="7221574724100909818">Viene usata l'icona lucchetto per le connessioni sicure</translation>
 <translation id="7229365071755865554">Attiva il salvataggio delle password utilizzando Gestore delle password</translation>
 <translation id="7229975860249300121">Contiene un'espressione regolare che viene usata per stabilire quali Account Google possono essere impostati come account principali del browser in <ph name="PRODUCT_NAME" /> (ossia l'account che viene scelto durante la procedura di attivazione della sincronizzazione).
@@ -6294,6 +6353,7 @@
 <translation id="7587345076013230465">Richiedi all'utente di selezionare il certificato client quando il criterio di selezione automatica corrisponde a più certificati nella schermata di accesso</translation>
 <translation id="7587921466180902617">Attiva la versione sperimentale di Registra schermo per gli utenti di Family Link</translation>
 <translation id="759957074386651883">Impostazioni di Navigazione sicura</translation>
+<translation id="7602621823177962064">Disattiva i report sulle informazioni relative alla memoria del dispositivo</translation>
 <translation id="7604169113182304895">Le app Android potrebbero decidere volontariamente se rispettare o meno questo elenco. Non è possibile imporre il rispetto dell'elenco.</translation>
 <translation id="7612157962821894603">Contrassegni a livello di sistema da applicare all'avvio di <ph name="PRODUCT_NAME" /></translation>
 <translation id="7613115815080726221">Il periodo di tempo, in millisecondi, senza input dell'utente trascorso il quale viene compiuta l'azione stabilita per l'inattività.</translation>
@@ -6636,6 +6696,7 @@
 <translation id="7992613144342460685">Concedere l'autorizzazione per il posizionamento delle finestre su questi siti</translation>
 <translation id="7995610550667275367">Scansione (supportata dalla versione 87)</translation>
 <translation id="7999023147219236247">Criterio per le richieste di concessione delle autorizzazioni delle app. PERMISSION_POLICY_UNSPECIFIED: criterio non specificato. Se per un'autorizzazione non viene specificato alcun criterio ad alcun livello, viene usato per impostazione predefinita il comportamento "PROMPT". PROMPT: viene chiesto all'utente di concedere un'autorizzazione. GRANT: viene concessa automaticamente un'autorizzazione. DENY: viene negata automaticamente un'autorizzazione.</translation>
+<translation id="7999336306414770162">Disattiva i report sulle informazioni VPD del dispositivo</translation>
 <translation id="7999818120028621358">Attiva la generazione di rapporti sugli eventi di prevenzione di fughe di dati</translation>
 <translation id="8001701200415781021">Limita gli Account Google che è possibile impostare come account principali del browser in <ph name="PRODUCT_NAME" /></translation>
 <translation id="800595420827930383">Utilizza lo strumento di verifica dei certificati della piattaforma precedente</translation>
@@ -6686,6 +6747,7 @@
 <translation id="8056273037819805106">Verranno usate le credenziali di accesso di <ph name="PRODUCT_OS_NAME" /> per l'autenticazione della rete su un proxy gestito.</translation>
 <translation id="8056800559672904373">Un account gestito deve essere un account principale e non deve avere account secondari. L'importazione dei dati di navigazione esistenti è consentita al momento della creazione del profilo</translation>
 <translation id="8059164285174960932">URL su cui i client di accesso remoto dovrebbero ottenere il token di autenticazione</translation>
+<translation id="8059352177830050556">Attiva i report sulle informazioni relative alla retroilluminazione del dispositivo</translation>
 <translation id="8062375903420954294">Questo criterio permette di applicare restrizioni agli indirizzi IP e alle interfacce che WebRTC utilizza quando prova a trovare la migliore connessione disponibile. Consulta la sezione 5.2 del documento RFC 8828 (https://tools.ietf.org/html/rfc8828.html#section-5.2). Se il criterio non viene configurato, per impostazione predefinita vengono usate tutte le interfacce disponibili.</translation>
 <translation id="8062485064082966327">Usa un servizio Google anonimo per fornire descrizioni automatiche alle immagini senza etichetta</translation>
 <translation id="8071371098891664137">Se per il criterio <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" /> viene scelta l'opzione <ph name="PRINTERS_BLOCKLIST" />, la configurazione del criterio <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> consente di specificare le stampanti che gli utenti non possono usare. L'utente avrà a disposizione tutte le stampanti, tranne quelle i cui ID sono elencati in questo criterio. Gli ID devono corrispondere ai campi <ph name="ID_FIELD" /> o <ph name="GUID_FIELD" /> del file specificato nel criterio <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />.</translation>
@@ -7002,6 +7064,7 @@
 <translation id="8367488518695804749">Non consentire la visualizzazione di popup nei siti</translation>
 <translation id="8369602308428138533">Ritardo disattivazione schermo in caso di utilizzo di CA</translation>
 <translation id="8371178326720637170">Consente alle estensioni gestite di utilizzare l'API Enterprise Hardware Platform</translation>
+<translation id="8373176843640227330">Disattiva i report sulle informazioni Bluetooth del dispositivo</translation>
 <translation id="8375817202037102567">Blocca l'accesso di scrittura di file e directory su questi siti</translation>
 <translation id="8378266419596669629">Blocca l'autorizzazione per i caratteri locali su questi siti</translation>
 <translation id="8379317372795444261">L'autenticazione <ph name="BASIC_AUTH" /> è consentita per le connessioni HTTP</translation>
@@ -7050,6 +7113,7 @@
 
        Questo criterio verrà rimosso nella versione 95 di <ph name="PRODUCT_NAME" />.</translation>
 <translation id="8427466947904008809">Consenti a CRD di eseguire richieste API WebAuthn trasferite al proxy da un host remoto.</translation>
+<translation id="8428295225823548121">Attiva i report sulle informazioni relative alla memoria del dispositivo</translation>
 <translation id="8428635849021776523">Disattiva la generazione di report Android</translation>
 <translation id="8433186206711564395">Impostazioni di rete</translation>
 <translation id="8433769814000220721">Attiva contenuti suggeriti</translation>
@@ -7481,6 +7545,7 @@
 <translation id="8882255181490012651">Non consente agli utenti che hanno attivato Phone Hub di accedere a foto e video recenti acquisiti sul loro telefono</translation>
 <translation id="8887709920496070892">Il periodo di tempo, in millisecondi, senza input dell'utente trascorso il quale viene mostrata una finestra di dialogo di avviso.</translation>
 <translation id="8890438048579188548">Nascondi avvisi di ritiro di <ph name="CLOUD_PRINT_NAME" /></translation>
+<translation id="8891334958985336685">Disattiva i report sulle informazioni di sistema del dispositivo</translation>
 <translation id="8892286064305622118">Spazio libero su disco necessario per <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="8892783613915541293">Ritardi e azioni da compiere quando il dispositivo è inattivo durante l'utilizzo dell'alimentazione CA.</translation>
 <translation id="8897796778265450949">Limita il tempo per cui un utente autenticato tramite GAIA senza SAML può accedere offline</translation>
@@ -7548,6 +7613,7 @@
 <translation id="8977192934280677167">Consenti l'accesso al provider di ricerca predefinito dal menu contestuale di ricerca</translation>
 <translation id="8983537551095611459">Configura l'elenco degli ID delle estensioni esenti dalla procedura di pulizia della sessione Ospite gestita limitata</translation>
 <translation id="8983539044126123594">Attiva l'accesso con Account Google aggiuntivi</translation>
+<translation id="8985219286836584291">Attiva i report sulle informazioni di sistema del dispositivo</translation>
 <translation id="8992176907758534924">Non consentire la visualizzazione di immagini nei siti</translation>
 <translation id="8994954504552592260">Consente di attivare la migrazione dei dispositivi gestiti <ph name="MS_AD_NAME" /> nella gestione del cloud. Questo criterio consente di avviare da remoto una migrazione touchless di più dispositivi di una società. Inoltre, la migrazione sarà il più trasparente possibile per gli utenti finali.
 
@@ -7809,6 +7875,7 @@
       Se il criterio è impostato su Falso, solo gli utenti presenti nella lista consentita <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" /> potranno eseguire l'accesso.
 
       Se il criterio è impostato su Vero o non viene configurato, tutti gli utenti potranno accedere.</translation>
+<translation id="966425658642788645">Applica il comportamento predefinito</translation>
 <translation id="971677226939413180">L'opzione Stampa come immagine non può essere selezionata dagli utenti</translation>
 <translation id="974349541138387272">Specifica il modello URI del resolver DNS over HTTPS desiderato</translation>
 <translation id="979467274961593903">Non consentire l'uso del debug remoto</translation>
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb
index 064457f..a4a53a7 100644
--- a/components/policy/resources/policy_templates_ko.xtb
+++ b/components/policy/resources/policy_templates_ko.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876"><ph name="PRODUCT_OS_NAME" /> 로그인 화면에서 사용되는 언어를 구성합니다.
 
       이 정책이 설정되면 로그인 화면이 항상 이 정책의 첫 번째 값에 의해 주어지는 언어로 표시됩니다(이 정책은 향후 호환성을 위해 목록으로 정의됨). 이 정책이 설정되지 않거나 빈 목록으로 설정되는 경우 로그인 화면이 최종 사용자 세션의 언어로 표시됩니다. 이 정책이 유효한 언어가 아닌 값으로 설정되는 경우 로그인 화면이 대체 언어(현재 en-US)로 표시됩니다.</translation>
+<translation id="1050158007881386475">기기 보드 상태 보고 사용 중지</translation>
 <translation id="1052499923181221200">SamlInSessionPasswordChangeEnabled가 True가 아닌 경우 이 정책은 아무런 영향도 미치지 않습니다.
       정책이 True이고 이 정책이 예를 들어 14로 설정되었다면 이는 비밀번호가 특정 날짜에 만료되기 14일 전에 SAML 사용자에게 알림이 표시된다는 의미입니다.
       사용자는 비밀번호가 만료되기 전에 세션 중 비밀번호를 변경하고 업데이트함으로써 이 문제에 즉시 대처할 수 있습니다.
@@ -330,6 +331,7 @@
       'Forced'(2)를 선택하면 프로필 선택도구를 사용자가 숨길 수 없습니다. 사용 가능한 프로필이 하나뿐인 경우에도 프로필 선택도구가 표시됩니다.</translation>
 <translation id="1339174690935954950">사용자가 의견을 제출하지 못하도록 차단</translation>
 <translation id="1342918903685430097">기기에 허용되는 최소 <ph name="PRODUCT_OS_NAME" /> 버전을 설정합니다.</translation>
+<translation id="1343128241903870688">기기 앱 정보 보고 사용 중지</translation>
 <translation id="1347198119056266798">이 정책은 지원 중단되었으므로 <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> 및 <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />을(를) 사용하세요. <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> 또는 <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> 정책(지원 중단됨)이 설정된 경우 이 정책은 무시됩니다.
 
       강제로 Google 웹 검색에서 검색이 세이프서치가 활성화된 상태에서 실행되도록 하며 사용자가 이 설정을 변경하지 못하게 합니다. 또한 이 설정은 YouTube에서 강제로 보통 제한 모드를 사용하도록 합니다.
@@ -369,6 +371,7 @@
 <translation id="1393485621820363363">사용 설정된 엔터프라이즈 기기 프린터</translation>
 <translation id="1395505489889158859">사용자 이름 및 파일 이름을 기본 프린터로 보낼 수 있도록 허용</translation>
 <translation id="1397855852561539316">기본 검색 공급자 추천 URL</translation>
+<translation id="1402227992519954892">기기 앱 정보 보고 사용 설정</translation>
 <translation id="141279920573530952">정책을 설정하면 사용 가능한 모든 직렬 포트에 대한 액세스 권한을 자동으로 부여받는 사이트의 목록을 작성할 수 있습니다.
 
       URL은 유효해야 하며 그렇지 않으면 정책이 무시됩니다. URL의 원본(스킴, 호스트, 포트)만 고려됩니다.
@@ -614,6 +617,7 @@
 <translation id="1616280227447957376">특정 출처의 SSL 경고 페이지 클릭 연결 허용</translation>
 <translation id="1617235075406854669">브라우저 및 다운로드 기록을 삭제하도록 설정합니다.</translation>
 <translation id="1620510694547887537">카메라</translation>
+<translation id="162162247775156979">기기 저장용량 상태 보고 사용 중지</translation>
 <translation id="1626379196197114720">뒤로-앞으로 캐시 사용 허용</translation>
 <translation id="1628974048137236820">새 탭 페이지에 카드 표시 안함</translation>
 <translation id="1630263002012156148">정책을 사용으로 설정하면 새 탭 페이지가 사용자의 홈페이지로 설정되고 기존 홈페이지 URL 위치는 무시됩니다. 정책을 사용 안함으로 설정하면 사용자의 홈페이지 URL을 chrome://newtab으로 설정하지 않는 한 홈페이지가 새 탭 페이지로 지정되지 않습니다.
@@ -1106,6 +1110,7 @@
 <translation id="2043770014371753404">사용 중지된 엔터프라이즈 프린터</translation>
 <translation id="2057317273526988987">URL 목록 액세스 허용</translation>
 <translation id="2058055310819710697">분리된 앱 개발자 모드를 사용 설정합니다.</translation>
+<translation id="205807990145127714">신호 강도 이벤트를 보고하기 위한 텔레메트리 데이터</translation>
 <translation id="2061123930713023976">네트워크 패킷 캡처 디버깅 허용</translation>
 <translation id="2061810934846663491">원격 액세스 호스트에 필요한 도메인 이름을 설정합니다.</translation>
 <translation id="2062632109797189011">지원 중단된 window.mydomainStorageInfo API를 다시 사용 설정합니다.</translation>
@@ -1707,8 +1712,12 @@
 <translation id="2665422249821137126">로그인 화면에서 큰 커서 사용</translation>
 <translation id="2667894101494585925">최적화 가이드 가져오기를 사용 설정합니다.</translation>
 <translation id="2672012807430078509">SMB 마운트용 인증 프로토콜로 NTLM을 사용할지 여부를 제어합니다.</translation>
+<translation id="2673363037046384711">최종 사용자가 고효율 모드를 사용 또는 사용 중지할 수 있음</translation>
 <translation id="2678503605767349615">기기 수준 필수 클라이언트 인증서</translation>
 <translation id="268577405881275241">데이터 압축 프록시 기능 사용</translation>
+<translation id="268695908564263739">이 정책은 고효율 모드 설정을 사용 또는 사용 중지합니다. 이렇게 설정하면 백그라운드에서 일정 시간이 지난 후에 탭을 닫아 메모리를 확보할 수 있습니다.
+      정책을 설정하지 않으면 최종 사용자가 chrome://settings/performance에서 이 설정을 제어할 수 있습니다.
+      </translation>
 <translation id="2691668238491124549">정책을 설정하면(추천으로만) 관리 세션의 추천 언어가 목록 상단으로 이동하며, 정책에 표시되는 순서를 따릅니다. 첫 번째 추천 언어는 사전 선택됩니다.
 
       설정하지 않으면 현재 UI 언어가 사전 선택됩니다.
@@ -2911,6 +2920,7 @@
 <translation id="3898345958122666461">NTLMv2 사용 중지</translation>
 <translation id="3898795800259311780">화면 캡처 허용 또는 거부</translation>
 <translation id="3903313632842363082">기기 사용자 보고 사용 중지</translation>
+<translation id="3904304709151553598">기기 팬 정보 보고 사용 중지</translation>
 <translation id="3907683835264956726">잠금 화면에서 온라인 사용자 로그인을 사용 설정합니다. 이 정책이 true로 설정되어 있으면 <ph name="POLICY" /> 등에 의해 잠금 화면에서 온라인 재인증이 실행됩니다.
       잠금 화면에 있거나 다음에 조건이 충족된 후 사용자가 화면을 잠갔을 때 재인증이 즉시 실행됩니다.
       정책이 false로 설정되거나 아무 설정도 되어 있지 않으면 사용자는 항상 로컬 사용자 인증 정보로 화면을 잠금 해제할 수 있습니다.</translation>
@@ -2955,6 +2965,7 @@
 
           정책이 설정되지 않으면 처음에는 로그인 화면에서 고정키가 사용되지 않지만 나중에 사용자가 언제든지 사용 설정할 수 있습니다.</translation>
 <translation id="3927291637826333102">출처의 바탕화면, 창, 탭 캡처 허용</translation>
+<translation id="3928726028264020458">기기 VPD 정보 보고 사용 설정</translation>
 <translation id="3943930334592166130">이 정책은 <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" />와 일치하는 인증서가 여러 개일 때 사용자에게 클라이언트 인증서를 선택하라는 메시지를 표시할지 제어합니다.
       정책을 사용으로 설정하면 자동 선택 정책과 일치하는 인증서가 여러 개 있을 때마다 사용자에게 클라이언트 인증서를 선택하라는 메시지가 표시됩니다.
       정책을 사용 안함으로 설정하거나 설정하지 않으면 자동 선택과 일치하는 인증서가 없을 때만 사용자에게 메시지가 표시됩니다.</translation>
@@ -3044,6 +3055,7 @@
       <ph name="MS_WIN_NAME" />의 경우 이 기능은 <ph name="MS_AD_NAME" /> 도메인에 연결된 인스턴스, Windows 10 Pro에서 실행되는 인스턴스 또는 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />에 등록된 인스턴스에서만 사용할 수 있습니다. <ph name="MAC_OS_NAME" />의 경우에는 MDM을 통해 관리되는 인스턴스 또는 MCX를 통해 도메인에 연결된 인스턴스에서만 사용할 수 있습니다.</translation>
 <translation id="4043796890723386527">사용자가 <ph name="LACROS_NAME" /> 브라우저에서 보조 프로필을 만들어 사용하거나 게스트 모드를 사용하지 못하도록 차단</translation>
 <translation id="4051723201852944592">창 오클루전 사용 설정</translation>
+<translation id="4052529125939620019">시작 시 CryptoToken 구성요소 확장 프로그램 로드</translation>
 <translation id="4053157306171963473">기기 활동 시간 보고 사용 중지</translation>
 <translation id="4056910949759281379">SPDY 프로토콜 사용 중지</translation>
 <translation id="4061107397839125009">정책을 설정하면 알림 표시가 불가능한 사이트를 지정하는 URL 패턴 목록을 설정할 수 있습니다.
@@ -3102,6 +3114,37 @@
 
       정책을 설정하면 사용자가 변경할 수 없습니다. 설정하지 않으면 처음에는 터치 키보드가 사용 중지되지만 사용자가 언제든지 사용 설정할 수 있습니다.</translation>
 <translation id="412697421478384751">사용자가 잠금 화면 PIN으로 보안 강도가 약한 PIN을 사용할 수 있게 허용</translation>
+<translation id="4130565559631908067">이 정책을 통해 브라우저에서 퍼스트 파티 세트 기능에 사용하는 세트 목록을 재정의할 수 있습니다.
+
+      브라우저의 퍼스트 파티 세트 목록에 포함된 각 세트는 퍼스트 파티 세트 요구사항을 충족해야 합니다.
+      퍼스트 파티 세트에는 하나의 소유자 사이트 및 하나 이상의 구성원 사이트가 포함되어야 합니다.
+      세트에는 해당 세트가 소유 중인 서비스 사이트 목록과 사이트의 모든 ccTLD 변형에 대한 매핑 정보도 포함될 수 있습니다.
+      <ph name="PRODUCT_NAME" />에서 사용하는 퍼스트 파티 세트에 관한 자세한 내용은 https://github.com/WICG/first-party-sets를 참고하세요.
+
+      퍼스트 파티 세트의 모든 사이트는 HTTPS를 통해 제공되는 등록 가능한 도메인이어야 합니다. 또한 퍼스트 파티 세트의 각 사이트는 고유해야 합니다. 즉, 한 사이트는 퍼스트 파티 세트에 한 번만 표시될 수 있습니다.
+
+      정책에 제공된 사전이 비어 있는 경우 브라우저에서는 공개된 퍼스트 파티 세트 목록을 사용합니다.
+
+      <ph name="REPLACEMENTS" /> 목록의 퍼스트 파티 세트에 포함된 모든 사이트 중 브라우저 목록의
+      퍼스트 파티 세트에도 포함된 사이트가 있다면 브라우저의 퍼스트 파티 세트에서 삭제됩니다.
+      그런 다음 정책의 퍼스트 파티 세트가 브라우저의 퍼스트 파티 세트 목록에 추가됩니다.
+
+      <ph name="ADDITIONS" /> 목록의 퍼스트 파티 세트에 포함된 모든 사이트 중 브라우저 목록의 퍼스트 파티 세트에도
+      포함된 사이트가 있는 경우, 새로운 퍼스트 파티 세트가 브라우저 목록에 추가될 수 있도록 브라우저의 퍼스트 파티 세트가
+      업데이트됩니다. 브라우저 목록이 업데이트되고 나면
+      정책의 퍼스트 파티 세트가 브라우저의 퍼스트 파티 세트 목록에 추가됩니다.
+
+      브라우저의 퍼스트 파티 세트 목록에 포함된 모든 사이트 중 어떠한 사이트도 2개 이상의 세트에
+      포함되어서는 안 됩니다. 이는 <ph name="REPLACEMENTS" /> 목록 및 <ph name="ADDITIONS" /> 목록에도
+      적용되는 요구사항입니다. 마찬가지로 하나의 사이트가 <ph name="REPLACEMENTS" /> 목록과
+      <ph name="ADDITIONS" /> 목록 모두에 포함되어서는 안 됩니다.
+
+      와일드 카드(*)는 정책 값으로 사용할 수 없으며 이러한 목록의 퍼스트 파티 세트 내에서도 지원되지 않습니다.
+
+      정책에서 제공하는 모든 세트는 유효한 퍼스트 파티 세트여야 하며, 그렇지 않은 경우
+      관련 오류 메시지가 표시됩니다.
+
+      이 정책은 <ph name="MS_AD_NAME" /> 도메인에 연결된 Windows 인스턴스, 기기 관리용으로 등록된 Windows 10 Pro 또는 Enterprise 인스턴스, MDM을 통해 관리되거나 MCX(Mac OS X용 관리 클라이언트)를 통해 도메인에 연결된 macOS 인스턴스에서만 사용할 수 있습니다.</translation>
 <translation id="4138655880188755661">시간 제한</translation>
 <translation id="4147818922357566987">중요한 수정사항과 관련된 변형만 사용</translation>
 <translation id="4150201353443180367">디스플레이</translation>
@@ -3701,6 +3744,7 @@
       정책을 사용 안함으로 설정하거나 설정하지 않으면 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />가 옵션으로 간주되고 실패할 경우 <ph name="PRODUCT_NAME" /> 실행 프로세스가 차단되지 않습니다.
 
       데스크톱의 머신 범위 클라우드 정책 등록에서 이 정책을 사용합니다. 자세한 내용은 https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744를 참고하세요.</translation>
+<translation id="488996881569316769">네트워크 텔레메트리</translation>
 <translation id="4890453377345554695">정책을 설정하면 URL 패턴 목록을 만들어 사용자에게 호스트 운영체제의 파일 시스템 내 파일 또는 디렉터리에 대한 쓰기 액세스 권한을 요청할 수 있는 사이트를 지정하는 것이 가능합니다.
 
       정책을 설정하지 않았을 때 <ph name="DEFAULT_FILE_SYSTEM_WRITE_GUARD_SETTING_POLICY_NAME" />이 설정되어 있으면 모든 사이트에 적용되며 설정되어 있지 않으면 사용자의 개인 설정이 적용됩니다.
@@ -3922,6 +3966,7 @@
 <translation id="5148753489738115745"><ph name="PRODUCT_FRAME_NAME" />이(가) <ph name="PRODUCT_NAME" />을(를) 실행할 때 사용되는 추가 매개변수를 지정하도록 허용합니다.
 
           해당 정책이 설정되지 않았다면 기본 명령줄이 사용됩니다.</translation>
+<translation id="5151099177901233471">기기 시간대 정보 보고 사용 설정</translation>
 <translation id="5152393033264257734">DNS 가로채기 검사 및 'http://intranetsite/'를 찾으셨나요? 정보 표시줄을 허용합니다.</translation>
 <translation id="5152787786897382519">Chromium과 Chrome의 일부 정책 그룹은 특정 기능 제어를 위해 서로 종속되는 경우도 있습니다. 이러한 세트는 다음의 정책 그룹으로 대표됩니다. 정책의 출처가 여러 개일 수 있으므로 우선순위가 가장 높은 출처의 값만 적용됩니다. 같은 그룹에서 우선순위가 낮은 출처의 값은 무시됩니다. 우선순위는 <ph name="POLICY_PRIORITY_DOC_URL" />에 정의되어 있습니다.</translation>
 <translation id="5153187201534281749">툴바의 브라우저 실험 아이콘</translation>
@@ -4032,6 +4077,7 @@
 
       정책이 설정되지 않거나 유효하지 않으면 '채널 다운그레이드 시 보완할 대상 채널 대기'와 동일하게 동작합니다.</translation>
 <translation id="5229339291699779956">기기가 완전히 정상 작동하도록 Thunderbolt/USB4 주변기기에 대한 PCIe 터널링을 사용 설정</translation>
+<translation id="5230095739094490896">'client-name' IPP 속성 템플릿 인쇄</translation>
 <translation id="5233239004553860036">정책을 <ph name="POLICY_VALUE_ALL" />로 설정하거나 설정하지 않으면 관리 계정이 어떤 계정으로든 사용될 수 있습니다. 그 결과 관리 계정이 보조 계정이 될 수 있으며, 이때 브라우저 프로필에서 관리 계정이 기본 계정으로 로그인된 경우에만 정책을 수신할 수 있습니다.
       다음과 같은 경우에는 계정에 설정된 정책이 시행되지 않습니다.
         -  OS 수준(계정 설정)에서 보조 계정인 경우
@@ -4063,6 +4109,7 @@
       이때 '버전'은 '61.0.3163.120'과 같은 정확한 버전 또는 '61.0'과 같은 버전 접두어 중 하나를 의미합니다.  </translation>
 <translation id="5247973380763021389">사용자 클라우드 정책이 머신 클라우드 정책보다 우선 적용되지 않도록 방지</translation>
 <translation id="5249453807420671499">사용자가 Kerberos 계정을 추가할 수 있음</translation>
+<translation id="5249555581286638799">고효율 모드 사용 설정</translation>
 <translation id="5252210248395576403">이 정책은 선택한 콘텐츠에 액세스하고 번역 결과를 얻기 위해 정보를 서버로 보낼 권한을 빠른 답변에 부여합니다.
 
       정책을 사용 설정하거나 설정하지 않으면 빠른 답변 번역이 사용 설정됩니다.
@@ -4071,6 +4118,7 @@
 
       정책을 False로 설정하거나 설정하지 않으면 통합 바탕화면이 사용 중지되며 사용자가 사용 설정할 수 없습니다.</translation>
 <translation id="5255162913209987122">권장 가능</translation>
+<translation id="525543707238275321">기기 CPU 정보 보고 사용 중지</translation>
 <translation id="5257395339965216304">호스팅된 앱 데이터</translation>
 <translation id="5262320080678421295">Symantec Corporation의 이전 PKI에서 발급된 인증서에 대한 트러스트 사용 중지</translation>
 <translation id="5266173014392157048">이 정책은 지원 중단되었으므로 ‘<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />’ 정책을 대신 사용하세요.
@@ -4135,6 +4183,7 @@
       이 정책을 구성하지 않으면 <ph name="PRODUCT_NAME" />에서 기본 최대 버전이 사용됩니다.
 
       정책을 구성하는 경우, 'tls1.2' 또는 'tls1.3' 중 하나로 설정할 수 있습니다. 설정되면 <ph name="PRODUCT_NAME" />에서 지정된 버전보다 높은 SSL/TLS 버전이 사용되지 않습니다. 인식할 수 없는 값은 무시됩니다.</translation>
+<translation id="5329018127554115226">고효율 모드가 사용 중지됩니다.</translation>
 <translation id="5330684698007383292"><ph name="PRODUCT_FRAME_NAME" />이(가) 다음 콘텐츠 유형을 다루도록 허용</translation>
 <translation id="5331746669335642668"><ph name="PRODUCT_NAME" /> 클라우드 정책이 플랫폼 정책에 우선합니다.</translation>
 <translation id="5346587320074666194">이 사이트에서 센서에 액세스할 수 없도록 차단</translation>
@@ -4330,6 +4379,7 @@
       이 정책은 채널 전환에 적용되지 않습니다.</translation>
 <translation id="5519331583722582543">터치 키보드가 필기 인식을 통한 입력을 지원할 수 있는지 나타내는 부울 플래그입니다.</translation>
 <translation id="5519619299971727565">Linux 앱 사용량 보고 사용 중지</translation>
+<translation id="5521035900165046997">기기 블루투스 정보 보고 사용 설정</translation>
 <translation id="5521875416764302911">사용자가 <ph name="PRODUCT_NAME" />에 로그인하지 못하도록 차단</translation>
 <translation id="5526184558582921522">Quirks 서버로 쿼리 및 잠재적인 하드웨어별 구성 파일 다운로드 허용</translation>
 <translation id="5526701598901867718">모두(안전하지 않음)</translation>
@@ -4385,6 +4435,7 @@
 <translation id="5598417829613725146">캔버스(버전 90 이후 지원)</translation>
 <translation id="5599461642204007579"><ph name="MS_AD_NAME" /> 관리 설정</translation>
 <translation id="5601503069213153581">PIN</translation>
+<translation id="5607021831414604820">기기 저장용량 상태 보고 사용 설정</translation>
 <translation id="5614865701790130558">정책 기반 확장 프로그램 설치 이벤트 로그</translation>
 <translation id="5618398258385745432">비밀번호 조회를 위한 재인증 시작 전에 관련 설정을 사용했습니다. 그 이후에는 설정한 사항과 이 정책이 Chrome의 작동에 영향을 주지 않았습니다. 현재 Chrome은 비밀번호 관리자 설정 페이지에서 일반 텍스트로 비밀번호를 표시하는 것을 사용 중지하도록 정책을 설정했을 때와 동일하게 작동합니다. 따라서 설정 페이지에는 자리표시자만 포함되어 있으며, 사용자가 '표시'를 클릭하는 경우(해당하는 경우 다시 인증해야 함)에만 Chrome에서 비밀번호를 표시합니다. 정책의 원본 설명은 아래와 같습니다.
 
@@ -4494,6 +4545,7 @@
       참고: 다시 시작하거나 로그아웃하면 캐시가 삭제됩니다.</translation>
 <translation id="5717973246079053225">관리 프로필 클라우드 보고 사용 안함</translation>
 <translation id="572155275267014074">Android 설정</translation>
+<translation id="5722577409367087850">확장 프로그램 로드</translation>
 <translation id="5728154254076636808"><ph name="PRODUCT_NAME" /> 프로필 데이터 로밍 사본 생성을 사용 설정합니다.</translation>
 <translation id="5729308727912841256">Kerberos 비밀번호입니다. <ph name="PASSWORD_PLACEHOLDER" /> 자리표시자는 로그인 비밀번호로 교체됩니다.</translation>
 <translation id="5732972008943405952">처음 실행할 때 기본 브라우저에서 양식 자동 완성 데이터 가져오기</translation>
@@ -4755,6 +4807,7 @@
       정책을 사용 중지하면 사용자가 쿠폰을 사용할 수 없습니다.</translation>
 <translation id="6046615715547751255">상세 보고 제어 허용 안함</translation>
 <translation id="6048199181629830227">피크 시프트 전력 관리 사용</translation>
+<translation id="6049117606554031363">기기 보드 상태 보고 사용 설정</translation>
 <translation id="6053681087509103368">WebRTC에서 지원 중단된 버전의 TLD/DTLS 프로토콜을 사용하도록 허용</translation>
 <translation id="6058879286588763839"><ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />보다 우선 적용되는 <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" />를 지정하지 않는 한 <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />에서 배터리 충전 모드 전원 관리 정책을 지정합니다(기기에서 지원되는 경우). 배터리 수명을 연장하기 위해 정책에서 스트레스와 소모를 최소화하여 동적으로 배터리 충전을 제어합니다.
 
@@ -4787,6 +4840,7 @@
 <translation id="6099853574908182288">기본 컬러 인쇄 모드</translation>
 <translation id="6102342563050263313">URL 프래그먼트에서 지정한 텍스트로 스크롤 사용 설정</translation>
 <translation id="6102449843040973938"><ph name="BOREALIS_NAME" />가 기기에서 실행되는 것을 차단하지 않음</translation>
+<translation id="610892566190435199">기기 전원 상태 보고 사용 설정</translation>
 <translation id="6111936128861357925">공룡 부활절 달걀 게임 허용</translation>
 <translation id="6112524153927257380">정책을 설정하면 사용자가 다운로드 보안 관련 결정을 우회할 수 없습니다.
 
@@ -4934,6 +4988,7 @@
       이 정책은 기업에서 샌드박스를 방해하는 보안 소프트웨어 설정을 사용하는 경우 필요에 따라 오디오 샌드박스를 사용 중지할 수 있도록 만들어졌습니다.</translation>
 <translation id="624818583115864448">포트 554(2021년 10월 15일까지 차단 해제될 수 있음)</translation>
 <translation id="6252773211180267325">사용자가 <ph name="BOREALIS_NAME" />를 실행하는 것을 차단하지 않음</translation>
+<translation id="625580680776945310">고효율 모드가 사용 설정됩니다.</translation>
 <translation id="6258658183356534534">User-Agent Client Hints GREASE 업데이트 기능을 제어합니다.</translation>
 <translation id="6261643884958898336">기기 식별 정보 보고</translation>
 <translation id="6265892395051519509">이 사이트에서 센서에 액세스하도록 허용</translation>
@@ -5093,6 +5148,7 @@
 <translation id="6368403635025849609">이 사이트에서 자바스크립트 허용</translation>
 <translation id="6371561334154580937">마지막 창 종료 시 로그아웃 대화상자 표시</translation>
 <translation id="6372105930898423193">기본으로 사용 중지되어 있는 경우에도 AppCache 기능이 다시 사용 설정되도록 허용합니다.</translation>
+<translation id="6373299801585455337">기기 CPU 정보 보고 사용 설정</translation>
 <translation id="6376540107659524656">터미널 시스템 앱에서 SSH를 사용 중지합니다.</translation>
 <translation id="6376659517206731212">필수로 설정할 수 있음</translation>
 <translation id="6377031865393559909">사용자가 데스크 템플릿을 사용하도록 허용</translation>
@@ -5100,6 +5156,7 @@
 <translation id="6378393933102834628">정책을 True로 설정하면 앱 바로가기가 표시됩니다. 정책을 False로 설정하면 앱 바로가기가 표시되지 않습니다.
 
       정책을 설정하면 사용자가 변경할 수 없습니다. 설정하지 않으면 사용자가 앱 바로가기를 북마크바 컨텍스트 메뉴에서 표시하거나 숨길지를 결정합니다.</translation>
+<translation id="638003144128412430">기기 시간대 정보 보고 사용 중지</translation>
 <translation id="6382351416269252693">자동으로 로컬 글꼴 권한을 거부하는 사이트를 지정하도록 사이트 URL 패턴 목록을 설정합니다. 이렇게 하면 로컬 글꼴에 관한 정보를 볼 수 있는 사이트 기능이 제한됩니다.
 
       유효한 사이트 URL 패턴에 관한 자세한 내용은 다음을 참고하세요. https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns 와일드 카드(<ph name="WILDCARD_VALUE" />)를 사용할 수 있습니다. 이 정책은 출처만 기준으로 일치 여부를 판단하므로 URL 패턴의 경로는 무시됩니다.
@@ -5146,6 +5203,7 @@
 <translation id="6440051664870270040">사이트에서 동시에 팝업을 탐색하고 열도록 허용</translation>
 <translation id="6447948611083700881">백업 및 복원이 사용 중지됨</translation>
 <translation id="6449476513004303784">사용자가 인증서를 관리하도록 허용 안함</translation>
+<translation id="6452882999388592166">정책을 사용으로 설정하면 브라우저 시작 시 내장된 CryptoToken 구성요소 확장 프로그램이 로드됩니다. 사용 안함으로 설정하거나 설정하지 않으면 시작 시 CryptoToken이 로드되지 않습니다. 이 정책은 M106에서 CryptoToken이 삭제되면서 발생한 부작용으로 `chrome.runtime`이 정의되지 않음에 따라 손상된 사이트를 수정하기 위한 임시방편입니다. 웹사이트에서는 무조건적으로 정의되는 `chrome.runtime`에 의존해서는 안 됩니다.</translation>
 <translation id="6453641799812499182">새로운 <ph name="CORS" /> 구현에서 <ph name="CORS" /> 확인 완화를 사용 설정</translation>
 <translation id="645425387487868471"><ph name="PRODUCT_NAME" /> 강제 로그인 사용</translation>
 <translation id="6455842857207956758">비밀번호 동기화 토큰의 값을 모니터링하고 비밀번호가 업데이트되어 동기화가 필요할 때 사용자가 온라인 재인증을 완료하도록 하여 여러 대의 Chrome 기기에서 SAML 비밀번호 동기화를 사용하도록 설정합니다.
@@ -5220,6 +5278,7 @@
 <translation id="6506486086262398387">정책을 사용 설정하면 <ph name="PRODUCT_OS_NAME" />의 네트워크 파일 공유 기능에서 필요한 경우 SMB 공유 항목 인증에 NTLM을 사용합니다. 사용 중지하면 SMB 공유 항목에 NTLM 인증이 사용 중지됩니다.
 
       정책이 설정되지 않으면 관리 대상인 사용자에게는 이 동작이 사용 중지되며 다른 사용자에게는 기본적으로 사용 설정됩니다.</translation>
+<translation id="6513453889192806240">HTTPS 지연 시간</translation>
 <translation id="6515357889978918016"><ph name="PLUGIN_VM_NAME" /> 이미지</translation>
 <translation id="6518102411616460786">채널 다운그레이드 시 보완할 대상 채널 대기</translation>
 <translation id="6520802717075138474">처음 실행 시 기본 브라우저에서 검색엔진 가져오기</translation>
@@ -5489,6 +5548,12 @@
 
       이 정책을 False로 설정하거나 설정하지 않으면 사용자에게 <ph name="PLUGIN_VM_NAME" />이(가) 사용 설정되지 않습니다.
       정책을 True로 설정하면 다른 설정에서도 허용하는 한 사용자가 <ph name="PLUGIN_VM_NAME" />을(를) 사용하도록 설정됩니다. <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> 및 <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" />이(가) True로 설정되고 <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> 또는 <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />이(가) 설정되어야 <ph name="PLUGIN_VM_NAME" />이(가) 실행될 수 있습니다.</translation>
+<translation id="6750902920405577210">신호 강도 변경 이벤트에 관해 보고할 텔레메트리 데이터 목록입니다.
+
+      지정된 각 텔레메트리 데이터는 해당 제어 정책에 의해 사용 중지되지 않은 경우에만 보고됩니다.
+      https_latency 및 network_telemetry에 대한 제어 정책은 ReportDeviceNetworkStatus입니다.
+
+      정책을 설정하지 않으면 신호 강도 변경 이벤트에 대한 추가 텔레메트리 데이터가 보고되지 않습니다.</translation>
 <translation id="6752711782954612641"><ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" />가 사용 설정되어 있으면 <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> 설정은 POST로 URL을 검색할 때의 매개변수를 지정합니다. 이 매개변수는 쉼표로 구분된 이름 값의 쌍으로 구성됩니다. 값이 <ph name="SEARCH_TERM_MARKER" />와 같은 템플릿 매개변수면 실제 검색어 데이터로 교체됩니다.
 
       <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" />를 설정하지 않으면 GET 메서드를 사용해 검색 요청이 전송됩니다.</translation>
@@ -5627,6 +5692,7 @@
 <translation id="6903814433019432303">이 정책은 판매 모드일 때만 사용할 수 있습니다.
 
       데모 세션을 시작할 때 URL 세트가 로드되는지 결정합니다. 이 정책은 초기 URL 설정에 필요한 다른 모든 메커니즘을 무시하기 때문에 특정 사용자와 관련되지 않은 세션에만 적용할 수 있습니다.</translation>
+<translation id="6903818804346914108">기기 팬 정보 보고 사용 설정</translation>
 <translation id="6905405893096403868">이 정책을 문자열 목록으로 설정하면 각 문자열이 별도의 명령줄 매개변수로 대체 브라우저에 전달됩니다. <ph name="MS_WIN_NAME" />에서는 매개변수와 공백이 합쳐집니다. <ph name="MAC_OS_NAME" /> 및 <ph name="LINUX_OS_NAME" />에서는 매개변수에 공백이 포함될 수 있으며 이 경우에도 여전히 하나의 매개변수로 처리됩니다.
 
       매개변수에 <ph name="URL_PLACEHOLDER" />이(가) 있으면 <ph name="URL_PLACEHOLDER" />이(가) 열릴 페이지의 URL로 대체됩니다. 매개변수에 <ph name="URL_PLACEHOLDER" />이(가) 없으면 이 URL이 명령줄 끝에 추가됩니다.
@@ -5929,6 +5995,7 @@
 <translation id="718126088895133062">이 정책은 이 기기의 <ph name="PLUGIN_VM_NAME" /> 라이선스 사용자 ID를 지정합니다.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">맞춤법 오류를 해결하는 데 도움이 되는 Google 웹 서비스 사용</translation>
+<translation id="7187248416163189586">기기 백라이트 정보 보고 사용 중지</translation>
 <translation id="718850220532931090">이 정책은 지원 중단되었으므로 <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />를 대신 사용하세요.
 
       정책을 설정하면 원격 증명에 <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> 함수 <ph name="CHALLENGE_USER_KEY_FUNCTION" />를 사용하도록 허용되는 확장 프로그램을 지정합니다. 이 목록에 확장 프로그램이 포함되어야 API를 사용할 수 있습니다.
@@ -5952,6 +6019,7 @@
 <translation id="7207095846245296855">Google 세이프서치 강제 실행</translation>
 <translation id="7211368186050418507">시간대 자동 감지 기능을 사용하지 않습니다.</translation>
 <translation id="7216442368414164495">사용자가 세이프 브라우징 확장 보고를 선택하도록 허용</translation>
+<translation id="721970071627370558">기기 전원 상태 보고 사용 중지</translation>
 <translation id="7221574724100909818">보안 연결일 경우 자물쇠 아이콘 표시</translation>
 <translation id="7229365071755865554">비밀번호 관리자를 통한 비밀번호 저장 기능 사용</translation>
 <translation id="7229975860249300121"><ph name="PRODUCT_NAME" />에서 어떤 Google 계정이 브라우저 기본 계정(동기화 선택 과정에서 선택된 계정)으로 설정될 수 있는지 결정하는 데 사용되는 정규 표현식을 포함합니다. 동기화 선택 과정에서 선택된 계정입니다.
@@ -6311,6 +6379,7 @@
 <translation id="7587345076013230465">자동 선택 정책과 일치하는 인증서가 여러 개 있을 때마다 로그인 화면에서 사용자에게 클라이언트 인증서를 선택하라는 메시지 표시</translation>
 <translation id="7587921466180902617">Family Link 사용자용 스크린캐스트 dogfood 사용 설정</translation>
 <translation id="759957074386651883">세이프 브라우징 설정</translation>
+<translation id="7602621823177962064">기기 메모리 정보 보고 사용 중지</translation>
 <translation id="7604169113182304895">Android 앱이 자발적으로 이 목록을 사용하도록 선택할 수 있습니다. 강제로 Android 앱에서 이 목록을 사용하도록 할 수 없습니다.</translation>
 <translation id="7612157962821894603"><ph name="PRODUCT_NAME" /> 시작 시 시스템 전체 플래그 적용</translation>
 <translation id="7613115815080726221">사용자 입력이 없어서 유휴 작업이 실행되기까지 걸리는 시간(밀리초)입니다.</translation>
@@ -6658,6 +6727,7 @@
 <translation id="7992613144342460685">사이트에 창 배치 권한 허용</translation>
 <translation id="7995610550667275367">스캔(버전 87부터 지원됨)</translation>
 <translation id="7999023147219236247">앱에 대한 권한 요청을 승인하기 위한 정책입니다. PERMISSION_POLICY_UNSPECIFIED: 정책이 지정되지 않았습니다. 어느 수준에서든지 권한에 지정된 정책이 없으면 기본적으로 'PROMPT' 동작이 사용됩니다. PROMPT: 사용자에게 권한을 부여하도록 요청합니다. GRANT: 자동으로 권한을 부여합니다. DENY: 자동으로 권한을 거부합니다.</translation>
+<translation id="7999336306414770162">기기 VPD 정보 보고 사용 중지</translation>
 <translation id="7999818120028621358">데이터 유출 방지 이벤트 보고 사용</translation>
 <translation id="8001701200415781021"><ph name="PRODUCT_NAME" />에서 어떤 Google 계정이 브라우저 기본 계정으로 설정될 수 있는지 제한합니다.</translation>
 <translation id="800595420827930383">기존 플랫폼 인증서 확인 기능 사용</translation>
@@ -6708,6 +6778,7 @@
 <translation id="8056273037819805106"><ph name="PRODUCT_OS_NAME" /> 로그인 사용자 인증 정보가 관리 프록시 네트워크 인증에 사용됩니다.</translation>
 <translation id="8056800559672904373">관리 계정은 기본 계정이어야 하고 보조 계정이 없어야 하며 프로필 생성 시 기존 인터넷 사용 기록을 가져오도록 허용됨</translation>
 <translation id="8059164285174960932">원격 액세스 클라이언트가 인증 토큰을 확보해야 하는 URL</translation>
+<translation id="8059352177830050556">기기 백라이트 정보 보고 사용 설정</translation>
 <translation id="8062375903420954294">이 정책은 사용 가능한 최상의 연결을 찾으려고 할 때 WebRTC가 사용하는 IP 주소 및 인터페이스를 제한할 수 있습니다. RFC 8828 섹션 5.2(https://tools.ietf.org/html/rfc8828.html#section-5.2)를 참고하세요. 설정하지 않으면 기본적으로 가능한 모든 인터페이스를 사용합니다.</translation>
 <translation id="8062485064082966327">익명의 Google 서비스를 통해 라벨이 지정되지 않은 이미지에 자동 생성된 설명 제공</translation>
 <translation id="8071371098891664137"><ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" />에 <ph name="PRINTERS_BLOCKLIST" />을 선택할 경우 <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" />를 설정하면 사용자가 사용할 수 없는 프린터가 지정됩니다. ID가 이 정책에 명시된 프린터를 제외한 모든 프린터가 사용자에게 제공됩니다. ID는 <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />에 지정된 파일의 <ph name="ID_FIELD" /> 또는 <ph name="GUID_FIELD" /> 필드와 일치해야 합니다.</translation>
@@ -7025,6 +7096,7 @@
 <translation id="8367488518695804749">모든 사이트에서 팝업 표시 허용 안함</translation>
 <translation id="8369602308428138533">AC 전원으로 실행할 때 화면 꺼짐 지연</translation>
 <translation id="8371178326720637170">관리되는 확장 프로그램에서 Enterprise Hardware Platform API를 사용할 수 있도록 허용합니다.</translation>
+<translation id="8373176843640227330">기기 블루투스 정보 보고 사용 중지</translation>
 <translation id="8375817202037102567">다음 사이트에서 파일 및 디렉터리 쓰기 액세스 차단</translation>
 <translation id="8378266419596669629">사이트에서 로컬 글꼴 권한 차단</translation>
 <translation id="8379317372795444261">HTTP 연결에서 <ph name="BASIC_AUTH" /> 인증 허용</translation>
@@ -7073,6 +7145,7 @@
 
        이 정책은 <ph name="PRODUCT_NAME" /> 버전 95에서 삭제됩니다.</translation>
 <translation id="8427466947904008809">CRD가 원격 호스트에서 프록시된 WebAuthn API 요청을 실행하도록 허용합니다.</translation>
+<translation id="8428295225823548121">기기 메모리 정보 보고 사용 설정</translation>
 <translation id="8428635849021776523">Android 보고서 사용 중지</translation>
 <translation id="8433186206711564395">네트워크 설정</translation>
 <translation id="8433769814000220721">추천 콘텐츠 사용 설정</translation>
@@ -7273,6 +7346,18 @@
 
       False로 설정되어 있으면 어떠한 탭도 중단되지 않습니다.</translation>
 <translation id="8619748440665904084">처음 실행 시 양식 자동 완성 데이터 가져오기 사용 중지</translation>
+<translation id="8620103780247748230">이 정책은 인쇄 작업에서 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> IPP(인터넷 인쇄 프로토콜) 속성 값을 제어합니다.
+
+      정책을 문자열로 설정하면 모든 인쇄 작업에 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> 항목을 하나 더 추가하는 효과가 있습니다. 추가된 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> 항목의 <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> 구성요소는 변수를 대체한 후 정책 값으로 설정됩니다.
+
+      지원되는 변수는 <ph name="DIRECTORY_ID_PLACEHOLDER" />, <ph name="SERIAL_NUMBER_PLACEHOLDER" />, <ph name="ASSET_ID_PLACEHOLDER" />, <ph name="ANNOTATED_LOCATION_PLACEHOLDER" />, <ph name="USER_EMAIL_PLACEHOLDER" />, <ph name="USER_EMAIL_NAME_PLACEHOLDER" />, <ph name="USER_EMAIL_DOMAIN" />입니다. 지원되지 않는 자리표시자 변수는 확장되지 않습니다.
+
+      변수를 대체한 후의 결과 값은 인쇄 가능한 <ph name="ASCII" /> 문자로만 구성되고 길이가 255자를 초과하지 않는 경우 유효한 것으로 간주됩니다.
+
+      개인 정보 보호를 위해 이 정책은 <ph name="IPPS_PROTOCOL" />, <ph name="HTTPS_PROTOCOL" />, <ph name="USB_PROTOCOL" /> 또는 <ph name="IPP_USB_PROTOCOL" /> 프로토콜을 사용하여 프린터와 통신할 때만 적용됩니다. 또한 이 정책은 <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> 속성을 지원하는 프린터에만 적용됩니다.
+
+      정책을 설정하지 않거나 빈 값 또는 잘못된 값으로 설정하면 <ph name="CLIENT_INFO_PLACEHOLDER" />가 인쇄 작업 요청에 추가되지 않습니다.
+      </translation>
 <translation id="8623672932476443039">정책을 사용으로 설정하면 사용자가 분리된 앱 개발자 모드를 사용할 수 있습니다.
       정책을 사용 안함으로 설정하면 사용자가 해당 기능에 액세스할 수 없게 됩니다.
       정책을 설정하지 않은 경우 기본값은 ChromeOS에서 기업 관리 사용자에게는 허용되지 않고 그 외 모든 사용자 및 OS에는 허용되는 것입니다.</translation>
@@ -7497,6 +7582,7 @@
 <translation id="8882255181490012651">휴대전화 허브를 통해 휴대전화에서 최근 촬영한 사진 및 동영상에 액세스하도록 선택한 사용자를 허용하지 않습니다.</translation>
 <translation id="8887709920496070892">사용자의 입력 없어서 경고 대화상자가 표시되기까지 걸리는 시간(밀리초)입니다.</translation>
 <translation id="8890438048579188548"><ph name="CLOUD_PRINT_NAME" /> 지원 중단 경고 숨기기</translation>
+<translation id="8891334958985336685">기기 시스템 정보 보고 사용 중지</translation>
 <translation id="8892286064305622118"><ph name="PLUGIN_VM_NAME" />에 필요한 디스크 여유 공간</translation>
 <translation id="8892783613915541293">기기가 유휴 상태에서 AC 전원으로 구동되는 경우 취할 지연과 작업입니다.</translation>
 <translation id="8897796778265450949">SAML 없이 GAIA를 통해 인증된 사용자가 오프라인으로 로그인할 수 있는 기간 제한</translation>
@@ -7567,6 +7653,7 @@
 <translation id="8977192934280677167">기본 검색 공급업체 컨텍스트 메뉴 검색 액세스 허용</translation>
 <translation id="8983537551095611459">제한된 관리되가 게스트 세션 정리 절차에서 제외되는 확장 프로그램 ID 목록을 구성합니다.</translation>
 <translation id="8983539044126123594">추가 Google 계정으로 로그인 사용함</translation>
+<translation id="8985219286836584291">기기 시스템 정보 보고 사용 설정</translation>
 <translation id="8992176907758534924">모든 사이트에서 이미지 표시 허용 안함</translation>
 <translation id="8994954504552592260"><ph name="MS_AD_NAME" /> 관리 기기를 클라우드 관리로 이전할 수 있게 합니다. 이 정책은 회사 내 여러 기기의 터치리스 이전을 원격으로 시작할 수 있게 합니다. 또한 각 이전 단계가 최종 사용자에게 가능한 한 투명하게 공개됩니다.
 
@@ -7835,6 +7922,7 @@
       이 정책을 False로 설정하면 <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" />에 있는 사용자만 로그인할 수 있습니다.
 
       정책을 True로 설정하거나 설정하지 않으면 모든 사용자가 로그인할 수 있습니다.</translation>
+<translation id="966425658642788645">기본 동작 적용</translation>
 <translation id="971677226939413180">사용자가 이미지로 인쇄 옵션을 선택할 수 없음</translation>
 <translation id="974349541138387272">원하는 DNS-over-HTTPS 리졸버의 URI 템플릿 지정</translation>
 <translation id="979467274961593903">원격 디버깅 사용을 허용하지 않습니다.</translation>
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb
index 3fd7edc..93bf2db 100644
--- a/components/policy/resources/policy_templates_nl.xtb
+++ b/components/policy/resources/policy_templates_nl.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">Hiermee wordt de taal geconfigureerd die wordt afgedwongen op het <ph name="PRODUCT_OS_NAME" />-inlogscherm.
 
       Als dit beleid is ingesteld, wordt het inlogscherm altijd weergegeven in de taal die is aangegeven door de eerste waarde van dit beleid (het beleid wordt gedefinieerd als een lijst voor voorwaartse compatibiliteit). Als dit beleid niet is ingesteld of is ingesteld op een lege lijst, wordt het inlogscherm weergegeven in de taal van de laatste gebruikerssessie. Als dit beleid is ingesteld op een waarde die geen geldige taal is, wordt het inlogscherm weergegeven in een reservetaal (momenteel en-US).</translation>
+<translation id="1050158007881386475">Rapportage van moederbordstatus van apparaat uitzetten</translation>
 <translation id="1052499923181221200">Dit beleid heeft geen effect, tenzij SamlInSessionPasswordChangeEnabled is ingesteld op true.
       Als dat beleid is ingesteld op true en dit beleid bijvoorbeeld is ingesteld op 14, ontvangen SAML-gebruikers 14 dagen van tevoren een melding dat hun wachtwoord op een bepaalde datum verloopt.
       Ze kunnen dit direct oplossen door tijdens een sessie het wachtwoord te wijzigen voordat het verloopt.
@@ -325,6 +326,7 @@
       Als Verplicht (2) is geselecteerd, kunnen gebruikers de profielkiezer niet onderdrukken. De profielkiezer wordt ook getoond als er maar één profiel beschikbaar is.</translation>
 <translation id="1339174690935954950">Niet toestaan dat gebruikers feedback indienen</translation>
 <translation id="1342918903685430097">Stel de minimaal toegestane <ph name="PRODUCT_OS_NAME" />-versie in voor het apparaat.</translation>
+<translation id="1343128241903870688">Rapportage van app-informatie van apparaat uitzetten</translation>
 <translation id="1347198119056266798">Dit beleid is verouderd. Gebruik in plaats daarvan <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> en <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />. Dit beleid wordt genegeerd als het beleid <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> of <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> (verouderd) is ingesteld.
 
       Hiermee wordt afgedwongen dat zoekopdrachten in Google Zoeken worden uitgevoerd met SafeSearch ingesteld op 'actief' en wordt voorkomen dat gebruikers deze instelling kunnen wijzigen. Met deze instelling wordt ook de gemiddelde Beperkte modus op YouTube afgedwongen.
@@ -364,6 +366,7 @@
 <translation id="1393485621820363363">Zakelijke apparaatprinters aangezet</translation>
 <translation id="1395505489889158859">Gebruikersnaam en bestandsnaam naar systeemeigen printers sturen aanzetten</translation>
 <translation id="1397855852561539316">Voorgestelde URL voor standaardzoekprovider</translation>
+<translation id="1402227992519954892">Rapportage van app-informatie van apparaat aanzetten</translation>
 <translation id="141279920573530952">Als je dit beleid instelt, kun je een lijst met sites maken die automatisch toestemming krijgen voor toegang tot alle beschikbare seriële poorten.
 
       De URL's moeten geldig zijn, anders wordt het beleid genegeerd. Er wordt alleen gekeken naar de oorsprong (schema, host en poort) van de URL.
@@ -609,6 +612,7 @@
 <translation id="1616280227447957376">Doorgaan vanaf de SSL-waarschuwingspagina toestaan voor specifieke herkomsten</translation>
 <translation id="1617235075406854669">Verwijdering van browser- en downloadgeschiedenis aanzetten</translation>
 <translation id="1620510694547887537">Camera</translation>
+<translation id="162162247775156979">Rapportage van opslagstatus van apparaat uitzetten</translation>
 <translation id="1626379196197114720">Toestaan dat de Back-Forward Cache wordt gebruikt</translation>
 <translation id="1628974048137236820">Geen kaarten te zien op de pagina Nieuw tabblad</translation>
 <translation id="1630263002012156148">Als je het beleid toepast, wordt de pagina 'Nieuw tabblad' gebruikt als homepage van de gebruiker en wordt de URL voor de homepage genegeerd. Als je het beleid niet toepast, wordt de pagina 'Nieuw tabblad' nooit gebruikt als homepage van de gebruiker, tenzij de URL voor de homepage is ingesteld op chrome://newtab.
@@ -1668,8 +1672,12 @@
 <translation id="2665422249821137126">Grote muisaanwijzer op het inlogscherm gebruiken</translation>
 <translation id="2667894101494585925">Ophalen van optimalisatiegids aanzetten</translation>
 <translation id="2672012807430078509">Bepaalt of NTLM is aangezet als verificatieprotocol voor SMB-activeringen</translation>
+<translation id="2673363037046384711">De eindgebruiker kan de modus voor hoge efficiëntie aan- of uitzetten.</translation>
 <translation id="2678503605767349615">Vereiste clientcertificaten voor het hele apparaat</translation>
 <translation id="268577405881275241">Proxyfunctie voor comprimeren van gegevens aanzetten</translation>
+<translation id="268695908564263739">Met dit beleid kun je de modus voor hoge efficiëntie aan- of uitzetten. Door deze instelling worden tabbladen na een bepaalde tijd op de achtergrond verwijderd om geheugen vrij te maken.
+      Als je dit beleid niet instelt, kan de eindgebruiker deze instelling beheren in chrome://settings/performance.
+      </translation>
 <translation id="2691668238491124549">Als je het beleid instelt (alleen zoals aanbevolen), worden aanbevolen landinstellingen voor een beheerde sessie bovenaan de lijst geplaatst, in de volgorde waarin ze in het beleid worden weergegeven. De eerste aanbevolen landinstelling is vooraf geselecteerd.
 
       Als je het beleid niet instelt, wordt de landinstelling van de huidige UI vooraf geselecteerd.
@@ -2865,6 +2873,7 @@
 <translation id="3898345958122666461">NTLMv2 uitzetten</translation>
 <translation id="3898795800259311780">Screenshots toestaan of weigeren</translation>
 <translation id="3903313632842363082">Rapportage voor gebruikers van apparaat uitzetten</translation>
+<translation id="3904304709151553598">Rapportage van ventilatorinformatie van apparaat uitzetten</translation>
 <translation id="3907683835264956726">Zet online inloggen van gebruikers op een vergrendelscherm aan. Als het beleid wordt ingesteld op True, wordt online opnieuw verifiëren op een vergrendelscherm geactiveerd door <ph name="POLICY" />.
       Opnieuw verifiëren wordt onmiddellijk afgedwongen als het vergrendelscherm actief is, of de volgende keer dat een gebruiker het scherm vergrendelt nadat aan deze voorwaarde is voldaan.
       Als het beleid is ingesteld op False of niet is ingesteld, kunnen gebruikers het scherm altijd ontgrendelen met de lokale inloggegevens.</translation>
@@ -2908,6 +2917,7 @@
 
           Als dit beleid niet is ingesteld, staan de plaktoetsen in eerste instantie uit op het inlogscherm. De gebruiker kan deze functie op elk gewenst moment aanzetten.</translation>
 <translation id="3927291637826333102">Bureaublad-, venster- en tabbladopname door deze oorsprongen toestaan</translation>
+<translation id="3928726028264020458">Rapportage van VPD-informatie van apparaat aanzetten</translation>
 <translation id="3943930334592166130">Met dit beleid bepaal je of de gebruiker wordt gevraagd een clientcertificaat te selecteren als meerdere certificaten overeenkomen met <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" />.
       Als je dit beleid toepast, wordt de gebruiker gevraagd een clientcertificaat te selecteren als het beleid voor automatisch selecteren overeenkomt met meerdere certificaten.
       Als je dit beleid niet toepast of niet instelt, wordt de gebruiker misschien alleen gevraagd een clientcertificaat te selecteren als geen enkel certificaat overeenkomt met de automatische selectie.</translation>
@@ -2997,6 +3007,7 @@
       In <ph name="MS_WIN_NAME" /> is deze functionaliteit alleen beschikbaar voor instanties die zijn gekoppeld aan een <ph name="MS_AD_NAME" />-domein, worden uitgevoerd in Windows 10 Pro of zijn ingeschreven voor <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />. In <ph name="MAC_OS_NAME" /> is deze functionaliteit alleen beschikbaar voor instanties die via MDM worden beheerd of via MCX aan een domein zijn gekoppeld.</translation>
 <translation id="4043796890723386527">Voorkomen dat gebruikers secundaire profielen maken en gebruiken of dat ze de gastmodus gebruiken in de <ph name="LACROS_NAME" />-browser</translation>
 <translation id="4051723201852944592">Occlusie van vensters aanzetten</translation>
+<translation id="4052529125939620019">De componentextensie CryptoToken laden bij opstarten</translation>
 <translation id="4053157306171963473">Rapportage voor tijd van apparaatactiviteit uitzetten</translation>
 <translation id="4056910949759281379">SPDY-protocol uitzetten</translation>
 <translation id="4061107397839125009">Als je het beleid instelt, kun je een lijst met URL-patronen instellen van de sites die geen meldingen mogen bekijken.
@@ -3055,6 +3066,29 @@
 
       Als je het beleid instelt, kunnen gebruikers het niet wijzigen. Als je dit beleid niet instelt, staat het schermtoetsenbord in eerste instantie uit, maar kunnen gebruikers het op elk moment aanzetten.</translation>
 <translation id="412697421478384751">Gebruikers toestaan om zwakke pincodes in te stellen als pincode voor het vergrendelscherm</translation>
+<translation id="4130565559631908067">Dit beleid biedt een manier om de lijst met reeksen te overschrijven die de browser gebruikt voor first-party sets-functies.
+
+      Elke reeks in de lijst met first-party sets van de browser moet voldoen aan de vereisten van een first-party set.
+      Een first-party set moet een eigenaarsite en een of meer lidsites bevatten.
+      Een reeks kan ook een lijst bevatten van servicesites waarvan de set de eigenaar is, evenals een routebeschrijving van een site naar alle ccTLD-varianten.
+      Zie //github.com/WICG/first-party-sets voor meer informatie over first-party sets van <ph name="PRODUCT_NAME" />.
+
+      Alle sites in een first-party set moeten een registreerbaar domein zijn dat via HTTPS wordt gehost. Elke site in een first-party set moet ook uniek zijn. Dit betekent dat een site niet meer dan één keer kan worden vermeld in een first-party set.
+
+      Als dit beleid een leeg woordenboek krijgt, gebruikt de browser de openbare lijst met first-party sets.
+
+      Voor alle sites in een first-party set uit de lijst <ph name="REPLACEMENTS" /> geldt dat als een site ook aanwezig is in een first-party set in de lijst van de browser, die site wordt verwijderd uit de first-party set van de browser.
+      Daarna wordt de first-party set van het beleid toegevoegd aan de lijst met first-party sets van de browser.
+
+      Voor alle sites in een first-party set uit de lijst <ph name="ADDITIONS" /> geldt dat als een site ook aanwezig is in een first-party set in de lijst van de browser, de first-party set van de browser wordt geüpdatet zodat de nieuwe first-party set kan worden toegevoegd aan de lijst van de browser. Nadat de lijst van de browser is geüpdatet, wordt de first-party set van het beleid toegevoegd aan de lijst met first-party sets van de browser.
+
+      De lijst met first-party sets van de browser vereist dat voor alle sites op de lijst geen site in meer dan 1 reeks is opgenomen. Dit is ook vereist voor zowel de lijst <ph name="REPLACEMENTS" /> als de lijst <ph name="ADDITIONS" />. Een site kan ook niet in zowel de lijst <ph name="REPLACEMENTS" /> als de lijst <ph name="ADDITIONS" /> staan.
+
+      Jokertekens (*) worden zowel in first-party sets als in deze lijsten niet ondersteund als beleidswaarde.
+
+      Alle reeksen die in dit beleid worden opgegeven, moeten geldige first-party sets zijn. Zo niet, dan krijg je de relevante foutmelding.
+
+      Dit beleid is alleen beschikbaar voor Windows-instanties die zijn gekoppeld aan een <ph name="MS_AD_NAME" />-domein, voor Windows 10 Pro- of Enterprise-instanties die zijn ingeschreven voor apparaatbeheer en voor macOS-instanties die worden beheerd via MDM of aan een domein zijn gekoppeld via MCX.</translation>
 <translation id="4138655880188755661">Tijdslimiet</translation>
 <translation id="4147818922357566987">Varianten alleen aanzetten voor essentiële oplossingen</translation>
 <translation id="4150201353443180367">Weergave</translation>
@@ -3860,6 +3894,7 @@
 <translation id="5148753489738115745">Hiermee kun je extra parameters opgeven die worden gebruikt wanneer <ph name="PRODUCT_FRAME_NAME" /> <ph name="PRODUCT_NAME" /> start.
 
           Als dit beleid niet is ingesteld, wordt de standaardopdrachtregel gebruikt.</translation>
+<translation id="5151099177901233471">Rapportage van tijdzone-informatie van apparaat aanzetten</translation>
 <translation id="5152393033264257734">Controles voor DNS-onderschepping en infobalken voor 'bedoelde je http://intranetsite/' toestaan.</translation>
 <translation id="5152787786897382519">Zowel Chromium als Google Chrome bevatten enkele beleidsgroepen die voor het beheer van een functie van elkaar afhankelijk zijn. Deze reeksen worden vertegenwoordigd door de volgende beleidsgroepen. Aangezien beleidsregels meerdere bronnen kunnen hebben, worden alleen waarden afkomstig van de bron met de hoogste prioriteit toegepast. Waarden van een bron met een lagere prioriteit in dezelfde groep worden genegeerd. De prioriteitsvolgorde wordt gedefinieerd in <ph name="POLICY_PRIORITY_DOC_URL" />.</translation>
 <translation id="5153187201534281749">Icoon voor experimentele browserfuncties op werkbalk</translation>
@@ -4002,6 +4037,7 @@
       'Versie' kan in dit geval een exacte versie zijn (zoals '61.0.3163.120') of een versievoorvoegsel (zoals '61.0').  </translation>
 <translation id="5247973380763021389">Voorkomen dat cloudbeleidsregels voor gebruikers cloudbeleidsregels voor machines overschrijven.</translation>
 <translation id="5249453807420671499">Gebruikers kunnen Kerberos-accounts toevoegen</translation>
+<translation id="5249555581286638799">Modus voor hoge efficiëntie aanzetten</translation>
 <translation id="5252210248395576403">Dit beleid geeft Snelle antwoorden toegang tot geselecteerde content en toestemming om de informatie naar de server te sturen om vertaalresultaten te krijgen.
 
       Als je het beleid toepast of niet instelt, wordt Vertaling van Snelle antwoorden aangezet.
@@ -4010,6 +4046,7 @@
 
       Als je het beleid instelt op False of niet instelt, wordt 'Geïntegreerde desktop' uitgezet. Gebruikers kunnen deze functie dan niet aanzetten.</translation>
 <translation id="5255162913209987122">Kan worden aanbevolen</translation>
+<translation id="525543707238275321">Rapportage van CPU-informatie van apparaat uitzetten</translation>
 <translation id="5257395339965216304">Gegevens van gehoste apps</translation>
 <translation id="5262320080678421295">Vertrouwen in certificaten van de verouderde PKI van Symantec Corporation uitzetten</translation>
 <translation id="5266173014392157048">Dit beleid is beëindigd. Gebruik in plaats daarvan het beleid <ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />.
@@ -4074,6 +4111,7 @@
       Als dit beleid niet is ingesteld, gebruikt <ph name="PRODUCT_NAME" /> de standaard maximale versie.
 
       Dit beleid kan ook worden ingesteld op een van de volgende waarden: 'tls1.2' of 'tls1.3'. Wanneer dit beleid is ingesteld, gebruikt <ph name="PRODUCT_NAME" /> geen hogere SSL-/TLS-versies dan de opgegeven versie. Als er een waarde wordt ingesteld die niet wordt herkend, wordt deze genegeerd.</translation>
+<translation id="5329018127554115226">De modus voor hoge efficiëntie wordt uitgezet.</translation>
 <translation id="5330684698007383292"><ph name="PRODUCT_FRAME_NAME" /> toestaan de volgende soorten content te verwerken.</translation>
 <translation id="5331746669335642668"><ph name="PRODUCT_NAME" />-cloudbeleid krijgt voorrang op het platformbeleid.</translation>
 <translation id="5346587320074666194">Toegang tot sensoren op deze sites blokkeren</translation>
@@ -4270,6 +4308,7 @@
       Dit beleid is niet van toepassing op kanaalwisselingen.</translation>
 <translation id="5519331583722582543">Een Booleaanse markering die aangeeft of het schermtoetsenbord de optie voor invoer via handschriftherkenning heeft.</translation>
 <translation id="5519619299971727565">Gebruiksrapportage voor Linux-apps uitzetten</translation>
+<translation id="5521035900165046997">Rapportage van bluetooth-informatie van apparaat aanzetten</translation>
 <translation id="5521875416764302911">Voorkomen dat gebruikers inloggen op <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">Query's naar de Quirks Server en potentiële downloads van hardwarespecifieke configuratiebestanden toestaan</translation>
 <translation id="5526701598901867718">Alle (onbeveiligd)</translation>
@@ -4325,6 +4364,7 @@
 <translation id="5598417829613725146">Canvas (ondersteund vanaf versie 90)</translation>
 <translation id="5599461642204007579">Beheerinstellingen voor <ph name="MS_AD_NAME" /></translation>
 <translation id="5601503069213153581">Pincode</translation>
+<translation id="5607021831414604820">Rapportage van opslagstatus van apparaat aanzetten</translation>
 <translation id="5614865701790130558">Gebeurtenissen voor op beleid gebaseerde installaties van extensies registreren</translation>
 <translation id="5618398258385745432">De bijbehorende instelling werd gebruikt voordat hernieuwde verificatie voor de weergave van wachtwoorden is geïntroduceerd. Sindsdien hebben de instelling en dit beleid geen invloed gehad op het gedrag van Chrome. Het huidige gedrag van Chrome is nu hetzelfde alsof het beleid was ingesteld om wachtwoorden niet als leesbare tekst te tonen op de pagina met instellingen voor Wachtwoordmanager. Dat betekent dat de pagina met instellingen alleen een tijdelijke aanduiding bevat. Chrome laat het wachtwoord alleen zien als de gebruiker op Tonen klikt (en zo nodig de hernieuwde verificatie uitvoert). De oorspronkelijke beschrijving van het beleid volgt hieronder.
 
@@ -4433,6 +4473,7 @@
       Opmerking: Het cachegeheugen wordt gewist als je opnieuw opstart en uitlogt.</translation>
 <translation id="5717973246079053225">Cloudrapportage voor beheerde profielen uitzetten</translation>
 <translation id="572155275267014074">Android-instellingen</translation>
+<translation id="5722577409367087850">De extensie laden</translation>
 <translation id="5728154254076636808">Aanmaak van roaming-exemplaren voor <ph name="PRODUCT_NAME" />-profielgegevens aanzetten</translation>
 <translation id="5729308727912841256">Kerberos-wachtwoord. De tijdelijke aanduiding <ph name="PASSWORD_PLACEHOLDER" /> wordt vervangen door het wachtwoord voor inloggen.</translation>
 <translation id="5732972008943405952">Formuliergegevens voor Automatisch invullen importeren uit standaardbrowser bij eerste uitvoering</translation>
@@ -4683,6 +4724,7 @@
       Als je het beleid niet toepast, kunnen gebruikers deze aanbiedingen niet inwisselen.</translation>
 <translation id="6046615715547751255">Opties voor gedetailleerde rapportage niet toestaan</translation>
 <translation id="6048199181629830227">Stroombeheer voor piekuren aanzetten</translation>
+<translation id="6049117606554031363">Rapportage van moederbordstatus van apparaat aanzetten</translation>
 <translation id="6053681087509103368">Toestaan dat WebRTC verouderde versies van het TLD-/DTLS-protocol gebruikt</translation>
 <translation id="6058879286588763839">Als je <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> instelt, geef je het stroombeheerbeleid voor de batterijoplaadmodus op (als dit wordt ondersteund op het apparaat), tenzij <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" /> is opgegeven (dat voorrang krijgt op <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />). Dit beleid beheert het opladen van de batterij op dynamische wijze door spanning en belasting te minimaliseren. Zo wordt de batterijduur verlengd.
 
@@ -4715,6 +4757,7 @@
 <translation id="6099853574908182288">Standaard kleurenmodus voor afdrukken</translation>
 <translation id="6102342563050263313">Scrollen naar opgegeven tekst in URL-fragmenten aanzetten</translation>
 <translation id="6102449843040973938">Niet voorkomen dat <ph name="BOREALIS_NAME" /> wordt uitgevoerd op een apparaat</translation>
+<translation id="610892566190435199">Rapportage van aan/uit-status van apparaat aanzetten</translation>
 <translation id="6111936128861357925">Easter egg-dinosaurusgame toestaan</translation>
 <translation id="6112524153927257380">Als je het beleid instelt, kunnen gebruikers de keuzes voor downloadbeveiliging niet omzeilen.
 
@@ -4858,6 +4901,7 @@
       Dit beleid is bedoeld om bedrijven de flexibiliteit te bieden om de audiosandbox uit te zetten als ze instellingen voor beveiligingssoftware gebruiken die de sandbox kunnen verstoren.</translation>
 <translation id="624818583115864448">poort 554 (blokkering kan worden opgeheven tot 15-10-2021)</translation>
 <translation id="6252773211180267325">Niet voorkomen dat <ph name="BOREALIS_NAME" /> wordt uitgevoerd voor een gebruiker</translation>
+<translation id="625580680776945310">De modus voor hoge efficiëntie wordt aangezet.</translation>
 <translation id="6258658183356534534">De GREASE-updatefunctie voor User-Agent Client Hints beheren.</translation>
 <translation id="6261643884958898336">ID-gegevens van machine rapporteren</translation>
 <translation id="6265892395051519509">Toegang tot sensoren op deze sites toestaan</translation>
@@ -5016,6 +5060,7 @@
 <translation id="6368403635025849609">JavaScript toestaan op deze sites</translation>
 <translation id="6371561334154580937">Dialoogvenster voor uitloggen tonen als het laatste venster wordt gesloten.</translation>
 <translation id="6372105930898423193">Hiermee sta je toe dat de AppCache-functie opnieuw wordt aangezet, ook als deze standaard is uitgezet.</translation>
+<translation id="6373299801585455337">Rapportage van CPU-informatie van apparaat aanzetten</translation>
 <translation id="6376540107659524656">SSH uitzetten in Terminal System App</translation>
 <translation id="6376659517206731212">Kan verplicht zijn</translation>
 <translation id="6377031865393559909">Toestaan dat gebruikers bureautemplates gebruiken</translation>
@@ -5023,6 +5068,7 @@
 <translation id="6378393933102834628">Als je het beleid instelt op 'True', wordt de app-snelkoppeling getoond. Als je het beleid instelt op 'False', wordt deze snelkoppeling nooit getoond.
 
       Als je het beleid instelt, kunnen gebruikers het niet wijzigen. Als je het beleid niet instelt, kunnen gebruikers aangeven of de app-snelkoppeling moet worden getoond of verborgen in het contextmenu van de bookmarkbalk.</translation>
+<translation id="638003144128412430">Rapportage van tijdzone-informatie van apparaat uitzetten</translation>
 <translation id="6382351416269252693">Hiermee wordt een lijst met URL-patronen voor sites ingesteld waarmee sites worden gespecificeerd waarvoor het recht voor lokale lettertypen automatisch wordt geweigerd. Dit beperkt de mogelijkheid van sites om informatie over lokale lettertypen te bekijken.
 
       Ga naar https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns voor gedetailleerde informatie over geldige site-URL-patronen. Jokertekens, <ph name="WILDCARD_VALUE" />, zijn toegestaan. Dit beleid zoekt alleen overeenkomsten op basis van de herkomst, dus elk pad in het URL-patroon wordt genegeerd.
@@ -5068,6 +5114,7 @@
 <translation id="6440051664870270040">Toestaan dat sites tegelijkertijd kunnen navigeren en pop-ups kunnen openen</translation>
 <translation id="6447948611083700881">Back-up en herstel staat uit</translation>
 <translation id="6449476513004303784">Gebruikers niet toestaan certificaten te beheren</translation>
+<translation id="6452882999388592166">Als je dit beleid toepast, wordt de ingebouwde componentextensie CryptoToken geladen bij het opstarten. Als je het beleid niet toepast of niet instelt, wordt CryptoToken niet geladen als de browser opstart. Dit beleid is bedoeld als tijdelijke oplossing voor sites die problemen hebben doordat 'chrome.runtime' niet gedefinieerd is als gevolg van de verwijdering van CryptoToken in M106. Websites mogen niet afhankelijk zijn van een zonder voorwaarden gedefinieerde 'chrome.runtime'.</translation>
 <translation id="6453641799812499182"><ph name="CORS" />-controlebeperkingen voor de nieuwe <ph name="CORS" />-implementatie aanzetten</translation>
 <translation id="645425387487868471">Inloggen voor <ph name="PRODUCT_NAME" /> verplichten</translation>
 <translation id="6455842857207956758">Hiermee wordt SAML-wachtwoordsynchronisatie tussen meerdere Chrome-apparaten aangezet door de waarde van de wachtwoordsynchronisatietoken te monitoren en een gebruiker de online verificatie opnieuw te laten uitvoeren als het wachtwoord is geüpdatet en moet worden gesynchroniseerd.
@@ -5554,6 +5601,7 @@
 <translation id="6903814433019432303">Dit beleid wordt alleen toegepast in de winkelmodus.
 
       Bepaalt welke reeks URL's moet worden geladen als de demosessie wordt gestart. Dit beleid overschrijft alle andere procedures voor het instellen van de eerste URL en kan daarom alleen worden toegepast in een sessie die niet is toegewezen aan een specifieke gebruiker.</translation>
+<translation id="6903818804346914108">Rapportage van ventilatorinformatie van apparaat aanzetten</translation>
 <translation id="6905405893096403868">Als je dit beleid instelt op een lijst met tekenreeksen, wordt elke tekenreeks doorgegeven aan de alternatieve browser als afzonderlijke opdrachtregelparameter. In <ph name="MS_WIN_NAME" /> worden de parameters samengevoegd met spaties. In <ph name="MAC_OS_NAME" /> en <ph name="LINUX_OS_NAME" /> mag een parameter spaties bevatten en wordt dan nog steeds verwerkt als één parameter.
 
       Als een parameter <ph name="URL_PLACEHOLDER" /> bevat, wordt <ph name="URL_PLACEHOLDER" /> vervangen door de URL van de pagina die moet worden geopend. Als geen enkele parameter <ph name="URL_PLACEHOLDER" /> bevat, wordt de URL toegevoegd aan het einde van de opdrachtregel.
@@ -5854,6 +5902,7 @@
 <translation id="718126088895133062">Met dit beleid wordt de licentiegebruikers-ID voor <ph name="PLUGIN_VM_NAME" /> voor dit apparaat opgegeven.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">Een Google-webservice gebruiken om spelfouten op te lossen</translation>
+<translation id="7187248416163189586">Rapportage van achtergrondverlichtingsinformatie van apparaat uitzetten</translation>
 <translation id="718850220532931090">Dit beleid is verouderd. Gebruik in plaats daarvan <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />.
 
       Als je het beleid instelt, geef je de toegestane extensies op die de <ph name="ENTERPRISE_PLATFORM_KEYS_API" />-functie <ph name="CHALLENGE_USER_KEY_FUNCTION" /> moet gebruiken voor externe bevestiging. Extensies moeten op deze lijst staan om de API te gebruiken.
@@ -5877,6 +5926,7 @@
 <translation id="7207095846245296855">Google SafeSearch afdwingen</translation>
 <translation id="7211368186050418507">Tijdzone nooit automatisch detecteren</translation>
 <translation id="7216442368414164495">Hiermee kunnen gebruikers zich aanmelden voor uitgebreide rapportage van Safe Browsing</translation>
+<translation id="721970071627370558">Rapportage van aan/uit-status van apparaat uitzetten</translation>
 <translation id="7221574724100909818">Hangsloticoon gebruiken voor beveiligde verbindingen</translation>
 <translation id="7229365071755865554">Opslag van wachtwoorden met de Wachtwoordmanager aanzetten</translation>
 <translation id="7229975860249300121">Bevat een reguliere expressie die wordt gebruikt om te bepalen welke Google-accounts kunnen worden ingesteld als primair browseraccount in <ph name="PRODUCT_NAME" /> (oftewel het account dat wordt gekozen als de gebruiker synchronisatie toestaat).
@@ -6236,6 +6286,7 @@
 <translation id="7587345076013230465">De gebruiker vragen om het clientcertificaat te selecteren als het beleid voor automatische selectie overeenkomt met meerdere certificaten op het inlogscherm</translation>
 <translation id="7587921466180902617">Dogfood-versie van Screencast aanzetten voor gebruikers van Family Link</translation>
 <translation id="759957074386651883">Safe Browsing-instellingen</translation>
+<translation id="7602621823177962064">Rapportage van geheugeninformatie van apparaat uitzetten</translation>
 <translation id="7604169113182304895">Het is mogelijk dat Android-apps deze lijst op vrijwillige basis respecteren. Je kunt ze niet dwingen om de lijst te respecteren.</translation>
 <translation id="7612157962821894603">Markeringen voor het hele systeem die worden toegepast bij het starten van <ph name="PRODUCT_NAME" /></translation>
 <translation id="7613115815080726221">De tijdsduur zonder gebruikersinvoer waarna de actie voor inactiviteit wordt ondernomen (in milliseconden)</translation>
@@ -6582,6 +6633,7 @@
 <translation id="7992613144342460685">Het recht voor vensterplaatsing toestaan voor deze sites</translation>
 <translation id="7995610550667275367">Scannen (ondersteund vanaf versie 87)</translation>
 <translation id="7999023147219236247">Beleid om rechten aan apps te verlenen. PERMISSION_POLICY_UNSPECIFIED: Beleid niet gespecificeerd. Als er geen beleid is gespecificeerd voor een recht op een bepaald niveau, wordt het gedrag PROMPT standaard gebruikt. PROMPT: De gebruiker vragen een recht te verlenen. GRANT: Een recht automatisch verlenen. DENY: Een recht automatisch weigeren.</translation>
+<translation id="7999336306414770162">Rapportage van VPD-informatie van apparaat uitzetten</translation>
 <translation id="7999818120028621358">Rapportage van gebeurtenissen ter voorkoming van datalekken aanzetten</translation>
 <translation id="8001701200415781021">Beperken welke Google-accounts mogen worden ingesteld als primaire browseraccounts in <ph name="PRODUCT_NAME" /></translation>
 <translation id="800595420827930383">De verouderde platformcertificaatverificatie gebruiken</translation>
@@ -6632,6 +6684,7 @@
 <translation id="8056273037819805106">De inloggegevens van <ph name="PRODUCT_OS_NAME" /> worden gebruikt voor netwerkverificatie van een beheerde proxy.</translation>
 <translation id="8056800559672904373">Een beheerd account moet een primair account zijn, mag geen secundaire accounts hebben en bestaande browsegegevens mogen worden geïmporteerd bij het maken van een profiel</translation>
 <translation id="8059164285174960932">URL waarbij clients met externe toegang hun verificatietoken moeten ophalen</translation>
+<translation id="8059352177830050556">Rapportage van achtergrondverlichtingsinformatie van apparaat aanzetten</translation>
 <translation id="8062375903420954294">Dit beleid maakt het mogelijk om te beperken welke IP-adressen en interfaces worden gebruikt door WebRTC als naar de beste beschikbare verbinding wordt gezocht. Zie RFC 8828 artikel 5.2 (https://tools.ietf.org/html/rfc8828.html#section-5.2). Als dit niet is ingesteld, worden standaard alle beschikbare interfaces gebruikt.</translation>
 <translation id="8062485064082966327">Een anonieme Google-service gebruiken voor automatische beschrijvingen van niet-gelabelde afbeeldingen</translation>
 <translation id="8071371098891664137">Als <ph name="PRINTERS_BLOCKLIST" /> wordt gekozen voor <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" />, kun je door <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> in te stellen aangeven welke printers gebruikers niet kunnen gebruiken. Alle printers zijn beschikbaar voor de gebruiker, behalve de ID's in dit beleid. De ID's moeten overeenkomen met het veld <ph name="ID_FIELD" /> of <ph name="GUID_FIELD" /> in het bestand dat is opgegeven in <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />.</translation>
@@ -6948,6 +7001,7 @@
 <translation id="8367488518695804749">Niet toestaan dat sites pop-ups tonen</translation>
 <translation id="8369602308428138533">Vertraging voor uitzetten van scherm als op netstroom wordt gewerkt</translation>
 <translation id="8371178326720637170">Hiermee kunnen beheerde extensies de Enterprise Hardware Platform-API gebruiken</translation>
+<translation id="8373176843640227330">Rapportage van bluetooth-informatie van apparaat uitzetten</translation>
 <translation id="8375817202037102567">Schrijftoegang tot bestanden en directory's voor deze sites blokkeren</translation>
 <translation id="8378266419596669629">Het recht voor lokale lettertypen blokkeren op deze sites</translation>
 <translation id="8379317372795444261"><ph name="BASIC_AUTH" />-verificatie is toegestaan voor HTTP-verbindingen</translation>
@@ -6996,6 +7050,7 @@
 
        Dit beleid wordt verwijderd in <ph name="PRODUCT_NAME" />-versie 95.</translation>
 <translation id="8427466947904008809">Toestaan dat CRD WebAuthn API-verzoeken uitvoert die afkomstig zijn van een externe host.</translation>
+<translation id="8428295225823548121">Rapportage van geheugeninformatie van apparaat aanzetten</translation>
 <translation id="8428635849021776523">Android-rapporten uitzetten</translation>
 <translation id="8433186206711564395">Netwerkinstellingen</translation>
 <translation id="8433769814000220721">Voorgestelde content aanzetten</translation>
@@ -7426,6 +7481,7 @@
 <translation id="8882255181490012651">Hierdoor kunnen gebruikers die Telefoonhub toestaan, geen toegang krijgen tot recente foto's en video's die ze hebben gemaakt op hun telefoon</translation>
 <translation id="8887709920496070892">De tijdsduur zonder gebruikersinvoer waarna een waarschuwingsdialoogvenster wordt getoond (in milliseconden)</translation>
 <translation id="8890438048579188548">Waarschuwingen over beëindiging van <ph name="CLOUD_PRINT_NAME" /> verbergen</translation>
+<translation id="8891334958985336685">Rapportage van systeeminformatie van apparaat uitzetten</translation>
 <translation id="8892286064305622118">Vrije schijfruimte vereist voor <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="8892783613915541293">Vertragingen en acties die moeten worden ondernomen als het apparaat inactief is en op netvoeding werkt</translation>
 <translation id="8897796778265450949">Beperk de tijd dat een gebruiker die via GAIA is geverifieerd zonder SAML, offline kan inloggen.</translation>
@@ -7493,6 +7549,7 @@
 <translation id="8977192934280677167">Toegang toestaan tot standaard zoekprovider in contextmenu</translation>
 <translation id="8983537551095611459">De lijst met extensie-ID's instellen die zijn vrijgesteld van de opschoonprocedure voor beperkte beheerde gastsessies</translation>
 <translation id="8983539044126123594">Inloggen met extra Google-accounts aanzetten</translation>
+<translation id="8985219286836584291">Rapportage van systeeminformatie van apparaat aanzetten</translation>
 <translation id="8992176907758534924">Niet toestaan dat sites afbeeldingen tonen</translation>
 <translation id="8994954504552592260">Hiermee zet je de migratie van door <ph name="MS_AD_NAME" /> beheerde apparaten naar cloudbeheer aan. Met dit beleid kun je op afstand een contactloze migratie van meerdere apparaten in een bedrijf starten. Bovendien is de migratie zo transparant mogelijk voor de eindgebruikers.
 
@@ -7761,6 +7818,7 @@
       Als dit beleid is ingesteld op False, kunnen alleen gebruikers inloggen die zijn opgenomen in <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" />.
 
       Als dit beleid is ingesteld op True of niet is ingesteld, kunnen alle gebruikers inloggen.</translation>
+<translation id="966425658642788645">Standaardgedrag toepassen</translation>
 <translation id="971677226939413180">Optie 'Afdrukken als afbeelding' niet beschikbaar voor gebruikersselectie.</translation>
 <translation id="974349541138387272">URI-template van gewenste DNS-over-HTTPS-resolver opgeven</translation>
 <translation id="979467274961593903">Het gebruik van foutopsporing op afstand niet toestaan</translation>
diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb
index 0d6988cc..40d1208 100644
--- a/components/policy/resources/policy_templates_ru.xtb
+++ b/components/policy/resources/policy_templates_ru.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">Устанавливает региональные настройки для экрана входа <ph name="PRODUCT_OS_NAME" />.
 
       Если правило настроено, для экрана входа будет задан язык, указанный первым (правило определяется списком для прямой совместимости). Если правило не настроено или указан пустой список, будут использоваться региональные настройки последнего сеанса пользователя. Если задано некорректное значение, будет использоваться резервное значение (en-US).</translation>
+<translation id="1050158007881386475">Отключить отправку данных о статусе процессора устройства</translation>
 <translation id="1052499923181221200">Это правило действует, только если в правиле SamlInSessionPasswordChangeEnabled установлено значение True.
       Когда это правило включено и в нем установлено, к примеру, значение 14, — это означает, что пользователи SAML будут предупреждены за 14 дней до того, как срок действия их пароля истечет.
       Получив уведомление, пользователи сразу смогут изменить пароль во время сеанса.
@@ -327,6 +328,7 @@
       Если установлено значение Forced (2), пользователи не смогут закрыть окно, пока не сделают выбор. Оно будет появляться, даже если доступен только один профиль.</translation>
 <translation id="1339174690935954950">Запретить пользователям оставлять отзывы</translation>
 <translation id="1342918903685430097">Настроить версию <ph name="PRODUCT_OS_NAME" />, минимально допустимую для устройства</translation>
+<translation id="1343128241903870688">Отключить отправку данных о приложениях на устройстве</translation>
 <translation id="1347198119056266798">Правило больше не поддерживается, вместо него используются <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> и <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />. Правило будет игнорироваться, если не включено одно из следующих правил: <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />, <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> или <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> (устаревшее).
 
       Оно включает Безопасный поиск Google и запрещает пользователям менять эту настройку. При этом также включается умеренный Безопасный режим на YouTube.
@@ -366,6 +368,7 @@
 <translation id="1393485621820363363">Принтеры, доступные на устройствах компании</translation>
 <translation id="1395505489889158859">Разрешить отправлять имя пользователя и название файла локальным принтерам</translation>
 <translation id="1397855852561539316">URL используемой по умолчанию поисковой системы для запроса подсказок</translation>
+<translation id="1402227992519954892">Включить отправку данных о приложениях на устройстве</translation>
 <translation id="141279920573530952">С помощью этого правила вы можете задать список сайтов, которым будет автоматически предоставляться доступ ко всем доступным последовательным портам.
 
       Необходимо указывать действительные URL, иначе правило будет игнорироваться. Учитывается только источник URL (схема, хост и порт).
@@ -611,6 +614,7 @@
 <translation id="1616280227447957376">Разрешить пропуск предупреждений об ошибках SSL на определенных страницах</translation>
 <translation id="1617235075406854669">Удаление истории просмотров и загрузок браузера</translation>
 <translation id="1620510694547887537">Камера</translation>
+<translation id="162162247775156979">Отключить отправку данных о статусе хранилища устройства</translation>
 <translation id="1626379196197114720">Разрешить использование возвратного кеша</translation>
 <translation id="1628974048137236820">Не показывать подсказки на странице быстрого доступа</translation>
 <translation id="1630263002012156148">Если правило включено, в качестве главной страницы используется страница быстрого доступа. Заданный URL главной страницы игнорируется. Если правило выключено, страница быстрого доступа открывается, только когда в качестве URL главной страницы указан путь chrome://newtab.
@@ -1095,6 +1099,7 @@
 <translation id="2043770014371753404">Недоступные корпоративные принтеры</translation>
 <translation id="2057317273526988987">Разрешить доступ к списку URL</translation>
 <translation id="2058055310819710697">Включить режим разработчика изолированных приложений</translation>
+<translation id="205807990145127714">Данные телеметрии, которые необходимо передавать при изменении силы сигнала</translation>
 <translation id="2061123930713023976">Разрешить захват сетевых пакетов для отладки</translation>
 <translation id="2061810934846663491">Настроить доменные имена для хостов удаленного доступа</translation>
 <translation id="2062632109797189011">Снова сделать window.webkitStorageInfo API доступным</translation>
@@ -1696,8 +1701,12 @@
 <translation id="2665422249821137126">Включить большой курсор на экране входа</translation>
 <translation id="2667894101494585925">Разрешить получение метаданных и моделей машинного обучения при загрузке страниц</translation>
 <translation id="2672012807430078509">Определяет, можно ли использовать NTLM в качестве протокола аутентификации для подключенных ресурсов SMB</translation>
+<translation id="2673363037046384711">Конечный пользователь может включать или отключать режим высокой эффективности</translation>
 <translation id="2678503605767349615">Обязательные сертификаты клиента на уровне устройства</translation>
 <translation id="268577405881275241">Использовать прокси-сервер для сжатия данных</translation>
+<translation id="268695908564263739">Правило позволяет включать или отключать режим высокой эффективности. Он помогает освободить память, закрывая вкладки, которые некоторое время оставались неактивными.
+      Если правило не настроено, конечный пользователь может включать или отключать этот режим на странице chrome://settings/performance.
+      </translation>
 <translation id="2691668238491124549">Если правило настроено (оно работает только как рекомендация), рекомендованные региональные настройки для управляемого сеанса перемещаются в верхнюю часть списка в том порядке, в котором они указаны в правиле. В этом случае по умолчанию выбирается первый вариант.
 
       Если значение не установлено, используются текущие региональные настройки интерфейса.
@@ -2899,6 +2908,7 @@
 <translation id="3898345958122666461">Отключить NTLMv2</translation>
 <translation id="3898795800259311780">Разрешить или запретить показ экрана</translation>
 <translation id="3903313632842363082">Отключить отправку данных о пользователях устройства</translation>
+<translation id="3904304709151553598">Отключить отправку данных о вентиляторе устройства</translation>
 <translation id="3907683835264956726">Это правило позволяет пользователю войти в аккаунт на заблокированном экране. Если для правила выбрано значение True, повторная аутентификация на заблокированном экране запускается в онлайн-режиме, например с помощью правила <ph name="POLICY" />.
       Процедура повторной аутентификации запускается принудительно, если экран заблокирован системой или пользователем и соблюдено соответствующее условие.
       Если правило не настроено или для него задано значение False, пользователи могут в любой момент разблокировать экран, указав свои локальные учетные данные.</translation>
@@ -2941,6 +2951,7 @@
 
           Если значение не задано, залипание клавиш на экране входа будет по умолчанию отключено, но пользователь сможет включить его в любой момент.</translation>
 <translation id="3927291637826333102">Разрешить захват рабочего стола, окна и вкладки этими источниками</translation>
+<translation id="3928726028264020458">Включить отправку данных о VPD</translation>
 <translation id="3943930334592166130">Это правило определяет, запрашивать ли выбор сертификата клиента, если <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" /> соответствует несколько сертификатов.
       Если правило включено, пользователю предлагается выбрать один из сертификатов клиента, соответствующих правилу автоматического выбора.
       Если правило отключено или не настроено, пользователю предлагается указать сертификат, только когда нет сертификатов, соответствующих правилу автоматического выбора.</translation>
@@ -3030,6 +3041,7 @@
       В <ph name="MS_WIN_NAME" /> это правило можно настроить только на устройствах, которые входят в домен <ph name="MS_AD_NAME" />, на которых установлена ОС Windows 10 Pro или которые зарегистрированы в программе "<ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />". В <ph name="MAC_OS_NAME" /> правило поддерживается только на устройствах, которые контролируются с помощью ПО для управления мобильными устройствами или добавлены в домен через MCX.</translation>
 <translation id="4043796890723386527">Запретить пользователям создавать дополнительные профили и использовать гостевой режим в браузере <ph name="LACROS_NAME" /></translation>
 <translation id="4051723201852944592">Включить перекрытие окон</translation>
+<translation id="4052529125939620019">Загружать расширение CryptoToken при запуске</translation>
 <translation id="4053157306171963473">Отключить отправку данных о продолжительности работы устройства</translation>
 <translation id="4056910949759281379">Отключение протокола SPDY</translation>
 <translation id="4061107397839125009">Позволяет задать список шаблонов URL для указания сайтов, которым запрещено показывать уведомления.
@@ -3088,6 +3100,38 @@
 
       Если правило настроено, пользователи не могут изменить его. Если правило не настроено, экранная клавиатура будет выключена по умолчанию, но пользователи смогут включить ее в любое время.</translation>
 <translation id="412697421478384751">Разрешать пользователям устанавливать ненадежные PIN-коды для разблокировки экрана</translation>
+<translation id="4130565559631908067">Это правило позволяет переопределять список наборов, которые браузер использует для функций First-Party Set.
+
+      Каждый набор в списке браузера должен соответствовать требованиям набора First-Party Set.
+      First-Party Set должен состоять из сайта-владельца и одного или нескольких сайтов-участников.
+      Набор также может содержать список сервисов, которыми он владеет, и данные от сайта обо всех вариантах национальных доменов верхнего уровня.
+      Дополнительную информацию о наборах First-Party Set, которые использует <ph name="PRODUCT_NAME" />, можно найти на странице https://github.com/WICG/first-party-sets.
+
+      Каждый сайт в наборе First-Party Set должен быть указан как регистрируемый домен, который использует протокол HTTPS. Кроме того, каждый сайт в наборе First-Party Set должен быть уникальным.
+      Это значит, что сайт нельзя вносить в набор First-Party Set несколько раз.
+
+      Если для правила указан пустой словарь, браузер использует общедоступный список наборов First-Party Set.
+
+      Для всех сайтов набора First-Party Set из списка <ph name="REPLACEMENTS" /> справедливо следующее: если сайт указан
+      в First-Party Set в списке браузера, такой сайт будет удален из набора First-Party Set браузера.
+      Взамен в список наборов First-Party Set браузера будет добавлен First-Party Set из правила.
+
+      Для всех сайтов набора First-Party Set из списка <ph name="ADDITIONS" /> справедливо следующее: если сайт указан
+      в First-Party Set в списке браузера, First-Party Set браузера будет обновлен,
+      чтобы в список браузера можно было добавить новый First-Party Set. После обновления
+      в список наборов First-Party Set браузера будет добавлен First-Party Set из правила.
+
+      Каждый сайт в списке наборов First-Party Set браузера должен
+      быть указан только в одном наборе. Это требование распространяется на списки <ph name="REPLACEMENTS" />
+      и <ph name="ADDITIONS" />. Сайт также не может находиться одновременно в
+      списках <ph name="REPLACEMENTS" /> и <ph name="ADDITIONS" />.
+
+      Подстановочные знаки (*) нельзя указывать в значениях правила и в наборах First-Party Set из списков.
+
+      Все наборы, предоставленные в правиле, должны быть действительными наборами First-Party Set, иначе
+      выдается надлежащее сообщение об ошибке.
+
+      Правило можно использовать только на устройствах Windows, входящих в домен <ph name="MS_AD_NAME" />, на устройствах Windows 10 Pro или Enterprise с регистрацией в консоли администратора, а также на устройствах macOS, которые контролируются с помощью системы управления мобильными устройствами или добавлены в домен через MCX.</translation>
 <translation id="4138655880188755661">Ограничение времени</translation>
 <translation id="4147818922357566987">Разрешить только модификации, связанные с критическими исправлениями</translation>
 <translation id="4150201353443180367">Экран</translation>
@@ -3686,6 +3730,7 @@
       Если правило отключено или не задано, регистрация через <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> не обязательна. В случае неудачи запуск <ph name="PRODUCT_NAME" /> не блокируется.
 
       Это правило используется на компьютерах. Подробнее: https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744.</translation>
+<translation id="488996881569316769">Телеметрия сети</translation>
 <translation id="4890453377345554695">Позволяет задать шаблоны URL для указания сайтов, которым разрешено запрашивать у пользователей право на запись файлов или каталогов в файловой системе хоста.
 
       Если правило не настроено, для всех сайтов действует правило <ph name="DEFAULT_FILE_SYSTEM_WRITE_GUARD_SETTING_POLICY_NAME" /> при условии, что оно задано. В противном случае применяются персональные настройки пользователя.
@@ -3907,6 +3952,7 @@
 <translation id="5148753489738115745">Позволяет задать дополнительные параметры, которые используются при запуске <ph name="PRODUCT_NAME" /> из <ph name="PRODUCT_FRAME_NAME" />.
 
           Если это правило не задано, действуют настройки командной строки по умолчанию.</translation>
+<translation id="5151099177901233471">Включить отправку данных о часовом поясе устройства</translation>
 <translation id="5152393033264257734">Разрешить выполнять проверки на перехват DNS и показывать информационные панели с вопросом о том, не хотел ли пользователь ввести адрес сайта в интранете</translation>
 <translation id="5152787786897382519">В Chromium и Google Chrome есть группы взаимозависимых правил, которые определяют работу различных функций. Эти группы приведены ниже. Если у правила несколько источников, применяются значения из источника с наивысшим приоритетом, а остальные значения игнорируются. Информация о приоритете правил доступна на странице <ph name="POLICY_PRIORITY_DOC_URL" />.</translation>
 <translation id="5153187201534281749">Значок экспериментальных функций браузера на панели инструментов</translation>
@@ -4015,6 +4061,7 @@
 
       Если правило не настроено или заданное значение недействительно, устройство работает так же, как при выборе варианта "Ждать выхода той же стабильной версии".</translation>
 <translation id="5229339291699779956">Включает туннелирование PCIe для периферийных устройств, использующих Thunderbolt или USB4, без ограничения их возможностей</translation>
+<translation id="5230095739094490896">Шаблон атрибута IPP client-name для печати</translation>
 <translation id="5233239004553860036">Если правило не настроено или для него установлено значение <ph name="POLICY_VALUE_ALL" />, управляемые аккаунты можно использовать как дополнительные. Аккаунтом можно управлять с помощью правил, только если он указан как основной в профиле браузера.
       Управление невозможно в следующих случаях:
         -  Аккаунт задан как дополнительный на уровне ОС (в настройках аккаунта).
@@ -4046,6 +4093,7 @@
       Указать можно либо точную версию, например 61.0.3163.120, либо первое число в ее номере, например 61.0.  </translation>
 <translation id="5247973380763021389">Запретить правилам облачных сервисов на уровне пользователей переопределять правила облачных сервисов на уровне устройств</translation>
 <translation id="5249453807420671499">Разрешить пользователям добавлять аккаунты Kerberos</translation>
+<translation id="5249555581286638799">Включить режим высокой эффективности</translation>
 <translation id="5252210248395576403">Это правило определяет, может ли функция "Быстрые ответы" получать доступ к выбранному контенту и отправлять данные на сервер, чтобы выполнять перевод.
 
       Если правило включено или не настроено, перевод с помощью функции "Быстрые ответы" будет разрешен.
@@ -4054,6 +4102,7 @@
 
       Если правило не настроено или указано значение False, режим единого рабочего стола будет отключен и пользователи не смогут его включить.</translation>
 <translation id="5255162913209987122">Рекомендуется</translation>
+<translation id="525543707238275321">Отключить отправку данных о ЦП устройства</translation>
 <translation id="5257395339965216304">Данные размещенных приложений</translation>
 <translation id="5262320080678421295">Не доверять сертификатам, выданным устаревшей инфраструктурой открытых ключей Symantec Corporation</translation>
 <translation id="5266173014392157048">Это правило больше не поддерживается. Используйте вместо него правило <ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />.
@@ -4118,6 +4167,7 @@
       Если правило не настроено, <ph name="PRODUCT_NAME" /> использует максимальную версию по умолчанию.
 
       Если вы укажете значение tls1.2 или tls1.3, <ph name="PRODUCT_NAME" /> не будет использовать более новые версии SSL и TLS. Неподдерживаемые значения будут игнорироваться.</translation>
+<translation id="5329018127554115226">Режим высокой эффективности будет отключен</translation>
 <translation id="5330684698007383292">Типы содержания, которые <ph name="PRODUCT_FRAME_NAME" /> может обрабатывать</translation>
 <translation id="5331746669335642668">Разрешить переопределять правило платформы при помощи облачного правила <ph name="PRODUCT_NAME" /></translation>
 <translation id="5346587320074666194">Запрет указанным сайтам доступа к датчикам</translation>
@@ -4312,6 +4362,7 @@
       Это правило не применяется к переключателям каналов.</translation>
 <translation id="5519331583722582543">Логический флаг, который указывает, доступно ли распознавание рукописного текста на экранной клавиатуре.</translation>
 <translation id="5519619299971727565">Отключить создание отчетов об использовании приложений для Linux</translation>
+<translation id="5521035900165046997">Включить отправку данных о Bluetooth на устройстве</translation>
 <translation id="5521875416764302911">Запретить пользователям входить в <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">Разрешить отправку запросов на Quirks Server и скачивание файлов конфигурации для аппаратного обеспечения</translation>
 <translation id="5526701598901867718">Все (небезопасно)</translation>
@@ -4367,6 +4418,7 @@
 <translation id="5598417829613725146">Canvas (поддерживается с версии 90)</translation>
 <translation id="5599461642204007579">Настройки управления <ph name="MS_AD_NAME" /></translation>
 <translation id="5601503069213153581">PIN-код</translation>
+<translation id="5607021831414604820">Включить отправку данных о статусе хранилища устройства</translation>
 <translation id="5614865701790130558">Ведение журнала событий, связанных с установкой расширений на основе правил</translation>
 <translation id="5618398258385745432">В Chrome была добавлена повторная аутентификация для доступа к паролям, и связанная настройка перестала действовать. Соответственно, это правило также больше не действует. Теперь Chrome работает так, как если бы правило запрещало просмотр паролей в незашифрованном виде в диспетчере. При этом пароль на странице настроек скрыт, но пользователь может нажать кнопку "Показать", ввести учетные данные аккаунта, если потребуется, и посмотреть пароль. Исходное описание правила приведено ниже.
 
@@ -4476,6 +4528,7 @@
       Примечание. При перезагрузке устройства или выходе из системы происходит очистка кеша.</translation>
 <translation id="5717973246079053225">Не отправлять отчеты управляемого профиля в консоль администратора</translation>
 <translation id="572155275267014074">Настройки Android</translation>
+<translation id="5722577409367087850">Загружать расширение</translation>
 <translation id="5728154254076636808">Разрешить создание перемещаемых копий данных для профиля сервиса "<ph name="PRODUCT_NAME" />"</translation>
 <translation id="5729308727912841256">Пароль Kerberos. На место тега <ph name="PASSWORD_PLACEHOLDER" /> будет подставлен пароль для входа.</translation>
 <translation id="5732972008943405952">Импорт данных для автозаполнения форм из браузера по умолчанию при первом запуске</translation>
@@ -4738,6 +4791,7 @@
       Если правило отключено, использовать предложения нельзя.</translation>
 <translation id="6046615715547751255">Запретить элементы управления для отчетов с высокой детализацией</translation>
 <translation id="6048199181629830227">Включить управление режимом пиковой нагрузки</translation>
+<translation id="6049117606554031363">Включить отправку данных о статусе процессора устройства</translation>
 <translation id="6053681087509103368">Разрешить WebRTC использовать устаревшие версии протоколов TLS и DTLS</translation>
 <translation id="6058879286588763839">Если правило <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" />, которое может переопределить <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />, не указано, то <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> задает режимы зарядки батареи при условии, что они поддерживаются на устройстве. С помощью этого правила можно контролировать процесс зарядки, чтобы увеличить время работы от батареи и свести к минимуму ее износ.
 
@@ -4770,6 +4824,7 @@
 <translation id="6099853574908182288">Цветная печать по умолчанию</translation>
 <translation id="6102342563050263313">Прокрутка до текстовых фрагментов, указанных в URL</translation>
 <translation id="6102449843040973938">Разрешить запуск <ph name="BOREALIS_NAME" /> на устройстве</translation>
+<translation id="610892566190435199">Включить отправку данных о состоянии питания устройства</translation>
 <translation id="6111936128861357925">Разрешает игру с динозавром</translation>
 <translation id="6112524153927257380">Если настроить правило, пользователи не смогут игнорировать решения о скачивании, принимаемые системой безопасности.
 
@@ -4914,6 +4969,7 @@
       Это правило дает компаниям возможность отключать тестовую среду для звука, если ее не позволяют использовать настройки ПО для обеспечения безопасности.</translation>
 <translation id="624818583115864448">порт 554 (можно разблокировать до 15.10.2021)</translation>
 <translation id="6252773211180267325">Разрешить запуск <ph name="BOREALIS_NAME" /> для пользователя</translation>
+<translation id="625580680776945310">Режим высокой эффективности будет включен</translation>
 <translation id="6258658183356534534">Управление обновлением алгоритма GREASE в подсказках агента пользователя клиента</translation>
 <translation id="6261643884958898336">Сообщать данные, идентифицирующие компьютер</translation>
 <translation id="6265892395051519509">Разрешение указанным сайтам доступа к датчикам</translation>
@@ -5085,6 +5141,7 @@
 <translation id="6368403635025849609">Разрешить JavaScript на этих сайтах</translation>
 <translation id="6371561334154580937">Показывать диалоговое окно подтверждения выхода, когда закрыто последнее окно</translation>
 <translation id="6372105930898423193">Разрешить повторное включение функции AppCache, даже когда она отключена по умолчанию</translation>
+<translation id="6373299801585455337">Включить отправку данных о ЦП устройства</translation>
 <translation id="6376540107659524656">Запретить протокол SSH в системном приложении терминала</translation>
 <translation id="6376659517206731212">Может быть обязательным</translation>
 <translation id="6377031865393559909">Разрешить пользователям применять шаблоны для рабочего стола</translation>
@@ -5092,6 +5149,7 @@
 <translation id="6378393933102834628">Если для правила задано значение True, кнопка "Сервисы" будет видна. Если задано значение False, кнопка всегда будет скрыта.
 
       Если вы настроите это правило, пользователи не смогут его изменить. Если правило не настроено, пользователи смогут через контекстное меню панели закладок включать или отключать показ кнопки "Сервисы".</translation>
+<translation id="638003144128412430">Отключить отправку данных о часовом поясе устройства</translation>
 <translation id="6382351416269252693">Позволяет задать список шаблонов URL для указания сайтов, которым автоматически запрещено использовать шрифты на устройстве. Это ограничит доступ сайтов к информации о шрифтах на устройстве.
 
       Подробнее о допустимых шаблонах URL: https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. Разрешается использовать подстановочные знаки (<ph name="WILDCARD_VALUE" />). Это правило работает только с адресами сайтов-источников, поэтому пути в шаблонах URL не учитываются.
@@ -5138,6 +5196,7 @@
 <translation id="6440051664870270040">Разрешить сайтам одновременно открывать всплывающее окно и переходить на новую страницу</translation>
 <translation id="6447948611083700881">Резервное копирование и восстановление системы отключено</translation>
 <translation id="6449476513004303784">Запретить пользователям управлять сертификатами</translation>
+<translation id="6452882999388592166">Если правило включено, встроенное расширение CryptoToken будет загружаться при запуске браузера. Если правило отключено или не настроено, встроенное расширение CryptoToken загружаться не будет. Мы добавили это правило временно, потому что API chrome.runtime не определялось на некоторых сайтах и приводило к ошибкам после удаления расширения CryptoToken из версии M106. Доступ к сайтам не должен зависеть от безусловного определения chrome.runtime.</translation>
 <translation id="6453641799812499182">Смягчение проверки <ph name="CORS" /> в новой реализации <ph name="CORS" /></translation>
 <translation id="645425387487868471">Включить обязательный вход в <ph name="PRODUCT_NAME" /></translation>
 <translation id="6455842857207956758">Позволяет синхронизировать пароли SAML на разных устройствах Chrome. Для этого правило отслеживает значение токена синхронизации паролей и запускает повторную аутентификацию пользователя в онлайн-режиме, когда пароль обновляется и его нужно синхронизировать.
@@ -5212,6 +5271,7 @@
 <translation id="6506486086262398387">Если правило включено, функция общих сетевых папок в <ph name="PRODUCT_OS_NAME" /> при необходимости будет использовать протокол NTLM для аутентификации при доступе к общим папкам по протоколу SMB. Если правило отключено, протокол NTLM для аутентификации применяться не будет.
 
       Если правило не задано, оно будет по умолчанию считаться выключенным для профилей, управляемых администратором, и включенным для остальных.</translation>
+<translation id="6513453889192806240">Время реакции HTTPS</translation>
 <translation id="6515357889978918016">Образ <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="6518102411616460786">Ждать выхода той же стабильной версии</translation>
 <translation id="6520802717075138474">Импорт сведений о поисковых системах из браузера, используемого по умолчанию, при первом запуске.</translation>
@@ -5481,6 +5541,12 @@
 
       Если правило не настроено или для него задано значение False, пользователь не сможет запускать <ph name="PLUGIN_VM_NAME" />.
       Если для правила задано значение True, пользователь сможет запускать <ph name="PLUGIN_VM_NAME" /> при условии, что это не противоречит другим настройкам. Чтобы пользователи могли запускать <ph name="PLUGIN_VM_NAME" />, необходимо задать значение True для правил <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> и <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" />, а также настроить правило <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> или <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />.</translation>
+<translation id="6750902920405577210">Список данных телеметрии, которые отправляются при изменении силы сигнала.
+
+      Сведения о каждом блоке данных будут передаваться только при условии, что он не отключен соответствующим правилом.
+      Для https_latency и network_telemetry используется правило ReportDeviceNetworkStatus.
+
+      Если правило не настроено, то при изменении силы сигнала дополнительные данные телеметрии передаваться не будут.</translation>
 <translation id="6752711782954612641">Если правило <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> включено, то настройка <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> содержит список параметров, используемых в поисковых запросах методом POST. Список состоит из пар "имя-значение", разделенных запятыми. Если в качестве значения указан параметр шаблона (например, <ph name="SEARCH_TERM_MARKER" />), он заменяется фактическими данными.
 
       Если правило <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> не настроено, для поисковых запросов используется метод GET.</translation>
@@ -5619,6 +5685,7 @@
 <translation id="6903814433019432303">Эти правила действуют только в базовом режиме.
 
       Определяет набор URL-адресов, которые загружаются в демонстрационном сеансе. Эти правила превалируют над другими возможностями для настройки стартовой страницы. Их нельзя применить к конкретному пользователю.</translation>
+<translation id="6903818804346914108">Включить отправку данных о вентиляторе устройства</translation>
 <translation id="6905405893096403868">Если в правиле задан список строк, каждая из них передается в альтернативный браузер как отдельный параметр командной строки. В <ph name="MS_WIN_NAME" /> параметры объединяются через пробелы. В <ph name="MAC_OS_NAME" /> и <ph name="LINUX_OS_NAME" /> параметр может сам содержать пробелы и при этом обрабатываться как единое целое.
 
       Если тот или иной параметр содержит переменную <ph name="URL_PLACEHOLDER" />, то вместо <ph name="URL_PLACEHOLDER" /> подставляется URL открываемой страницы. Если ни в одном параметре нет переменной <ph name="URL_PLACEHOLDER" />, нужный URL добавляется в конце командной строки.
@@ -5919,6 +5986,7 @@
 <translation id="718126088895133062">Правило позволяет задать идентификатор пользователя <ph name="PLUGIN_VM_NAME" /> для этого устройства.</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">Использовать веб-сервис Google для проверки правописания</translation>
+<translation id="7187248416163189586">Отключить отправку данных о подсветке устройства</translation>
 <translation id="718850220532931090">Это правило больше не поддерживается. Вместо него используется правило <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />.
 
       Правило позволяет указать, какие расширения могут проходить удаленную проверку с помощью функции <ph name="CHALLENGE_USER_KEY_FUNCTION" />, входящей в <ph name="ENTERPRISE_PLATFORM_KEYS_API" />. Чтобы разрешить использование API, расширения необходимо добавить в список.
@@ -5942,6 +6010,7 @@
 <translation id="7207095846245296855">Позволяет принудительно включить Безопасный поиск Google</translation>
 <translation id="7211368186050418507">Не определять часовой пояс автоматически</translation>
 <translation id="7216442368414164495">Позволить пользователям включить расширенную отчетность безопасного просмотра</translation>
+<translation id="721970071627370558">Отключить отправку данных о состоянии питания устройства</translation>
 <translation id="7221574724100909818">Использовать для безопасных соединений значок блокировки</translation>
 <translation id="7229365071755865554">Включить сохранение паролей с помощью диспетчера</translation>
 <translation id="7229975860249300121">Содержит регулярное выражение, которое позволяет определить, какой аккаунт Google можно назначить в качестве основного в <ph name="PRODUCT_NAME" /> (т. е. аккаунта, который выбирается при включении синхронизации).
@@ -6299,6 +6368,7 @@
 <translation id="7587345076013230465">Предлагать пользователю выбрать сертификат клиента, если правилу автоматического выбора соответствует несколько сертификатов на экране входа</translation>
 <translation id="7587921466180902617">Включить тестовую версию Screencast для пользователей Family Link</translation>
 <translation id="759957074386651883">Настройки Безопасного просмотра</translation>
+<translation id="7602621823177962064">Отключить отправку данных о памяти устройства</translation>
 <translation id="7604169113182304895">Вы не можете принудить приложения Android соблюдать правила в отношении этого списка.</translation>
 <translation id="7612157962821894603">Системные настройки, действующие при запуске <ph name="PRODUCT_NAME" /></translation>
 <translation id="7613115815080726221">Период неактивности пользователя, после которого будет выполнен переход в режим бездействия (в миллисекундах).</translation>
@@ -6641,6 +6711,7 @@
 <translation id="7992613144342460685">Разрешить размещение окон на этих сайтах</translation>
 <translation id="7995610550667275367">Сканирование (поддерживается с версии 87)</translation>
 <translation id="7999023147219236247">Правила разрешений для приложений. PERMISSION_POLICY_UNSPECIFIED: правило не настроено. В этом случае по умолчанию используется значение PROMPT. PROMPT: пользователю предлагается предоставить приложению необходимые разрешения. GRANT: разрешение предоставляется автоматически. DENY: запрос на получение разрешения автоматически отклоняется.</translation>
+<translation id="7999336306414770162">Отключить отправку данных о VPD</translation>
 <translation id="7999818120028621358">Показывать события, связанные с предотвращением утечки данных</translation>
 <translation id="8001701200415781021">Определяет, какой аккаунт Google можно назначить основным в <ph name="PRODUCT_NAME" /></translation>
 <translation id="800595420827930383">Использовать устаревший инструмент верификации, предоставляемый платформой</translation>
@@ -6691,6 +6762,7 @@
 <translation id="8056273037819805106">Учетные данные <ph name="PRODUCT_OS_NAME" /> используются для подключения к управляемому прокси-серверу.</translation>
 <translation id="8056800559672904373">Управляемый аккаунт должен быть основным и не иметь дополнительных аккаунтов, а во время создания профиля можно импортировать существующие данные о работе браузера</translation>
 <translation id="8059164285174960932">URL, по которому клиенты удаленного доступа должны получать токены аутентификации</translation>
+<translation id="8059352177830050556">Включить отправку данных о подсветке устройства</translation>
 <translation id="8062375903420954294">Правило позволяет определить, какие IP-адреса и интерфейсы WebRTC будет использовать при поиске оптимального подключения. Подробнее см. в RFC 8828, раздел 5.2 (https://tools.ietf.org/html/rfc8828.html#section-5.2). Если правило не настроено, по умолчанию используются все доступные интерфейсы.</translation>
 <translation id="8062485064082966327">Использовать анонимный сервис Google, чтобы автоматически получать описания для изображений</translation>
 <translation id="8071371098891664137">Если в правиле <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" /> задан параметр <ph name="PRINTERS_BLOCKLIST" />, правило <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> определяет принтеры, с которыми не может работать пользователь. Пользователям запрещено работать только с теми принтерами, идентификаторы которых указаны в правиле. Эти идентификаторы должны соответствовать значениям полей <ph name="ID_FIELD" /> и <ph name="GUID_FIELD" /> в файле, указанном в правиле <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" />.</translation>
@@ -7011,6 +7083,7 @@
 <translation id="8367488518695804749">Блокировать всплывающие окна на всех сайтах</translation>
 <translation id="8369602308428138533">Задержка отключения экрана при работе от сети</translation>
 <translation id="8371178326720637170">Разрешает управляемым расширениям использовать Enterprise Hardware Platform API</translation>
+<translation id="8373176843640227330">Отключить отправку данных о Bluetooth на устройстве</translation>
 <translation id="8375817202037102567">Блокировать на этих сайтах доступ для записи к файлам и каталогам</translation>
 <translation id="8378266419596669629">Запретить этим сайтам доступ к шрифтам на устройстве</translation>
 <translation id="8379317372795444261"><ph name="BASIC_AUTH" /> аутентификация при подключении по HTTP разрешена</translation>
@@ -7059,6 +7132,7 @@
 
        Это правило будет удалено в <ph name="PRODUCT_NAME" /> 95.</translation>
 <translation id="8427466947904008809">Разрешить Удаленному рабочему столу Chrome выполнять запросы к WebAuthn API из удаленных хостов.</translation>
+<translation id="8428295225823548121">Включить отправку данных о памяти устройства</translation>
 <translation id="8428635849021776523">Отключить создание отчетов о статусе Android</translation>
 <translation id="8433186206711564395">Настройки сети</translation>
 <translation id="8433769814000220721">Включение рекомендованного контента</translation>
@@ -7259,6 +7333,18 @@
 
       Если выбрано значение False, вкладки всегда работают.</translation>
 <translation id="8619748440665904084">Запретить импорт данных для автозаполнения форм при первом запуске</translation>
+<translation id="8620103780247748230">Это правило определяет значение атрибута IPP <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> в заданиях печати.
+
+      Если вы укажете значение для правила, то к каждому заданию печати будет добавляться дополнительный объект <ph name="CLIENT_INFO_IPP_ATTRIBUTE" />. После подстановки переменных параметру <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> добавленного объекта <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> будет присвоено значение правила.
+
+      Поддерживаются следующие переменные: <ph name="DIRECTORY_ID_PLACEHOLDER" />, <ph name="SERIAL_NUMBER_PLACEHOLDER" />, <ph name="ASSET_ID_PLACEHOLDER" />, <ph name="ANNOTATED_LOCATION_PLACEHOLDER" />, <ph name="USER_EMAIL_PLACEHOLDER" />, <ph name="USER_EMAIL_NAME_PLACEHOLDER" />, <ph name="USER_EMAIL_DOMAIN" />. Переменные для плейсхолдеров, которые не поддерживаются, не будут подставлены.
+
+      Полученное после подстановки значение считается действительным, если оно состоит только из печатных символов <ph name="ASCII" /> и его длина не больше 255.
+
+      Обратите внимание, что по соображениям конфиденциальности это правило применяется только для обмена данными с принтером по протоколам <ph name="IPPS_PROTOCOL" />, <ph name="HTTPS_PROTOCOL" />, <ph name="USB_PROTOCOL" /> и <ph name="IPP_USB_PROTOCOL" />. Кроме того, принтер при этом должен поддерживать <ph name="CLIENT_NAME_IPP_ATTRIBUTE" />.
+
+      Если правило не настроено или для него задано недопустимое или пустое значение, атрибут <ph name="CLIENT_INFO_PLACEHOLDER" /> не будет добавляться к заданиям печати.
+      </translation>
 <translation id="8623672932476443039">Если правило включено, пользователям доступен режим разработчика изолированных приложений.
       Если правило отключено, этот режим недоступен.
       Если правило не настроено, по умолчанию доступ отключен для корпоративных аккаунтов в Chrome OS и включен для остальных пользователей и операционных систем.</translation>
@@ -7485,6 +7571,7 @@
 <translation id="8882255181490012651">Запрещает доступ с помощью функции "Управление телефоном" к недавним фото и видео, хранящимся на телефоне</translation>
 <translation id="8887709920496070892">Время бездействия, после которого появляется диалоговое окно с предупреждением (в миллисекундах).</translation>
 <translation id="8890438048579188548">Скрывать предупреждения о прекращении поддержки сервиса "<ph name="CLOUD_PRINT_NAME" />"</translation>
+<translation id="8891334958985336685">Отключить отправку данных о системе устройства</translation>
 <translation id="8892286064305622118">Требуется свободное пространство на диске для <ph name="PLUGIN_VM_NAME" /></translation>
 <translation id="8892783613915541293">Задержки и действия в случае, когда устройство находится в режиме ожидания и работает от сети.</translation>
 <translation id="8897796778265450949">Ограничение времени, на протяжении которого пользователи, выполнившие аутентификацию с помощью GAIA без SAML, могут входить в аккаунт офлайн</translation>
@@ -7555,6 +7642,7 @@
 <translation id="8977192934280677167">Доступ к поисковой системе по умолчанию в контекстном меню</translation>
 <translation id="8983537551095611459">Настроить список идентификаторов расширений, для которых не будет выполняться процедура очистки управляемого гостевого сеанса с ограниченным доступом</translation>
 <translation id="8983539044126123594">Разрешить вход в дополнительные аккаунты Google</translation>
+<translation id="8985219286836584291">Включить отправку данных о системе устройства</translation>
 <translation id="8992176907758534924">Запретить показ изображений на всех сайтах</translation>
 <translation id="8994954504552592260">Разрешение перехода устройств, контролируемых <ph name="MS_AD_NAME" />, под облачное управление. Это правило позволяет удаленно запускать автоматический переход контроля над устройствами внутри компании. Процесс перехода будет максимально прозрачным и понятным для конечных пользователей.
 
@@ -7816,6 +7904,7 @@
       Если установлено значение False, выполнять вход смогут только пользователи, указанные в правиле <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" />.
 
       Если задано значение True или правило не настроено, выполнять вход смогут все пользователи.</translation>
+<translation id="966425658642788645">Использовать поведение по умолчанию</translation>
 <translation id="971677226939413180">Параметр "Печатать как изображение" отсутствует</translation>
 <translation id="974349541138387272">Указать шаблон URI нужного преобразователя DNS поверх HTTPS</translation>
 <translation id="979467274961593903">Запретить удаленную отладку</translation>
diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb
index 1910b9a..6cfa5c3 100644
--- a/components/policy/resources/policy_templates_zh-CN.xtb
+++ b/components/policy/resources/policy_templates_zh-CN.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">配置强制在 <ph name="PRODUCT_OS_NAME" />登录屏幕上使用的语言区域。
 
       如果此政策已设置,登录屏幕将会始终以此政策的第一个值指定的语言区域显示(为便于向前兼容,此政策会以列表的形式进行指定)。如果此政策未设置或设为空列表,登录屏幕则会以最后一次用户会话所采用的语言区域显示。如果此政策设为无效的语言区域值,登录屏幕便会以相应的后备语言区域显示(当前的后备语言区域是“en-US”)。</translation>
+<translation id="1050158007881386475">停用设备主板状态报告功能</translation>
 <translation id="1052499923181221200">除非 SamlInSessionPasswordChangeEnabled 设为 true,否则此政策不会生效。
       如果上述政策设为 true,并且此政策设为(例如)14,则表示系统会比到期日提前 14 天向 SAML 用户发送通知,让他们知道自己的密码即将在某一天到期。
       然后,SAML 用户可立即采取应对措施,方法是:通过执行会话期间密码更改,在密码到期前更新密码。
@@ -323,6 +324,7 @@
       如果您选择了“强制”(2),用户将无法禁止显示个人资料选择器,即使只有 1 份可用的个人资料也是如此。</translation>
 <translation id="1339174690935954950">阻止用户提交反馈</translation>
 <translation id="1342918903685430097">为设备配置允许使用的最低 <ph name="PRODUCT_OS_NAME" /> 版本。</translation>
+<translation id="1343128241903870688">停用设备应用信息报告功能</translation>
 <translation id="1347198119056266798">此政策已被弃用,请改用 <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> 和 <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />。如果设置了 <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> 政策、<ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> 政策或(已弃用的)<ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> 政策,则系统会忽略此政策。
 
       强制启用安全搜索功能来处理 Google 网页搜索中的查询,并禁止用户更改此设置。此设置还会强制启用 YouTube“适中”受限模式。
@@ -362,6 +364,7 @@
 <translation id="1393485621820363363">已启用企业设备打印机</translation>
 <translation id="1395505489889158859">允许向原生打印机发送用户名和文件名</translation>
 <translation id="1397855852561539316">默认搜索服务提供商建议网址</translation>
+<translation id="1402227992519954892">启用设备应用信息报告功能</translation>
 <translation id="141279920573530952">通过设置此政策,您可以罗列一些网址,以指定自动授权哪些网站访问所有可用的串行端口。
 
       这些网址必须有效,否则系统会忽略此政策。系统将仅考虑相应网址的来源(架构、主机和端口)。
@@ -606,6 +609,7 @@
 <translation id="1616280227447957376">允许从特定来源上的 SSL 警告页面继续操作</translation>
 <translation id="1617235075406854669">允许删除浏览器历史记录和下载记录</translation>
 <translation id="1620510694547887537">摄像头</translation>
+<translation id="162162247775156979">停用设备存储状态报告功能</translation>
 <translation id="1626379196197114720">允许使用往返缓存</translation>
 <translation id="1628974048137236820">“新标签页”页面不会显示卡片</translation>
 <translation id="1630263002012156148">如果此政策已启用,系统会使用“新标签页”页面作为用户的主页,并忽略所有主页网址位置。如果此政策已停用,系统绝不会使用“新标签页”页面作为用户的主页,除非用户将主页网址设为 chrome://newtab。
@@ -1665,8 +1669,12 @@
 <translation id="2665422249821137126">在登录屏幕上启用大号光标</translation>
 <translation id="2667894101494585925">启用优化指南提取功能</translation>
 <translation id="2672012807430078509">控制是否允许将 NTLM 作为 SMB 装载功能的身份验证协议</translation>
+<translation id="2673363037046384711">最终用户可以启用或停用高效模式。</translation>
 <translation id="2678503605767349615">必需的设备级客户端证书</translation>
 <translation id="268577405881275241">启用数据压缩代理功能</translation>
+<translation id="268695908564263739">此政策用于启用或停用“高效模式”设置。如果启用了该设置,系统会在一段时间后在后台舍弃标签页以回收内存。
+      如果此政策未设置,最终用户可在 chrome://settings/performance 上控制该设置。
+      </translation>
 <translation id="2691668238491124549">通过设置此政策(仅当推荐您这样做时),您可将系统为受管理自助服务终端推荐的语言区域移至列表顶部,并使它们按照在此政策中的显示顺序排列。系统会预先选择所推荐的第一个语言区域。
 
       如果您不设置此政策,系统会预先选择界面的当前语言区域。
@@ -2858,6 +2866,7 @@
 <translation id="3898345958122666461">开启 NTLMv2</translation>
 <translation id="3898795800259311780">允许或拒绝屏幕截图</translation>
 <translation id="3903313632842363082">停用设备用户报告功能</translation>
+<translation id="3904304709151553598">停用设备风扇信息报告功能</translation>
 <translation id="3907683835264956726">允许在线用户从锁定屏幕上登录。如果此政策设为 true,<ph name="POLICY" /> 等政策会触发在锁定屏幕上在线重新验证用户身份的机制。
       当用户已在锁定屏幕上或者在满足相应条件后下次锁定屏幕时,系统会立即强制重新验证用户身份。
       如果此政策设为 false 或未设置,用户始终都能使用自己的本地凭据解锁屏幕。</translation>
@@ -2901,6 +2910,7 @@
 
           如果您未设置此政策,粘滞键在登录屏幕上最初会处于停用状态,但用户可随时启用它。</translation>
 <translation id="3927291637826333102">允许这些来源使用桌面、窗口和标签页截取功能</translation>
+<translation id="3928726028264020458">启用设备 VPD 信息报告功能</translation>
 <translation id="3943930334592166130">此政策旨在控制是否让系统在有多个证书与 <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" /> 匹配时提示用户选择客户端证书。
       如果此政策已启用,每当自动选择政策与多个证书匹配时,系统都会提示用户选择客户端证书。
       如果此政策已停用或未设置,只有当无任何证书与自动选择政策匹配时,系统才会提示用户。</translation>
@@ -2990,6 +3000,7 @@
       在 <ph name="MS_WIN_NAME" /> 上,此功能仅适用于已加入 <ph name="MS_AD_NAME" /> 网域的实例、在 Windows 10 专业版上运行的实例,或已注册 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />的实例。在 <ph name="MAC_OS_NAME" /> 上,此功能仅适用于通过 MDM 进行管理或通过 MCX 加入网域的实例。</translation>
 <translation id="4043796890723386527">禁止用户在 <ph name="LACROS_NAME" /> 浏览器中创建和使用次级个人资料以及使用访客模式</translation>
 <translation id="4051723201852944592">启用窗口遮挡</translation>
+<translation id="4052529125939620019">在浏览器启动时加载 CryptoToken 组件扩展程序</translation>
 <translation id="4053157306171963473">停用设备活动时长报告功能</translation>
 <translation id="4056910949759281379">停用 SPDY 协议</translation>
 <translation id="4061107397839125009">通过设置此政策,您可以创建一个网址格式列表,从而指定哪些网站无法显示通知。
@@ -3048,6 +3059,29 @@
 
       如果您设置了此政策,用户便无法更改相关设置。如果您未设置此政策,屏幕键盘最初会处于关闭状态,但用户可随时开启它。</translation>
 <translation id="412697421478384751">允许用户设置安全性较低的锁定屏幕 PIN 码</translation>
+<translation id="4130565559631908067">此政策提供了一种方式,以覆盖浏览器用来实现 First-Party Set 功能的集合列表。
+
+      浏览器的 First-Party Set 列表中的每个集合都必须符合 First-Party Set 要求。
+      每个 First-Party Set 都必须包含一个所有者网站以及一个或多个成员网站。
+      每个集合还可包含其拥有的一系列服务网站,以及从某个网站到其所有 ccTLD 变体的映射关系。
+      如需详细了解 <ph name="PRODUCT_NAME" /> 使用的 First-Party Set,请参阅 https://github.com/WICG/first-party-sets。
+
+      每个 First-Party Set 中的所有网站都必须是采用 HTTPS 协议的可注册网域。此外,First-Party Set 中的每个网站都必须互不相同,也就是说:同一个网站不能在 First-Party Set 中列出多次。
+
+      如果此政策设为一个空字典,浏览器会使用 First-Party Set 的公开列表。
+
+      对于来自 <ph name="REPLACEMENTS" /> 列表的 First-Party Set 中的所有网站,如果某个网站也存在于浏览器列表所含的 First-Party Set 中,则该网站会被从浏览器的 First-Party Set 中移除。
+      之后,此政策的 First-Party Set 将被添加到浏览器的 First-Party Set 列表中。
+
+      对于来自 <ph name="ADDITIONS" /> 列表的 First-Party Set 中的所有网站,如果某个网站也存在于浏览器列表所含的 First-Party Set 中,则浏览器的 First-Party Set 会被更新,以将新的 First-Party Set 添加到浏览器的列表中。待浏览器的列表更新完毕后,此政策的 First-Party Set 将被添加到浏览器的 First-Party Set 列表中。
+
+      浏览器的 First-Party Set 列表要求其中的所有网站都不得出现在多个集合中。<ph name="REPLACEMENTS" /> 列表和 <ph name="ADDITIONS" /> 列表也都有这样的要求。同理,同一个网站不能既出现在 <ph name="REPLACEMENTS" /> 列表中又出现在 <ph name="ADDITIONS" /> 列表中。
+
+      通配符 (*) 无法用作政策值,也无法用于这些列表所含的任何 First-Party Set 中。
+
+      此政策提供的所有集合都必须是有效的 First-Party Set;如果无效,则会触发相应的错误。
+
+      此政策仅适用于已加入 <ph name="MS_AD_NAME" /> 网域的 Windows 实例,或者已注册设备管理服务的 Windows 10 专业版或企业版实例,以及通过 MDM 进行管理或通过 MCX 加入网域的 macOS 实例。</translation>
 <translation id="4138655880188755661">时限</translation>
 <translation id="4147818922357566987">仅启用与重要修复程序有关的变体</translation>
 <translation id="4150201353443180367">显示</translation>
@@ -3854,6 +3888,7 @@
 <translation id="5148753489738115745">可让您指定在 <ph name="PRODUCT_FRAME_NAME" />启动 <ph name="PRODUCT_NAME" />时所使用的其他参数。
 
           如果未设置此政策,系统将会使用默认命令行。</translation>
+<translation id="5151099177901233471">启用设备时区信息报告功能</translation>
 <translation id="5152393033264257734">允许使用 DNS 拦截检查功能和“您是不是要前往 http://intranetsite/?”信息栏。</translation>
 <translation id="5152787786897382519">Chromium 和 Google Chrome 均有一些政策组,其中的政策以相互依赖的方式来控制某项功能。这些集合由以下政策组表示。如果相关政策有多个来源,系统仅会应用来源优先级最高的值。同一组中来源优先级较低的值会被忽略。<ph name="POLICY_PRIORITY_DOC_URL" /> 中定义了优先级顺序。</translation>
 <translation id="5153187201534281749">在工具栏中显示浏览器实验性功能图标</translation>
@@ -3995,6 +4030,7 @@
       此处的“Version”既可以是确切版本(如“61.0.3163.120”),也可以是版本前缀(如“61.0”)。  </translation>
 <translation id="5247973380763021389">禁止用户级云政策覆盖计算机级云政策。</translation>
 <translation id="5249453807420671499">用户可以添加 Kerberos 帐号</translation>
+<translation id="5249555581286638799">启用高效模式</translation>
 <translation id="5252210248395576403">此政策旨在授权快速解答功能访问所选内容并将相关信息发送给服务器,以获得翻译结果。
 
       如果此政策已启用或未设置,系统将启用快速解答翻译功能。
@@ -4003,6 +4039,7 @@
 
       如果此政策设为 False 或未设置,系统将关闭“统一桌面”,而且用户无法开启该功能。</translation>
 <translation id="5255162913209987122">可推荐</translation>
+<translation id="525543707238275321">停用设备 CPU 信息报告功能</translation>
 <translation id="5257395339965216304">托管的应用数据</translation>
 <translation id="5262320080678421295">不信任 Symantec Corporation 旧版 PKI 颁发的证书</translation>
 <translation id="5266173014392157048">此政策已被弃用,请改用“<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />”政策。
@@ -4067,6 +4104,7 @@
       如果您不配置此政策,<ph name="PRODUCT_NAME" /> 便会使用默认的最高版本。
 
       如果您想配置此政策,则可将其设为“tls1.2”或“tls1.3”。如果您设置了此政策,<ph name="PRODUCT_NAME" /> 将不会使用任何高于指定版本的 SSL/TLS 版本。无法识别的值会被忽略。</translation>
+<translation id="5329018127554115226">将停用高效模式。</translation>
 <translation id="5330684698007383292">允许 <ph name="PRODUCT_FRAME_NAME" />处理以下内容类型</translation>
 <translation id="5331746669335642668"><ph name="PRODUCT_NAME" /> 云政策会替换平台政策。</translation>
 <translation id="5346587320074666194">禁止在这些网站上使用传感器</translation>
@@ -4261,6 +4299,7 @@
       此政策不适用于版本切换。</translation>
 <translation id="5519331583722582543">一个布尔值标记,用于表明屏幕键盘能否提供基于手写识别的输入功能。</translation>
 <translation id="5519619299971727565">停用 Linux 应用使用情况报告</translation>
+<translation id="5521035900165046997">启用设备蓝牙信息报告功能</translation>
 <translation id="5521875416764302911">禁止用户登录 <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">允许向 Quirks Server 发送查询并酌情下载硬件专用配置文件</translation>
 <translation id="5526701598901867718">所有(不安全)</translation>
@@ -4316,6 +4355,7 @@
 <translation id="5598417829613725146">画布(在 90 版及更高版本中受支持)</translation>
 <translation id="5599461642204007579"><ph name="MS_AD_NAME" /> 管理设置</translation>
 <translation id="5601503069213153581">PIN 码</translation>
+<translation id="5607021831414604820">启用设备存储状态报告功能</translation>
 <translation id="5614865701790130558">记录基于政策的扩展程序安装事件</translation>
 <translation id="5618398258385745432">在我们推出“查看密码时需重新验证”这一规定之前,我们是使用相关的设置来控制用户能否查看密码。自这一规定推出后,相关设置以及此政策便不再对 Chrome 的行为有任何影响。Chrome 的当前行为等同于此政策设为在密码管理器设置页面中禁止以明文形式显示密码。这意味着,设置页面中包含的只是一个占位符,仅当用户点击“显示”(并进行重新验证,如果适用的话)后,Chrome 才会显示相应密码。此政策的原始描述如下所示:
 
@@ -4424,6 +4464,7 @@
       注意:重启设备和退出帐号会清除缓存。</translation>
 <translation id="5717973246079053225">为受管理个人资料停用云报告功能</translation>
 <translation id="572155275267014074">Android 设置</translation>
+<translation id="5722577409367087850">加载该扩展程序</translation>
 <translation id="5728154254076636808">允许创建 <ph name="PRODUCT_NAME" /> 个人资料数据的漫游副本</translation>
 <translation id="5729308727912841256">Kerberos 密码。占位符 <ph name="PASSWORD_PLACEHOLDER" /> 会被登录密码取代。</translation>
 <translation id="5732972008943405952">首次运行时,从默认浏览器导入自动填充表单数据</translation>
@@ -4675,6 +4716,7 @@
       如果此政策已停用,用户将无法兑换这类优惠。</translation>
 <translation id="6046615715547751255">不允许使用精细报告控件</translation>
 <translation id="6048199181629830227">启用用电高峰转移电源管理</translation>
+<translation id="6049117606554031363">启用设备主板状态报告功能</translation>
 <translation id="6053681087509103368">允许 WebRTC 使用已过时的 TLD/DTLS 协议版本</translation>
 <translation id="6058879286588763839">您可以通过设置 <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> 来指定电池充电模式电源管理政策(如果相应设备支持的话),除非指定了会覆盖 <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> 的 <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" />。此政策会动态地控制电池充电,尽可能减少电池应力和损耗,从而延长电池寿命。
 
@@ -4707,6 +4749,7 @@
 <translation id="6099853574908182288">默认打印颜色模式</translation>
 <translation id="6102342563050263313">允许滚动至网址片段指定的文本所在的位置</translation>
 <translation id="6102449843040973938">允许 <ph name="BOREALIS_NAME" /> 在设备上运行</translation>
+<translation id="610892566190435199">启用设备电源状态报告功能</translation>
 <translation id="6111936128861357925">允许用户玩恐龙复活节彩蛋游戏</translation>
 <translation id="6112524153927257380">如果您设置了此政策,用户便无法绕过下载安全性决策。
 
@@ -4851,6 +4894,7 @@
       借助此政策,当企业使用的安全软件设置会干扰音频沙盒时,他们就能够灵活地停用沙盒。</translation>
 <translation id="624818583115864448">端口 554(可在 2021 年 10 月 15 日之前解禁)</translation>
 <translation id="6252773211180267325">允许用户运行 <ph name="BOREALIS_NAME" /></translation>
+<translation id="625580680776945310">将启用高效模式。</translation>
 <translation id="6258658183356534534">控制 User-Agent Client Hints GREASE Update 功能。</translation>
 <translation id="6261643884958898336">报告机器标识信息</translation>
 <translation id="6265892395051519509">允许在这些网站上使用传感器</translation>
@@ -5010,6 +5054,7 @@
 <translation id="6368403635025849609">在这些网站上允许 JavaScript</translation>
 <translation id="6371561334154580937">在用户关闭最后一个窗口时显示让用户确认退出登录的对话框。</translation>
 <translation id="6372105930898423193">允许重新启用 AppCache 功能,即使此功能默认处于关闭状态。</translation>
+<translation id="6373299801585455337">启用设备 CPU 信息报告功能</translation>
 <translation id="6376540107659524656">停用终端系统应用中的 SSH</translation>
 <translation id="6376659517206731212">可强制执行</translation>
 <translation id="6377031865393559909">允许用户使用桌面模板</translation>
@@ -5017,6 +5062,7 @@
 <translation id="6378393933102834628">如果此政策设为 True,系统会显示应用快捷方式。如果此政策设为 False,系统一律不会显示此类快捷方式。
 
       如果您设置了此政策,用户便无法更改它。如果您不设置此政策,用户可从书签栏上下文菜单中选择显示/隐藏应用快捷方式。</translation>
+<translation id="638003144128412430">停用设备时区信息报告功能</translation>
 <translation id="6382351416269252693">供您用来设置一个网站网址格式列表,从而指定要让系统自动拒绝向哪些网站授予本地字体权限。此设置会限制网站查看本地字体相关信息的能力。
 
       如需详细了解有效网站网址格式,请访问 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。允许使用通配符 <ph name="WILDCARD_VALUE" />。此政策只能根据源进行匹配,所以网址格式中的任何路径都会被忽略。
@@ -5062,6 +5108,7 @@
 <translation id="6440051664870270040">允许网站在导航的同时打开弹出式窗口</translation>
 <translation id="6447948611083700881">已停用备份和恢复服务</translation>
 <translation id="6449476513004303784">禁止用户管理证书</translation>
+<translation id="6452882999388592166">如果此政策已启用,系统会在浏览器启动时加载内置的 CryptoToken 组件扩展程序。如果此政策已停用或未设置,系统不会在浏览器启动时加载 CryptoToken。此政策旨在作为一种临时的变通方案,用于处理因未定义“chrome.runtime”(这是由于在 M106 中移除 CryptoToken 所致的不良后果)而无法正常运行的网站。网站不得依赖于无条件定义的“chrome.runtime”。</translation>
 <translation id="6453641799812499182">在新版 <ph name="CORS" /> 实现方案中启用 <ph name="CORS" /> 检查缓解功能</translation>
 <translation id="645425387487868471">为 <ph name="PRODUCT_NAME" /> 启用强制登录功能</translation>
 <translation id="6455842857207956758">允许在多部 Chrome 设备之间同步 SAML 密码,方法是:监控密码同步令牌的值,并在密码已更新且需要同步时要求用户在线重新验证身份。
@@ -5542,6 +5589,7 @@
 <translation id="6903814433019432303">此政策仅在零售模式下有效。
 
       确定在演示会话启动时要加载的网址集。此政策将替换其他任何用于设置初始网址的机制,因此仅适用于与特定用户无关的会话。</translation>
+<translation id="6903818804346914108">启用设备风扇信息报告功能</translation>
 <translation id="6905405893096403868">如果此政策设为一系列字符串,系统会将每个字符串作为单独的命令行参数传递到备用浏览器。在 <ph name="MS_WIN_NAME" /> 上,这些参数会以空格连接。在 <ph name="MAC_OS_NAME" /> 和 <ph name="LINUX_OS_NAME" /> 上,参数可以包含空格,但仍会被视为单个参数。
 
       如果有参数包含 <ph name="URL_PLACEHOLDER" />,系统会将 <ph name="URL_PLACEHOLDER" /> 替换成要打开的网页对应的网址。如果没有参数包含 <ph name="URL_PLACEHOLDER" />,系统会将网址附加到命令行的末尾。
@@ -5844,6 +5892,7 @@
 <translation id="718126088895133062">此政策旨在为该设备指定 <ph name="PLUGIN_VM_NAME" /> 许可用户 ID。</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">使用 Google 网络服务来帮助修正拼写错误</translation>
+<translation id="7187248416163189586">停用设备背光信息报告功能</translation>
 <translation id="718850220532931090">此政策已被弃用,请改用 <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />。
 
       通过设置此政策,您可以指定哪些扩展程序能够使用 <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> 函数 <ph name="CHALLENGE_USER_KEY_FUNCTION" /> 进行远程认证。只有添加到此列表中的扩展程序才能使用该 API。
@@ -5866,6 +5915,7 @@
 <translation id="7207095846245296855">强制启用 Google 安全搜索功能</translation>
 <translation id="7211368186050418507">一律不自动检测时区</translation>
 <translation id="7216442368414164495">允许用户启用安全浏览扩展报告功能</translation>
+<translation id="721970071627370558">停用设备电源状态报告功能</translation>
 <translation id="7221574724100909818">使用锁形图标表示安全连接</translation>
 <translation id="7229365071755865554">允许使用密码管理器保存密码</translation>
 <translation id="7229975860249300121">这项政策包含一个正则表达式,用于决定哪些 Google 帐号可以设定为 <ph name="PRODUCT_NAME" /> 中的浏览器主帐号(也就是在同步功能启用流程中所选的帐号)。
@@ -6224,6 +6274,7 @@
 <translation id="7587345076013230465">当登录屏幕上有多份客户端证书与自动选择政策匹配时,提示用户做出选择</translation>
 <translation id="7587921466180902617">为 Family Link 用户启用“屏幕录制”功能 dogfood</translation>
 <translation id="759957074386651883">安全浏览设置</translation>
+<translation id="7602621823177962064">停用设备内存信息报告功能</translation>
 <translation id="7604169113182304895">Android 应用可能会主动选择采纳该列表。您无法强制此类应用采纳该列表。</translation>
 <translation id="7612157962821894603">在 <ph name="PRODUCT_NAME" /> 启动时应用于整个系统的设置</translation>
 <translation id="7613115815080726221">系统应在设备闲置多久(以毫秒为单位)后采取闲置操作</translation>
@@ -6565,6 +6616,7 @@
 <translation id="7992613144342460685">向这些网站授予窗口放置权限</translation>
 <translation id="7995610550667275367">扫描(自 87 版起受支持)</translation>
 <translation id="7999023147219236247">此政策用于向应用授予所请求的权限。PERMISSION_POLICY_UNSPECIFIED:未指定此政策。如果在任何等级都未针对相应权限指定政策,系统便会默认使用“PROMPT”行为。PROMPT:提示用户授予相应权限。GRANT:自动授予相应权限。DENY:自动拒绝授予相应权限。</translation>
+<translation id="7999336306414770162">停用设备 VPD 信息报告功能</translation>
 <translation id="7999818120028621358">启用关于数据泄露预防事件的报告</translation>
 <translation id="8001701200415781021">限制哪些 Google 帐号可以设置为 <ph name="PRODUCT_NAME" /> 中的浏览器主帐号</translation>
 <translation id="800595420827930383">使用旧版平台证书验证程序</translation>
@@ -6615,6 +6667,7 @@
 <translation id="8056273037819805106"><ph name="PRODUCT_OS_NAME" />登录凭据会被用于向受管理的代理进行网络身份验证。</translation>
 <translation id="8056800559672904373">受管理的帐号必须是主帐号,无任何辅助帐号,而且允许用户在创建个人资料时导入现有浏览数据</translation>
 <translation id="8059164285174960932">远程访问客户端获取身份验证令牌的网址</translation>
+<translation id="8059352177830050556">启用设备背光信息报告功能</translation>
 <translation id="8062375903420954294">通过设置此政策,您可以限制 WebRTC 在尝试查找最佳的可用连接时会使用的 IP 地址和接口。若要了解详情,请参阅 RFC 8828 第 5.2 条 (https://tools.ietf.org/html/rfc8828.html#section-5.2)。如果您未设置此政策,WebRTC 会默认使用所有可用接口。</translation>
 <translation id="8062485064082966327">使用匿名 Google 服务为无标签图片提供自动说明</translation>
 <translation id="8071371098891664137">如果为 <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" /> 选择了 <ph name="PRINTERS_BLOCKLIST" />,您便可通过设置 <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> 来指定用户不能使用哪些打印机。除了与此政策中所列 ID 对应的打印机之外,其他所有打印机都可供用户使用。ID 必须与 <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" /> 所指定文件内的<ph name="ID_FIELD" />或<ph name="GUID_FIELD" />字段相符。</translation>
@@ -6927,6 +6980,7 @@
 <translation id="8367488518695804749">不允许任何网站显示弹出式窗口</translation>
 <translation id="8369602308428138533">使用交流电源供电时的屏幕关闭延迟时间</translation>
 <translation id="8371178326720637170">允许受管理的扩展程序使用 Enterprise Hardware Platform API</translation>
+<translation id="8373176843640227330">停用设备蓝牙信息报告功能</translation>
 <translation id="8375817202037102567">禁止在这些网站上向文件和目录写入内容</translation>
 <translation id="8378266419596669629">拒绝向这些网站授予本地字体权限</translation>
 <translation id="8379317372795444261">允许通过 HTTP 连接进行<ph name="BASIC_AUTH" />身份验证</translation>
@@ -6975,6 +7029,7 @@
 
        在 <ph name="PRODUCT_NAME" /> 95 版中,此政策将被移除。</translation>
 <translation id="8427466947904008809">允许 CRD 执行远程主机通过代理发送的 WebAuthn API 请求。</translation>
+<translation id="8428295225823548121">启用设备内存信息报告功能</translation>
 <translation id="8428635849021776523">停用 Android 报告</translation>
 <translation id="8433186206711564395">网络设置</translation>
 <translation id="8433769814000220721">启用建议的内容</translation>
@@ -7393,6 +7448,7 @@
 <translation id="8882255181490012651">禁止已选择启用 Phone Hub 的用户访问其手机上近期拍摄的照片和视频</translation>
 <translation id="8887709920496070892">系统应在设备闲置多久(以毫秒为单位)后显示警告对话框</translation>
 <translation id="8890438048579188548">隐藏 <ph name="CLOUD_PRINT_NAME" />弃用警告</translation>
+<translation id="8891334958985336685">停用设备系统信息报告功能</translation>
 <translation id="8892286064305622118"><ph name="PLUGIN_VM_NAME" /> 所需的可用磁盘空间</translation>
 <translation id="8892783613915541293">当设备闲置且使用交流电源供电时应执行的操作以及相应延迟时间</translation>
 <translation id="8897796778265450949">限制通过 GAIA(不使用 SAML)验证身份的用户可离线登录的时长</translation>
@@ -7460,6 +7516,7 @@
 <translation id="8977192934280677167">允许在上下文菜单中使用默认搜索服务提供商进行搜索</translation>
 <translation id="8983537551095611459">配置要从受限受管理访客会话清理过程中排除的扩展程序的 ID 列表</translation>
 <translation id="8983539044126123594">允许使用其他 Google 帐号登录</translation>
+<translation id="8985219286836584291">启用设备系统信息报告功能</translation>
 <translation id="8992176907758534924">不允许任何网站显示图片</translation>
 <translation id="8994954504552592260">借助此政策,您可允许将 <ph name="MS_AD_NAME" /> 管理的设备迁移到云管理服务。此政策允许从远程启动对公司中多部设备的无接触式迁移,还会尽可能提供充足的信息以便最终用户随时掌握迁移进度。
 
@@ -7721,6 +7778,7 @@
       如果此政策设为 false,只有 <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" /> 中列出的用户才能登录。
 
       如果此政策设为 true 或未配置,所有用户都将能够登录。</translation>
+<translation id="966425658642788645">应用默认行为</translation>
 <translation id="971677226939413180">不提供“以图片形式打印”选项供用户选择。</translation>
 <translation id="974349541138387272">指定所需 DNS-over-HTTPS 解析器的 URI 模板</translation>
 <translation id="979467274961593903">不允许进行远程调试</translation>
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb
index 50f700b..48f5d17 100644
--- a/components/policy/resources/policy_templates_zh-TW.xtb
+++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -69,6 +69,7 @@
 <translation id="1049138910114524876">設定 <ph name="PRODUCT_OS_NAME" /> 登入畫面上執行的語言代碼。
 
       如果設定這項政策,系統將一律以這項政策第一個值指定的語言代碼顯示登入畫面 (為了日後的相容性,系統會將政策定義為清單)。  如果未設定這項政策,或將政策設定為空白清單,系統將以上一個使用者工作階段的語言代碼顯示登入畫面。  如果這項政策設定的值不是有效的語言代碼,系統則將以備用語言代碼 (目前為 en-US) 顯示登入畫面。</translation>
+<translation id="1050158007881386475">停用裝置主機板狀態回報功能</translation>
 <translation id="1052499923181221200">除非 SamlInSessionPasswordChangeEnabled 設為 True,否則這項政策沒有影響。
       如果將該項政策設為 True,且將本政策設為 14 (舉例而言),系統會在 14 天前通知 SAML 使用者,表示密碼即將在特定日期到期。
       這樣一來,使用者即可立即在工作階段中變更和更新密碼,以免密碼到期。
@@ -321,6 +322,7 @@
       如果選取了「Forced」(2),使用者將無法隱藏設定檔選擇畫面。即使只有一個設定檔,瀏覽器也會顯示設定檔選擇畫面。</translation>
 <translation id="1339174690935954950">禁止使用者提出意見回饋</translation>
 <translation id="1342918903685430097">設定裝置的最低 <ph name="PRODUCT_OS_NAME" /> 版本限制。</translation>
+<translation id="1343128241903870688">停用裝置應用程式資訊回報功能</translation>
 <translation id="1347198119056266798">這項政策已遭淘汰,請改用 <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" /> 和 <ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" />。如果設定 <ph name="FORCE_GOOGLE_SAFE_SEARCH_POLICY_NAME" />、<ph name="FORCE_YOUTUBE_RESTRICT_POLICY_NAME" /> 或 <ph name="FORCE_YOUTUBE_SAFETY_MODE_POLICY_NAME" /> 政策 (已淘汰),系統會忽略這項政策。
 
       將 Google 網頁搜尋中的「安全搜尋」功能強制設為啟用,並禁止使用者變更這項設定。這項設定也會強制執行中度的 YouTube 嚴格篩選模式。
@@ -360,6 +362,7 @@
 <translation id="1393485621820363363">已啟用企業裝置印表機</translation>
 <translation id="1395505489889158859">允許將使用者名稱和檔案名稱傳送給原生印表機</translation>
 <translation id="1397855852561539316">預設搜尋引擎建議網址</translation>
+<translation id="1402227992519954892">啟用裝置應用程式資訊回報功能</translation>
 <translation id="141279920573530952">你可以透過這項政策設定網站清單,指定哪些網站會自動取得權限,能夠存取所有可用的序列埠。
 
       網址必須是有效網址,否則系統會忽略這項政策。系統只會檢視網址的來源,包括通訊標準、主機名稱和通訊埠。
@@ -605,6 +608,7 @@
 <translation id="1616280227447957376">允許忽略特定來源的 SSL 警告網頁繼續瀏覽</translation>
 <translation id="1617235075406854669">啟用刪除瀏覽器和下載記錄</translation>
 <translation id="1620510694547887537">攝影機</translation>
+<translation id="162162247775156979">停用裝置儲存空間狀態回報功能</translation>
 <translation id="1626379196197114720">允許使用往返快取</translation>
 <translation id="1628974048137236820">新分頁不會顯示卡片</translation>
 <translation id="1630263002012156148">如果將這項政策設為啟用,系統會將使用者的首頁設為「新分頁」,並忽略所有首頁網址位置。如果將這項政策設為停用,使用者的首頁一律不會是「新分頁」,除非使用者的首頁網址設為 chrome://newtab。
@@ -1071,6 +1075,7 @@
 <translation id="2043770014371753404">停用的企業印表機</translation>
 <translation id="2057317273526988987">允許存取網址清單</translation>
 <translation id="2058055310819710697">啟用已隔離應用程式的開發人員模式</translation>
+<translation id="205807990145127714">要用於回報信號強度事件的遙測資料。</translation>
 <translation id="2061123930713023976">允許針對網路封包擷取作業進行偵錯</translation>
 <translation id="2061810934846663491">為遠端存取主機設定必要的網域名稱</translation>
 <translation id="2062632109797189011">重新啟用已淘汰的 window.webkitStorageInfo API</translation>
@@ -1671,8 +1676,12 @@
 <translation id="2665422249821137126">在登入畫面上啟用大型游標</translation>
 <translation id="2667894101494585925">啟用最佳化指南擷取功能</translation>
 <translation id="2672012807430078509">控管是否要為 SMB 掛接功能啟用 NTLM 驗證通訊協定</translation>
+<translation id="2673363037046384711">使用者可以啟用或停用高效率模式。</translation>
 <translation id="2678503605767349615">必須提供裝置通用用戶端憑證</translation>
 <translation id="268577405881275241">啟用資料壓縮 Proxy 功能</translation>
+<translation id="268695908564263739">這項政策可啟用或停用高效率模式設定。這項設定能讓系統在一段時間後於背景捨棄分頁,以便回收記憶體。
+      如果不設定這項政策,使用者將可透過 chrome://settings/performance 控制這項設定。
+      </translation>
 <translation id="2691668238491124549">如果設定了這項政策 (只能設為「建議」),系統會將受管理工作階段的建議語言代碼移至清單頂端,並按照政策中顯示的順序排列。系統會預先選取第一個建議語言代碼。
       如果未設定,系統會預先選取目前的 UI 語言代碼。
 
@@ -2853,6 +2862,7 @@
 <translation id="3898345958122666461">停用 NTLMv2</translation>
 <translation id="3898795800259311780">允許或拒絕螢幕擷取</translation>
 <translation id="3903313632842363082">停用裝置使用者回報功能</translation>
+<translation id="3904304709151553598">停用裝置風扇資訊回報功能</translation>
 <translation id="3907683835264956726">在螢幕鎖定畫面上啟用線上使用者登入功能。如果將這項政策設為 True,<ph name="POLICY" /> 等政策會觸發螢幕鎖定畫面上的線上重新驗證功能。
       當使用者停留在螢幕鎖定畫面上,或下次在符合條件後鎖定螢幕時,系統會立即強制執行重新驗證。
       如果將這項政策設為 False 或不予設定,使用者一律可以使用本機憑證解鎖螢幕。</translation>
@@ -2896,6 +2906,7 @@
 
           如果不設定這項政策,系統會在初次顯示登入畫面時停用相黏鍵功能,但使用者隨時可以啟用。</translation>
 <translation id="3927291637826333102">依這些來源允許執行螢幕畫面、視窗和分頁擷取功能</translation>
+<translation id="3928726028264020458">啟用裝置 VPD 資訊回報功能</translation>
 <translation id="3943930334592166130">當多個憑證與 <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_POLICY_NAME" /> 相符時,這項政策可控管是否要提示使用者選取用戶端憑證。
       如果將這項政策設為 Enabled,每當自動選取政策與多個憑證相符時,系統會提示使用者選取用戶端憑證。
       如果將這項政策設為 Disabled 或不予設定,則只有在沒有任何符合自動選取政策的憑證時,系統才會提示使用者。</translation>
@@ -2984,6 +2995,7 @@
       在 <ph name="MS_WIN_NAME" /> 上,這項功能僅適用於已加入 <ph name="MS_AD_NAME" /> 網域的執行個體、在 Windows 10 專業版上執行的執行個體,或是已註冊 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />服務的執行個體。在 <ph name="MAC_OS_NAME" /> 上,這項功能僅適用於透過行動裝置管理 (MDM) 軟體進行管理或透過 MCX 加入網域的執行個體。</translation>
 <translation id="4043796890723386527">禁止使用者在 <ph name="LACROS_NAME" /> 瀏覽器中建立及使用次要設定檔,以及使用訪客模式</translation>
 <translation id="4051723201852944592">啟用視窗遮蔽功能</translation>
+<translation id="4052529125939620019">啟動時載入 CryptoToken 元件擴充功能</translation>
 <translation id="4053157306171963473">停用裝置活動時間回報功能</translation>
 <translation id="4056910949759281379">停用 SPDY 通訊協定</translation>
 <translation id="4061107397839125009">你可以透過這項政策設定網址模式清單,用於指定無法顯示通知的網站。
@@ -3042,6 +3054,28 @@
 
       如果設定了這項政策,使用者將無法變更設定。如果未設定,系統會先關閉螢幕小鍵盤,但使用者隨時可以開啟。</translation>
 <translation id="412697421478384751">允許使用者設定強度不足的螢幕鎖定 PIN 碼</translation>
+<translation id="4130565559631908067">你可以使用這項政策覆寫瀏覽器用於「第一方集合」功能的集合清單。
+
+      瀏覽器在第一方集合清單中列出的每個集合,都必須符合第一方集合的規定。
+      第一方集合必須包含擁有者網站和一或多個成員網站。
+      此外,集合中也可包含擁有的服務網站清單,以及網站與其所有 ccTLD 變數的對應資訊。
+      
+如要進一步瞭解 <ph name="PRODUCT_NAME" /> 使用的第一方集合,請前往 https://github.com/WICG/first-party-sets。
+
+      第一方集合中的所有網站都必須是透過 HTTPS 提供的可註冊網域。此外,第一方集合中的每個網站也不得重複,這表示網站在第一方集合中只能列出一次。
+
+      如果你在這項政策中指定空白的字典,瀏覽器會使用第一方集合的公開清單。
+
+      對於 <ph name="REPLACEMENTS" /> 清單中第一方集合的所有網站,假如某個網站同時也列在瀏覽器清單中的第一方集合,則系統會將該網站從瀏覽器的第一方集合中移除。
+      移除後,系統會將政策的第一方集合加入瀏覽器的第一方集合清單中。
+
+      對於 <ph name="ADDITIONS" /> 清單中第一方集合的所有網站,假如某個網站同時也列在瀏覽器清單中的第一方集合,則系統會更新瀏覽器的第一方集合清單,以便將新的第一方集合加入瀏覽器的清單中。待瀏覽器的清單更新完成後,系統就會將政策的第一方集合加入瀏覽器的第一方集合清單中。
+
+      瀏覽器的第一方集合清單所列的所有網站,均不得重複列於其他集合中。這項要求也同樣適用於 <ph name="REPLACEMENTS" /> 清單和 <ph name="ADDITIONS" /> 清單。同樣地,一個網站也不得重複列在 <ph name="REPLACEMENTS" /> 清單和 <ph name="ADDITIONS" /> 清單中。
+
+      萬用字元 (*) 不得用做政策值,也不可用在這些清單中的任何第一方集合。
+
+      政策提供的所有集合都必須是有效的第一方集合,如果無效,就會顯示相應錯誤。這項政策僅適用於已加入 <ph name="MS_AD_NAME" /> 網域的 Windows 執行個體、或是已註冊裝置管理服務的 Windows 10 專業版或企業版執行個體。如果是 macOS 執行個體,必須透過行動裝置管理 (MDM) 或利用 MCX 加入某個網域才能使用。</translation>
 <translation id="4138655880188755661">時間限制</translation>
 <translation id="4147818922357566987">僅啟用與重大修正項目相關的變化版本</translation>
 <translation id="4150201353443180367">顯示設定</translation>
@@ -3628,6 +3662,7 @@
       如果將這項政策設為停用或不設定,使用者可選擇是否要註冊 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />。如果註冊失敗,系統不會封鎖 <ph name="PRODUCT_NAME" /> 啟動程序。
 
       在電腦上註冊裝置範圍內的雲端政策時會使用這項政策。詳情請參閱 https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744。</translation>
+<translation id="488996881569316769">網路遙測</translation>
 <translation id="4890453377345554695">你可以透過這項政策建立網址模式清單,指定哪些網站可以要求使用者授予寫入權限,以寫入主機作業系統中檔案系統的檔案或目錄。
 
       如果未設定這項政策,系統會針對所有網站套用 <ph name="DEFAULT_FILE_SYSTEM_WRITE_GUARD_SETTING_POLICY_NAME" /> 政策 (如果已設定)。否則系統會套用使用者的個人設定。
@@ -3850,6 +3885,7 @@
 <translation id="5148753489738115745">允許你指定 <ph name="PRODUCT_FRAME_NAME" /> 啟動 <ph name="PRODUCT_NAME" /> 時使用的其他參數。
 
           如果未設定這項政策,系統會使用預設命令列。</translation>
+<translation id="5151099177901233471">啟用裝置時區資訊回報功能</translation>
 <translation id="5152393033264257734">允許 DNS 攔截檢查功能,以及你是不是要前往「http://intranetsite/」資訊列。</translation>
 <translation id="5152787786897382519">Chromium 和 Google Chrome 有部分政策群組具有相依關係,依此共同管控特定功能。這些組合如下列政策群組所示。由於政策可能具有多個來源,系統只會套用群組中最高優先來源所提供的值,忽略同個群組中優先順序較低的來源所提供的值。請參閱 <ph name="POLICY_PRIORITY_DOC_URL" /> 瞭解來源的優先順序。</translation>
 <translation id="5153187201534281749">工具列中的瀏覽器實驗功能圖示</translation>
@@ -3958,6 +3994,7 @@
 
       如果政策未設定或無效,則行為會等同於「等待目標版本跟上版本降級」。</translation>
 <translation id="5229339291699779956">為 Thunderbolt/USB4 周邊裝置啟用 PCIe 通道,讓周邊裝置執行完整功能</translation>
+<translation id="5230095739094490896">列印 'client-name' IPP 屬性範本</translation>
 <translation id="5233239004553860036">如果將這項政策設為 <ph name="POLICY_VALUE_ALL" /> 或不設定,系統會允許受管理帳戶的所有使用情況。這麼做可能導致受管理帳戶變更為次要帳戶,進而讓該帳戶只有在做為主要帳戶登入瀏覽器設定檔時才能接收政策。
     在下列情況下,系統不會強制執行對該帳戶設定的政策:
         -  在 OS 層級 (帳戶設定) 做為次要帳戶
@@ -3989,6 +4026,7 @@
       此處的「版本」可以指確切版本 (例如「61.0.3163.120」),也可以指版本前置字元 (例如「61.0」)。  </translation>
 <translation id="5247973380763021389">禁止使用者雲端政策覆寫裝置雲端政策。</translation>
 <translation id="5249453807420671499">使用者可以新增 Kerberos 帳戶</translation>
+<translation id="5249555581286638799">啟用高效率模式</translation>
 <translation id="5252210248395576403">這項政策可讓快速解答功能存取所選內容,並將相關資訊傳送給伺服器,進而取得翻譯結果。
 
       如果將這項政策設為啟用或不設定,系統會啟用快速解答的翻譯功能。
@@ -3997,6 +4035,7 @@
 
       如果將這項政策設為 False 或不設定,系統會停用整合桌面,且使用者無法啟用這項功能。</translation>
 <translation id="5255162913209987122">建議使用</translation>
+<translation id="525543707238275321">停用裝置 CPU 資訊回報功能</translation>
 <translation id="5257395339965216304">代管的應用程式資料</translation>
 <translation id="5262320080678421295">停止信任由 Symantec 公司舊版 PKI 核發的憑證</translation>
 <translation id="5266173014392157048">這項政策已遭淘汰,請改用「<ph name="AUTH_NEGOTIATE_DELEGATE_ALLOWLIST_POLICY_NAME" />」政策。
@@ -4061,6 +4100,7 @@
       如果未設定這項政策,<ph name="PRODUCT_NAME" /> 會使用預設最高版本。
 
       如要設定這項政策,則可使用的設定值包括:「tls1.2」或「tls1.3」。設定後,<ph name="PRODUCT_NAME" /> 就不會使用高於指定版本的 SSL/TLS 版本。系統會忽略無法辨識的值。</translation>
+<translation id="5329018127554115226">系統將停用高效率模式。</translation>
 <translation id="5330684698007383292">允許 <ph name="PRODUCT_FRAME_NAME" /> 處理列出的內容類型</translation>
 <translation id="5331746669335642668"><ph name="PRODUCT_NAME" /> 雲端政策會覆寫平台政策。</translation>
 <translation id="5346587320074666194">禁止在這些網站上存取感應器</translation>
@@ -4254,6 +4294,7 @@
       版本切換不適用這項政策。</translation>
 <translation id="5519331583722582543">布林值標記,表示螢幕小鍵盤是否能透過手寫辨識技術提供輸入功能。</translation>
 <translation id="5519619299971727565">停用 Linux 應用程式使用情形報告功能</translation>
+<translation id="5521035900165046997">啟用裝置藍牙資訊回報功能</translation>
 <translation id="5521875416764302911">禁止使用者登入 <ph name="PRODUCT_NAME" /></translation>
 <translation id="5526184558582921522">允許向 Quirks Server 發送查詢,並有機會下載硬體專屬設定檔</translation>
 <translation id="5526701598901867718">全部 (不安全)</translation>
@@ -4309,6 +4350,7 @@
 <translation id="5598417829613725146">畫布 (自 90 版開始支援)</translation>
 <translation id="5599461642204007579"><ph name="MS_AD_NAME" /> 管理設定</translation>
 <translation id="5601503069213153581">PIN 碼</translation>
+<translation id="5607021831414604820">啟用裝置儲存空間狀態回報功能</translation>
 <translation id="5614865701790130558">記錄以政策為根據的擴充功能安裝事件</translation>
 <translation id="5618398258385745432">我們先前曾以類似設定來控管使用者是否可查看密碼,但在新增重新驗證功能後,該設定與這項政策已不再適用於 Chrome 的運作方式。目前 Chrome 的運作方式,相當於這項政策禁止在密碼管理員設定頁面以純文字顯示密碼。也就是說,設定頁面只會顯示預留位置,使用者必須點選 [顯示] 並重新驗證 (如果適用),Chrome 才會顯示密碼。這項政策的原始說明如下:
 
@@ -4415,6 +4457,7 @@
       注意:重新啟動裝置及登出帳戶都會清除快取。</translation>
 <translation id="5717973246079053225">停用受管理設定檔的雲端報告功能</translation>
 <translation id="572155275267014074">Android 設定</translation>
+<translation id="5722577409367087850">載入擴充功能</translation>
 <translation id="5728154254076636808">允許建立 <ph name="PRODUCT_NAME" /> 設定檔資料的漫遊複本</translation>
 <translation id="5729308727912841256">Kerberos 密碼。<ph name="PASSWORD_PLACEHOLDER" /> 預留位置會由登入密碼取代。</translation>
 <translation id="5732972008943405952">首次執行時從預設瀏覽器匯入自動填入表單資料</translation>
@@ -4656,6 +4699,7 @@
       如果將這項政策設為停用,使用者將無法兌換這類優惠。</translation>
 <translation id="6046615715547751255">禁止使用精細回報控制項</translation>
 <translation id="6048199181629830227">開啟用電尖峰轉移電源管理功能</translation>
+<translation id="6049117606554031363">啟用裝置主機板狀態回報功能</translation>
 <translation id="6053681087509103368">允許 WebRTC 使用過時的 TLD/DTLS 通訊協定版本</translation>
 <translation id="6058879286588763839">除非已指定會覆寫 <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" /> 的 <ph name="DEVICE_ADVANCED_BATTERY_CHARGE_MODE_ENABLED_POLICY_NAME" />,否則你可以透過設定 <ph name="DEVICE_BATTERY_CHARGE_MODE_POLICY_NAME" />,在支援的裝置上指定充電模式電源管理政策。為了延長電池壽命,這項政策會透過盡可能避免過度使用及損耗電池,以動態方式控制充電狀態。
 
@@ -4688,6 +4732,7 @@
 <translation id="6099853574908182288">預設列印色彩模式</translation>
 <translation id="6102342563050263313">啟用捲動至網址片段所指定文字的功能</translation>
 <translation id="6102449843040973938">允許在裝置上執行 <ph name="BOREALIS_NAME" /></translation>
+<translation id="610892566190435199">啟用裝置電源狀態回報功能</translation>
 <translation id="6111936128861357925">允許 Dinosaur Easter Egg Game (恐龍復活節彩蛋遊戲)</translation>
 <translation id="6112524153927257380">如果設定這項政策,使用者就無法略過下載作業安全性判斷機制。
 
@@ -4831,6 +4876,7 @@
      這項政策的用途是讓企業能彈性停用音訊沙箱,避免安全性軟體的設定干擾沙箱運作。</translation>
 <translation id="624818583115864448">通訊埠 554 (2021 年 10 月 15 日前可解除封鎖)</translation>
 <translation id="6252773211180267325">允許使用者執行 <ph name="BOREALIS_NAME" /></translation>
+<translation id="625580680776945310">系統將啟用高效率模式。</translation>
 <translation id="6258658183356534534">控制 User-Agent Client Hints GREASE Update 功能。</translation>
 <translation id="6261643884958898336">回報裝置識別資訊</translation>
 <translation id="6265892395051519509">允許在這些網站上存取感應器</translation>
@@ -4988,6 +5034,7 @@
 <translation id="6368403635025849609">允許這些網站的 JavaScript</translation>
 <translation id="6371561334154580937">在最後一個關閉的視窗上顯示登出對話方塊。</translation>
 <translation id="6372105930898423193">允許重新啟用 AppCache 功能 (即使預設值為停用)。</translation>
+<translation id="6373299801585455337">啟用裝置 CPU 資訊回報功能</translation>
 <translation id="6376540107659524656">停用 Terminal System App 中的 SSH</translation>
 <translation id="6376659517206731212">可強制實行</translation>
 <translation id="6377031865393559909">允許使用者使用桌面範本</translation>
@@ -4995,6 +5042,7 @@
 <translation id="6378393933102834628">如果將這項政策設為 True,系統會顯示應用程式捷徑。如果將這項政策設為 False,系統一律不會顯示應用程式捷徑。
 
       如果設定這項政策,使用者將無法變更。如果未設定,使用者可以從書籤列內容選單中設定要顯示或隱藏應用程式捷徑。</translation>
+<translation id="638003144128412430">停用裝置時區資訊回報功能</translation>
 <translation id="6382351416269252693">你可以設定網站網址模式清單,指定哪些網站可以自動拒絕本機字型權限。這會限制網站查看本機字型相關資訊。
 
       如要進一步瞭解有效的網站網址模式,請前往 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。你也可以使用萬用字元 (<ph name="WILDCARD_VALUE" />)。這項政策只會根據來源進行比對,因此會忽略網址模式中的路徑。
@@ -5039,6 +5087,7 @@
 <translation id="6440051664870270040">允許同時在多個網站中進行瀏覽及開啟彈出式視窗</translation>
 <translation id="6447948611083700881">備份與還原功能已停用</translation>
 <translation id="6449476513004303784">不允許使用者管理憑證</translation>
+<translation id="6452882999388592166">如果設為啟用,系統會在啟動時載入內建的 CryptoToken 元件擴充功能。如果設為停用或不設定,瀏覽器啟動時就不會載入 CryptoToken。在 M106 中,我們移除了 CryptoToken,因而導致「chrome.runtime」呈現未定義的狀態。這項政策是用於處理網站因此故障的暫時性解決方案。網站不應無條件將「chrome.runtime」視為已定義。</translation>
 <translation id="6453641799812499182">在新版 <ph name="CORS" /> 模式中啟用 <ph name="CORS" /> 檢查安全防護措施</translation>
 <translation id="645425387487868471">啟用 <ph name="PRODUCT_NAME" /> 的強制登入功能</translation>
 <translation id="6455842857207956758">在密碼更新完成且需要同步時,監控密碼同步權杖的值,並讓使用者在線上進行重新驗證,以啟用多部 Chrome 之間的 SAML 密碼同步功能。
@@ -5113,6 +5162,7 @@
 <translation id="6506486086262398387">如果將這項政策設為啟用,<ph name="PRODUCT_OS_NAME" />的網路檔案共用功能會在必要時對 SMB 共用檔案使用 NTLM 驗證機制。如果設為停用,將會關閉 SMB 共用檔案的 NTLM 驗證機制。
 
       如果不設定這項政策,系統預設會為受管理的使用者停用此機制,其他使用者則會設為啟用。</translation>
+<translation id="6513453889192806240">HTTPS 延遲</translation>
 <translation id="6515357889978918016"><ph name="PLUGIN_VM_NAME" /> 圖片</translation>
 <translation id="6518102411616460786">等待目標版本跟上版本降級</translation>
 <translation id="6520802717075138474">第一次執行時從預設瀏覽器匯入搜尋引擎</translation>
@@ -5380,6 +5430,12 @@
 
       如果將這項政策設為 False 或不設定,系統不會為使用者啟用 <ph name="PLUGIN_VM_NAME" />。
       如果設為 True,在其他相關設定也允許這項操作的情況下,系統會為使用者啟用 <ph name="PLUGIN_VM_NAME" />。為了讓 <ph name="PLUGIN_VM_NAME" /> 順利執行,你必須將 <ph name="PLUGIN_VM_ALLOWED_POLICY_NAME" /> 和 <ph name="USER_PLUGIN_VM_ALLOWED_POLICY_NAME" /> 設為 True,並設定 <ph name="PLUGIN_VM_LICENSE_KEY_POLICY_NAME" /> 或 <ph name="PLUGIN_VM_USER_ID_POLICY_NAME" />。</translation>
+<translation id="6750902920405577210">要用於回報信號強度變更事件的遙測資料清單。
+
+      除非控管政策未停用回報功能,否則系統將回報每一項指定的遙測資料。
+      https_latency 和 network_telemetry 的控管政策為 ReportDeviceNetworkStatus。
+
+      如果未設定,系統就不會回報任何信號強度變更事件的額外遙測資料。</translation>
 <translation id="6752711782954612641">如果已啟用 <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> 政策,你可以設定 <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> 政策來指定使用 POST 搜尋網址時的參數。設定值由名稱和值的組合所構成 (以半形逗號分隔多個設定值)。如果值為範本參數 (例如 <ph name="SEARCH_TERM_MARKER" />),實際的搜尋字詞資料會取代該參數。
 
       如果未設定 <ph name="DEFAULT_SEARCH_PROVIDER_SEARCH_URL_POST_PARAMS_POLICY_NAME" /> 政策,系統會使用 GET 方法傳送搜尋要求。</translation>
@@ -5518,6 +5574,7 @@
 <translation id="6903814433019432303">僅在零售模式下啟用這項政策。
 
       決定在啟用示範工作階段時,要載入的網址組。這項政策會覆寫任何其他機制,設定起始網址,因此只可以套用至與特定使用者無關的工作階段。</translation>
+<translation id="6903818804346914108">啟用裝置風扇資訊回報功能</translation>
 <translation id="6905405893096403868">如果將這項政策設為字串清單,系統會將每個字串以個別指令行參數的形式傳送到替代瀏覽器。在 <ph name="MS_WIN_NAME" /> 上,這些參數會以空格連接起來。在 <ph name="MAC_OS_NAME" /> 和 <ph name="LINUX_OS_NAME" /> 上,參數可包含空格,但仍會被視為單一參數。
 
       如果有參數包含 <ph name="URL_PLACEHOLDER" />,系統會將 <ph name="URL_PLACEHOLDER" /> 替換成要開啟的網頁網址。如果沒有參數包含 <ph name="URL_PLACEHOLDER" />,則網址會附加在指令列結尾。
@@ -5821,6 +5878,7 @@
 <translation id="718126088895133062">這項政策會為這部裝置指定 <ph name="PLUGIN_VM_NAME" /> 授權使用者 ID。</translation>
 <translation id="7185078796915954712">TLS 1.3</translation>
 <translation id="7185630966939835143">使用 Google 網路服務來協助解決拼字錯誤</translation>
+<translation id="7187248416163189586">停用裝置背光資訊回報功能</translation>
 <translation id="718850220532931090">這項政策已遭淘汰,請改用 <ph name="ATTESTATION_EXTENSION_ALLOWLIST_POLICY_NAME" />。
 
       你可以透過這項政策指定要讓哪些擴充功能使用 <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> 的 <ph name="CHALLENGE_USER_KEY_FUNCTION" /> 函式進行遠端認證。只有列在這個清單上的擴充功能才能使用該 API。
@@ -5843,6 +5901,7 @@
 <translation id="7207095846245296855">強制啟用 Google 安全搜尋模式</translation>
 <translation id="7211368186050418507">一律不自動偵測時區</translation>
 <translation id="7216442368414164495">允許使用者採用安全瀏覽模式的進階回報功能</translation>
+<translation id="721970071627370558">停用裝置電源狀態回報功能</translation>
 <translation id="7221574724100909818">使用鎖頭圖示代表安全連線</translation>
 <translation id="7229365071755865554">允許使用密碼管理員儲存密碼</translation>
 <translation id="7229975860249300121">這項政策包含一個規則運算式,用來決定哪些 Google 帳戶可以設定為 <ph name="PRODUCT_NAME" /> 中的瀏覽器主要帳戶 (也就是在同步功能啟用流程中所選的帳戶)。
@@ -6201,6 +6260,7 @@
 <translation id="7587345076013230465">每當自動選取政策與多個憑證相符時,在登入畫面中提示使用者選取用戶端憑證</translation>
 <translation id="7587921466180902617">為 Family Link 使用者啟用螢幕側錄 Dogfood 測試</translation>
 <translation id="759957074386651883">安全瀏覽設定</translation>
+<translation id="7602621823177962064">停用裝置記憶體資訊回報功能</translation>
 <translation id="7604169113182304895">Android 應用程式可以選擇是否使用這份清單,你無法強制套用。</translation>
 <translation id="7612157962821894603">要在 <ph name="PRODUCT_NAME" /> 啟動時套用的全系統設定</translation>
 <translation id="7613115815080726221">閒置動作執行前的緩衝時間長度 (以毫秒為單位)。如果使用者在這段時間內沒有任何動作,系統就會採取閒置動作</translation>
@@ -6533,6 +6593,7 @@
 <translation id="7992613144342460685">允許這些網站取得視窗放置權限</translation>
 <translation id="7995610550667275367">掃描 (自 87 版起開始支援)</translation>
 <translation id="7999023147219236247">這項政策可控管如何授予應用程式要求的權限。PERMISSION_POLICY_UNSPECIFIED:未指定政策。如未針對任何層級的權限指定政策,系統會預設採取「PROMPT」值對應的行為。PROMPT:提示使用者授予權限。GRANT:自動授予權限。DENY:自動拒絕授予權限。</translation>
+<translation id="7999336306414770162">停用裝置 VPD 資訊回報功能</translation>
 <translation id="7999818120028621358">啟用資料外洩防護事件的回報功能</translation>
 <translation id="8001701200415781021">限制哪些 Google 帳戶可以設定為 <ph name="PRODUCT_NAME" /> 中的瀏覽器主要帳戶</translation>
 <translation id="800595420827930383">使用舊版平台憑證驗證器</translation>
@@ -6583,6 +6644,7 @@
 <translation id="8056273037819805106">使用者可利用 <ph name="PRODUCT_OS_NAME" />登入憑證向受管理的 Proxy 進行網路驗證。</translation>
 <translation id="8056800559672904373">受管理帳戶必須是主要帳戶,不可包含任何次要帳戶。此外,使用者在建立設定檔時,可以匯入現有的瀏覽資料</translation>
 <translation id="8059164285174960932">遠端存取用戶端取得驗證憑證的來源網址</translation>
+<translation id="8059352177830050556">啟用裝置背光資訊回報功能</translation>
 <translation id="8062375903420954294">這項政策可用來限制 WebRTC 在嘗試尋找最佳可用連線時,能夠使用哪些 IP 位址和介面。請參閱 RFC 8828 第 5.2 節(https://tools.ietf.org/html/rfc8828.html#section-5.2)。如果不設定這項政策,WebRTC 就會預設使用所有可用介面。</translation>
 <translation id="8062485064082966327">使用去識別化的 Google 服務,針對無標籤圖片提供自動產生的說明</translation>
 <translation id="8071371098891664137">如果在 <ph name="PRINTERS_BULK_ACCESS_MODE_POLICY_NAME" /> 中選擇了 <ph name="PRINTERS_BLOCKLIST" />,系統會根據 <ph name="PRINTERS_BULK_BLOCKLIST_POLICY_NAME" /> 的設定指定使用者不能操作的印表機。除了這項政策所列 ID 的印表機外,其他印表機皆可供使用。印表機 ID 必須與 <ph name="PRINTERS_BULK_CONFIGURATION_POLICY_NAME" /> 政策指定檔案的 <ph name="ID_FIELD" /> 或 <ph name="GUID_FIELD" /> 欄位值相符。</translation>
@@ -6892,6 +6954,7 @@
 <translation id="8367488518695804749">不允許任何網站顯示彈出式視窗</translation>
 <translation id="8369602308428138533">在 AC 供電環境下執行時的螢幕關閉延遲時間</translation>
 <translation id="8371178326720637170">啟用受管理擴充功能以使用 Enterprise Hardware Platform API</translation>
+<translation id="8373176843640227330">停用裝置藍牙資訊回報功能</translation>
 <translation id="8375817202037102567">禁止這些網站對檔案和目錄的寫入權限</translation>
 <translation id="8378266419596669629">封鎖這些網站上的本機字型權限</translation>
 <translation id="8379317372795444261">允許透過 HTTP 連線使用<ph name="BASIC_AUTH" />驗證</translation>
@@ -6939,6 +7002,7 @@
 
        這項政策將在 <ph name="PRODUCT_NAME" /> 第 95 版中移除。</translation>
 <translation id="8427466947904008809">允許 CRD 執行遠端主機透過 Proxy 傳送的 WebAuthn API 要求。</translation>
+<translation id="8428295225823548121">啟用裝置記憶體資訊回報功能</translation>
 <translation id="8428635849021776523">停用 Android 報告功能</translation>
 <translation id="8433186206711564395">網路設定</translation>
 <translation id="8433769814000220721">啟用推薦內容</translation>
@@ -7130,6 +7194,16 @@
 
       如果將這項政策設為 False,系統將不會凍結任何分頁。</translation>
 <translation id="8619748440665904084">不允許在第一次執行時匯入自動填入表單資料</translation>
+<translation id="8620103780247748230">這項政策可控管列印工作中的 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> IPP (網際網路列印通訊協定) 屬性值。
+
+      如果將這項政策設為字串,每個列印工作中就會新增額外的 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> 項目。替換變數後,系統會將新增的 <ph name="CLIENT_INFO_IPP_ATTRIBUTE" /> 項目 <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> 成員設為政策值。支援的變數包括 <ph name="DIRECTORY_ID_PLACEHOLDER" />、<ph name="SERIAL_NUMBER_PLACEHOLDER" />、<ph name="ASSET_ID_PLACEHOLDER" />、<ph name="ANNOTATED_LOCATION_PLACEHOLDER" />、<ph name="USER_EMAIL_PLACEHOLDER" />、<ph name="USER_EMAIL_NAME_PLACEHOLDER" />、<ph name="USER_EMAIL_DOMAIN" />。系統不會展開不支援的預留位置變數。
+
+      如果變數僅包含 <ph name="ASCII" /> 可列印字元,且長度不超過 255 個半形字元,替換變數後產生的值就會視為有效。
+
+      請注意,基於隱私考量,這項政策僅適用於透過 <ph name="IPPS_PROTOCOL" />、<ph name="HTTPS_PROTOCOL" />、<ph name="USB_PROTOCOL" /> 或 <ph name="IPP_USB_PROTOCOL" /> 通訊協定與印表機的通訊。此外,這項政策僅適用於支援 <ph name="CLIENT_NAME_IPP_ATTRIBUTE" /> 的印表機。
+
+      如果未設定這項政策、設為空白或無效值,系統就不會在列印工作要求中新增額外的 <ph name="CLIENT_INFO_PLACEHOLDER" />。
+      </translation>
 <translation id="8623672932476443039">如果將這項政策設為啟用,使用者可以存取「已隔離應用程式的開發人員模式」。
       如果將這項政策設為停用,使用者將無法存取這些功能。
       如果不設定這項政策,在預設情況下,Chrome OS 上受企業管理的使用者將無法存取這個模式,其他作業系統上的一般使用者則可存取這個模式。</translation>
@@ -7351,6 +7425,7 @@
 <translation id="8882255181490012651">禁止 Phone Hub 的使用者存取手機上最近拍攝的相片和影片</translation>
 <translation id="8887709920496070892">顯示警告對話方塊前的閒置時間長度 (以毫秒為單位)。如果使用者在這段時間內沒有任何動作,系統就會顯示警告對話方塊</translation>
 <translation id="8890438048579188548">隱藏 <ph name="CLOUD_PRINT_NAME" />淘汰警告訊息</translation>
+<translation id="8891334958985336685">停用裝置系統資訊回報功能</translation>
 <translation id="8892286064305622118"><ph name="PLUGIN_VM_NAME" /> 需要的可用磁碟空間</translation>
 <translation id="8892783613915541293">使用 AC 電源供電的裝置閒置時,系統採取的動作和延遲管理電源行動</translation>
 <translation id="8897796778265450949">限制透過 GAIA 驗證 (未使用 SAML) 的使用者可離線登入的時間</translation>
@@ -7420,6 +7495,7 @@
 <translation id="8977192934280677167">允許透過內容選單使用預設搜尋引擎</translation>
 <translation id="8983537551095611459">設定擴充功能 ID 清單,從有限制的受管理訪客工作階段清除程序中排除這些擴充功能</translation>
 <translation id="8983539044126123594">允許使用其他 Google 帳戶登入</translation>
+<translation id="8985219286836584291">啟用裝置系統資訊回報功能</translation>
 <translation id="8992176907758534924">不允許任何網站顯示圖片</translation>
 <translation id="8994954504552592260">允許將 <ph name="MS_AD_NAME" /> 管理的裝置遷移至雲端管理服務。這項政策允許遠端遷移公司中的多部裝置,不用實際接觸即可開始遷移。此外,遷移作業會盡可能提供充足資訊,方便使用者掌握進度。
 
@@ -7680,6 +7756,7 @@
       如果將這項政策設為 false,代表只有 <ph name="DEVICE_USER_ALLOWLIST_POLICY_NAME" /> 中的使用者才能登入。
 
       如果將這項政策設為 true 或不設定,則所有使用者都能登入。</translation>
+<translation id="966425658642788645">套用預設行為</translation>
 <translation id="971677226939413180">使用者無法選擇「以圖片形式列印」選項。</translation>
 <translation id="974349541138387272">指定所需 DNS-over-HTTPS 解析器的 URI 範本</translation>
 <translation id="979467274961593903">禁止使用遠端偵錯功能</translation>
diff --git a/components/reading_list/core/reading_list_store.cc b/components/reading_list/core/reading_list_store.cc
index f74ff53..d4ef7b3 100644
--- a/components/reading_list/core/reading_list_store.cc
+++ b/components/reading_list/core/reading_list_store.cc
@@ -241,7 +241,12 @@
       // Send to sync
       std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb =
           merged_entry->AsReadingListSpecifics();
-      DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb));
+#if !defined(NDEBUG)
+      std::unique_ptr<ReadingListEntry> initial_entry(
+          ReadingListEntry::FromReadingListSpecifics(specifics, clock_->Now()));
+      DCHECK(CompareEntriesForSync(*(initial_entry->AsReadingListSpecifics()),
+                                   *entry_sync_pb));
+#endif
       auto entity_data = std::make_unique<syncer::EntityData>();
       *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb;
       entity_data->name = entry_sync_pb->entry_id();
diff --git a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm
index 1feb0b1..1100f13 100644
--- a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm
+++ b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm
@@ -4,7 +4,9 @@
 
 #include "components/remote_cocoa/app_shim/select_file_dialog_bridge.h"
 
+#include <AppKit/AppKit.h>
 #include <CoreServices/CoreServices.h>
+#include <Foundation/Foundation.h>
 #include <stddef.h>
 
 #include "base/files/file_util.h"
@@ -489,10 +491,32 @@
         index = 1;
       }
     } else {
-      NSArray* urls = [static_cast<NSOpenPanel*>(panel_) URLs];
-      for (NSURL* url in urls)
-        if ([url isFileURL])
-          paths.push_back(base::mac::NSStringToFilePath([url path]));
+      // This does not use ObjCCast because the underlying object could be a
+      // non-exported AppKit type (https://crbug.com/995476).
+      NSOpenPanel* open_panel = static_cast<NSOpenPanel*>(panel_);
+
+      for (NSURL* url in open_panel.URLs) {
+        if (!url.isFileURL)
+          continue;
+        NSString* path = url.path;
+
+        // There is a bug in macOS where, despite a request to disallow file
+        // selection, files/packages are able to be selected. If indeed file
+        // selection was disallowed, drop any files selected.
+        // https://crbug.com/1357523, FB11405008
+        if (!open_panel.canChooseFiles) {
+          BOOL is_directory;
+          BOOL exists =
+              [[NSFileManager defaultManager] fileExistsAtPath:path
+                                                   isDirectory:&is_directory];
+          BOOL is_package =
+              [[NSWorkspace sharedWorkspace] isFilePackageAtPath:path];
+          if (!exists || !is_directory || is_package)
+            continue;
+        }
+
+        paths.push_back(base::mac::NSStringToFilePath(path));
+      }
     }
   }
 
diff --git a/components/reporting/storage/BUILD.gn b/components/reporting/storage/BUILD.gn
index 10d99f1f..14b089c3 100644
--- a/components/reporting/storage/BUILD.gn
+++ b/components/reporting/storage/BUILD.gn
@@ -12,6 +12,7 @@
 
   deps = [
     "//base",
+    "//components/reporting/proto:record_constants",
     "//components/reporting/resources:resource_interface",
   ]
 }
diff --git a/components/reporting/storage/storage.cc b/components/reporting/storage/storage.cc
index 2fe6541..e04137a 100644
--- a/components/reporting/storage/storage.cc
+++ b/components/reporting/storage/storage.cc
@@ -43,96 +43,9 @@
 namespace reporting {
 
 namespace {
-
-// Parameters of individual queues.
-// TODO(b/159352842): Deliver space and upload parameters from outside.
-
-constexpr base::FilePath::CharType kSecurityQueueSubdir[] =
-    FILE_PATH_LITERAL("Security");
-constexpr base::FilePath::CharType kSecurityQueuePrefix[] =
-    FILE_PATH_LITERAL("P_Security");
-
-constexpr base::FilePath::CharType kImmediateQueueSubdir[] =
-    FILE_PATH_LITERAL("Immediate");
-constexpr base::FilePath::CharType kImmediateQueuePrefix[] =
-    FILE_PATH_LITERAL("P_Immediate");
-
-constexpr base::FilePath::CharType kFastBatchQueueSubdir[] =
-    FILE_PATH_LITERAL("FastBatch");
-constexpr base::FilePath::CharType kFastBatchQueuePrefix[] =
-    FILE_PATH_LITERAL("P_FastBatch");
-constexpr base::TimeDelta kFastBatchUploadPeriod = base::Seconds(1);
-
-constexpr base::FilePath::CharType kSlowBatchQueueSubdir[] =
-    FILE_PATH_LITERAL("SlowBatch");
-constexpr base::FilePath::CharType kSlowBatchQueuePrefix[] =
-    FILE_PATH_LITERAL("P_SlowBatch");
-constexpr base::TimeDelta kSlowBatchUploadPeriod = base::Seconds(20);
-
-constexpr base::FilePath::CharType kBackgroundQueueSubdir[] =
-    FILE_PATH_LITERAL("Background");
-constexpr base::FilePath::CharType kBackgroundQueuePrefix[] =
-    FILE_PATH_LITERAL("P_Background");
-constexpr base::TimeDelta kBackgroundQueueUploadPeriod = base::Minutes(1);
-
-constexpr base::FilePath::CharType kManualQueueSubdir[] =
-    FILE_PATH_LITERAL("Manual");
-constexpr base::FilePath::CharType kManualQueuePrefix[] =
-    FILE_PATH_LITERAL("P_Manual");
-constexpr base::TimeDelta kManualUploadPeriod = base::TimeDelta::Max();
-
 constexpr base::FilePath::CharType kEncryptionKeyFilePrefix[] =
     FILE_PATH_LITERAL("EncryptionKey.");
 constexpr int32_t kEncryptionKeyMaxFileSize = 256;
-constexpr uint64_t kQueueSize = 2UL * 1024UL * 1024UL;
-
-// Failed upload retry delay: if an upload fails and there are no more incoming
-// events, collected events will not get uploaded for an indefinite time (see
-// b/192666219).
-constexpr base::TimeDelta kFailedUploadRetryDelay = base::Seconds(1);
-
-// Returns vector of <priority, queue_options> for all expected queues in
-// Storage. Queues are all located under the given root directory.
-std::vector<std::pair<Priority, QueueOptions>> ExpectedQueues(
-    const StorageOptions& options) {
-  return {
-      std::make_pair(SECURITY,
-                     QueueOptions(options)
-                         .set_subdirectory(kSecurityQueueSubdir)
-                         .set_file_prefix(kSecurityQueuePrefix)
-                         .set_upload_retry_delay(kFailedUploadRetryDelay)
-                         .set_max_single_file_size(kQueueSize)),
-      std::make_pair(IMMEDIATE,
-                     QueueOptions(options)
-                         .set_subdirectory(kImmediateQueueSubdir)
-                         .set_file_prefix(kImmediateQueuePrefix)
-                         .set_upload_retry_delay(kFailedUploadRetryDelay)
-                         .set_max_single_file_size(kQueueSize)),
-      std::make_pair(FAST_BATCH, QueueOptions(options)
-                                     .set_subdirectory(kFastBatchQueueSubdir)
-                                     .set_file_prefix(kFastBatchQueuePrefix)
-                                     .set_upload_period(kFastBatchUploadPeriod)
-                                     .set_max_single_file_size(kQueueSize)),
-      std::make_pair(SLOW_BATCH, QueueOptions(options)
-                                     .set_subdirectory(kSlowBatchQueueSubdir)
-                                     .set_file_prefix(kSlowBatchQueuePrefix)
-                                     .set_upload_period(kSlowBatchUploadPeriod)
-                                     .set_max_single_file_size(kQueueSize)),
-      std::make_pair(BACKGROUND_BATCH,
-                     QueueOptions(options)
-                         .set_subdirectory(kBackgroundQueueSubdir)
-                         .set_file_prefix(kBackgroundQueuePrefix)
-                         .set_upload_period(kBackgroundQueueUploadPeriod)
-                         .set_max_single_file_size(kQueueSize)),
-      std::make_pair(MANUAL_BATCH,
-                     QueueOptions(options)
-                         .set_subdirectory(kManualQueueSubdir)
-                         .set_file_prefix(kManualQueuePrefix)
-                         .set_upload_period(kManualUploadPeriod)
-                         .set_upload_retry_delay(kFailedUploadRetryDelay)
-                         .set_max_single_file_size(kQueueSize)),
-  };
-}
 }  // namespace
 
 // Uploader interface adaptor for individual queue.
@@ -290,8 +203,8 @@
 
 class Storage::KeyInStorage {
  public:
-  explicit KeyInStorage(base::StringPiece signature_verification_public_key,
-                        const base::FilePath& directory)
+  KeyInStorage(base::StringPiece signature_verification_public_key,
+               const base::FilePath& directory)
       : verifier_(signature_verification_public_key), directory_(directory) {}
   ~KeyInStorage() = default;
 
@@ -559,7 +472,7 @@
       : public TaskRunnerContext<StatusOr<scoped_refptr<Storage>>> {
    public:
     StorageInitContext(
-        const std::vector<std::pair<Priority, QueueOptions>>& queues_options,
+        const StorageOptions::QueuesOptionsList& queues_options,
         scoped_refptr<Storage> storage,
         base::OnceCallback<void(StatusOr<scoped_refptr<Storage>>)> callback)
         : TaskRunnerContext<StatusOr<scoped_refptr<Storage>>>(
@@ -673,8 +586,8 @@
       Response(std::move(storage_));
     }
 
-    const std::vector<std::pair<Priority, QueueOptions>> queues_options_;
-    scoped_refptr<Storage> storage_;
+    const StorageOptions::QueuesOptionsList queues_options_;
+    const scoped_refptr<Storage> storage_;
     int32_t count_ = 0;
     Status final_status_;
   };
@@ -686,8 +599,8 @@
                   std::move(async_start_upload_cb)));
 
   // Asynchronously run initialization.
-  Start<StorageInitContext>(ExpectedQueues(storage->options_),
-                            std::move(storage), std::move(completion_cb));
+  Start<StorageInitContext>(options.ProduceQueuesOptions(), std::move(storage),
+                            std::move(completion_cb));
 }
 
 Storage::Storage(const StorageOptions& options,
diff --git a/components/reporting/storage/storage.h b/components/reporting/storage/storage.h
index 59d7bdf..b303d232 100644
--- a/components/reporting/storage/storage.h
+++ b/components/reporting/storage/storage.h
@@ -70,8 +70,6 @@
   // be paased here.
   void UpdateEncryptionKey(SignedEncryptionInfo signed_encryption_key);
 
-  const StorageOptions& options() const { return options_; }
-
   Storage(const Storage& other) = delete;
   Storage& operator=(const Storage& other) = delete;
 
diff --git a/components/reporting/storage/storage_configuration.cc b/components/reporting/storage/storage_configuration.cc
index 7919eb7..e1f54ba 100644
--- a/components/reporting/storage/storage_configuration.cc
+++ b/components/reporting/storage/storage_configuration.cc
@@ -4,8 +4,58 @@
 
 #include "components/reporting/storage/storage_configuration.h"
 
+#include "base/files/file_path.h"
+
 namespace reporting {
 
+namespace {
+
+// Parameters of individual queues.
+// TODO(b/159352842): Deliver space and upload parameters from outside.
+
+constexpr base::FilePath::CharType kSecurityQueueSubdir[] =
+    FILE_PATH_LITERAL("Security");
+constexpr base::FilePath::CharType kSecurityQueuePrefix[] =
+    FILE_PATH_LITERAL("P_Security");
+
+constexpr base::FilePath::CharType kImmediateQueueSubdir[] =
+    FILE_PATH_LITERAL("Immediate");
+constexpr base::FilePath::CharType kImmediateQueuePrefix[] =
+    FILE_PATH_LITERAL("P_Immediate");
+
+constexpr base::FilePath::CharType kFastBatchQueueSubdir[] =
+    FILE_PATH_LITERAL("FastBatch");
+constexpr base::FilePath::CharType kFastBatchQueuePrefix[] =
+    FILE_PATH_LITERAL("P_FastBatch");
+constexpr base::TimeDelta kFastBatchUploadPeriod = base::Seconds(1);
+
+constexpr base::FilePath::CharType kSlowBatchQueueSubdir[] =
+    FILE_PATH_LITERAL("SlowBatch");
+constexpr base::FilePath::CharType kSlowBatchQueuePrefix[] =
+    FILE_PATH_LITERAL("P_SlowBatch");
+constexpr base::TimeDelta kSlowBatchUploadPeriod = base::Seconds(20);
+
+constexpr base::FilePath::CharType kBackgroundQueueSubdir[] =
+    FILE_PATH_LITERAL("Background");
+constexpr base::FilePath::CharType kBackgroundQueuePrefix[] =
+    FILE_PATH_LITERAL("P_Background");
+constexpr base::TimeDelta kBackgroundQueueUploadPeriod = base::Minutes(1);
+
+constexpr base::FilePath::CharType kManualQueueSubdir[] =
+    FILE_PATH_LITERAL("Manual");
+constexpr base::FilePath::CharType kManualQueuePrefix[] =
+    FILE_PATH_LITERAL("P_Manual");
+constexpr base::TimeDelta kManualUploadPeriod = base::TimeDelta::Max();
+
+constexpr uint64_t kQueueSize = 2UL * 1024UL * 1024UL;
+
+// Failed upload retry delay: if an upload fails and there are no more incoming
+// events, collected events will not get uploaded for an indefinite time (see
+// b/192666219).
+constexpr base::TimeDelta kFailedUploadRetryDelay = base::Seconds(1);
+
+}  // namespace
+
 StorageOptions::StorageOptions()
     : memory_resource_(base::MakeRefCounted<MemoryResourceImpl>(
           4u * 1024uLL * 1024uLL)),  // 4 MiB by default
@@ -15,6 +65,48 @@
 StorageOptions::StorageOptions(const StorageOptions& options) = default;
 StorageOptions::~StorageOptions() = default;
 
+// Returns vector of <priority, queue_options> for all expected queues in
+// Storage. Queues are all located under the given root directory.
+StorageOptions::QueuesOptionsList StorageOptions::ProduceQueuesOptions() const {
+  return {
+      std::make_pair(MANUAL_BATCH,
+                     QueueOptions(*this)
+                         .set_subdirectory(kManualQueueSubdir)
+                         .set_file_prefix(kManualQueuePrefix)
+                         .set_upload_period(kManualUploadPeriod)
+                         .set_upload_retry_delay(kFailedUploadRetryDelay)
+                         .set_max_single_file_size(kQueueSize)),
+      std::make_pair(BACKGROUND_BATCH,
+                     QueueOptions(*this)
+                         .set_subdirectory(kBackgroundQueueSubdir)
+                         .set_file_prefix(kBackgroundQueuePrefix)
+                         .set_upload_period(kBackgroundQueueUploadPeriod)
+                         .set_max_single_file_size(kQueueSize)),
+      std::make_pair(SLOW_BATCH, QueueOptions(*this)
+                                     .set_subdirectory(kSlowBatchQueueSubdir)
+                                     .set_file_prefix(kSlowBatchQueuePrefix)
+                                     .set_upload_period(kSlowBatchUploadPeriod)
+                                     .set_max_single_file_size(kQueueSize)),
+      std::make_pair(FAST_BATCH, QueueOptions(*this)
+                                     .set_subdirectory(kFastBatchQueueSubdir)
+                                     .set_file_prefix(kFastBatchQueuePrefix)
+                                     .set_upload_period(kFastBatchUploadPeriod)
+                                     .set_max_single_file_size(kQueueSize)),
+      std::make_pair(IMMEDIATE,
+                     QueueOptions(*this)
+                         .set_subdirectory(kImmediateQueueSubdir)
+                         .set_file_prefix(kImmediateQueuePrefix)
+                         .set_upload_retry_delay(kFailedUploadRetryDelay)
+                         .set_max_single_file_size(kQueueSize)),
+      std::make_pair(SECURITY,
+                     QueueOptions(*this)
+                         .set_subdirectory(kSecurityQueueSubdir)
+                         .set_file_prefix(kSecurityQueuePrefix)
+                         .set_upload_retry_delay(kFailedUploadRetryDelay)
+                         .set_max_single_file_size(kQueueSize)),
+  };
+}
+
 QueueOptions::QueueOptions(const StorageOptions& storage_options)
     : storage_options_(storage_options) {}
 QueueOptions::QueueOptions(const QueueOptions& options) = default;
diff --git a/components/reporting/storage/storage_configuration.h b/components/reporting/storage/storage_configuration.h
index c52d1db..036bc9b 100644
--- a/components/reporting/storage/storage_configuration.h
+++ b/components/reporting/storage/storage_configuration.h
@@ -6,17 +6,23 @@
 #define COMPONENTS_REPORTING_STORAGE_STORAGE_CONFIGURATION_H_
 
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "base/files/file_path.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
+#include "components/reporting/proto/synced/record_constants.pb.h"
 #include "components/reporting/resources/disk_resource_impl.h"
 #include "components/reporting/resources/memory_resource_impl.h"
 #include "components/reporting/resources/resource_interface.h"
 
 namespace reporting {
 
+// Forward declaration.
+class QueueOptions;
+
 // Storage options class allowing to set parameters individually, e.g.:
 // Storage::Create(Options()
 //                     .set_directory("/var/cache/reporting")
@@ -26,14 +32,22 @@
 //                 callback);
 class StorageOptions {
  public:
+  using QueuesOptionsList = std::vector<std::pair<Priority, QueueOptions>>;
+
   StorageOptions();
   StorageOptions(const StorageOptions& options);
   StorageOptions& operator=(const StorageOptions& options) = delete;
-  ~StorageOptions();
+  virtual ~StorageOptions();
   StorageOptions& set_directory(const base::FilePath& directory) {
     directory_ = directory;
     return *this;
   }
+
+  // Generates list of queues with their priorities, ordered from logically
+  // lowest to the highest (not the order of `Priority` enumerator!)
+  // Can be overridden by tests to modify queues options.
+  virtual QueuesOptionsList ProduceQueuesOptions() const;
+
   StorageOptions& set_signature_verification_public_key(
       base::StringPiece signature_verification_public_key) {
     signature_verification_public_key_ =
@@ -142,7 +156,7 @@
 
  private:
   // Whole storage options, which this queue options are based on.
-  const StorageOptions& storage_options_;
+  const StorageOptions storage_options_;
 
   // Subdirectory of the Storage location assigned for this StorageQueue.
   base::FilePath directory_;
diff --git a/components/reporting/storage/storage_queue_stress_test.cc b/components/reporting/storage/storage_queue_stress_test.cc
index feed94f8..ab515a3 100644
--- a/components/reporting/storage/storage_queue_stress_test.cc
+++ b/components/reporting/storage/storage_queue_stress_test.cc
@@ -177,22 +177,6 @@
     task_environment_.RunUntilIdle();
   }
 
-  QueueOptions BuildStorageQueueOptionsImmediate() const {
-    return QueueOptions(options_)
-        .set_subdirectory(FILE_PATH_LITERAL("D1"))
-        .set_file_prefix(FILE_PATH_LITERAL("F0001"))
-        .set_max_single_file_size(GetParam());
-  }
-
-  QueueOptions BuildStorageQueueOptionsPeriodic(
-      base::TimeDelta upload_period = base::Seconds(1)) const {
-    return BuildStorageQueueOptionsImmediate().set_upload_period(upload_period);
-  }
-
-  QueueOptions BuildStorageQueueOptionsOnlyManual() const {
-    return BuildStorageQueueOptionsPeriodic(base::TimeDelta::Max());
-  }
-
   void AsyncStartTestUploader(
       UploaderInterface::UploadReason reason,
       UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) {
@@ -238,7 +222,14 @@
         &write_waiter);
 
     SCOPED_TRACE(base::StrCat({"Create ", base::NumberToString(iStart)}));
-    CreateTestStorageQueueOrDie(BuildStorageQueueOptionsOnlyManual());
+    CreateTestStorageQueueOrDie(
+        QueueOptions(options_)
+            .set_subdirectory(FILE_PATH_LITERAL("D1"))
+            .set_file_prefix(FILE_PATH_LITERAL("F0001"))
+            .set_max_single_file_size(GetParam())
+            .set_upload_period(base::TimeDelta::Max())
+            .set_upload_retry_delay(
+                base::TimeDelta()));  // No retry by default.
 
     // Write into the queue at random order (simultaneously).
     SCOPED_TRACE(base::StrCat({"Write ", base::NumberToString(iStart)}));
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc
index 34d54f0..4c390791 100644
--- a/components/reporting/storage/storage_queue_unittest.cc
+++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -573,12 +573,11 @@
                                                  sequencing_ids);
   }
 
-  QueueOptions BuildStorageQueueOptionsImmediate(
-      base::TimeDelta upload_retry_delay = base::Seconds(1)) const {
+  QueueOptions BuildStorageQueueOptionsImmediate() const {
     return QueueOptions(options_)
         .set_subdirectory(FILE_PATH_LITERAL("D1"))
         .set_file_prefix(FILE_PATH_LITERAL("F0001"))
-        .set_upload_retry_delay(upload_retry_delay)
+        .set_upload_retry_delay(base::TimeDelta())  // No retry by default.
         .set_max_single_file_size(testing::get<0>(GetParam()));
   }
 
@@ -1559,7 +1558,9 @@
 }
 
 TEST_P(StorageQueueTest, WriteAndImmediateUploadWithFailure) {
-  CreateTestStorageQueueOrDie(BuildStorageQueueOptionsImmediate());
+  CreateTestStorageQueueOrDie(
+      BuildStorageQueueOptionsImmediate().set_upload_retry_delay(
+          base::Seconds(1)));
 
   // Write a record as Immediate, initiating an upload which fails
   // and then restarts.
@@ -1588,7 +1589,9 @@
 }
 
 TEST_P(StorageQueueTest, WriteAndImmediateUploadWithoutConfirmation) {
-  CreateTestStorageQueueOrDie(BuildStorageQueueOptionsImmediate());
+  CreateTestStorageQueueOrDie(
+      BuildStorageQueueOptionsImmediate().set_upload_retry_delay(
+          base::Seconds(1)));
 
   // Write a record as Immediate, initiating an upload which fails
   // and then restarts.
@@ -1777,9 +1780,8 @@
 }
 
 TEST_P(StorageQueueTest, WriteRecordWithInvalidFilePrefix) {
-  QueueOptions options = BuildStorageQueueOptionsPeriodic();
-  options.set_file_prefix(kInvalidFilePrefix);
-  CreateTestStorageQueueOrDie(options);
+  CreateTestStorageQueueOrDie(
+      BuildStorageQueueOptionsPeriodic().set_file_prefix(kInvalidFilePrefix));
   Status write_result = WriteString(kData[0]);
   EXPECT_FALSE(write_result.ok());
   EXPECT_EQ(write_result.error_code(), error::ALREADY_EXISTS);
@@ -1820,7 +1822,9 @@
 }
 
 TEST_P(StorageQueueTest, UploadWithInsufficientMemory) {
-  CreateTestStorageQueueOrDie(BuildStorageQueueOptionsPeriodic());
+  CreateTestStorageQueueOrDie(
+      BuildStorageQueueOptionsPeriodic().set_upload_retry_delay(
+          base::Seconds(1)));
   WriteStringOrDie(kData[0]);
 
   const auto original_total_memory = options_.memory_resource()->GetTotal();
diff --git a/components/reporting/storage/storage_unittest.cc b/components/reporting/storage/storage_unittest.cc
index eebb5ee..018332a 100644
--- a/components/reporting/storage/storage_unittest.cc
+++ b/components/reporting/storage/storage_unittest.cc
@@ -63,6 +63,33 @@
 // Test uploader counter - for generation of unique ids.
 std::atomic<int64_t> next_uploader_id{0};
 
+// Storage options to be used in tests.
+class TestStorageOptions : public StorageOptions {
+ public:
+  TestStorageOptions() = default;
+
+  QueuesOptionsList ProduceQueuesOptions() const override {
+    // Call base class method.
+    auto queues_options = StorageOptions::ProduceQueuesOptions();
+    for (auto& queue_options : queues_options) {
+      // Disable upload retry.
+      queue_options.second.set_upload_retry_delay(upload_retry_delay_);
+    }
+    // Make adjustments.
+    return queues_options;
+  }
+
+  // Prepare options adjustment.
+  // Must be called before the options are used by Storage::Create().
+  void set_upload_retry_delay(base::TimeDelta upload_retry_delay) {
+    upload_retry_delay_ = upload_retry_delay;
+  }
+
+ private:
+  base::TimeDelta upload_retry_delay_{
+      base::TimeDelta()};  // no retry by default
+};
+
 // Context of single decryption. Self-destructs upon completion or failure.
 class SingleDecryptionContext {
  public:
@@ -187,6 +214,7 @@
  protected:
   void SetUp() override {
     ASSERT_TRUE(location_.CreateUniqueTempDir());
+    options_.set_directory(location_.GetPath());
 
     // Disallow uploads unless other expectation is set (any later EXPECT_CALL
     // will take precedence over this one).
@@ -203,6 +231,9 @@
       // Generate signing key pair.
       test::GenerateSigningKeyPair(signing_private_key_,
                                    signature_verification_public_key_);
+      options_.set_signature_verification_public_key(std::string(
+          reinterpret_cast<const char*>(signature_verification_public_key_),
+          kKeySize));
       // Create decryption module.
       auto decryptor_result = test::Decryptor::Create();
       ASSERT_OK(decryptor_result.status()) << decryptor_result.status();
@@ -731,20 +762,17 @@
     // Let asynchronous activity finish.
     task_environment_.RunUntilIdle();
     if (storage_) {
-      const auto memory_resource = storage_->options().memory_resource();
-      const auto disk_space_resource =
-          storage_->options().disk_space_resource();
       storage_.reset();
       // StorageQueue is destructed on a thread,
       // so we need to wait for all queues to destruct.
       task_environment_.RunUntilIdle();
-      // Make sure all memory is deallocated.
-      ASSERT_THAT(memory_resource->GetUsed(), Eq(0u));
-      // Make sure all disk is not reserved (files remain, but Storage is not
-      // responsible for them anymore).
-      ASSERT_THAT(disk_space_resource->GetUsed(), Eq(0u));
     }
     expect_to_need_key_ = false;
+    // Make sure all memory is deallocated.
+    ASSERT_THAT(options_.memory_resource()->GetUsed(), Eq(0u));
+    // Make sure all disk is not reserved (files remain, but Storage is not
+    // responsible for them anymore).
+    ASSERT_THAT(options_.disk_space_resource()->GetUsed(), Eq(0u));
   }
 
   StatusOr<scoped_refptr<Storage>> CreateTestStorageWithFailedKeyDelivery(
@@ -765,17 +793,7 @@
     return storage;
   }
 
-  StorageOptions BuildTestStorageOptions() const {
-    StorageOptions options;
-    options.set_directory(location_.GetPath());
-    if (is_encryption_enabled()) {
-      // Encryption enabled.
-      options.set_signature_verification_public_key(std::string(
-          reinterpret_cast<const char*>(signature_verification_public_key_),
-          kKeySize));
-    }
-    return options;
-  }
+  const StorageOptions& BuildTestStorageOptions() const { return options_; }
 
   void AsyncStartMockUploader(
       UploaderInterface::UploadReason reason,
@@ -909,6 +927,7 @@
   uint8_t signing_private_key_[kSignKeySize];
 
   base::ScopedTempDir location_;
+  TestStorageOptions options_;
   scoped_refptr<test::Decryptor> decryptor_;
   scoped_refptr<Storage> storage_;
   SignedEncryptionInfo signed_encryption_key_;
@@ -1549,6 +1568,9 @@
 }
 
 TEST_P(StorageTest, WriteAndImmediateUploadWithFailure) {
+  // Reset options to enable failure retry.
+  options_.set_upload_retry_delay(base::Seconds(1));
+
   CreateTestStorageOrDie(BuildTestStorageOptions());
 
   // Write a record as Immediate, initiating an upload which fails
diff --git a/components/segmentation_platform/internal/database/signal_database_impl.cc b/components/segmentation_platform/internal/database/signal_database_impl.cc
index a4635de..efd6b42 100644
--- a/components/segmentation_platform/internal/database/signal_database_impl.cc
+++ b/components/segmentation_platform/internal/database/signal_database_impl.cc
@@ -13,6 +13,7 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/feature_list.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/clock.h"
 #include "base/time/time.h"
@@ -28,6 +29,9 @@
 namespace segmentation_platform {
 namespace {
 
+constexpr base::Feature kSegmentationCompactionFix{
+    "SegmentationCompactionFix", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // TODO(shaktisahu): May be make this a class member for ease of testing.
 bool FilterKeyBasedOnRange(proto::SignalType signal_type,
                            uint64_t name_hash,
@@ -76,7 +80,10 @@
 
 SignalDatabaseImpl::SignalDatabaseImpl(std::unique_ptr<SignalProtoDb> database,
                                        base::Clock* clock)
-    : database_(std::move(database)), clock_(clock) {}
+    : database_(std::move(database)),
+      clock_(clock),
+      should_fix_compaction_(
+          base::FeatureList::IsEnabled(kSegmentationCompactionFix)) {}
 
 SignalDatabaseImpl::~SignalDatabaseImpl() = default;
 
@@ -250,7 +257,8 @@
     std::unique_ptr<std::map<std::string, proto::SignalData>> entries) {
   TRACE_EVENT("segmentation_platform",
               "SignalDatabaseImpl::OnGetSamplesForCompaction");
-  if (!success || !entries || entries->empty() || entries->size() == 1) {
+  if (!success || !entries || entries->empty() ||
+      (should_fix_compaction_ && entries->size() == 1)) {
     std::move(callback).Run(success);
     return;
   }
@@ -269,7 +277,7 @@
 
     // If the database was already compacted, and some entry was added with
     // older timestamp, then append signals, and do not delete the key.
-    if (pair.first != compact_key) {
+    if (!(should_fix_compaction_ && pair.first == compact_key)) {
       keys_to_delete->emplace_back(pair.first);
     }
   }
diff --git a/components/segmentation_platform/internal/database/signal_database_impl.h b/components/segmentation_platform/internal/database/signal_database_impl.h
index b77a2b60..0fc9d0f 100644
--- a/components/segmentation_platform/internal/database/signal_database_impl.h
+++ b/components/segmentation_platform/internal/database/signal_database_impl.h
@@ -105,6 +105,10 @@
   // than 1 second are cleaned up on the subsequent invocation to WriteSample().
   std::map<SignalKey, proto::SignalData> recently_added_signals_;
 
+  // Enables the compaction fix. TODO(https://crbug.com/1357272): remove this
+  // after fixing the bug.
+  const bool should_fix_compaction_;
+
   base::WeakPtrFactory<SignalDatabaseImpl> weak_ptr_factory_{this};
 };
 
diff --git a/components/services/storage/public/mojom/cache_storage_control.mojom b/components/services/storage/public/mojom/cache_storage_control.mojom
index f81663d0..bee5de22 100644
--- a/components/services/storage/public/mojom/cache_storage_control.mojom
+++ b/components/services/storage/public/mojom/cache_storage_control.mojom
@@ -22,9 +22,11 @@
 // Observer interface for receiving callbacks after cache storage changes.
 interface CacheStorageObserver {
   // Called when caches are created or deleted.
+  // TODO(crbug.com/1218097): Pass bucket information also.
   OnCacheListChanged(blink.mojom.StorageKey storage_key);
 
   // Called when the content of a cache has been modified.
+  // TODO(crbug.com/1218097): Pass bucket information also.
   OnCacheContentChanged(blink.mojom.StorageKey storage_key,
                         string cache_name);
 };
@@ -38,6 +40,7 @@
 interface CacheStorageControl {
   // Binds a CacheStorage receiver to the CacheStorageControl to access
   // the cache storage for a particular storage key and owner.
+  // TODO(crbug.com/1218097): Allow custom bucket names.
   AddReceiver(
       network.mojom.CrossOriginEmbedderPolicy policy,
       pending_remote<network.mojom.CrossOriginEmbedderPolicyReporter>?
diff --git a/components/strings/components_strings_af.xtb b/components/strings/components_strings_af.xtb
index 203523d..3be67a2 100644
--- a/components/strings/components_strings_af.xtb
+++ b/components/strings/components_strings_af.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Toestelontsluiting</translation>
 <translation id="1269516672602708785">Skep vinnig 'n nuwe werf in Google Sites</translation>
 <translation id="1270502636509132238">Oplaaimetode</translation>
+<translation id="1273592791152866347">Prysnasporing is af</translation>
 <translation id="1281476433249504884">Stapelaar 1</translation>
 <translation id="1285320974508926690">Moet nooit hierdie werf vertaal nie</translation>
 <translation id="1288548991597756084">Stoor kaart veilig</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Vryware en deelware</translation>
 <translation id="1553358976309200471">Dateer Chrome op</translation>
+<translation id="1554003749331233619">Jy spoor nou hierdie produk na. Hierdie bladsy is in <ph name="LAST_BOOKMARKS_FOLDER" /> gestoor</translation>
 <translation id="1555130319947370107">Blou</translation>
 <translation id="1559447966090556585">Kry kennisgewings?</translation>
 <translation id="1559528461873125649">Daar is geen so 'n lêer of gids nie</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Bestuur Google-rekening; druk Enter om jou inligting, privaatheid en sekuriteit in jou Google-rekening te bestuur</translation>
 <translation id="2436186046335138073">Laat <ph name="HANDLER_HOSTNAME" /> toe om alle <ph name="PROTOCOL" />-skakels oop te maak?</translation>
 <translation id="2438874542388153331">Vierpons regs</translation>
+<translation id="2443309680964448806">Iets is fout. Jou verandering is nie gestoor nie.</translation>
 <translation id="2448295565072560657">Randtoestelle wat aan hierdie toestel gekoppel is terwyl jy aangemeld is</translation>
 <translation id="2450021089947420533">Reise</translation>
 <translation id="2463739503403862330">Vul in</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">Weet wanneer jy hierdie toestel aktief gebruik</translation>
 <translation id="3180358318770512945">Ouerskap</translation>
 <translation id="3187306450550410410">Aanpasbare werkreëlings</translation>
+<translation id="3190736958609431397">Stop nasporing</translation>
 <translation id="319282854780294203">Sosiale netwerke</translation>
 <translation id="3194737229810486521"><ph name="URL" /> wil data permanent op jou toestel berg</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> op <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">Betaalmetodes</translation>
 <translation id="3391030046425686457">Afleweringadres</translation>
 <translation id="3391482648489541560">lêerwysiging</translation>
+<translation id="3392028486601120379">Daar is ’n pad vir die URL-patroon "<ph name="URL_PATTERN" />" gespesifiseer. Paaie word nie vir hierdie sleutel gesteun nie. Verwyder asseblief die pad en probeer weer, byvoorbeeld, *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Oplaaimetode</translation>
 <translation id="3399952811970034796">Afleweringadres</translation>
 <translation id="3402261774528610252">Die verbinding wat gebruik word om hierdie werf te laai, gebruik TLS 1.0 of TLS 1.1, wat opgeskort is en in die toekoms gedeaktiveer sal word. Nadat dit gedeaktiveer is, sal gebruikers verhinder word om hierdie werf te laai. Die bediener moet TLS 1.2 of nuwer aktiveer.</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">Stoor in Google-rekening</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Program:</translation>
+<translation id="3647286794400715637">Elke URL-stringinskrywing moet 1 tot 2 URL'e bevat.</translation>
 <translation id="3650584904733503804">Stawing suksesvol</translation>
 <translation id="3653033846669030038">Temaparke</translation>
 <translation id="3655241534245626312">Gaan na toestemminginstellings</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">Jou administrateur bestuur jou blaaier.</translation>
 <translation id="3740319564441798148">Langafstandbus- en spoorvervoer</translation>
 <translation id="3744111561329211289">Agtergrondsinkronisering</translation>
+<translation id="3744286742364977428">Lêers wat jy aflaai, word na Google Cloud of derde partye gestuur om ontleed te word. Hulle kan byvoorbeeld vir sensitiewe data of wanware geskandeer word en kan op grond van maatskappybeleide geberg word.</translation>
 <translation id="3744899669254331632">Jy kan <ph name="SITE" /> nie nou onmiddelllik besoek nie, omdat die webwerf deurmekaar eiebewyse gestuur het wat Chrome nie kan verwerk nie. Netwerkfoute en -aanvalle is gewoonlik tydelik, so hierdie bladsy sal waarskynlik later werk.</translation>
 <translation id="3745099705178523657">Nadat jy bevestig het, sal kaartbesonderhede vanaf jou Google-rekening met hierdie werf gedeel word.</translation>
 <translation id="3748148204939282805">Aanvallers op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan jou dalk mislei om iets gevaarlik te doen, soos om sagteware te installeer of jou persoonlike inligting bekend te maak (byvoorbeeld: wagwoorde, foonnommers of kredietkaartinligting). <ph name="BEGIN_LEARN_MORE_LINK" />Kom meer te wete<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">Skep Geleentheid-knoppie; druk Enter om vinnig 'n nuwe geleentheid in Google Kalender te skep</translation>
 <translation id="4088981014127559358">Skuif prent langs Y-as op kant 1</translation>
 <translation id="4089152113577680600">Laai 14</translation>
+<translation id="4097288585054919042">Skakel opletberigte af</translation>
 <translation id="4098354747657067197">Misleidende werf voor</translation>
 <translation id="4099048595830172239">Administrateursbeleid beveel aan dat jy nie jou skerm met <ph name="APPLICATION_TITLE" /> deel wanneer vertroulike inhoud sigbaar is nie:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, druk Tab en dan Enter om lettertipegroottes en lettersoorte in Chrome te pasmaak</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">Gedeaktiveer</translation>
 <translation id="4176535426287761656">Tyddele en vakansie-eiendomme</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Stop prysnasporing</translation>
 <translation id="4194250254487269611">Jou kaart kan nie nou gestoor word nie</translation>
 <translation id="4196861286325780578">Herdoen skuif</translation>
 <translation id="4202554117186904723">Vyfde rol</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">Herbegin jou toestel</translation>
 <translation id="4277028893293644418">Stel wagwoord terug</translation>
 <translation id="4278390842282768270">Toegelaat</translation>
+<translation id="4282346679996504092">Opletberigte vir hierdie produk is afgeskakel en die boekmerk is verwyder</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Hierdie kaart is in jou Google-rekening gestoor}other{Hierdie kaarte is in jou Google-rekening gestoor}}</translation>
 <translation id="4287885627794386150">Kwalifiseer vir proeflopie, maar nie aktief nie</translation>
 <translation id="4297502707443874121">Miniprent vir bladsy <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">Die template wat jy gespesifiseer het, kan weens 'n fout met die DnsOverHttpsMode-beleid dalk nie toegepas word nie.</translation>
 <translation id="4358461427845829800">Bestuur betaalmetodes …</translation>
 <translation id="4359160567981085931">Jy het sopas jou wagwoord op 'n misleidende werf ingevoer. Chrome kan help. Klik Beskerm Rekening om jou wagwoord te verander en stel Google in kennis dat jou rekening dalk in gevaar is.</translation>
+<translation id="4363222835916186793">Opletberigte vir hierdie produk is afgeskakel</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">Sekuriteitsgeval vind plaas</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">Die inligting wat jy op die punt is om in te dien, is nie veilig nie</translation>
 <translation id="4796594887379589189">Taakrekening-ID</translation>
 <translation id="4798078619018708837">Voer die vervaldatum en CVC vir <ph name="CREDIT_CARD" /> in om jou kaartbesonderhede op te dateer. Nadat jy bevestig het, sal kaartbesonderhede vanaf jou Google-rekening met hierdie werf gedeel word.</translation>
+<translation id="4798269756263412078">Kry kennisgewings as die prys op enige werf daal. Opletberigte sal na jou e-pos toe gestuur word.</translation>
 <translation id="4800132727771399293">Gaan jou vervaldatum en CVC na en probeer weer</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Gebruik Raak-ID</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">Randhegting regs</translation>
 <translation id="5398772614898833570">Advertensies is geblokkeer</translation>
 <translation id="5400836586163650660">Grys</translation>
+<translation id="540630185148148480">Skakel opletberigte aan</translation>
 <translation id="540969355065856584">Hierdie bediener kon nie bewys dat dit <ph name="DOMAIN" /> is nie; sy sekuriteitsertifikaat is nie op die oomblik geldig nie. Dit kan veroorsaak word deur 'n wanopstelling of 'n aanvaller wat jou verbinding onderskep.</translation>
 <translation id="5412040515238827314">Ongeldige formaat: ’n lys patrone word verwag.</translation>
 <translation id="5412236728747081950">Hierdie werf kry jou belangstellings van Chrome af om vir jou relevanter advertensies te wys</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">Gaan jou vervalmaand na en probeer weer</translation>
 <translation id="558420943003240152">Bestuur wagwoorde en wagwoordsleutels …</translation>
 <translation id="5586446728396275693">Geen gestoorde adresse nie</translation>
+<translation id="5586831831248371458">Deursoek <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Platformgebruiker</translation>
 <translation id="5593349413089863479">Verbinding is nie heeltemal veilig nie</translation>
 <translation id="5595485650161345191">Wysig adres</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">Voeg virtuele kaart by</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Maak tans <ph name="SITE_NAME" /> oop …</translation>
+<translation id="5947508410139465809">Lêers wat jy oplaai of aanheg, word na Google Cloud of derde partye gestuur om ontleed te word. Hulle kan byvoorbeeld vir sensitiewe data of wanware geskandeer word en kan op grond van maatskappybeleide geberg word.</translation>
 <translation id="5951495562196540101">Kan nie met 'n verbruikerrekening inskryf nie (verpakte lisensie beskikbaar).</translation>
 <translation id="5953516610448771166">Intydse Onderskrifte is nie beskikbaar vir hierdie media nie. Blokkeer <ph name="CONTENT_SETTINGS" /> vir hierdie werf om onderskrifte te kry.</translation>
 <translation id="5955063559762970069">Hotelle en akkommodasie</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">Jou verbinding aan hierdie werf is nie veilig nie</translation>
 <translation id="6180316780098470077">Herprobeer-interval</translation>
 <translation id="61877208875190028">Vroueklere</translation>
+<translation id="6194209731893739467">Sien al jou nagespoorde produkte hier</translation>
 <translation id="6195371403461054755">Geologie</translation>
 <translation id="6196640612572343990">Blokkeer derdeparty-webkoekies</translation>
 <translation id="6203231073485539293">Gaan jou internetverbinding na</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Jou toestel sal nou herbegin}=1{Jou toestel sal oor 1 sekonde herbegin}other{Jou toestel sal oor # sekondes herbegin}}</translation>
+<translation id="6301104306974789820">Kry prysnasporingkennisgewings</translation>
 <translation id="6302269476990306341">Google Assistent in Chrome stop tans</translation>
 <translation id="6305205051461490394"><ph name="URL" /> is onbereikbaar.</translation>
 <translation id="6311165245110979290">Virtuele kaart is beskikbaar</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">Bevestig vormherindiening</translation>
 <translation id="6456955391422100996">Advertensie is verwyder.</translation>
 <translation id="6457206614190510200">Saalhegting</translation>
+<translation id="6457455098507772300">Opletberigte oor prysdalings verskyn as opspringkennisgewings op jou rekenaar</translation>
 <translation id="6458606150257356946">Plak in elk geval</translation>
 <translation id="6464094930452079790">prente</translation>
 <translation id="6465306955648956876">Bestuur wagwoorde …</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Vee uit</translation>
 <translation id="6645291930348198241">Kry toegang tot webkoekies en werfdata.</translation>
+<translation id="6645478838938543427">Opletberigte oor prysdalings sal na <ph name="EMAIL_ADDRESS" /> toe gestuur word</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Geen}=1{Vanaf 1 werf (jy sal nie uit jou Google-rekening afgemeld word nie)}other{Vanaf # werwe (jy sal nie uit jou Google-rekening afgemeld word nie)}}</translation>
 <translation id="6648459603387803038">Jou administrateur kan jou blaaieropstelling oor 'n afstand verander. Aktiwiteit op hierdie toestel kan ook buite Chrome bestuur word.</translation>
 <translation id="6648524591329069940">Seriflettertipe</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">Geen beleid gestel nie</translation>
 <translation id="7186367841673660872">Die bladsy is vertaal uit <ph name="ORIGINAL_LANGUAGE" /> in <ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Rasieleiding</translation>
+<translation id="7192188280913829296">Die kenmerk "vendor_id" moet ook gespesifiseer wees.</translation>
 <translation id="7192203810768312527">Maak <ph name="SIZE" /> beskikbaar. Sommige werwe sal dalk stadiger laai met jou volgende besoek.</translation>
 <translation id="7193661028827781021">Naslaanwerke</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb
index 20327d05..e646f26 100644
--- a/components/strings/components_strings_ar.xtb
+++ b/components/strings/components_strings_ar.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">فتح قفل الجهاز</translation>
 <translation id="1269516672602708785">‏إنشاء موقع إلكتروني جديد في "مواقع Google" بسرعة</translation>
 <translation id="1270502636509132238">طريقة الاستلام</translation>
+<translation id="1273592791152866347">ميزة تتبُّع السعر غير مفعَّلة</translation>
 <translation id="1281476433249504884">المكدِّس 1</translation>
 <translation id="1285320974508926690">عدم ترجمة هذا الموقع مطلقًا</translation>
 <translation id="1288548991597756084">حفظ البطاقة بأمان</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">برامج مجانية وتجريبية</translation>
 <translation id="1553358976309200471">‏تحديث Chrome‏</translation>
+<translation id="1554003749331233619">أنت الآن تتتبّع سعر هذا المنتج. تم حفظ هذه الصفحة في "<ph name="LAST_BOOKMARKS_FOLDER" />".</translation>
 <translation id="1555130319947370107">أزرق</translation>
 <translation id="1559447966090556585">هل تريد تلقّي إشعارات؟</translation>
 <translation id="1559528461873125649">لا وجود لمثل هذا الملف أو الدليل</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">‏إدارة حساب Google: اضغط على مفتاح Enter لإدارة المعلومات والخصوصية والأمان في حسابك على Google.</translation>
 <translation id="2436186046335138073">هل تريد السماح لـ <ph name="HANDLER_HOSTNAME" /> بفتح كل روابط <ph name="PROTOCOL" />؟</translation>
 <translation id="2438874542388153331">عمل أربعة ثقوب يمينًا</translation>
+<translation id="2443309680964448806">حدث خطأ، ولم يتم حفظ التغيير الذي أجريته.</translation>
 <translation id="2448295565072560657">الأجهزة الملحقة المُرفقة بهذا الجهاز عند تسجيل الدخول</translation>
 <translation id="2450021089947420533">رحلات البحث</translation>
 <translation id="2463739503403862330">ملء</translation>
@@ -820,6 +823,7 @@
 <translation id="317878711435188021">رصد استخدامك النشط لهذا الجهاز</translation>
 <translation id="3180358318770512945">تربية الأبناء</translation>
 <translation id="3187306450550410410">ترتيبات العمل المرن</translation>
+<translation id="3190736958609431397">إيقاف التتبُّع</translation>
 <translation id="319282854780294203">شبكات اجتماعية</translation>
 <translation id="3194737229810486521">يريد <ph name="URL" /> تخزين البيانات بشكل دائم على جهازك.</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> على <ph name="SERVER_NAME" /></translation>
@@ -905,6 +909,7 @@
 <translation id="3387261909427947069">طرق الدفع</translation>
 <translation id="3391030046425686457">عنوان التسليم</translation>
 <translation id="3391482648489541560">تعديل الملفات</translation>
+<translation id="3392028486601120379">‏يتضمن نمط عنوان URL "<ph name="URL_PATTERN" />" مسارًا محددًا، وحيث إنّ المسارات غير متوافقة مع هذا المفتاح، يُرجى إزالة المسار والمحاولة مرة أخرى، على سبيل المثال، *://example.com/ =&gt; *://example.com".</translation>
 <translation id="3395827396354264108">طريقة الاستلام</translation>
 <translation id="3399952811970034796">عنوان التسليم</translation>
 <translation id="3402261774528610252">‏إن الاتصال المستخدَم لتحميل هذا الموقع الإلكتروني يعتمد على إصدارات متوقفة، مثل TLS 1.0 أو 1.1 TLS. وسيتم إيقاف هذه الإصدارات كليًا في المستقبل. وعندما يتم إيقافها كليًا، سيتم منع المستخدمين من تحميل هذا الموقع الإلكتروني. على الخادم تفعيل TLS 1.2 أو إصدار أحدث.</translation>
@@ -1000,6 +1005,7 @@
 <translation id="3637662659967048211">‏حفظ المعلومات في حساب Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">التطبيق:</translation>
+<translation id="3647286794400715637">‏يجب أن يحتوي كل إدخال في سلسلة عناوين URL على عنوان URL واحد (كحد أدني) أو اثنين (كحد أقصى).</translation>
 <translation id="3650584904733503804">تم التحقق بنجاح</translation>
 <translation id="3653033846669030038">متنزهات ترفيهية</translation>
 <translation id="3655241534245626312">الانتقال إلى إعدادات الأذونات</translation>
@@ -1039,6 +1045,7 @@
 <translation id="3738166223076830879">يتولّى مشرفك إدارة متصفِّحك.</translation>
 <translation id="3740319564441798148">حافلات وقطارات للمسافات الطويلة</translation>
 <translation id="3744111561329211289">المزامنة في الخلفية</translation>
+<translation id="3744286742364977428">‏يتم إرسال الملفات التي تنزِّلها إلى Google Cloud أو جهات خارجية لتحليلها. على سبيل المثال، قد يتم فحص هذه الملفات بحثًا عن بيانات حسّاسة أو برامج ضارة، وقد يتم تخزينها استنادًا إلى سياسات الشركة.</translation>
 <translation id="3744899669254331632">‏لا يمكنك زيارة <ph name="SITE" /> في الوقت الحالي لأن الموقع أرسل اعتمادات مختلطة حيث لا يستطيع Chromium المعالجة. أخطاء الشبكة وهجماتها عادةً ما تكون مؤقتة، لذلك من المحتمل أن تعمل هذه الصفحة في وقت لاحق.</translation>
 <translation id="3745099705178523657">‏بعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حسابك على Google مع هذا الموقع الإلكتروني.</translation>
 <translation id="3748148204939282805">قد يخدعك المهاجمون على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> لاتّخاذ إجراءات خطيرة، مثل تثبيت برامج معيّنة أو كشف معلوماتك الشخصية (مثل كلمات المرور أو أرقام الهاتف أو بطاقات الائتمان). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1146,6 +1153,7 @@
 <translation id="4087296516249690906">‏زرّ إنشاء حدث: اضغط على مفتاح Enter لإنشاء حدث جديد في "تقويم Google" بسرعة.</translation>
 <translation id="4088981014127559358">‏طباعة جانب واحد image Y shift</translation>
 <translation id="4089152113577680600">الدُرج 14</translation>
+<translation id="4097288585054919042">إيقاف التنبيهات</translation>
 <translation id="4098354747657067197">أنت بصدد الانتقال إلى موقع إلكتروني مخادع</translation>
 <translation id="4099048595830172239">تحظر سياسة المشرف مشاركة الشاشة مع تطبيق <ph name="APPLICATION_TITLE" /> عند عرض محتوى سري:</translation>
 <translation id="4099391883283080991">‏<ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />، اضغط على مفتاح Tab ثم مفتاح Enter لتخصيص أحجام الخطوط وأنماطها في Chrome.</translation>
@@ -1182,6 +1190,7 @@
 <translation id="4176463684765177261">غير مفعّل</translation>
 <translation id="4176535426287761656">عقارات بنظام الملكية المشتركة، أو لقضاء العطلات</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">إيقاف تتبُّع السعر</translation>
 <translation id="4194250254487269611">يتعذّر حفظ بطاقتك الآن.</translation>
 <translation id="4196861286325780578">إ&amp;عادة النقل</translation>
 <translation id="4202554117186904723">اللفافة الخامسة</translation>
@@ -1228,6 +1237,7 @@
 <translation id="4275830172053184480">إعادة تشغيل جهازك</translation>
 <translation id="4277028893293644418">إعادة ضبط كلمة المرور</translation>
 <translation id="4278390842282768270">منح الإذن</translation>
+<translation id="4282346679996504092">تم إيقاف التنبيهات لهذا المنتج وتمت إزالة الإشارة المرجعية من الصفحة.</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{‏تم حفظ هذه البطاقة في حسابك على Google}zero{‏تم حفظ هذه البطاقات في حسابك على Google}two{‏تم حفظ هاتين البطاقتين في حسابك على Google}few{‏تم حفظ هذه البطاقات في حسابك على Google}many{‏تم حفظ هذه البطاقات في حسابك على Google}other{‏تم حفظ هذه البطاقات في حسابك على Google}}</translation>
 <translation id="4287885627794386150">حسابك مؤهّل للحصول على إصدار تجريبي ولكنّه غير نشِط.</translation>
 <translation id="4297502707443874121">صورة مصغّرة لصفحة <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1266,6 +1276,7 @@
 <translation id="4358059973562876591">‏قد لا يتم تطبيق النماذج التي حدّدتها بسبب حدوث خطأ في سياسة DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">إدارة طرق الدفع...</translation>
 <translation id="4359160567981085931">‏لقد أدخلت للتو كلمة مرورك في موقع إلكتروني مريب. يمكن لـ Chrome مساعدتك. لتغيير كلمة مرورك وإشعار Google أن حسابك قد يكون معرّضًا للخطر، انقر على "حماية الحساب".</translation>
+<translation id="4363222835916186793">تم إيقاف التنبيهات لهذا المنتج.</translation>
 <translation id="4367563149485757821">‏Number-12 (مغلف)</translation>
 <translation id="437040971055499437">وقوع حدث أمني</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1419,6 +1430,7 @@
 <translation id="4792686369684665359">المعلومات التي تريد إرسالها غير محمية</translation>
 <translation id="4796594887379589189">رقم تعريف حساب المهمة</translation>
 <translation id="4798078619018708837">‏يمكنك إدخال تاريخ انتهاء الصلاحية ورمز التحقّق (CVC) لبطاقة <ph name="CREDIT_CARD" /> لتحديث تفاصيلها. وبعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حسابك على Google مع هذا الموقع الإلكتروني.</translation>
+<translation id="4798269756263412078">يمكنك الحصول على تنبيهات في حال انخفاض السعر على أي موقع إلكتروني. سيتم إرسال التنبيهات إلى عنوان بريدك الإلكتروني.</translation>
 <translation id="4800132727771399293">‏تحقق من تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) وأعد المحاولة مرة أخرى.</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">‏استخدام ميزة Touch ID</translation>
@@ -1662,6 +1674,7 @@
 <translation id="5396631636586785122">خزم الحواف يمينًا</translation>
 <translation id="5398772614898833570">تم حظر الإعلانات</translation>
 <translation id="5400836586163650660">رمادي</translation>
+<translation id="540630185148148480">تفعيل التنبيهات</translation>
 <translation id="540969355065856584">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />؛ بل إن شهادة الأمان الخاصة به غير صالحة حاليًا. وربما يكون السبب في ذلك وجود خطأ في التكوين أو اعترض أحد المهاجمين للاتصال.</translation>
 <translation id="5412040515238827314">تنسيق غير صالح: كان من المتوقّع ظهور قائمة بالأنماط.</translation>
 <translation id="5412236728747081950">‏يتعرّف هذا الموقع الإلكتروني على اهتماماتك من خلال متصفّح Chrome ويعرض لك إعلانات تناسبك أكثر.</translation>
@@ -1726,6 +1739,7 @@
 <translation id="5580958916614886209">تحقق من شهر انتهاء الصلاحية وأعِد المحاولة مرة أخرى</translation>
 <translation id="558420943003240152">إدارة كلمات المرور ومفاتيح المرور…</translation>
 <translation id="5586446728396275693">لا توجد عناوين محفوظة</translation>
+<translation id="5586831831248371458">البحث على <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">مستخدم النظام الأساسي</translation>
 <translation id="5593349413089863479">الاتصال بهذا الموقع الإلكتروني غير آمن تمامًا</translation>
 <translation id="5595485650161345191">تعديل العنوان</translation>
@@ -1845,6 +1859,7 @@
 <translation id="5938153366081463283">إضافة بطاقة افتراضية</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">جارٍ فتح <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">‏إنّ الملفات التي تحمِّلها أو ترفقها يتم إرسالها إلى Google Cloud أو جهات خارجية لتحليلها. على سبيل المثال، قد يتم فحص هذه الملفات بحثًا عن بيانات حسّاسة أو برامج ضارة، وقد يتم تخزينها استنادًا إلى سياسات الشركة.</translation>
 <translation id="5951495562196540101">لا يمكن التسجيل باستخدام حساب المستهلك (الترخيص المجمّع متوفّر).</translation>
 <translation id="5953516610448771166">لا تتوفّر ميزة "النسخ النصي التلقائي" لهذه الوسائط. للحصول على الشرح، يمكنك إيقاف <ph name="CONTENT_SETTINGS" /> على هذا الموقع الإلكتروني.</translation>
 <translation id="5955063559762970069">فنادق وأماكن إقامة</translation>
@@ -1933,6 +1948,7 @@
 <translation id="6177128806592000436">إن اتصالك بهذا الموقع غير آمن</translation>
 <translation id="6180316780098470077">الفاصل الزمني لإعادة المحاولة</translation>
 <translation id="61877208875190028">ملابس سيدات</translation>
+<translation id="6194209731893739467">الاطّلاع هنا على جميع المنتجات التي يتمّ تتبّع أسعارها</translation>
 <translation id="6195371403461054755">جيولوجيا</translation>
 <translation id="6196640612572343990">حظر ملفات تعريف الارتباط للجهات الخارجية</translation>
 <translation id="6203231073485539293">التحقق من اتصالك بالإنترنت</translation>
@@ -1968,6 +1984,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{ستتم إعادة تشغيل جهازك الآن}=1{ستتم إعادة تشغيل جهازك بعد ثانية واحدة}two{ستتم إعادة تشغيل جهازك بعد ثانيتين}few{ستتم إعادة تشغيل جهازك بعد # ثوانٍ}many{ستتم إعادة تشغيل جهازك بعد # ثانية}other{ستتم إعادة تشغيل جهازك بعد # ثانية}}</translation>
+<translation id="6301104306974789820">الحصول على الإشعارات الخاصة بتتبُّع أسعار المنتجات</translation>
 <translation id="6302269476990306341">‏جارٍ إيقاف "مساعد Google" على Chrome</translation>
 <translation id="6305205051461490394">يتعذر الوصول إلى <ph name="URL" />.</translation>
 <translation id="6311165245110979290">البطاقة الافتراضية متوفّرة</translation>
@@ -2027,6 +2044,7 @@
 <translation id="6451458296329894277">تأكيد إعادة إرسال النموذج</translation>
 <translation id="6456955391422100996">تمت إزالة الإعلان.</translation>
 <translation id="6457206614190510200">خزم من المنتصف</translation>
+<translation id="6457455098507772300">تظهر التنبيهات بشأن انخفاض الأسعار كإشعارات منبثقة على سطح المكتب.</translation>
 <translation id="6458606150257356946">اللصق على أي حال</translation>
 <translation id="6464094930452079790">الصور</translation>
 <translation id="6465306955648956876">إدارة كلمات المرور...</translation>
@@ -2084,6 +2102,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">محو</translation>
 <translation id="6645291930348198241">الوصول إلى بيانات الموقع الإلكتروني وملفات تعريف الارتباط</translation>
+<translation id="6645478838938543427">سيتم إرسال التنبيهات بشأن انخفاض الأسعار إلى عنوان البريد الإلكتروني <ph name="EMAIL_ADDRESS" />.</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{بدون}=1{‏من موقع إلكتروني واحد (لن يتم تسجيل خروجك من حسابك على Google)}two{‏من موقعي ويب (#) (لن يتم تسجيل خروجك من حسابك على Google)}few{‏من # مواقع إلكترونية (لن يتم تسجيل خروجك من حسابك على Google)}many{‏من # موقع إلكتروني (لن يتم تسجيل خروجك من حسابك على Google)}other{‏من # موقع إلكتروني (لن يتم تسجيل خروجك من حسابك على Google)}}</translation>
 <translation id="6648459603387803038">‏يمكن لمشرفك تغيير إعداد المتصفِّح عن بُعد. وقد تتم أيضًا إدارة النشاط على هذا الجهاز خارج Chrome.</translation>
 <translation id="6648524591329069940">‏خط Serif</translation>
@@ -2277,6 +2296,7 @@
 <translation id="7182878459783632708">لم يتم ضبط أي سياسات</translation>
 <translation id="7186367841673660872">تمت ترجمة هذه الصفحة من اللغة<ph name="ORIGINAL_LANGUAGE" />إلى اللغة<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">فِرَق تشجيع</translation>
+<translation id="7192188280913829296">‏يجب أيضًا تحديد السمة "vendor_id".</translation>
 <translation id="7192203810768312527">يوفِّر <ph name="SIZE" />. قد يتم تحميل بعض المواقع الإلكترونية بشكل أبطأ عند زيارتها في المرة القادمة.</translation>
 <translation id="7193661028827781021">مراجع</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_az.xtb b/components/strings/components_strings_az.xtb
index de6c941..8a35c1c1 100644
--- a/components/strings/components_strings_az.xtb
+++ b/components/strings/components_strings_az.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Cihazın kiliddən çıxarılması</translation>
 <translation id="1269516672602708785">Google Sayt'da cəld yeni sayt yaradın</translation>
 <translation id="1270502636509132238">Götürmə Üsulu</translation>
+<translation id="1273592791152866347">Qiymət izləməsi deaktivdir</translation>
 <translation id="1281476433249504884">Yığıcı 1</translation>
 <translation id="1285320974508926690">Bu saytı heç vaxt tərcümə etməyin</translation>
 <translation id="1288548991597756084">Kartı etibarlı şəkildə saxlayın</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Texniki-D</translation>
 <translation id="1551884710160394169">Pulsuz paylaşılan proqramlar</translation>
 <translation id="1553358976309200471">Chrome'u güncəlləşdirin</translation>
+<translation id="1554003749331233619">İndi bu məhsulu izləyirsiniz. Bu səhifə <ph name="LAST_BOOKMARKS_FOLDER" /> qovluğunda saxlanılıb</translation>
 <translation id="1555130319947370107">Mavi</translation>
 <translation id="1559447966090556585">Bildiriş əldə edilsin?</translation>
 <translation id="1559528461873125649">Belə fayl və ya direktoriya yoxdur</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">"Google Hesabını idarə edin" düyməsi, Enter düyməsinə basaraq Google Hesabınızda məlumat, məxfilik və təhlükəsizliyinizi idarə edin</translation>
 <translation id="2436186046335138073"><ph name="HANDLER_HOSTNAME" /> hostuna bütün <ph name="PROTOCOL" /> linklərini açmaq icazəsi verirsiniz?</translation>
 <translation id="2438874542388153331">Sağdan dördlü deşik açın</translation>
+<translation id="2443309680964448806">Xəta oldu. Dəyişiklik yadda saxlanmayıb.</translation>
 <translation id="2448295565072560657">Daxil olduğunuz zaman bu cihaza əlavə edilmiş köməkçi cihazlar</translation>
 <translation id="2450021089947420533">Baxışlar</translation>
 <translation id="2463739503403862330">Doldurun</translation>
@@ -817,6 +820,7 @@
 <translation id="317878711435188021">Bu cihazdan nə zaman aktiv şəkildə istifadə etdiyinizi bilmək</translation>
 <translation id="3180358318770512945">Valideynlik</translation>
 <translation id="3187306450550410410">Çevik iş mühiti</translation>
+<translation id="3190736958609431397">İzləməyin</translation>
 <translation id="319282854780294203">Sosial şəbəkələr</translation>
 <translation id="3194737229810486521"><ph name="URL" /> datanı həmişəlik cihazınızda saxlamaq istəyir</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> <ph name="SERVER_NAME" /> serverində</translation>
@@ -902,6 +906,7 @@
 <translation id="3387261909427947069">Ödəniş Üsulları</translation>
 <translation id="3391030046425686457">Çatdırılma ünvanı</translation>
 <translation id="3391482648489541560">fayl redaktəsi</translation>
+<translation id="3392028486601120379">"<ph name="URL_PATTERN" />" keçid modeli üçün yol təyin edilib. Bu açar üçün yollar dəstəklənmir, yolu silib yenidən cəhd edin. Məs. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Götürmə üsulu</translation>
 <translation id="3399952811970034796">Çatdırılma Ünvanı</translation>
 <translation id="3402261774528610252">Bu saytı yükləmək üçün istifadə edilən bağlantı köhnələn və gələcəkdə söndürüləcək TLS 1.0 və ya TLS 1.1 versiyasından istifadə etdi. Söndürüldükdən sonra istifadəçilərin bu saytı yükləməsinin qarşısı alınacaq. Server TLS 1.2 və ya daha sonrakı versiyanı aktivləşdirməlidir.</translation>
@@ -995,6 +1000,7 @@
 <translation id="3637662659967048211">Google Hesabında saxlayın</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Tətbiq:</translation>
+<translation id="3647286794400715637">Hər bir keçid sətri daxiletməsində 1-2 keçid olmalıdır.</translation>
 <translation id="3650584904733503804">Yoxlama uğurludur</translation>
 <translation id="3653033846669030038">Tematik parklar</translation>
 <translation id="3655241534245626312">İcazə ayarlarına keçin</translation>
@@ -1033,6 +1039,7 @@
 <translation id="3738166223076830879">Brauzeriniz administratorunuz tərəfindən idarə edilir.</translation>
 <translation id="3740319564441798148">Uzun məsafəli avtobus və dəmir yolu</translation>
 <translation id="3744111561329211289">Arxa fon sinx</translation>
+<translation id="3744286742364977428">Endirdiyiniz fayllar təhlil üçün Google Cloud'a və ya üçüncü tərəflərə göndərilir. Məsələn, onlar həssas data və ya zərərli proqrama görə skanlana və şirkət siyasətlərinə əsasən saxlana bilər.</translation>
 <translation id="3744899669254331632">Sayt güvənsiz kredensiallar göndərdiyi üçün <ph name="SITE" /> ünvanına girə bilməzsiniz.</translation>
 <translation id="3745099705178523657">Təsdiqlədikdən sonra Google Hesabındakı kart məlumatları bu saytda paylaşılacaq.</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> saytındakı hücumçular Sizi zərərli proqram təminatı quraşdırmaq və ya şəxsi məlumatı (məsələn, parol, telefon nömrəsi və ya kredit kartları) paylaşmaq kimi təhlükəli işləri görməyə sövq edə bilər. <ph name="BEGIN_LEARN_MORE_LINK" />Ətraflı məlumat<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1140,6 +1147,7 @@
 <translation id="4087296516249690906">"Tədbir yaradın" düyməsi, Enter düyməsinə basaraq Google Calendar'da cəld yeni tədbir yaradın</translation>
 <translation id="4088981014127559358">Şəklin 1-ci tərəfinin Y oxu üzrə yerdəyişməsi</translation>
 <translation id="4089152113577680600">Qab 14</translation>
+<translation id="4097288585054919042">Bildirişləri deaktiv edin</translation>
 <translation id="4098354747657067197">Qabaqda aldadıcı site</translation>
 <translation id="4099048595830172239">Administrator siyasəti məxfi kontent görünəndə ekranınızı <ph name="APPLICATION_TITLE" /> ilə paylaşmağı tövsiyə etmir:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tab düyməsi, sonra Enter düyməsinə basaraq Chrome'da şrift ölçülərini və şriftləri fərdiləşdirin</translation>
@@ -1176,6 +1184,7 @@
 <translation id="4176463684765177261">Deaktiv edildi</translation>
 <translation id="4176535426287761656">Vaxt keçirmə və tətil yerləri</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Qiyməti izləməyin</translation>
 <translation id="4194250254487269611">Hazırda kartınızı yadda saxlamaq mümkün deyil</translation>
 <translation id="4196861286325780578">Hərəkəti təkrarlayın</translation>
 <translation id="4202554117186904723">Beşinci Rulon</translation>
@@ -1222,6 +1231,7 @@
 <translation id="4275830172053184480">Cihazınızı yenidən başladın</translation>
 <translation id="4277028893293644418">Parolu sıfırlayın</translation>
 <translation id="4278390842282768270">İcazə verilib</translation>
+<translation id="4282346679996504092">Bu məhsul üçün xəbərdarlıqlar deaktiv edilib və əlfəcin silinib</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Bu kart Google Hesabında yadda saxlanılıb}other{Bu kartlar Google Hesabında yadda saxlanılıb}}</translation>
 <translation id="4287885627794386150">Sınaq üçün uyğundur, lakin aktiv deyil</translation>
 <translation id="4297502707443874121"><ph name="THUMBNAIL_PAGE" /> səhifəsi üçün miniatür</translation>
@@ -1260,6 +1270,7 @@
 <translation id="4358059973562876591">DnsOverHttpsMode siyasətində xəta olduğuna görə qeyd etdiyiniz şablonlar tətbiq edilməyə bilər.</translation>
 <translation id="4358461427845829800">Ödəniş üsullarını idarə edin...</translation>
 <translation id="4359160567981085931">İndicə parolunuzu aldadıcı saytda daxil etdiniz. Chrome yardım edə bilər. Parolunuzu dəyişmək və Google'a hesabınızın təhlükədə ola biləcəyini bildirmək üçün "Hesabı Qoruyun" seçiminə toxunun.</translation>
+<translation id="4363222835916186793">Bu məhsul üçün xəbərdarlıqlar deaktiv edilib</translation>
 <translation id="4367563149485757821">Nömrə-12 (Zərf)</translation>
 <translation id="437040971055499437">Güvənlik tədbiri baş verir</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1412,6 +1423,7 @@
 <translation id="4792686369684665359">Təqdim etmək üzrə olduğunuz məlumat güvənli deyil</translation>
 <translation id="4796594887379589189">İş hesabı ID'si</translation>
 <translation id="4798078619018708837">Kart məlumatlarını yeniləmək üçün <ph name="CREDIT_CARD" /> kartının bitmə tarixini və CVC-ni daxil edin. Təsdiqlədikdən sonra Google Hesabındakı kart məlumatları bu saytda paylaşılacaq.</translation>
+<translation id="4798269756263412078">Hər hansı bir saytda qiymət enərsə, bildiriş alın Xəbərdarlıqlar e-poçtunuza göndəriləcək.</translation>
 <translation id="4800132727771399293">Bitmə tarixi və CVC nömrəsini yoxlayın və yenidən cəhd edin</translation>
 <translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
 <translation id="4806051791961048632">Toxunuş ID-sindən istifadə edin</translation>
@@ -1655,6 +1667,7 @@
 <translation id="5396631636586785122">Sağdan kənarını tikin</translation>
 <translation id="5398772614898833570">Reklamlar blok edildi</translation>
 <translation id="5400836586163650660">Boz</translation>
+<translation id="540630185148148480">Xəbərdarlıqları aktiv edin</translation>
 <translation id="540969355065856584">Bu server <ph name="DOMAIN" /> domenini təsdiqləyə bilmir; güvənlik sertifikatı hazırda etibarlı deyil. Buna yanlış konfiqurasiya və ya hücumçu tərəfindən bağlantının ələ keçirilməsi səbəb ola bilər.</translation>
 <translation id="5412040515238827314">Yanlış format: Model siyahısı gözlənilir.</translation>
 <translation id="5412236728747081950">Bu sayt sizə daha uyğun reklamlar göstərmək üçün Chrome'dan maraqlarınızı əldə edir</translation>
@@ -1719,6 +1732,7 @@
 <translation id="5580958916614886209">Bitmə ayını yoxlayın və yenidən cəhd edin</translation>
 <translation id="558420943003240152">Parolları və şifrələri idarə edin…</translation>
 <translation id="5586446728396275693">Yadda saxlanılmış ünvan yoxdur</translation>
+<translation id="5586831831248371458">Axtarın: <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Platforma istifadəçisi</translation>
 <translation id="5593349413089863479">Bağlantı tam güvənli deyil</translation>
 <translation id="5595485650161345191">Ünvana düzəliş edin</translation>
@@ -1838,6 +1852,7 @@
 <translation id="5938153366081463283">Virtual kart əlavə edin</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> açılır…</translation>
+<translation id="5947508410139465809">Yüklədiyiniz və ya əlavə etdiyiniz fayllar təhlil üçün Google Cloud'a və ya üçüncü tərəflərə göndərilir. Məsələn, onlar həssas data və ya zərərli proqrama görə skanlana və şirkət siyasətlərinə əsasən saxlana bilər.</translation>
 <translation id="5951495562196540101">Müştəri hesabı (toplu lisenziya əlçatandır) ilə qeydiyyatdan keçmək mümkün deyil.</translation>
 <translation id="5953516610448771166">Canlı Altyazı bu media üçün əlçatan deyil. Altyazıları əldə etmək üçün bu saytda <ph name="CONTENT_SETTINGS" /> ayarını blok edin.</translation>
 <translation id="5955063559762970069">Otel və qonaqlama</translation>
@@ -1926,6 +1941,7 @@
 <translation id="6177128806592000436">Bu sayta olan bağlantınız güvənli deyil</translation>
 <translation id="6180316780098470077">Təkrar cəhd intervalı</translation>
 <translation id="61877208875190028">Qadın geyimləri</translation>
+<translation id="6194209731893739467">Bütün izlənən məhsulları burada görə bilərsiniz</translation>
 <translation id="6195371403461054755">Geologiya</translation>
 <translation id="6196640612572343990">Üçüncü tərəf kukiləri blok edin</translation>
 <translation id="6203231073485539293">İnternet bağlantısını yoxlayın</translation>
@@ -1961,6 +1977,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Cihazınız indi yenidən başladılacaq}=1{Cihazınız 1 saniyə ərzində yenidən başladılacaq}other{Cihazınız # saniyə ərzində yenidən başladılacaq}}</translation>
+<translation id="6301104306974789820">Qiymət izləmə bildirişləri alın</translation>
 <translation id="6302269476990306341">Google Assistent Chrome'da dayanmağa başlayır</translation>
 <translation id="6305205051461490394"><ph name="URL" /> əlçatmazdır.</translation>
 <translation id="6311165245110979290">Virtual kart əlçatandır</translation>
@@ -2020,6 +2037,7 @@
 <translation id="6451458296329894277">Formanın yenidən təqdim edilməsini təsdiq edin</translation>
 <translation id="6456955391422100996">Reklam silindi.</translation>
 <translation id="6457206614190510200">Yəhər tikişi vurun</translation>
+<translation id="6457455098507772300">Qiymət endirimi xəbərdarlıqları masaüstündə popap bildirişləri kimi görünür</translation>
 <translation id="6458606150257356946">İstənilən halda əlavə edin</translation>
 <translation id="6464094930452079790">şəkillər</translation>
 <translation id="6465306955648956876">Parolları İdarə edin...</translation>
@@ -2077,6 +2095,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Silin</translation>
 <translation id="6645291930348198241">Kukilər və sayt datasına giriş.</translation>
+<translation id="6645478838938543427">Qiymət endirimi xəbərdarlıqları <ph name="EMAIL_ADDRESS" /> ünvanına göndəriləcək</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Yoxdur}=1{1 saytdan (Google Hesabınızdan çıxmayacaqsınız)}other{ # saytdan (Google Hesabınızdan çıxmayacaqsınız)}}</translation>
 <translation id="6648459603387803038">Administrator brauzer quraşdırmasını uzaqdan dəyişə bilər. Bu cihazdakı fəaliyyət Chrome'dan kənarda da idarə edilə bilər.</translation>
 <translation id="6648524591329069940">Serif Şrifti</translation>
@@ -2270,6 +2289,7 @@
 <translation id="7182878459783632708">Heç bir siyasət müəyyən edilməyib</translation>
 <translation id="7186367841673660872">Bu səhifə <ph name="ORIGINAL_LANGUAGE" /> dilindən <ph name="LANGUAGE_LANGUAGE" /> dilinə tərcümə edilmişdir</translation>
 <translation id="718872491229180389">Çerlidinq</translation>
+<translation id="7192188280913829296">"Təchizatçı ID'si" atributu da qeyd edilməlidir.</translation>
 <translation id="7192203810768312527"><ph name="SIZE" /> yer boşaldır. Bəzi saytlar növbəti dəfə daxil olduğunuzda gec yüklənə bilər.</translation>
 <translation id="7193661028827781021">İstinad</translation>
 <translation id="719464814642662924">Viza</translation>
diff --git a/components/strings/components_strings_bs.xtb b/components/strings/components_strings_bs.xtb
index 8df3cc96..3c7c9127 100644
--- a/components/strings/components_strings_bs.xtb
+++ b/components/strings/components_strings_bs.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">Uredu</translation>
 <translation id="2742511345840685325">Stoni tenis</translation>
 <translation id="2742870351467570537">Ukloni odabrane stavke</translation>
+<translation id="2759825833388495838">unijeti zaporku u aplikaciju <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Stripovi</translation>
 <translation id="2765217105034171413">Malo</translation>
 <translation id="277133753123645258">Način dostave</translation>
diff --git a/components/strings/components_strings_cy.xtb b/components/strings/components_strings_cy.xtb
index 5b8df99..0cfdcb7 100644
--- a/components/strings/components_strings_cy.xtb
+++ b/components/strings/components_strings_cy.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Datgloi dyfais</translation>
 <translation id="1269516672602708785">Creu gwefan newydd yn Google Sites yn gyflym</translation>
 <translation id="1270502636509132238">Dull Casglu</translation>
+<translation id="1273592791152866347">Mae olrhain prisiau wedi'i ddiffodd</translation>
 <translation id="1281476433249504884">Pentyrrwr 1</translation>
 <translation id="1285320974508926690">Peidio byth â chyfieithu'r wefan hon</translation>
 <translation id="1288548991597756084">Cadw cerdyn yn ddiogel</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Peirianneg-D</translation>
 <translation id="1551884710160394169">Rhadwedd a rhanwedd</translation>
 <translation id="1553358976309200471">Diweddarwch Chrome</translation>
+<translation id="1554003749331233619">Rydych bellach yn olrhain y cynnyrch hwn. Mae'r dudalen hon wedi'i chadw yn <ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">Glas</translation>
 <translation id="1559447966090556585">Cael hysbysiadau?</translation>
 <translation id="1559528461873125649">Nid oes ffeil neu gyfeiriadur o'r fath yn bodoli</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Rheoli Cyfrif Google, pwyswch Enter i reoli eich gwybodaeth, preifatrwydd, a diogelwch yn eich Cyfrif Google</translation>
 <translation id="2436186046335138073">Rhoi caniatâd i <ph name="HANDLER_HOSTNAME" /> agor pob dolen <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Pedwar twll ar y dde</translation>
+<translation id="2443309680964448806">Aeth rhywbeth o'i le. Ni chafodd eich newid ei gadw.</translation>
 <translation id="2448295565072560657">Perifferolion wedi'u hatodi i'r ddyfais hon tra'ch bod wedi mewngofnodi</translation>
 <translation id="2450021089947420533">Teithiau</translation>
 <translation id="2463739503403862330">Llenwi</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">Gwybod pan fyddwch wrthi'n defnyddio'r ddyfais hon</translation>
 <translation id="3180358318770512945">Bod yn rhiant</translation>
 <translation id="3187306450550410410">Trefniadau gwaith hyblyg</translation>
+<translation id="3190736958609431397">Dadolrhain</translation>
 <translation id="319282854780294203">Rhwydweithiau cymdeithasol</translation>
 <translation id="3194737229810486521">Mae <ph name="URL" /> am storio data ar eich dyfais yn barhaol</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> ar <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">Dulliau Talu</translation>
 <translation id="3391030046425686457">Cyfeiriad anfon</translation>
 <translation id="3391482648489541560">golygu ffeiliau</translation>
+<translation id="3392028486601120379">Mae gan y patrwm URL "<ph name="URL_PATTERN" />" lwybr penodol. Ni chefnogir llwybrau ar gyfer yr allwedd hon, tynnwch y llwybr a rhowch gynnig arall arni. e.e. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Dull casglu</translation>
 <translation id="3399952811970034796">Cyfeiriad Anfon</translation>
 <translation id="3402261774528610252">Gwnaeth y cysylltiad a ddefnyddiwyd i lwytho'r wefan hon ddefnyddio TLS 1.0 neu TLS 1.1, sy'n hen a byddant yn cael eu diffodd yn y dyfodol. Ar ôl eu diffodd, bydd defnyddwyr yn cael eu rhwystro rhag llwytho'r wefan hon. Dylai'r gweinydd alluogi TLS 1.2 neu'n ddiweddarach</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">Cadw i Gyfrif Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Rhaglen:</translation>
+<translation id="3647286794400715637">Rhaid i bob cofnod llinyn cyfeiriadau URL gynnwys rhwng 1 a 2 gyfeiriad URL.</translation>
 <translation id="3650584904733503804">Wedi dilysu'n llwyddiannus</translation>
 <translation id="3653033846669030038">Parciau thema</translation>
 <translation id="3655241534245626312">Ewch i'r gosodiadau caniatadau</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">Rheolir eich porwr gan eich gweinyddwr</translation>
 <translation id="3740319564441798148">Bws a thrên pellter hir</translation>
 <translation id="3744111561329211289">Cysoni yn y cefndir</translation>
+<translation id="3744286742364977428">Anfonir ffeiliau rydych wedi'u lawrlwytho i Google Cloud neu drydydd partïon i'w dadansoddi. Er enghraifft, mae'n bosib y byddant yn cael eu sganio am ddata sensitif neu faleiswedd a gallent gael eu storio yn seiliedig ar bolisïau cwmni.</translation>
 <translation id="3744899669254331632">Ni allwch fynd i <ph name="SITE" /> ar hyn o bryd gan fod y wefan wedi anfon manylion sydd wedi'u sgramblo na all Google eu prosesu. Mae gwallau ac ymosodiadau rhwydwaith yn rhai dros dro fel arfer, felly mae'n debyg y bydd y dudalen hon yn gweithio'n nes ymlaen.</translation>
 <translation id="3745099705178523657">Ar ôl i chi gadarnhau, bydd manylion cardiau o'ch Cyfrif Google yn cael eu rhannu â'r wefan hon.</translation>
 <translation id="3748148204939282805">Gall ymosodwyr ar <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> eich twyllo i wneud rhywbeth peryglus megis gosod meddalwedd neu ddatgelu eich gwybodaeth bersonol (er enghraifft, cyfrineiriau, rhifau ffôn neu rifau cardiau credyd). <ph name="BEGIN_LEARN_MORE_LINK" />Dysgu rhagor<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">Botwm creu digwyddiad, pwyswch Enter i greu digwyddiad newydd yn Google Calendar yn gyflym</translation>
 <translation id="4088981014127559358">Sifft ochr 1 llun Y</translation>
 <translation id="4089152113577680600">Hambwrdd 14</translation>
+<translation id="4097288585054919042">Diffodd rhybuddion</translation>
 <translation id="4098354747657067197">Gwefan dwyllodrus o'ch blaen</translation>
 <translation id="4099048595830172239">Nid yw'r polisi gweinyddwr yn argymell rhannu eich sgrîn â <ph name="APPLICATION_TITLE" /> pan fydd cynnwys cyfrinachol yn weladwy:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Pwyswch Tab yna Enter i addasu meintiau ffont a theipiau yn Chrome</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">Mae wedi'i analluogi</translation>
 <translation id="4176535426287761656">Eiddo cyfran gyfnodol a gwyliau</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Olrhain prisiau</translation>
 <translation id="4194250254487269611">Ni ellir cadw eich cerdyn ar hyn o bryd</translation>
 <translation id="4196861286325780578">&amp;Ailwneud Symud</translation>
 <translation id="4202554117186904723">Pumed Rôl</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">Ailgychwynnwch eich dyfais</translation>
 <translation id="4277028893293644418">Ailosod cyfrinair</translation>
 <translation id="4278390842282768270">Caniateir</translation>
+<translation id="4282346679996504092">Mae hysbysiadau ar gyfer y cynnyrch hwn wedi'u diffodd a'r nod tudalen wedi'i ddileu</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Mae'r cerdyn hwn wedi'i gadw yn eich Cyfrif Google}zero{Mae'r cardiau hyn wedi'u cadw yn eich Cyfrif Google}two{Mae'r cardiau hyn wedi'u cadw yn eich Cyfrif Google}few{Mae'r cardiau hyn wedi'u cadw yn eich Cyfrif Google}many{Mae'r cardiau hyn wedi'u cadw yn eich Cyfrif Google}other{Mae'r cardiau hyn wedi'u cadw yn eich Cyfrif Google}}</translation>
 <translation id="4287885627794386150">Yn gymwys am dreial ond nid yw'n weithredol</translation>
 <translation id="4297502707443874121">Mân-lun ar gyfer tudalen <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">Mae'n bosib na fydd y templedi rydych wedi'u nodi yn cael eu cymhwyso oherwydd gwall gyda'r polisi DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Rheoli dulliau talu…</translation>
 <translation id="4359160567981085931">Rydych newydd nodi'ch cyfrinair ar wefan dwyllodrus. Gall Chrome helpu. I newid eich cyfrinair ac i hysbysu Google y gallai eich cyfrif fod mewn perygl, cliciwch ar Diogelu Cyfrif.</translation>
+<translation id="4363222835916186793">Mae hysbysiadau ar gyfer y cynnyrch hwn wedi'u diffodd</translation>
 <translation id="4367563149485757821">Rhif-12 (Amlen)</translation>
 <translation id="437040971055499437">Digwyddiad diogelwch yn digwydd</translation>
 <translation id="4372516964750095882">Ffanffold-UD</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">Nid yw'r wybodaeth rydych ar fin ei chyflwyno yn ddiogel</translation>
 <translation id="4796594887379589189">Rhif adnabod cyfrif swydd</translation>
 <translation id="4798078619018708837">Rhowch y dyddiad darfod a'r CVC ar gyfer <ph name="CREDIT_CARD" /> i ddiweddaru manylion eich cerdyn. Ar ôl i chi gadarnhau, bydd manylion cardiau o'ch Cyfrif Google yn cael eu rhannu â'r wefan hon.</translation>
+<translation id="4798269756263412078">Cael hysbysiadau os bydd y pris yn gostwng ar unrhyw wefan. Bydd hysbysiadau yn cael eu hanfon i'ch e-bost.</translation>
 <translation id="4800132727771399293">Gwiriwch eich dyddiad darfod a'ch CGS a rhowch gynnig arall arni</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Defnyddio TouchID</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">Pwyth ymyl dde</translation>
 <translation id="5398772614898833570">Rhwystrwyd hysbysebion</translation>
 <translation id="5400836586163650660">Llwyd</translation>
+<translation id="540630185148148480">Troi hysbysiadau ymlaen</translation>
 <translation id="540969355065856584">Ni allai'r gweinydd hwn brofi ei fod yn <ph name="DOMAIN" />; nid yw ei dystysgrif ddiogelwch yn ddilys ar hyn o bryd. Gall hyn gael ei achosi gan gamffurfweddiad neu ymosodwr yn rhyng-gipio'ch cysylltiad.</translation>
 <translation id="5412040515238827314">Fformat annilys: Disgwyl rhestr o batrymau.</translation>
 <translation id="5412236728747081950">Mae'r wefan hon yn cael eich diddordebau o Chrome i ddangos rhagor o hysbysebion defnyddiol i chi</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">Gwiriwch eich mis darfod a rhowch gynnig arall arni</translation>
 <translation id="558420943003240152">Rheoli cyfrineiriau a chodau pas…</translation>
 <translation id="5586446728396275693">Nid oes unrhyw gyfeiriadau sydd wedi'u cadw</translation>
+<translation id="5586831831248371458">Chwilio <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Defnyddiwr platfform</translation>
 <translation id="5593349413089863479">Nid yw'r cysylltiad yn gwbl ddiogel</translation>
 <translation id="5595485650161345191">Golygu cyfeiriad</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">Ychwanegu cerdyn rhithwir</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Wrthi'n agor <ph name="SITE_NAME" /></translation>
+<translation id="5947508410139465809">Anfonir ffeiliau rydych yn eu huwchlwytho neu eu hatodi i Google Cloud neu drydydd partïon i'w dadansoddi. Er enghraifft, mae'n bosib y byddant yn cael eu sganio am ddata sensitif neu faleiswedd a gallent gael eu storio yn seiliedig ar bolisïau cwmni.</translation>
 <translation id="5951495562196540101">Methu â chofrestru gyda chyfrif defnyddiwr (mae trwydded sydd wedi'i becynnu ar gael).</translation>
 <translation id="5953516610448771166">Nid yw Capsiynau Byw ar gael ar gyfer y cyfryngau hyn. I gael capsiynau, rhwystrwch <ph name="CONTENT_SETTINGS" /> ar gyfer y wefan hon.</translation>
 <translation id="5955063559762970069">Gwestai a llety</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">Nid yw eich cysylltiad â'r wefan hon yn ddiogel</translation>
 <translation id="6180316780098470077">Ysbaid rhoi cynnig arall arni</translation>
 <translation id="61877208875190028">Dillad menywod</translation>
+<translation id="6194209731893739467">Gweld eich holl gynhyrchion sy'n cael eu holrhain yma</translation>
 <translation id="6195371403461054755">Daeareg</translation>
 <translation id="6196640612572343990">Rhwystro cwcis trydydd parti</translation>
 <translation id="6203231073485539293">Gwiriwch eich cysylltiad Rhyngrwyd</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Bydd eich dyfais yn ailgychwyn nawr}=1{Bydd eich dyfais yn ailgychwyn mewn 1 eiliad}two{Bydd eich dyfais yn ailgychwyn mewn # eiliad}few{Bydd eich dyfais yn ailgychwyn mewn # eiliad}many{Bydd eich dyfais yn ailgychwyn mewn # eiliad}other{Bydd eich dyfais yn ailgychwyn mewn # eiliad}}</translation>
+<translation id="6301104306974789820">Cael hysbysiadau olrhain prisiau</translation>
 <translation id="6302269476990306341">Mae Google Assistant yn Chrome wrthi'n stopio</translation>
 <translation id="6305205051461490394">Ni ellir cyrraedd <ph name="URL" />.</translation>
 <translation id="6311165245110979290">Cerdyn rhithwir ar gael</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">Cadarnhau Ailgyflwyno Ffurflen</translation>
 <translation id="6456955391422100996">Tynnwyd yr hysbyseb.</translation>
 <translation id="6457206614190510200">Pwyth cyfrwy</translation>
+<translation id="6457455098507772300">Mae hysbysiadau gostyngiad pris yn ymddangos fel hysbysiadau naid ar eich bwrdd gwaith</translation>
 <translation id="6458606150257356946">Gludo beth bynnag</translation>
 <translation id="6464094930452079790">lluniau</translation>
 <translation id="6465306955648956876">Rheoli cyfrineiriau…</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Clirio</translation>
 <translation id="6645291930348198241">Cael mynediad at gwcis a data gwefan.</translation>
+<translation id="6645478838938543427">Anfonir rhybuddion gostyngiad pris i <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Dim}=1{O 1 wefan (ni fyddwch yn cael eich allgofnodi o'ch Cyfrif Google)}two{O # wefan (ni fyddwch yn cael eich allgofnodi o'ch Cyfrif Google)}few{O # gwefan (ni fyddwch yn cael eich allgofnodi o'ch Cyfrif Google)}many{O # gwefan (ni fyddwch yn cael eich allgofnodi o'ch Cyfrif Google)}other{O # gwefan (ni fyddwch yn cael eich allgofnodi o'ch Cyfrif Google)}}</translation>
 <translation id="6648459603387803038">Gall eich gweinyddwr newid gosodiadau eich porwr o bell. Gellir rheoli gweithgarwch ar y ddyfais hon y tu allan i Chrome hefyd.</translation>
 <translation id="6648524591329069940">Ffont serif</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">Nid oes unrhyw bolisïau wedi'u gosod</translation>
 <translation id="7186367841673660872">Mae'r dudalen hon wedi'i chyfieithu o<ph name="ORIGINAL_LANGUAGE" />i<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Codi hwyl</translation>
+<translation id="7192188280913829296">Rhaid nodi'r briodwedd "vendor_id" hefyd.</translation>
 <translation id="7192203810768312527">Yn creu <ph name="SIZE" />. Mae'n bosib y bydd rhai gwefannau yn llwytho'n arafach ar eich ymweliad nesaf.</translation>
 <translation id="7193661028827781021">Cyfeiriad</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb
index 4d94f94b..110f4be 100644
--- a/components/strings/components_strings_es-419.xtb
+++ b/components/strings/components_strings_es-419.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Desbloqueo del dispositivo</translation>
 <translation id="1269516672602708785">Crea un sitio nuevo en Google Sites rápidamente</translation>
 <translation id="1270502636509132238">Método de retiro</translation>
+<translation id="1273592791152866347">Se desactivó el seguimiento de precios</translation>
 <translation id="1281476433249504884">Apilador 1</translation>
 <translation id="1285320974508926690">Nunca traducir este sitio</translation>
 <translation id="1288548991597756084">Guarda tu tarjeta de forma segura</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Software gratuito y shareware</translation>
 <translation id="1553358976309200471">Actualizar Chrome</translation>
+<translation id="1554003749331233619">Estás realizando un seguimiento de este producto. Se guardó esta página en <ph name="LAST_BOOKMARKS_FOLDER" />.</translation>
 <translation id="1555130319947370107">Azul</translation>
 <translation id="1559447966090556585">¿Quieres recibir notificaciones?</translation>
 <translation id="1559528461873125649">El archivo o directorio no existe</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Botón Administrar la Cuenta de Google, presiona Intro para administrar la información, privacidad y seguridad de tu Cuenta de Google</translation>
 <translation id="2436186046335138073">¿Deseas permitir que <ph name="HANDLER_HOSTNAME" /> abra todos los vínculos de <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Perforación cuádruple a la derecha</translation>
+<translation id="2443309680964448806">Se produjo un error. No se guardó el cambio.</translation>
 <translation id="2448295565072560657">Hay periféricos adjuntos a este dispositivo cuando accedes</translation>
 <translation id="2450021089947420533">Exploraciones</translation>
 <translation id="2463739503403862330">Llenar</translation>
@@ -820,6 +823,7 @@
 <translation id="317878711435188021">Saber en qué momento estás usando activamente este dispositivo</translation>
 <translation id="3180358318770512945">Crianza</translation>
 <translation id="3187306450550410410">Acuerdos de trabajo flexibles</translation>
+<translation id="3190736958609431397">Dejar de realizar el seguimiento</translation>
 <translation id="319282854780294203">Redes sociales</translation>
 <translation id="3194737229810486521"><ph name="URL" /> desea almacenar datos de forma permanente en el dispositivo</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> en <ph name="SERVER_NAME" /></translation>
@@ -905,6 +909,7 @@
 <translation id="3387261909427947069">Formas de pago</translation>
 <translation id="3391030046425686457">Dirección de entrega</translation>
 <translation id="3391482648489541560">edición de archivo</translation>
+<translation id="3392028486601120379">El patrón de URL "<ph name="URL_PATTERN" />" tiene una ruta especificada. Esta clave no admite rutas. Quítalas y vuelve a intentarlo. P. ej., *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Método de retiro</translation>
 <translation id="3399952811970034796">Dirección de entrega</translation>
 <translation id="3402261774528610252">La conexión que se usó para cargar el sitio implementa el protocolo TLS 1.0 o TLS 1.1, los cuales son obsoletos y se inhabilitarán en el futuro. Cuando esto ocurra, los usuarios no podrán cargar el sitio. El servidor debe habilitar el protocolo TLS 1.2 o versiones posteriores.</translation>
@@ -1000,6 +1005,7 @@
 <translation id="3637662659967048211">Guardar en la Cuenta de Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Aplicación:</translation>
+<translation id="3647286794400715637">Cada entrada de string de URL debe contener entre 1 y 2 URLs.</translation>
 <translation id="3650584904733503804">Validación correcta</translation>
 <translation id="3653033846669030038">Parques temáticos</translation>
 <translation id="3655241534245626312">Ir a la configuración de permisos</translation>
@@ -1038,6 +1044,7 @@
 <translation id="3738166223076830879">Tu administrador gestiona el navegador.</translation>
 <translation id="3740319564441798148">Autobuses y trenes de larga distancia</translation>
 <translation id="3744111561329211289">Sincronización en segundo plano</translation>
+<translation id="3744286742364977428">Los archivos que descargas se envían a Google Cloud o a terceros para su análisis. Por ejemplo, es posible que se analicen en busca de datos sensibles o software malicioso y que se almacenen según las políticas de la empresa.</translation>
 <translation id="3744899669254331632">No puedes visitar <ph name="SITE" /> en este momento porque el sitio web envió credenciales encriptadas que Chromium no puede procesar. Los ataques y errores de red generalmente son temporales, por lo que esta página probablemente funcionará de nuevo más tarde.</translation>
 <translation id="3745099705178523657">Después de que confirmes esta acción, los datos de tu Cuenta de Google se compartirán con este sitio.</translation>
 <translation id="3748148204939282805">Es posible que los atacantes en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten engañarte para que realices alguna acción peligrosa, como instalar software o revelar información personal (p. ej., contraseñas, números de teléfono o tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1145,6 +1152,7 @@
 <translation id="4087296516249690906">Botón Crear evento, presiona Intro para crear un evento en el Calendario de Google rápidamente</translation>
 <translation id="4088981014127559358">Cambio en el eje Y del lado 1 de la imagen</translation>
 <translation id="4089152113577680600">Bandeja 14</translation>
+<translation id="4097288585054919042">Desactivar las alertas</translation>
 <translation id="4098354747657067197">Sitio engañoso</translation>
 <translation id="4099048595830172239">La política del administrador no recomienda compartir la pantalla con <ph name="APPLICATION_TITLE" /> cuando hay contenido confidencial visible:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, presiona Tab y, luego, Intro para personalizar el tamaño de las fuentes y los tipos de letra en Chrome</translation>
@@ -1181,6 +1189,7 @@
 <translation id="4176463684765177261">Inhabilitado</translation>
 <translation id="4176535426287761656">Propiedades para vacaciones y tiempos compartidos</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Dejar de realizar el seguimiento de precios</translation>
 <translation id="4194250254487269611">No se puede guardar tu tarjeta en este momento</translation>
 <translation id="4196861286325780578">&amp;Rehacer Mover</translation>
 <translation id="4202554117186904723">Quinto rollo</translation>
@@ -1227,6 +1236,7 @@
 <translation id="4275830172053184480">Reiniciar tu dispositivo</translation>
 <translation id="4277028893293644418">Restablecer contraseña</translation>
 <translation id="4278390842282768270">Permitido</translation>
+<translation id="4282346679996504092">Se desactivaron las alertas para este producto y se quitó el favorito</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Se guardó esta tarjeta en tu Cuenta de Google}other{Se guardaron estas tarjetas en tu Cuenta de Google}}</translation>
 <translation id="4287885627794386150">Apta para pruebas, pero no está activada</translation>
 <translation id="4297502707443874121">Miniatura para la página <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1265,6 +1275,7 @@
 <translation id="4358059973562876591">Debido a un error relacionado con la política DnsOverHttpsMode, es posible que no se apliquen las plantillas que especificaste.</translation>
 <translation id="4358461427845829800">Administrar formas de pago…</translation>
 <translation id="4359160567981085931">Ingresaste tu contraseña en un sitio engañoso. Chrome puede ayudarte. Para cambiar la contraseña y notificar a Google que tu cuenta podría estar en riesgo, haz clic en Proteger cuenta.</translation>
+<translation id="4363222835916186793">Se desactivaron las alertas para este producto</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">Se produjo un evento de seguridad</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1417,6 +1428,7 @@
 <translation id="4792686369684665359">La información que estás a punto de enviar no está protegida</translation>
 <translation id="4796594887379589189">ID de cuenta del trabajo</translation>
 <translation id="4798078619018708837">Ingresa la fecha de vencimiento y el CVC de la tarjeta <ph name="CREDIT_CARD" /> para actualizar los datos. Después de confirmar esta acción, esos datos en tu Cuenta de Google se compartirán con este sitio.</translation>
+<translation id="4798269756263412078">Recibe alertas si baja el precio en algún sitio. Las alertas se enviarán a tu correo electrónico.</translation>
 <translation id="4800132727771399293">Verifica la fecha de vencimiento y el CVC, y vuelve a intentarlo.</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Usar Touch ID</translation>
@@ -1660,6 +1672,7 @@
 <translation id="5396631636586785122">Costura de borde a la derecha</translation>
 <translation id="5398772614898833570">Anuncios bloqueados</translation>
 <translation id="5400836586163650660">Gris</translation>
+<translation id="540630185148148480">Activar las alertas</translation>
 <translation id="540969355065856584">Este servidor no pudo demostrar que se trata de <ph name="DOMAIN" />; el certificado de seguridad no es válido en este momento. Esto puede deberse a una configuración incorrecta o a un ataque que intercepta tu conexión.</translation>
 <translation id="5412040515238827314">El formato no es válido: se esperaba una lista de patrones.</translation>
 <translation id="5412236728747081950">Este sitio obtiene tus intereses de Chrome para mostrarte anuncios más relevantes</translation>
@@ -1724,6 +1737,7 @@
 <translation id="5580958916614886209">Comprueba el mes de vencimiento y vuelve a intentarlo</translation>
 <translation id="558420943003240152">Administrar contraseñas y claves de acceso…</translation>
 <translation id="5586446728396275693">No hay direcciones guardadas</translation>
+<translation id="5586831831248371458">Buscar <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Usuario de la plataforma</translation>
 <translation id="5593349413089863479">La conexión no es totalmente segura</translation>
 <translation id="5595485650161345191">Editar dirección</translation>
@@ -1843,6 +1857,7 @@
 <translation id="5938153366081463283">Agregar tarjeta virtual</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Abriendo <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">Los archivos que cargas o adjuntas se envían a Google Cloud o a terceros para su análisis. Por ejemplo, es posible que se analicen en busca de datos sensibles o software malicioso y que se almacenen según las políticas de la empresa.</translation>
 <translation id="5951495562196540101">No se puede realizar la inscripción con una cuenta personal (licencia de paquete disponible).</translation>
 <translation id="5953516610448771166">El Subtitulado instantáneo no está disponible para este contenido multimedia. Para obtener subtítulos, bloquea <ph name="CONTENT_SETTINGS" /> en este sitio.</translation>
 <translation id="5955063559762970069">Hoteles y alojamiento</translation>
@@ -1931,6 +1946,7 @@
 <translation id="6177128806592000436">Tu conexión con este sitio no es segura</translation>
 <translation id="6180316780098470077">Intervalo entre reintentos</translation>
 <translation id="61877208875190028">Ropa femenina</translation>
+<translation id="6194209731893739467">Encuentra todos tus productos con seguimiento aquí</translation>
 <translation id="6195371403461054755">Geología</translation>
 <translation id="6196640612572343990">Bloquear cookies de terceros</translation>
 <translation id="6203231073485539293">Comprueba tu conexión a Internet.</translation>
@@ -1966,6 +1982,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{El dispositivo se reiniciará ahora}=1{El dispositivo se reiniciará dentro de 1 segundo}other{El dispositivo se reiniciará dentro de # segundos}}</translation>
+<translation id="6301104306974789820">Recibir notificaciones de seguimiento de precios</translation>
 <translation id="6302269476990306341">Se está deteniendo el Asistente de Google en Chrome</translation>
 <translation id="6305205051461490394">No se puede acceder a <ph name="URL" />.</translation>
 <translation id="6311165245110979290">Tarjeta virtual disponible</translation>
@@ -2025,6 +2042,7 @@
 <translation id="6451458296329894277">Confirmar reenvío del formulario</translation>
 <translation id="6456955391422100996">Se quitó el anuncio.</translation>
 <translation id="6457206614190510200">Grapado en el pliegue central</translation>
+<translation id="6457455098507772300">Las alertas de descuentos se muestran como notificaciones emergentes en tu escritorio</translation>
 <translation id="6458606150257356946">Pegar de todos modos</translation>
 <translation id="6464094930452079790">imágenes</translation>
 <translation id="6465306955648956876">Administrar contraseñas…</translation>
@@ -2082,6 +2100,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Borrar</translation>
 <translation id="6645291930348198241">Acceder a las cookies y los datos de sitios</translation>
+<translation id="6645478838938543427">Las alertas de descuentos se enviarán a <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Ninguno}=1{De 1 sitio (no saldrás de tu cuenta de Google)}other{De # sitios (no saldrás de tu cuenta de Google)}}</translation>
 <translation id="6648459603387803038">El administrador puede cambiar la configuración de tu navegador de forma remota. Es posible que la actividad en este dispositivo también se administre fuera de Chrome.</translation>
 <translation id="6648524591329069940">Fuente Serif</translation>
@@ -2275,6 +2294,7 @@
 <translation id="7182878459783632708">No hay políticas establecidas.</translation>
 <translation id="7186367841673660872">Esta página se tradujo de<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Animación deportiva</translation>
+<translation id="7192188280913829296">También se debe especificar el atributo "vendor_id".</translation>
 <translation id="7192203810768312527">Esta acción libera hasta <ph name="SIZE" />. Es posible que algunos sitios carguen más lento en tu próxima visita.</translation>
 <translation id="7193661028827781021">Referencia</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb
index 8c3411d..623819b 100644
--- a/components/strings/components_strings_fa.xtb
+++ b/components/strings/components_strings_fa.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">باز کردن قفل دستگاه</translation>
 <translation id="1269516672602708785">‏ایجاد سریع سایت جدید در Google Sites</translation>
 <translation id="1270502636509132238">روش تحویل گرفتن</translation>
+<translation id="1273592791152866347">پیگیری قیمت خاموش شد</translation>
 <translation id="1281476433249504884">پشته‌ساز ۱</translation>
 <translation id="1285320974508926690">این سایت هرگز ترجمه نشود</translation>
 <translation id="1288548991597756084">ذخیره ایمن کارت</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">نرم‌افزار رایگان و اشتراکی</translation>
 <translation id="1553358976309200471">‏به‌روزرسانی Chrome</translation>
+<translation id="1554003749331233619">اکنون این محصول را پیگیری می‌کنید. این صفحه در <ph name="LAST_BOOKMARKS_FOLDER" /> ذخیره شده است</translation>
 <translation id="1555130319947370107">آبی</translation>
 <translation id="1559447966090556585">اعلان‌ها دریافت شود؟</translation>
 <translation id="1559528461873125649">فاقد چنین فایل یا دایرکتوری است</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">‏مدیریت «حساب Google»؛ برای مدیریت اطلاعات، حریم خصوصی، و امنیت در «حساب Google»، کلید «ورود» را فشار دهید</translation>
 <translation id="2436186046335138073">به <ph name="HANDLER_HOSTNAME" /> امکان داده شود همه پیوندهای <ph name="PROTOCOL" /> را باز کند؟</translation>
 <translation id="2438874542388153331">چهار سوراخ در راست</translation>
+<translation id="2443309680964448806">مشکلی پیش آمد. تغییر ذخیره نشد.</translation>
 <translation id="2448295565072560657">لوازم جانبی متصل به این دستگاه در مدت ورود به سیستم</translation>
 <translation id="2450021089947420533">سفرها</translation>
 <translation id="2463739503403862330">تکمیل</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">بداند چه زمانی به‌صورت فعال از این دستگاه استفاده می‌کنید</translation>
 <translation id="3180358318770512945">فرزندداری</translation>
 <translation id="3187306450550410410">ساعات کاری انعطاف‌پذیر</translation>
+<translation id="3190736958609431397">لغو پیگیری</translation>
 <translation id="319282854780294203">شبکه اجتماعی</translation>
 <translation id="3194737229810486521"><ph name="URL" /> می‌خواهد داده‌ها را برای همیشه در دستگاهتان ذخیره کند</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> در <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">روش‌های پرداخت</translation>
 <translation id="3391030046425686457">نشانی تحویل کالا</translation>
 <translation id="3391482648489541560">ویرایش فایل</translation>
+<translation id="3392028486601120379">‏در الگوی نشانی وب «<ph name="URL_PATTERN" />»، مسیری مشخص شده است. این کلید از مسیر پشتیبانی نمی‌کند، لطفاً مسیر را حذف کنید و دوباره امتحان کنید. برای مثال، ‎*://example.com/ =&gt; *://example.com",‎</translation>
 <translation id="3395827396354264108">روش تحویل گرفتن</translation>
 <translation id="3399952811970034796">نشانی تحویل کالا</translation>
 <translation id="3402261774528610252">اتصال استفاده‌شده برای بار کردن این سایت از «امنیت لایه انتقال» نسخه ۱.۰ یا ۱.۱ استفاده می‌کرد که منسوخ شده است و در آینده غیرفعال خواهد شد. بعد از غیرفعال شدن، کاربران نمی‌توانند این سایت را بار کنند. سرور باید «امنیت لایه انتقال» نسخه ۱.۲ یا بالاتر را فعال کند.</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">‏ذخیره در «حساب Google»</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">برنامه:</translation>
+<translation id="3647286794400715637">هر ورودی رشته نشانی وب باید بین ۱ تا ۲ نشانی وب داشته باشد.</translation>
 <translation id="3650584904733503804">ارزیابی موفق بود</translation>
 <translation id="3653033846669030038">پارک موضوعی</translation>
 <translation id="3655241534245626312">رفتن به تنظیمات اجازه</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">سرپرست شما مرورگرتان را مدیریت می‌کند.</translation>
 <translation id="3740319564441798148">اتوبوس و قطار بین‌شهری</translation>
 <translation id="3744111561329211289">همگام‌سازی پس‌زمینه</translation>
+<translation id="3744286742364977428">‏فایل‌هایی که بارگیری می‌کنید برای تجریه‌وتحلیل به Google Cloud یا اشخاص ثالث ارسال می‌شود. مثلاً ممکن است این فایل‌ها ازنظر وجود داده‌های حساس یا بدافزار اسکن شود و براساس خط‌مشی‌های شرکت ذخیره شود.</translation>
 <translation id="3744899669254331632">‏نمی‌توانید اکنون از <ph name="SITE" /> دیدن کنید زیرا وب‌سایت اعتبارنامه‌های درهمی ارسال کرده که Chromium نمی‌تواند پردازش کند. خطاها و حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صفحه بعداً کار می‌کند.</translation>
 <translation id="3745099705178523657">‏بعد از تأیید کردن، جزئیات کارت از حساب Google شما با این سایت هم‌رسانی می‌شود.</translation>
 <translation id="3748148204939282805">ممکن است مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> شما را فریب دهند تا اقدام خطرناکی همچون نصب نرم‌افزار یا افشای اطلاعات شخصی (مانند گذرواژه‌ها، پیام‌ها یا کارت‌های اعتباری) انجام دهید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">‏دکمه ایجاد رویداد؛ برای ایجاد سریع رویداد جدید در «تقویم Google»، کلید «ورود» را فشار دهید</translation>
 <translation id="4088981014127559358">‏روی ۱، تغییر جهت تصویر حول محور Y</translation>
 <translation id="4089152113577680600">سینی ۱۴</translation>
+<translation id="4097288585054919042">خاموش کردن هشدارها</translation>
 <translation id="4098354747657067197">احتیاط، سایت گول‌زننده</translation>
 <translation id="4099048595830172239">سیاست سرپرست توصیه می‌کند هرگاه محتوای محرمانه در صفحه‌نمایش شما نمایان باشد، صفحه را با <ph name="APPLICATION_TITLE" /> هم‌رسانی نکنید:</translation>
 <translation id="4099391883283080991">‏<ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />؛ برای سفارشی کردن اندازه قلم‌ها و طرح حروف در Chrome، کلید «جهش» و سپس «ورود» را فشار دهید</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">غیرفعال شد</translation>
 <translation id="4176535426287761656">املاک ویژه تعطیلات و مالکیت شراکتی</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">لغو پیگیری قیمت</translation>
 <translation id="4194250254487269611">متأسفیم، درحال‌حاضر نمی‌توان کارت شما را ذخیره کرد</translation>
 <translation id="4196861286325780578">&amp;انجام مجدد انتقال</translation>
 <translation id="4202554117186904723">رول پنجم</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">راه‌اندازی دستگاه خود</translation>
 <translation id="4277028893293644418">بازنشانی گذرواژه</translation>
 <translation id="4278390842282768270">مجاز است</translation>
+<translation id="4282346679996504092">هشدارهای این محصول خاموش شد و نشانک آن حذف شد</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{‏این کارت در حساب Google ذخیره شده است}one{‏این کارت‌ها در حساب Google ذخیره شده‌اند}other{‏این کارت‌ها در حساب Google ذخیره شده‌اند}}</translation>
 <translation id="4287885627794386150">برای دوره آزمایشی واجدشرایط هستید، اما فعال نیست</translation>
 <translation id="4297502707443874121">تصویر کوچک صفحه <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">‏ممکن است الگوهایی که مشخص کردید به‌دلیل خطای خط‌مشی DnsOverHttpsMode اعمال نشوند.</translation>
 <translation id="4358461427845829800">مدیریت روش‌های پرداخت…</translation>
 <translation id="4359160567981085931">‏اخیراً گذرواژه‌تان را در سایتی فریب‌کار وارد کرده‌اید. Chrome می‌تواند کمک کند. برای اینکه گذرواژه‌تان را تغییر دهید و به Google اطلاع دهید که شاید حسابتان درمعرض خطر باشد، روی «محافظت از حساب» کلیک کنید.</translation>
+<translation id="4363222835916186793">هشدارهای این محصول خاموش شد</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">رویداد امنیتی اتفاق می‌افتد</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">اطلاعاتی که می‌خواهید ارسال کنید ایمن نیست</translation>
 <translation id="4796594887379589189">شناسه حساب کار</translation>
 <translation id="4798078619018708837">‏برای به‌روزرسانی جزئیات کارت، تاریخ انقضا و CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید کردن، جزئیات کارت از حساب Google شما با این سایت هم‌رسانی می‌شود.</translation>
+<translation id="4798269756263412078">اگر قیمت در هر سایتی کاهش پیدا کرد، هشدار دریافت می‌کنید. هشدارها به ایمیلتان ارسال خواهد شد.</translation>
 <translation id="4800132727771399293">‏تاریخ انقضا و CVC را بررسی کرده و دوباره امتحان کنید</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">استفاده از شناسه لمسی</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">دوختن لبه راست</translation>
 <translation id="5398772614898833570">آگهی‌ها مسدود شدند</translation>
 <translation id="5400836586163650660">خاکستری</translation>
+<translation id="540630185148148480">روشن کردن هشدارها</translation>
 <translation id="540969355065856584">این سرور نتوانست ثابت کند که <ph name="DOMAIN" /> است؛ در حال حاضر، گواهی امنیتی آن معتبر نیست. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط حمله‌کننده ایجاد شده باشد.</translation>
 <translation id="5412040515238827314">قالب نامعتبر است: انتظار می‌رود فهرستی از الگوها وجود داشته باشد.</translation>
 <translation id="5412236728747081950">‏این سایت علایقتان را از Chrome می‌گیرد تا آگهی‌های مرتبط‌تری به شما نشان دهد</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">ماه انقضا را بررسی و دوباره امتحان کنید</translation>
 <translation id="558420943003240152">مدیریت گذرواژه‌ها و گذرکلیدها…</translation>
 <translation id="5586446728396275693">نشانی ذخیره‌شده‌ای وجود ندارد</translation>
+<translation id="5586831831248371458">جستجوی <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">کاربر پلاتفرم</translation>
 <translation id="5593349413089863479">اتصال کاملاً امن نیست</translation>
 <translation id="5595485650161345191">ویرایش آدرس</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">افزودن کارت مجازی</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">درحال باز کردن <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">‏فایل‌هایی که بارگذاری یا پیوست می‌کنید برای تجریه‌وتحلیل به Google Cloud یا اشخاص ثالث ارسال می‌شود. مثلاً ممکن است این فایل‌ها ازنظر وجود داده‌های حساس یا بدافزار اسکن شود و براساس خط‌مشی‌های شرکت ذخیره شود.</translation>
 <translation id="5951495562196540101">نمی‌توان با حساب مصرف‌کننده ثبت‌نام کرد (مجوز بسته‌بندی دردسترس است).</translation>
 <translation id="5953516610448771166">«زیرنویس ناشنوایان زنده» برای این رسانه دردسترس نیست. برای دریافت زیرنویس ناشنوایان، <ph name="CONTENT_SETTINGS" /> را برای این سایت مسدود کنید.</translation>
 <translation id="5955063559762970069">هتل و اقامتگاه</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">اتصال شما به این سایت امن نیست</translation>
 <translation id="6180316780098470077">فاصله زمانی امتحان مجدد</translation>
 <translation id="61877208875190028">لباس زنانه</translation>
+<translation id="6194209731893739467">همه محصولات پیگیری‌شده‌تان را در اینجا ببینید</translation>
 <translation id="6195371403461054755">زمین‌شناسی</translation>
 <translation id="6196640612572343990">مسدود کردن کوکی‌های شخص ثالث</translation>
 <translation id="6203231073485539293">اتصال اینترنتتان را بررسی کنید</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{دستگاه اکنون بازراه‌اندازی خواهد شد}=1{دستگاه یک ثانیه دیگر بازراه‌اندازی خواهد شد}one{دستگاه # ثانیه دیگر بازراه‌اندازی خواهد شد}other{دستگاه # ثانیه دیگر بازراه‌اندازی خواهد شد}}</translation>
+<translation id="6301104306974789820">دریافت اعلان‌های پیگیری قیمت</translation>
 <translation id="6302269476990306341">‏توقف «دستیار Google» در Chrome</translation>
 <translation id="6305205051461490394">دسترسی به <ph name="URL" /> امکان‌پذیر نیست.</translation>
 <translation id="6311165245110979290">کارت مجازی دردسترس است</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">تأیید ارسال مجدد فرم</translation>
 <translation id="6456955391422100996">آگهی حذف شد.</translation>
 <translation id="6457206614190510200">منگنه تخت</translation>
+<translation id="6457455098507772300">هشدارهای کاهش قیمت به‌صورت اعلان‌های بالاپر در میز کار نشان داده می‌شود</translation>
 <translation id="6458606150257356946">درهرصورت جای‌گذاری شود</translation>
 <translation id="6464094930452079790">تصاویر</translation>
 <translation id="6465306955648956876">مدیریت گذرواژه‌ها…</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">پاک کردن</translation>
 <translation id="6645291930348198241">به کوکی‌ها و داده‌های سایت دسترسی داشته باشد.</translation>
+<translation id="6645478838938543427">هشدارهای کاهش قیمت به <ph name="EMAIL_ADDRESS" /> ارسال خواهد شد</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{هیچ‌کدام}=1{‏از ۱ سایت (از سیستم حساب Google خود خارج نخواهید شد)}one{‏از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}other{‏از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}}</translation>
 <translation id="6648459603387803038">‏سرپرستتان می‌تواند تنظیم مرورگرتان را ازراه‌دور تغییر دهد. فعالیت انجام‌شده در این دستگاه می‌تواند از خارج از Chrome هم مدیریت شود.</translation>
 <translation id="6648524591329069940">‏قلم Serif</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">خط‌مشی‌ای تنظیم نشده</translation>
 <translation id="7186367841673660872">این صفحه از <ph name="ORIGINAL_LANGUAGE" /> به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است</translation>
 <translation id="718872491229180389">تشویق‌گری</translation>
+<translation id="7192188280913829296">‏مشخصه «vendor_id» نیز باید مشخص شود.</translation>
 <translation id="7192203810768312527"><ph name="SIZE" /> از فضا را آزاد می‌کند. ممکن است برخی از سایت‌ها در بازدیدهای بعدی کندتر بارگیری شوند.</translation>
 <translation id="7193661028827781021">مرجع</translation>
 <translation id="719464814642662924">ویزا</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb
index 2929633..e6006c6 100644
--- a/components/strings/components_strings_gu.xtb
+++ b/components/strings/components_strings_gu.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">બરાબર, સમજાઇ ગયું</translation>
 <translation id="2742511345840685325">ટેબલ ટેનિસ</translation>
 <translation id="2742870351467570537">પસંદ કરેલી આઇટમ્સને દૂર કરો</translation>
+<translation id="2759825833388495838"><ph name="APP_NAME" /> પર તમારો પાસવર્ડ ભરો</translation>
 <translation id="2764001903315068341">કૉમિક</translation>
 <translation id="2765217105034171413">નાનું</translation>
 <translation id="277133753123645258">વિતરણ પદ્ધતિ</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb
index e3782ab..d38d177 100644
--- a/components/strings/components_strings_hr.xtb
+++ b/components/strings/components_strings_hr.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">U redu</translation>
 <translation id="2742511345840685325">Stolni tenis</translation>
 <translation id="2742870351467570537">Ukloni odabrane stavke</translation>
+<translation id="2759825833388495838">unijeti zaporku u aplikaciju <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Stripovi</translation>
 <translation id="2765217105034171413">Mali</translation>
 <translation id="277133753123645258">Način dostave</translation>
diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb
index 8df846fb..75c0313 100644
--- a/components/strings/components_strings_hu.xtb
+++ b/components/strings/components_strings_hu.xtb
@@ -2865,7 +2865,7 @@
 <translation id="8820817407110198400">Könyvjelzők</translation>
 <translation id="882338992931677877">Manuális nyílás</translation>
 <translation id="8834380158646307944">Inkognitó ablakok bezárása gomb. Nyomja le az Enter billentyűt a jelenleg megnyitott összes inkognitó ablak bezárásához.</translation>
-<translation id="883848425547221593">Egyéb könyvjelzők</translation>
+<translation id="883848425547221593">További könyvjelzők</translation>
 <translation id="884264119367021077">Szállítási cím</translation>
 <translation id="884923133447025588">Nem található visszavonási mechanizmus.</translation>
 <translation id="8849262850971482943">Használja virtuális kártyáját a plusz biztonság érdekében</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb
index bdcc204..5fc20f6 100644
--- a/components/strings/components_strings_id.xtb
+++ b/components/strings/components_strings_id.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Buka kunci perangkat</translation>
 <translation id="1269516672602708785">Buat situs baru di Google Sites dengan cepat</translation>
 <translation id="1270502636509132238">Metode Pengambilan</translation>
+<translation id="1273592791152866347">Pemantauan harga nonaktif</translation>
 <translation id="1281476433249504884">Tempat kertas 1</translation>
 <translation id="1285320974508926690">Jangan pernah terjemahkan situs ini</translation>
 <translation id="1288548991597756084">Simpan kartu dengan aman</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Freeware &amp; shareware</translation>
 <translation id="1553358976309200471">Perbarui browser Chrome</translation>
+<translation id="1554003749331233619">Saat ini Anda sedang memantau produk ini. Halaman ini disimpan di <ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">Biru</translation>
 <translation id="1559447966090556585">Dapatkan notifikasi?</translation>
 <translation id="1559528461873125649">Tidak ada file atau direktori tersebut</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Kelola Akun Google, tekan Enter untuk mengelola info, privasi, dan keamanan di Akun Google Anda</translation>
 <translation id="2436186046335138073">Izinkan <ph name="HANDLER_HOSTNAME" /> membuka semua link <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Empat lubang di kanan</translation>
+<translation id="2443309680964448806">Terjadi error. Perubahan Anda tidak tersimpan.</translation>
 <translation id="2448295565072560657">Periferal yang terpasang ke perangkat ini saat Anda login</translation>
 <translation id="2450021089947420533">Perjalanan</translation>
 <translation id="2463739503403862330">Isi</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">Mengetahui saat Anda aktif menggunakan perangkat ini</translation>
 <translation id="3180358318770512945">Parenting</translation>
 <translation id="3187306450550410410">Pengaturan kerja fleksibel</translation>
+<translation id="3190736958609431397">Batalkan pemantauan</translation>
 <translation id="319282854780294203">Jaringan sosial</translation>
 <translation id="3194737229810486521"><ph name="URL" /> ingin menyimpan data di perangkat Anda secara permanen</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> di <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">Metode Pembayaran</translation>
 <translation id="3391030046425686457">Alamat pengiriman</translation>
 <translation id="3391482648489541560">pengeditan file</translation>
+<translation id="3392028486601120379">Pola URL "<ph name="URL_PATTERN" />" memiliki jalur yang ditetapkan. Jalur tidak didukung untuk kunci ini, hapus jalur dan coba lagi. Misalnya, *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Metode pengambilan</translation>
 <translation id="3399952811970034796">Alamat Pengiriman</translation>
 <translation id="3402261774528610252">Koneksi yang digunakan untuk memuat situs ini menggunakan TLS 1.0 atau TLS 1.1 yang tidak digunakan lagi dan akan dinonaktifkan pada waktu mendatang. Setelah dinonaktifkan, pengguna tidak akan dapat memuat situs ini. Sebaiknya server mengaktifkan TLS 1.2 atau yang lebih baru.</translation>
@@ -998,6 +1003,7 @@
 <translation id="3637662659967048211">Simpan ke Akun Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Aplikasi:</translation>
+<translation id="3647286794400715637">Setiap entri string URL harus berisi antara 1 hingga 2 URL.</translation>
 <translation id="3650584904733503804">Validasi berhasil</translation>
 <translation id="3653033846669030038">Taman hiburan</translation>
 <translation id="3655241534245626312">Buka setelan izin</translation>
@@ -1036,6 +1042,7 @@
 <translation id="3738166223076830879">Browser dikelola oleh administrator Anda.</translation>
 <translation id="3740319564441798148">Transportasi rel &amp; bus untuk jarak jauh</translation>
 <translation id="3744111561329211289">Sinkronisasi latar belakang</translation>
+<translation id="3744286742364977428">File yang Anda download akan dikirimkan ke Google Cloud atau pihak ketiga untuk analisis. Misalnya, file mungkin dipindai untuk mendeteksi data sensitif atau malware dan mungkin disimpan berdasarkan kebijakan perusahaan.</translation>
 <translation id="3744899669254331632">Anda tidak dapat mengunjungi <ph name="SITE" /> sekarang karena situs web mengirim kredensial tak beraturan yang tidak dapat diproses Chromium. Kesalahan jaringan dan serangan biasanya bersifat sementara, sehingga halaman ini mungkin akan bekerja nanti.</translation>
 <translation id="3745099705178523657">Setelah mengonfirmasi, detail kartu dari Akun Google Anda akan dibagikan dengan situs ini.</translation>
 <translation id="3748148204939282805">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat mengelabui Anda agar melakukan tindakan yang berbahaya seperti menginstal software atau mengungkap informasi pribadi Anda (misalnya sandi, nomor telepon, atau kartu kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1143,6 +1150,7 @@
 <translation id="4087296516249690906">Tombol Buat acara, tekan Enter untuk membuat acara baru di Google Kalender dengan cepat</translation>
 <translation id="4088981014127559358">Perpindahan image Y sisi 1</translation>
 <translation id="4089152113577680600">Baki 14</translation>
+<translation id="4097288585054919042">Nonaktifkan notifikasi</translation>
 <translation id="4098354747657067197">Situs yang akan dibuka berisi penipuan</translation>
 <translation id="4099048595830172239">Kebijakan administrator tidak merekomendasikan berbagi layar dengan <ph name="APPLICATION_TITLE" /> saat konten rahasia terlihat:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tekan tab lalu Enter untuk menyesuaikan ukuran font dan rupa huruf di Chrome</translation>
@@ -1179,6 +1187,7 @@
 <translation id="4176463684765177261">Dinonaktifkan</translation>
 <translation id="4176535426287761656">Properti hak guna &amp; liburan</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Batalkan pemantauan harga</translation>
 <translation id="4194250254487269611">Saat ini informasi kartu Anda tidak dapat disimpan</translation>
 <translation id="4196861286325780578">&amp;Ulangi pemindahan</translation>
 <translation id="4202554117186904723">Rol Kelima</translation>
@@ -1225,6 +1234,7 @@
 <translation id="4275830172053184480">Mulai ulang perangkat Anda</translation>
 <translation id="4277028893293644418">Reset sandi</translation>
 <translation id="4278390842282768270">Diizinkan</translation>
+<translation id="4282346679996504092">Notifikasi untuk produk ini telah dinonaktifkan dan bookmark dihapus</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Kartu ini telah disimpan di Akun Google Anda}other{Kartu-kartu ini telah disimpan di Akun Google Anda}}</translation>
 <translation id="4287885627794386150">Memenuhi syarat untuk uji coba tetapi tidak aktif</translation>
 <translation id="4297502707443874121">Thumbnail untuk halaman <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1263,6 +1273,7 @@
 <translation id="4358059973562876591">Template yang telah Anda tentukan mungkin tidak diterapkan karena terjadi error dengan kebijakan DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Kelola metode pembayaran...</translation>
 <translation id="4359160567981085931">Anda baru saja memasukkan sandi ke situs penipuan. Chrome dapat membantu. Untuk mengubah sandi dan memberi tahu Google bahwa akun Anda mungkin berisiko, klik Lindungi Akun.</translation>
+<translation id="4363222835916186793">Notifikasi untuk produk ini telah dinonaktifkan</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">Terjadi peristiwa keamanan</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1415,6 +1426,7 @@
 <translation id="4792686369684665359">Informasi yang akan Anda kirimkan tidak aman</translation>
 <translation id="4796594887379589189">ID akun tugas</translation>
 <translation id="4798078619018708837">Masukkan tanggal habis masa berlaku dan CVC untuk <ph name="CREDIT_CARD" /> guna memperbarui detail kartu. Setelah mengonfirmasi, detail kartu dari Akun Google Anda akan dibagikan dengan situs ini.</translation>
+<translation id="4798269756263412078">Dapatkan notifikasi jika ada diskon di situs mana pun. Notifikasi akan dikirim ke email Anda.</translation>
 <translation id="4800132727771399293">Periksa tanggal masa berlaku habis dan CVC, lalu coba lagi</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Gunakan Touch ID</translation>
@@ -1658,6 +1670,7 @@
 <translation id="5396631636586785122">Jahitan tepi di kanan</translation>
 <translation id="5398772614898833570">Iklan diblokir</translation>
 <translation id="5400836586163650660">Grey</translation>
+<translation id="540630185148148480">Aktifkan notifikasi</translation>
 <translation id="540969355065856584">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya saat ini tidak valid. Hal ini mungkin disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mengganggu koneksi internet Anda.</translation>
 <translation id="5412040515238827314">Format tidak valid: Format harus berupa daftar pola.</translation>
 <translation id="5412236728747081950">Situs ini mendapatkan minat Anda dari Chrome untuk menampilkan iklan yang lebih relevan</translation>
@@ -1722,6 +1735,7 @@
 <translation id="5580958916614886209">Periksa bulan kedaluwarsa dan coba lagi</translation>
 <translation id="558420943003240152">Kelola sandi dan kunci sandi …</translation>
 <translation id="5586446728396275693">Tidak ada alamat yang disimpan</translation>
+<translation id="5586831831248371458">Telusuri <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Pengguna platform</translation>
 <translation id="5593349413089863479">Koneksi tidak sepenuhnya aman</translation>
 <translation id="5595485650161345191">Edit alamat</translation>
@@ -1841,6 +1855,7 @@
 <translation id="5938153366081463283">Tambahkan kartu virtual</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Membuka <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">File yang Anda upload atau lampirkan akan dikirimkan ke Google Cloud atau pihak ketiga untuk analisis. Misalnya, file mungkin dipindai untuk mendeteksi data sensitif atau malware dan mungkin disimpan berdasarkan kebijakan perusahaan.</translation>
 <translation id="5951495562196540101">Tidak dapat mendaftar dengan akun konsumen (tersedia paket lisensi).</translation>
 <translation id="5953516610448771166">Teks Otomatis tidak tersedia untuk media ini. Untuk mendapatkan teks, blokir <ph name="CONTENT_SETTINGS" /> untuk situs ini.</translation>
 <translation id="5955063559762970069">Hotel &amp; penginapan</translation>
@@ -1929,6 +1944,7 @@
 <translation id="6177128806592000436">Sambungan Anda ke situs ini tidak aman</translation>
 <translation id="6180316780098470077">Interval percobaan ulang</translation>
 <translation id="61877208875190028">Pakaian wanita</translation>
+<translation id="6194209731893739467">Lihat semua produk yang dipantau di sini</translation>
 <translation id="6195371403461054755">Geologi</translation>
 <translation id="6196640612572343990">Blokir cookie pihak ketiga</translation>
 <translation id="6203231073485539293">Periksa koneksi internet Anda</translation>
@@ -1964,6 +1980,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Perangkat akan dimulai ulang sekarang}=1{Perangkat akan dimulai ulang dalam 1 detik}other{Perangkat akan dimulai ulang dalam # detik}}</translation>
+<translation id="6301104306974789820">Dapatkan notifikasi pemantauan harga</translation>
 <translation id="6302269476990306341">Asisten Google di Chrome sedang dihentikan</translation>
 <translation id="6305205051461490394"><ph name="URL" /> tidak dapat dijangkau.</translation>
 <translation id="6311165245110979290">Kartu virtual tersedia</translation>
@@ -2023,6 +2040,7 @@
 <translation id="6451458296329894277">Konfirmasikan Pengiriman Ulang Formulir</translation>
 <translation id="6456955391422100996">Iklan dihapus.</translation>
 <translation id="6457206614190510200">Jahitan kawat</translation>
+<translation id="6457455098507772300">Notifikasi diskon muncul sebagai notifikasi pop-up di desktop</translation>
 <translation id="6458606150257356946">Tetap tempelkan</translation>
 <translation id="6464094930452079790">gambar</translation>
 <translation id="6465306955648956876">Kelola sandi...</translation>
@@ -2080,6 +2098,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Hapus</translation>
 <translation id="6645291930348198241">Mengakses cookie dan data situs.</translation>
+<translation id="6645478838938543427">Notifikasi diskon akan dikirim ke <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Tidak ada}=1{Dari 1 situs (Anda tidak akan logout dari Akun Google)}other{Dari # situs (Anda tidak akan logout dari Akun Google)}}</translation>
 <translation id="6648459603387803038">Administrator dapat mengubah penyiapan browser Anda dari jarak jauh. Aktivitas di perangkat ini juga dapat dikelola di luar Chrome.</translation>
 <translation id="6648524591329069940">Font Serif</translation>
@@ -2273,6 +2292,7 @@
 <translation id="7182878459783632708">Tidak ada kebijakan yang disetel</translation>
 <translation id="7186367841673660872">Halaman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Pemandu sorak</translation>
+<translation id="7192188280913829296">Atribut "vendor_id" juga harus ditentukan.</translation>
 <translation id="7192203810768312527">Sediakan ruang sebesar <ph name="SIZE" />. Sebagian situs mungkin dimuat lebih lambat pada kunjungan Anda berikutnya.</translation>
 <translation id="7193661028827781021">Referensi</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb
index ac63f5f..d1ba1cf 100644
--- a/components/strings/components_strings_it.xtb
+++ b/components/strings/components_strings_it.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Sblocco dispositivo</translation>
 <translation id="1269516672602708785">Crea rapidamente un nuovo sito in Google Sites</translation>
 <translation id="1270502636509132238">Metodo di ritiro</translation>
+<translation id="1273592791152866347">Monitoraggio prezzi disattivato</translation>
 <translation id="1281476433249504884">Fascicolatore 1</translation>
 <translation id="1285320974508926690">Non tradurre mai questo sito</translation>
 <translation id="1288548991597756084">Salva la carta in modo sicuro</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Freeware e shareware</translation>
 <translation id="1553358976309200471">Aggiorna Chrome</translation>
+<translation id="1554003749331233619">Stai monitorando questo prodotto. Questa pagina è salvata in <ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">Blu</translation>
 <translation id="1559447966090556585">Ricevere notifiche?</translation>
 <translation id="1559528461873125649">Nessun file o directory corrispondente</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Gestisci l'Account Google, premi Invio per gestire le tue informazioni, la privacy e la sicurezza nel tuo Account Google</translation>
 <translation id="2436186046335138073">Consentire a <ph name="HANDLER_HOSTNAME" /> di aprire tutti i link <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Perforatura quadrupla a destra</translation>
+<translation id="2443309680964448806">Si è verificato un errore. La modifica non è stata salvata.</translation>
 <translation id="2448295565072560657">Periferiche collegate a questo dispositivo mentre hai eseguito l'accesso</translation>
 <translation id="2450021089947420533">Percorsi</translation>
 <translation id="2463739503403862330">Compila</translation>
@@ -816,6 +819,7 @@
 <translation id="317878711435188021">Sapere quando usi attivamente questo dispositivo</translation>
 <translation id="3180358318770512945">Educazione dei figli</translation>
 <translation id="3187306450550410410">Condizioni lavorative flessibili</translation>
+<translation id="3190736958609431397">Annulla monitoraggio</translation>
 <translation id="319282854780294203">Social network</translation>
 <translation id="3194737229810486521"><ph name="URL" /> vuole memorizzare in modo definitivo i dati sul dispositivo</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> su <ph name="SERVER_NAME" /></translation>
@@ -901,6 +905,7 @@
 <translation id="3387261909427947069">Metodi di pagamento</translation>
 <translation id="3391030046425686457">Indirizzo di consegna</translation>
 <translation id="3391482648489541560">modifica di file</translation>
+<translation id="3392028486601120379">È stato specificato un percorso per il pattern URL "<ph name="URL_PATTERN" />". I percorsi non sono supportati per questa chiave. Rimuovi il percorso e riprova. Ad esempio *://example.com/ =&gt; *://example.com"</translation>
 <translation id="3395827396354264108">Metodo di ritiro</translation>
 <translation id="3399952811970034796">Indirizzo di consegna</translation>
 <translation id="3402261774528610252">La connessione utilizzata per caricare il sito usava TLS 1.0 o TLS 1.1, che ora sono obsoleti e in futuro verranno disattivati. In seguito alla disattivazione, gli utenti non potranno caricare questo sito. Il server dovrà abilitare TLS 1.2 o versione successiva.</translation>
@@ -996,6 +1001,7 @@
 <translation id="3637662659967048211">Salva nell'Account Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Applicazione:</translation>
+<translation id="3647286794400715637">Ogni voce della stringa dell'URL deve contenere da 1 a 2 URL.</translation>
 <translation id="3650584904733503804">Convalida riuscita</translation>
 <translation id="3653033846669030038">Parchi tematici</translation>
 <translation id="3655241534245626312">Vai alle impostazioni dell'autorizzazione</translation>
@@ -1034,6 +1040,7 @@
 <translation id="3738166223076830879">Il tuo browser è gestito dal tuo amministratore.</translation>
 <translation id="3740319564441798148">Autobus e treni a lunga percorrenza</translation>
 <translation id="3744111561329211289">Sincronizzazione in background</translation>
+<translation id="3744286742364977428">I file che scarichi vengono inviati a Google Cloud o a terze parti per l'analisi. Ad esempio, potrebbero essere sottoposti a scansione per rilevare dati sensibili o malware e archiviati in base ai criteri aziendali.</translation>
 <translation id="3744899669254331632">Al momento non puoi visitare il sito <ph name="SITE" /> perché tale sito web ha inviato credenziali criptate che Chromium non è riuscito a elaborare. Gli attacchi e gli errori di rete in genere sono temporanei, pertanto è possibile che questa pagina funzioni più tardi.</translation>
 <translation id="3745099705178523657">Dopo essere stati confermati, i dati della carta del tuo Account Google saranno condivisi con questo sito.</translation>
 <translation id="3748148204939282805">Gli utenti malintenzionati presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero indurti con l'inganno a effettuare operazioni pericolose, come installare software o rivelare informazioni personali (ad esempio password, numeri di telefono o carte di credito). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1141,6 +1148,7 @@
 <translation id="4087296516249690906">Pulsante Crea evento, premi Invio per creare rapidamente un nuovo evento in Google Calendar</translation>
 <translation id="4088981014127559358">Spostamento Y lato 1 immagine</translation>
 <translation id="4089152113577680600">Vassoio 14</translation>
+<translation id="4097288585054919042">Disattiva gli avvisi</translation>
 <translation id="4098354747657067197">Sito ingannevole in vista</translation>
 <translation id="4099048595830172239">Il criterio dell'amministratore sconsiglia la condivisione dello schermo con <ph name="APPLICATION_TITLE" /> quando sono visibili contenuti riservati:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, premi Tab e poi Invio per personalizzare le dimensioni dei caratteri e i caratteri tipografici in Chrome</translation>
@@ -1177,6 +1185,7 @@
 <translation id="4176463684765177261">Disattivato</translation>
 <translation id="4176535426287761656">Multiproprietà e case vacanze</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Annulla monitoraggio prezzo</translation>
 <translation id="4194250254487269611">Al momento non è possibile salvare la carta</translation>
 <translation id="4196861286325780578">&amp;Ripeti spostamento</translation>
 <translation id="4202554117186904723">Quinto rullo</translation>
@@ -1223,6 +1232,7 @@
 <translation id="4275830172053184480">Riavvia il dispositivo</translation>
 <translation id="4277028893293644418">Reimposta password</translation>
 <translation id="4278390842282768270">Consenti</translation>
+<translation id="4282346679996504092">Gli avvisi per questo prodotto sono stati disattivati e il preferito è stato rimosso</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Questa carta è stata salvata nel tuo Account Google}other{Queste carte sono state salvate nel tuo Account Google}}</translation>
 <translation id="4287885627794386150">Funzionalità idonea per la prova, ma non attiva</translation>
 <translation id="4297502707443874121">Miniatura della pagina <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1261,6 +1271,7 @@
 <translation id="4358059973562876591">I modelli che hai specificato potrebbero non essere applicati a causa di un errore con il criterio DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Gestisci metodi di pagamento…</translation>
 <translation id="4359160567981085931">Hai appena inserito la tua password su un sito ingannevole. Chrome può aiutarti. Per cambiare la password e informare Google che il tuo account potrebbe essere a rischio, fai clic su Proteggi account.</translation>
+<translation id="4363222835916186793">Gli avvisi per questo prodotto sono stati disattivati</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">Si è verificato un evento di sicurezza</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1413,6 +1424,7 @@
 <translation id="4792686369684665359">Le informazioni che stai per inviare non sono protette</translation>
 <translation id="4796594887379589189">ID account lavoro</translation>
 <translation id="4798078619018708837">Inserisci la data di scadenza e il codice CVC della carta <ph name="CREDIT_CARD" /> per aggiornare i relativi dettagli. Dopo essere stati confermati, i dati della carta del tuo Account Google saranno condivisi con questo sito.</translation>
+<translation id="4798269756263412078">Ricevi avvisi se il prezzo cala su qualsiasi sito. Gli avvisi verranno inviati al tuo indirizzo email.</translation>
 <translation id="4800132727771399293">Controlla la data di scadenza e il codice CVC, poi riprova</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Usa Touch ID</translation>
@@ -1656,6 +1668,7 @@
 <translation id="5396631636586785122">Impuntura a destra</translation>
 <translation id="5398772614898833570">Annunci bloccati</translation>
 <translation id="5400836586163650660">Grigio</translation>
+<translation id="540630185148148480">Attiva gli avvisi</translation>
 <translation id="540969355065856584">Questo server non è riuscito a verificare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato valido in questa fase. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che ha intercettato la connessione.</translation>
 <translation id="5412040515238827314">Formato non valido: è previsto un elenco di pattern.</translation>
 <translation id="5412236728747081950">Questo sito acquisisce i tuoi interessi da Chrome per mostrarti annunci più pertinenti</translation>
@@ -1720,6 +1733,7 @@
 <translation id="5580958916614886209">Controlla il mese di scadenza e riprova</translation>
 <translation id="558420943003240152">Gestisci password e passkey…</translation>
 <translation id="5586446728396275693">Nessun indirizzo salvato</translation>
+<translation id="5586831831248371458">Cerca <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Utente della piattaforma</translation>
 <translation id="5593349413089863479">La connessione non è completamente sicura</translation>
 <translation id="5595485650161345191">Modifica indirizzo</translation>
@@ -1839,6 +1853,7 @@
 <translation id="5938153366081463283">Aggiungi carta virtuale</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Apertura di <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">I file che carichi o alleghi vengono inviati a Google Cloud o a terze parti per l'analisi. Ad esempio, potrebbero essere sottoposti a scansione per rilevare dati sensibili o malware e archiviati in base ai criteri aziendali.</translation>
 <translation id="5951495562196540101">Impossibile effettuare la registrazione con l'account consumer (è disponibile la licenza inclusa).</translation>
 <translation id="5953516610448771166">La funzionalità Sottotitoli in tempo reale non è disponibile per questi contenuti multimediali. Per visualizzare i sottotitoli codificati, blocca l'impostazione <ph name="CONTENT_SETTINGS" /> per questo sito.</translation>
 <translation id="5955063559762970069">Hotel e alloggi</translation>
@@ -1926,6 +1941,7 @@
 <translation id="6177128806592000436">La tua connessione a questo sito non è sicura</translation>
 <translation id="6180316780098470077">Intervallo tra tentativi</translation>
 <translation id="61877208875190028">Abbigliamento donna</translation>
+<translation id="6194209731893739467">Visualizza tutti i tuoi prodotti monitorati qui</translation>
 <translation id="6195371403461054755">Geologia</translation>
 <translation id="6196640612572343990">Blocca cookie di terze parti</translation>
 <translation id="6203231073485539293">Controlla la connessione a Internet</translation>
@@ -1961,6 +1977,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Il tuo dispositivo verrà riavviato adesso}=1{Il tuo dispositivo verrà riavviato tra 1 secondo}other{Il tuo dispositivo verrà riavviato tra # secondi}}</translation>
+<translation id="6301104306974789820">Ricevi notifiche per il monitoraggio dei prezzi</translation>
 <translation id="6302269476990306341">Interruzione dell'Assistente Google in Chrome</translation>
 <translation id="6305205051461490394"><ph name="URL" /> non è raggiungibile.</translation>
 <translation id="6311165245110979290">Carta virtuale disponibile</translation>
@@ -2020,6 +2037,7 @@
 <translation id="6451458296329894277">Conferma reinvio modulo</translation>
 <translation id="6456955391422100996">Annuncio rimosso.</translation>
 <translation id="6457206614190510200">Pinzatura centrale</translation>
+<translation id="6457455098507772300">Gli avvisi relativi ai cali di prezzo vengono visualizzati come notifiche popup sul desktop</translation>
 <translation id="6458606150257356946">Incolla comunque</translation>
 <translation id="6464094930452079790">immagini</translation>
 <translation id="6465306955648956876">Gestisci password…</translation>
@@ -2077,6 +2095,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Cancella</translation>
 <translation id="6645291930348198241">Accedere a cookie e dati del sito.</translation>
+<translation id="6645478838938543427">Gli avvisi relativi ai cali di prezzo verranno inviati a <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Nessuno}=1{Da 1 sito (non verrai disconnesso dal tuo Account Google)}other{Da # siti (non verrai disconnesso dal tuo Account Google)}}</translation>
 <translation id="6648459603387803038">L'amministratore può modificare da remoto la configurazione del browser. L'attività svolta su questo dispositivo potrebbe essere gestita anche al di fuori di Chrome.</translation>
 <translation id="6648524591329069940">Carattere serif</translation>
@@ -2270,6 +2289,7 @@
 <translation id="7182878459783632708">Nessuna norma impostata</translation>
 <translation id="7186367841673660872">Questa pagina è stata tradotta da<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Cheerleading</translation>
+<translation id="7192188280913829296">È necessario specificare anche l'attributo "vendor_id".</translation>
 <translation id="7192203810768312527">Consente di liberare <ph name="SIZE" />. Alcuni siti potrebbero caricarsi più lentamente alla prossima visita.</translation>
 <translation id="7193661028827781021">Consultazione</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb
index 36b99ac..f7f26828 100644
--- a/components/strings/components_strings_iw.xtb
+++ b/components/strings/components_strings_iw.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">ביטול נעילת המכשיר</translation>
 <translation id="1269516672602708785">‏יצירה מהירה של אתר חדש ב-Google Sites</translation>
 <translation id="1270502636509132238">שיטת איסוף</translation>
+<translation id="1273592791152866347">המעקב אחר מחירים מושבת</translation>
 <translation id="1281476433249504884">מערים 1</translation>
 <translation id="1285320974508926690">איני רוצה לקבל תרגום של אתר זה</translation>
 <translation id="1288548991597756084">שמירה מאובטחת של הכרטיס</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">תוכנות חינמיות ותוכנות שיתופיות</translation>
 <translation id="1553358976309200471">‏כדאי לעדכן את Chrome</translation>
+<translation id="1554003749331233619">בחרת לעקוב אחר המוצר הזה. הדף הזה נשמר ב<ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">כחול</translation>
 <translation id="1559447966090556585">לאפשר קבלת התראות?</translation>
 <translation id="1559528461873125649">אין קובץ או ספרייה בשם זה</translation>
@@ -560,6 +562,7 @@
 <translation id="2430968933669123598">‏ניהול חשבון Google, צריך להקיש על Enter כדי לנהל את המידע, הפרטיות והאבטחה בחשבון Google</translation>
 <translation id="2436186046335138073">האם לאפשר ל-<ph name="HANDLER_HOSTNAME" /> לפתוח את כל קישורי <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">4 ניקובים בצד ימין</translation>
+<translation id="2443309680964448806">משהו השתבש. השינוי לא נשמר.</translation>
 <translation id="2448295565072560657">ציוד היקפי שמחובר למכשיר הזה לאחר התחברות לחשבון שלך</translation>
 <translation id="2450021089947420533">תהליכים</translation>
 <translation id="2463739503403862330">מילוי</translation>
@@ -818,6 +821,7 @@
 <translation id="317878711435188021">לדעת מתי המכשיר הזה משמש אותך באופן פעיל</translation>
 <translation id="3180358318770512945">הורות</translation>
 <translation id="3187306450550410410">הסדרי עבודה גמישים</translation>
+<translation id="3190736958609431397">ביטול המעקב</translation>
 <translation id="319282854780294203">רשתות חברתיות</translation>
 <translation id="3194737229810486521"><ph name="URL" /> רוצה לאחסן נתונים במכשיר שלך באופן קבוע</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> בשרת <ph name="SERVER_NAME" /></translation>
@@ -903,6 +907,7 @@
 <translation id="3387261909427947069">אמצעי תשלום</translation>
 <translation id="3391030046425686457">כתובת למשלוח</translation>
 <translation id="3391482648489541560">עריכת קבצים</translation>
+<translation id="3392028486601120379">‏בתבנית ה-URL‏ <ph name="URL_PATTERN" /> צוין נתיב. אין תמיכה בנתיבים למפתח הזה. יש להסיר את הנתיב ולנסות שוב. לדוגמה: ‎*://example.com/‎ ‏=&gt; ‎*://example.com"‎,</translation>
 <translation id="3395827396354264108">שיטת איסוף</translation>
 <translation id="3399952811970034796">כתובת למשלוח</translation>
 <translation id="3402261774528610252">‏החיבור ששימש לצורך טעינת האתר הזה היה מבוסס על הפרוטוקול TLS 1.0 או TLS 1.1, שהוצא משימוש ויושבת בעתיד. אחרי שהפרוטוקול יושבת, משתמשים לא יוכלו לטעון את האתר הזה. יש להפעיל בשרת את הפרוטוקול TLS 1.2 ואילך.</translation>
@@ -998,6 +1003,7 @@
 <translation id="3637662659967048211">‏שמירה בחשבון Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">אפליקציה:</translation>
+<translation id="3647286794400715637">‏כל רשומת מחרוזת של כתובות URL חייבת להכיל כתובת URL אחת או שתיים.</translation>
 <translation id="3650584904733503804">האימות בוצע בהצלחה</translation>
 <translation id="3653033846669030038">פארקי שעשועים</translation>
 <translation id="3655241534245626312">להגדרות של ההרשאה</translation>
@@ -1035,6 +1041,7 @@
 <translation id="3738166223076830879">הדפדפן מנוהל על ידי מנהל המערכת</translation>
 <translation id="3740319564441798148">אוטובוסים ורכבות למרחקים ארוכים</translation>
 <translation id="3744111561329211289">סנכרון ברקע</translation>
+<translation id="3744286742364977428">‏קבצים שמורידים נשלחים אל Google Cloud או אל צדדים שלישיים לצורך ניתוח. לדוגמה, יכול להיות שהקבצים יעברו סריקה כדי לאתר מידע אישי רגיש או תוכנות זדוניות, וייתכן שהם יישמרו בהתאם למדיניות החברה.</translation>
 <translation id="3744899669254331632">‏אי אפשר להיכנס כרגע אל <ph name="SITE" /> מפני שהאתר שלח פרטי כניסה מעורבלים ש-Chromium אינו יכול לעבד. שגיאות רשת והתקפות הן בדרך כלל זמניות, לכן סביר להניח שדף זה יפעל כהלכה בהמשך.</translation>
 <translation id="3745099705178523657">‏אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון Google.</translation>
 <translation id="3748148204939282805">תוקפים באתר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> עלולים להונות אותך כדי לגרום לך לבצע פעולות מסוכנות, כמו התקנת תוכנה או חשיפת מידע אישי (לדוגמה, סיסמאות, מספרי טלפון או כרטיסי אשראי). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1142,6 +1149,7 @@
 <translation id="4087296516249690906">‏לחצן ליצירת אירוע, מקישים על Enter כדי ליצור במהירות אירוע חדש ביומן Google</translation>
 <translation id="4088981014127559358">‏הזזה של תמונה בצד 1 על ציר Y</translation>
 <translation id="4089152113577680600">מגש 14</translation>
+<translation id="4097288585054919042">כיבוי ההתראות</translation>
 <translation id="4098354747657067197">זהירות, אתר מטעה</translation>
 <translation id="4099048595830172239">לפי המדיניות של מנהל המערכת, לא מומלץ לשתף את המסך עם <ph name="APPLICATION_TITLE" /> כשמופיע בו תוכן סודי גלוי:</translation>
 <translation id="4099391883283080991">‏<ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, מקישים על Tab ואז על Enter כדי להתאים אישית את הגופנים וגודל הטקסט ב-Chrome</translation>
@@ -1178,6 +1186,7 @@
 <translation id="4176463684765177261">מושבת</translation>
 <translation id="4176535426287761656">יחידות נופש משותפות ונכסים לנופש</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">ביטול המעקב אחר המחירים</translation>
 <translation id="4194250254487269611">אי אפשר לשמור את הכרטיס שלך עכשיו</translation>
 <translation id="4196861286325780578">&amp;ביצוע מחדש של העברה</translation>
 <translation id="4202554117186904723">הגליל החמישי</translation>
@@ -1224,6 +1233,7 @@
 <translation id="4275830172053184480">הפעלת המכשיר מחדש</translation>
 <translation id="4277028893293644418">איפוס סיסמה</translation>
 <translation id="4278390842282768270">מותר</translation>
+<translation id="4282346679996504092">ההתראות לגבי המוצר הזה הושבתו והסימנייה הוסרה</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{‏הכרטיס הזה נשמר בחשבון Google שלך}two{‏הכרטיסים האלה נשמרו בחשבון Google שלך}many{‏הכרטיסים האלה נשמרו בחשבון Google שלך}other{‏הכרטיסים האלה נשמרו בחשבון Google שלך}}</translation>
 <translation id="4287885627794386150">מתאים להשתתפות בניסוי, לא פעיל</translation>
 <translation id="4297502707443874121">תמונה ממוזערת של הדף <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1262,6 +1272,7 @@
 <translation id="4358059973562876591">‏לא ניתן להחיל את התבניות שבחרת עקב שגיאה במדיניות DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">ניהול אמצעי תשלום...</translation>
 <translation id="4359160567981085931">‏הזנת כרגע את הסיסמה שלך באתר מטעה. אפשר לפתור את הבעיה בעזרת Chrome. כדי לשנות את הסיסמה ולהודיע ל-Google שייתכן כי החשבון בסיכון, יש ללחוץ על 'הגנה על החשבון'.</translation>
+<translation id="4363222835916186793">ההתראות לגבי המוצר הזה הושבתו</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)‎</translation>
 <translation id="437040971055499437">התרחשות של אירוע אבטחה</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1418,6 +1429,7 @@
 <translation id="4792686369684665359">המידע שבכוונתך לשלוח לא מאובטח</translation>
 <translation id="4796594887379589189">מזהה חשבון עבודה</translation>
 <translation id="4798078619018708837">‏כדי לעדכן את פרטי הכרטיס, יש להזין את תאריך התפוגה וקוד האימות של <ph name="CREDIT_CARD" />. אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון Google.</translation>
+<translation id="4798269756263412078">קבלת התראות על הנחות באתר כלשהו. ההתראות יישלחו אליך באימייל.</translation>
 <translation id="4800132727771399293">‏יש לבדוק את תאריך התפוגה ואת ה-CVC ולנסות שוב</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">‏שימוש ב-Touch ID</translation>
@@ -1661,6 +1673,7 @@
 <translation id="5396631636586785122">הידוק קצוות בצד ימין</translation>
 <translation id="5398772614898833570">מודעות חסומות</translation>
 <translation id="5400836586163650660">אפור</translation>
+<translation id="540630185148148480">הפעלת ההתראות</translation>
 <translation id="540969355065856584">שרת זה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו אינו תקף כעת. הסיבה לכך עשויה להיות תצורה שגויה או שתוקף מיירט את החיבור שלך.</translation>
 <translation id="5412040515238827314">פורמט לא תקין: אמורה להופיע רשימת תבניות.</translation>
 <translation id="5412236728747081950">‏יוצגו לך מודעות רלוונטיות יותר באתר על סמך תחומי העניין שלך מ-Chrome</translation>
@@ -1726,6 +1739,7 @@
 <translation id="5580958916614886209">יש לבדוק את חודש התפוגה ולנסות שוב</translation>
 <translation id="558420943003240152">ניהול סיסמאות ומפתחות גישה…</translation>
 <translation id="5586446728396275693">לא נשמרו כתובות</translation>
+<translation id="5586831831248371458">חיפוש מידע על <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">משתמש בפלטפורמה</translation>
 <translation id="5593349413089863479">החיבור לא לגמרי מאובטח</translation>
 <translation id="5595485650161345191">עריכת כתובת</translation>
@@ -1845,6 +1859,7 @@
 <translation id="5938153366081463283">הוספת כרטיס וירטואלי</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">פתיחה של <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">‏קבצים שמעלים או מצרפים נשלחים ל-Google Cloud או לצדדים שלישיים לצורך ניתוח. לדוגמה, יכול להיות שהקבצים יעברו סריקה כדי לאתר מידע אישי רגיש או תוכנות זדוניות, וייתכן שהם יישמרו בהתאם למדיניות החברה.</translation>
 <translation id="5951495562196540101">אי אפשר להירשם באמצעות חשבון פרטי (יש רישיון משויך זמין).</translation>
 <translation id="5953516610448771166">הכתוביות המיידיות לא זמינות לפריט המדיה הזה. כדי לקבל כתוביות, עליך לחסום <ph name="CONTENT_SETTINGS" /> לאתר הזה.</translation>
 <translation id="5955063559762970069">מלונות ואירוח</translation>
@@ -1933,6 +1948,7 @@
 <translation id="6177128806592000436">החיבור שלך לאתר הזה לא מאובטח</translation>
 <translation id="6180316780098470077">מרווח בין ניסיונות חוזרים</translation>
 <translation id="61877208875190028">בגדי נשים</translation>
+<translation id="6194209731893739467">כאן יופיעו כל המוצרים שבמעקב</translation>
 <translation id="6195371403461054755">גיאולוגיה</translation>
 <translation id="6196640612572343990">‏חסימת קובצי Cookie של צד שלישי</translation>
 <translation id="6203231073485539293">בדיקת חיבור האינטרנט</translation>
@@ -1968,6 +1984,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{המכשיר יופעל מחדש עכשיו}=1{המכשיר יופעל מחדש בתוך שנייה}two{המכשיר יופעל מחדש בתוך # שניות}many{המכשיר יופעל מחדש בתוך # שניות}other{המכשיר יופעל מחדש בתוך # שניות}}</translation>
+<translation id="6301104306974789820">קבלת התראות לגבי מעקב אחר מחירים</translation>
 <translation id="6302269476990306341">‏Google Assistant מופסקת ב-Chrome</translation>
 <translation id="6305205051461490394">לא ניתן לגשת אל <ph name="URL" />.</translation>
 <translation id="6311165245110979290">יש כרטיס וירטואלי זמין</translation>
@@ -2027,6 +2044,7 @@
 <translation id="6451458296329894277">אישור שליחה מחדש של הטופס</translation>
 <translation id="6456955391422100996">המודעה הוסרה.</translation>
 <translation id="6457206614190510200">קיפול והידוק של כפולות עמודים</translation>
+<translation id="6457455098507772300">התראות על הנחות מוצגות כהתראות קופצות במחשב</translation>
 <translation id="6458606150257356946">אני רוצה להדביק בכל זאת</translation>
 <translation id="6464094930452079790">תמונות</translation>
 <translation id="6465306955648956876">ניהול סיסמאות...</translation>
@@ -2084,6 +2102,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">ניקוי</translation>
 <translation id="6645291930348198241">‏לקבל גישה לקובצי Cookie ולנתוני אתרים.</translation>
+<translation id="6645478838938543427">התראות על הנחות יישלחו לכתובת <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{ללא}=1{‏מאתר אחד (לא תבוצע יציאה מחשבון Google שלך.)}two{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}many{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}other{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}}</translation>
 <translation id="6648459603387803038">‏מנהל המערכת יכול לשנות את הגדרת הדפדפן שלך מרחוק. בנוסף, ניתן לנהל את הפעילות במכשיר הזה מחוץ ל-Chrome.</translation>
 <translation id="6648524591329069940">‏גופן Serif</translation>
@@ -2277,6 +2296,7 @@
 <translation id="7182878459783632708">לא הוגדרה מדיניות</translation>
 <translation id="7186367841673660872">דף זה תורגם מ<ph name="ORIGINAL_LANGUAGE" />ל<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">עידוד בספורט</translation>
+<translation id="7192188280913829296">‏צריך לציין גם את המאפיין vendor_id.</translation>
 <translation id="7192203810768312527">פינוי של <ph name="SIZE" /> מהנפח. תיתכן טעינה איטית יותר של אתרים מסוימים בביקור הבא שלך.</translation>
 <translation id="7193661028827781021">חומרי עזר</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb
index 5429b1c..1b9b2a8 100644
--- a/components/strings/components_strings_ko.xtb
+++ b/components/strings/components_strings_ko.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">기기 잠금 해제</translation>
 <translation id="1269516672602708785">Google Sites에서 빠르게 새 사이트 만들기</translation>
 <translation id="1270502636509132238">픽업 방법</translation>
+<translation id="1273592791152866347">가격 추적 사용 중지됨</translation>
 <translation id="1281476433249504884">스태커 1</translation>
 <translation id="1285320974508926690">이 사이트 번역 안함</translation>
 <translation id="1288548991597756084">카드 안전하게 저장하기</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">프리웨어 및 셰어웨어</translation>
 <translation id="1553358976309200471">Chrome 업데이트</translation>
+<translation id="1554003749331233619">제품을 추적하는 중입니다. 페이지가 <ph name="LAST_BOOKMARKS_FOLDER" />에 저장되어 있습니다.</translation>
 <translation id="1555130319947370107">파란색</translation>
 <translation id="1559447966090556585">알림을 받으시겠습니까?</translation>
 <translation id="1559528461873125649">해당 파일이나 디렉터리가 없습니다.</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Google 계정 관리, Enter를 눌러 Google 계정에서 정보, 개인 정보 보호 및 보안 설정 관리</translation>
 <translation id="2436186046335138073"><ph name="HANDLER_HOSTNAME" />에서 모든 <ph name="PROTOCOL" /> 링크를 열도록 허용하시겠습니까?</translation>
 <translation id="2438874542388153331">오른쪽 4공 펀칭</translation>
+<translation id="2443309680964448806">문제가 발생했습니다. 변경사항이 저장되지 않았습니다.</translation>
 <translation id="2448295565072560657">로그인되어 있는 동안 이 기기에 연결된 주변기기</translation>
 <translation id="2450021089947420533">탐색 여정</translation>
 <translation id="2463739503403862330">입력</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">사용자가 현재 기기를 사용 중인지 확인합니다.</translation>
 <translation id="3180358318770512945">육아</translation>
 <translation id="3187306450550410410">유연 근무</translation>
+<translation id="3190736958609431397">추적 취소</translation>
 <translation id="319282854780294203">사회 연결망</translation>
 <translation id="3194737229810486521"><ph name="URL" />에서 내 기기에 데이터를 영구 저장하려고 합니다</translation>
 <translation id="3195213714973468956"><ph name="SERVER_NAME" />의 <ph name="PRINTER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">결제 수단</translation>
 <translation id="3391030046425686457">배송지 주소</translation>
 <translation id="3391482648489541560">파일 수정</translation>
+<translation id="3392028486601120379">URL 패턴 "<ph name="URL_PATTERN" />"에 지정된 경로가 있습니다. 이 키에는 경로가 지원되지 않습니다. *://example.com/ =&gt; *://example.com"과 같이 경로를 삭제한 후 다시 시도해 주세요.</translation>
 <translation id="3395827396354264108">수령 방법</translation>
 <translation id="3399952811970034796">배달 주소</translation>
 <translation id="3402261774528610252">이 사이트를 로드하는 데 사용된 연결에는 TLS 1.0 또는 TLS 1.1이 사용되었으며, 이러한 TLS는 지원이 중단되어 향후 사용 중지될 예정입니다. 사용 중지된 후에는 사용자가 이 사이트를 로드할 수 없습니다. 서버에서 TLS 1.2 이상을 사용해야 합니다.</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">Google 계정에 저장</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">애플리케이션:</translation>
+<translation id="3647286794400715637">모든 URL 문자열 항목에는 1~2개의 URL이 포함되어야 합니다.</translation>
 <translation id="3650584904733503804">유효성 검사 성공</translation>
 <translation id="3653033846669030038">테마파크</translation>
 <translation id="3655241534245626312">권한 설정으로 이동</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">관리자가 관리하는 브라우저입니다.</translation>
 <translation id="3740319564441798148">시외버스 및 철도</translation>
 <translation id="3744111561329211289">백그라운드 동기화</translation>
+<translation id="3744286742364977428">다운로드한 파일은 분석을 위해 Google Cloud 또는 서드 파티로 전송됩니다. 예를 들어 파일에 민감한 정보 또는 멀웨어가 있는지 검사하며 회사 정책에 따라 파일을 저장할 수도 있습니다.</translation>
 <translation id="3744899669254331632">웹사이트가 Chromium이 처리할 수 없는 암호화된 사용자 인증 정보를 전송하였으므로 지금은 <ph name="SITE" />에 방문할 수 없습니다. 네트워크 오류와 공격은 대체로 일시적인 문제이기 때문에 이후에는 이 페이지가 제대로 작동할 가능성이 높습니다.</translation>
 <translation id="3745099705178523657">카드를 확인하면 Google 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />의 공격자가 소프트웨어를 설치하거나 개인정보(예: 비밀번호, 전화번호, 신용카드)를 공개하는 등의 위험한 행동을 하도록 사용자를 속일 수 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />자세히 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">일정 만들기 버튼, Enter를 눌러 Google Calendar에서 빠르게 새 일정 만들기</translation>
 <translation id="4088981014127559358">첫 번째 면 이미지 Y 시프트</translation>
 <translation id="4089152113577680600">트레이 14</translation>
+<translation id="4097288585054919042">알림 사용 중지</translation>
 <translation id="4098354747657067197">사기성 사이트 주의</translation>
 <translation id="4099048595830172239">관리자 정책에 따라 기밀 콘텐츠가 화면에 표시되어 있을 때 <ph name="APPLICATION_TITLE" /> 앱과 화면을 공유하지 않는 것이 좋습니다.</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tab을 누른 다음 Enter를 눌러 Chrome의 글꼴 크기와 서체 맞춤설정</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">사용 중지됨</translation>
 <translation id="4176535426287761656">공동 사용 및 휴가용 별장</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">가격 추적 취소</translation>
 <translation id="4194250254487269611">지금은 카드를 저장할 수 없습니다.</translation>
 <translation id="4196861286325780578">이동 다시 실행(&amp;R)</translation>
 <translation id="4202554117186904723">5번째 롤</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">기기 다시 시작</translation>
 <translation id="4277028893293644418">비밀번호 재설정</translation>
 <translation id="4278390842282768270">허용</translation>
+<translation id="4282346679996504092">제품 관련 알림이 사용 중지되었으며 북마크가 삭제되었습니다.</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{다음 카드가 Google 계정에 저장되었습니다.}other{다음 카드가 Google 계정에 저장되었습니다.}}</translation>
 <translation id="4287885627794386150">무료 체험을 이용할 수 있으나 활성화되어 있지 않음</translation>
 <translation id="4297502707443874121"><ph name="THUMBNAIL_PAGE" /> 페이지 미리보기 이미지</translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">지정한 템플릿이 DnsOverHttpsMode 정책 오류로 인해 적용되지 않을 수 있습니다.</translation>
 <translation id="4358461427845829800">결제 수단 관리...</translation>
 <translation id="4359160567981085931">사기성 사이트에 비밀번호를 입력했습니다. Chrome이 계정 보호를 도와드립니다. 비밀번호를 변경하고 계정 보안 위험에 관해 Google에 알리려면 계정 보호를 클릭하세요.</translation>
+<translation id="4363222835916186793">제품 관련 알림이 사용 중지되었습니다.</translation>
 <translation id="4367563149485757821">Number-12(봉투)</translation>
 <translation id="437040971055499437">보안 관련 활동 발생</translation>
 <translation id="4372516964750095882">Fanfold-미국</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">안전하지 않은 정보를 제출하려 함</translation>
 <translation id="4796594887379589189">작업 계정 ID</translation>
 <translation id="4798078619018708837">카드 세부정보를 업데이트하려면 <ph name="CREDIT_CARD" /> 카드의 만료일과 CVC를 입력하세요. 카드를 확인하면 Google 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation>
+<translation id="4798269756263412078">사이트에서 가격이 인하되면 알림을 받게 됩니다. 알림은 사용자의 이메일 주소로 전송됩니다.</translation>
 <translation id="4800132727771399293">유효기간과 CVC를 확인한 후 다시 시도해 주세요.</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Touch ID 사용</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">오른쪽 에지 스티치</translation>
 <translation id="5398772614898833570">광고 차단됨</translation>
 <translation id="5400836586163650660">그레이</translation>
+<translation id="540630185148148480">알림 사용 설정</translation>
 <translation id="540969355065856584">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버의 보안 인증서가 현재 유효하지 않습니다. 서버를 잘못 설정했거나 공격자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
 <translation id="5412040515238827314">잘못된 형식: 패턴 목록이 필요합니다.</translation>
 <translation id="5412236728747081950">이 사이트는 Chrome에 저장된 내 관심분야 정보를 토대로 더욱 관련성 있는 광고를 표시합니다.</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">유효기간 월을 확인한 후 다시 시도해 주세요.</translation>
 <translation id="558420943003240152">비밀번호 및 패스키 관리…</translation>
 <translation id="5586446728396275693">저장된 주소 없음</translation>
+<translation id="5586831831248371458"><ph name="KEYWORD_SUFFIX" /> 검색</translation>
 <translation id="5587987780934666589">플랫폼 사용자</translation>
 <translation id="5593349413089863479">연결 보안이 완벽하지 않음</translation>
 <translation id="5595485650161345191">주소 수정</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">가상 카드 추가</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> 여는 중…</translation>
+<translation id="5947508410139465809">업로드 또는 첨부한 파일은 분석을 위해 Google Cloud 또는 서드 파티로 전송됩니다. 예를 들어 파일에 민감한 정보 또는 멀웨어가 있는지 검사하며 회사 정책에 따라 파일을 저장할 수도 있습니다.</translation>
 <translation id="5951495562196540101">일반 계정으로 등록할 수 없습니다(패키지 라이선스 사용 가능).</translation>
 <translation id="5953516610448771166">이 미디어에서는 실시간 자막을 사용할 수 없습니다. 자막을 이용하려면 사이트에서 <ph name="CONTENT_SETTINGS" /> 항목을 차단하세요.</translation>
 <translation id="5955063559762970069">호텔 및 숙박</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">이 사이트는 보안 연결(HTTPS)이 사용되지 않았습니다.</translation>
 <translation id="6180316780098470077">재시도 간격</translation>
 <translation id="61877208875190028">여성 의류</translation>
+<translation id="6194209731893739467">추적 중인 모든 제품을 여기에서 확인</translation>
 <translation id="6195371403461054755">지질학</translation>
 <translation id="6196640612572343990">타사 쿠키 차단</translation>
 <translation id="6203231073485539293">인터넷 연결을 확인하세요.</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{지금 기기가 다시 시작됩니다}=1{1초 후에 기기가 다시 시작됩니다}other{#초 후에 기기가 다시 시작됩니다}}</translation>
+<translation id="6301104306974789820">가격 추적 알림 받기</translation>
 <translation id="6302269476990306341">Chrome의 Google 어시스턴트 중지하는 중</translation>
 <translation id="6305205051461490394"><ph name="URL" />에 연결할 수 없습니다.</translation>
 <translation id="6311165245110979290">가상 카드 사용 가능</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">양식 다시 제출 확인</translation>
 <translation id="6456955391422100996">광고가 삭제되었습니다.</translation>
 <translation id="6457206614190510200">새들 스티치</translation>
+<translation id="6457455098507772300">가격 인하 알림이 바탕화면에 팝업 알림으로 표시됩니다.</translation>
 <translation id="6458606150257356946">무시하고 붙여넣기</translation>
 <translation id="6464094930452079790">이미지</translation>
 <translation id="6465306955648956876">비밀번호 관리...</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">삭제</translation>
 <translation id="6645291930348198241">쿠키 및 사이트 데이터에 액세스합니다.</translation>
+<translation id="6645478838938543427">가격 인하 알림이 <ph name="EMAIL_ADDRESS" /> 주소로 전송됩니다.</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{없음}=1{사이트 1개(Google 계정에서 로그아웃되지 않음)}other{사이트 #개(Google 계정에서 로그아웃되지 않음)}}</translation>
 <translation id="6648459603387803038">관리자가 원격으로 브라우저 설정을 변경할 수 있습니다. 이 기기의 활동은 Chrome 외부에서도 관리할 수 있습니다.</translation>
 <translation id="6648524591329069940">Serif 체</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">설정된 정책 없음</translation>
 <translation id="7186367841673660872">이 페이지는<ph name="ORIGINAL_LANGUAGE" />에서<ph name="LANGUAGE_LANGUAGE" />로 번역되었습니다.</translation>
 <translation id="718872491229180389">치어리딩</translation>
+<translation id="7192188280913829296">'vendor_id' 속성도 지정해야 합니다.</translation>
 <translation id="7192203810768312527"><ph name="SIZE" />의 저장용량을 확보합니다. 일부 사이트는 다음에 방문할 때 로드 속도가 느려질 수도 있습니다.</translation>
 <translation id="7193661028827781021">참조 문헌</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_lo.xtb b/components/strings/components_strings_lo.xtb
index 3af4268..bb15084 100644
--- a/components/strings/components_strings_lo.xtb
+++ b/components/strings/components_strings_lo.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">ການປົດລັອກອຸປະກອນ</translation>
 <translation id="1269516672602708785">ສ້າງເວັບໄຊໃໝ່ໃນ Google Sites ໄດ້ຢ່າງວ່ອງໄວ</translation>
 <translation id="1270502636509132238">ວິທີການຮັບເຄື່ອງ</translation>
+<translation id="1273592791152866347">ປິດການຕິດຕາມລາຄາແລ້ວ</translation>
 <translation id="1281476433249504884">ສະແຕັກເກີ້ 1</translation>
 <translation id="1285320974508926690">ຢ່າແປເວັບ​ໄຊ​ທ໌ນີ້</translation>
 <translation id="1288548991597756084">ບັນທຶກບັດໄວ້ຢ່າງປອດໄພ</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">ໂປຣແກຣມຟຣີ ແລະ ທົດລອງໃຊ້</translation>
 <translation id="1553358976309200471">ອັບ​ເດດ Chrome</translation>
+<translation id="1554003749331233619">ຕອນນີ້ທ່ານກຳລັງຕິດຕາມສິນຄ້ານີ້ແລ້ວ. ໜ້ານີ້ຖືກບັນທຶກໄວ້ໃນ <ph name="LAST_BOOKMARKS_FOLDER" /> ແລ້ວ</translation>
 <translation id="1555130319947370107">ສີ​ຟ້າ</translation>
 <translation id="1559447966090556585">ຮັບການແຈ້ງເຕືອນບໍ?</translation>
 <translation id="1559528461873125649">ບໍ່ມີໄຟລ໌ ຫຼືໄດເຣັກຕໍຣີດັ່ງກ່າວ</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">ຈັດການບັນຊີ Google, ກົດ Enter ເພື່ອຈັດການຂໍ້ມູນ, ຄວາມເປັນສ່ວນຕົວ ແລະ ຄວາມປອດໄພຂອງທ່ານໃນບັນຊີ Google ທ່ານ</translation>
 <translation id="2436186046335138073">ອະນຸຍາດໃຫ້ <ph name="HANDLER_HOSTNAME" /> ເປີດທຸກລິ້ງ <ph name="PROTOCOL" /> ບໍ?</translation>
 <translation id="2438874542388153331">ເຈາະຮູຢູ່ເບື້ອງຂວາສີ່ຮູ</translation>
+<translation id="2443309680964448806">ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ຍັງບໍ່ໄດ້ບັນທຶກການປ່ຽນແປງຂອງທ່ານເທື່ອ.</translation>
 <translation id="2448295565072560657">ມີການເຊື່ອມຕໍ່ອຸປະກອນຕໍ່ພ່ວງເຂົ້າກັບອຸປະກອນນີ້ໃນລະຫວ່າງທີ່ທ່ານຢູ່ໃນລະບົບ</translation>
 <translation id="2450021089947420533">ບັນທຶກ</translation>
 <translation id="2463739503403862330">ຕື່ມຂໍ້ມູນ</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">ຮູ້ເມື່ອທ່ານກຳລັງໃຊ້ອຸປະກອນນີ້ຢູ່</translation>
 <translation id="3180358318770512945">ການລ້ຽງດູ</translation>
 <translation id="3187306450550410410">ການຈັດກຽມງານທີ່ຍືດຍຸ່ນ</translation>
+<translation id="3190736958609431397">ເຊົາຕິດຕາມ</translation>
 <translation id="319282854780294203">ເຄືອຂ່າຍສັງຄົມ</translation>
 <translation id="3194737229810486521"><ph name="URL" /> ຕ້ອງການເກັບຂໍ້ມູນໄວ້ໃນອຸປະກອນຂອງທ່ານຢ່າງຖາວອນ</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> ໃນ <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">ວິທີການຈ່າຍເງິນ</translation>
 <translation id="3391030046425686457">ທີ່ຢູ່ການຈັດສົ່ງ</translation>
 <translation id="3391482648489541560">ການແກ້ໄຂໄຟລ໌</translation>
+<translation id="3392028486601120379">ຮູບແບບ URL "<ph name="URL_PATTERN" />" ມີເສັ້ນທາງທີ່ລະບຸໄວ້. ບໍ່ຮອງຮັບເສັ້ນທາງສຳລັບກະແຈນີ້, ກະລຸນາລຶບເສັ້ນທາງອອກແລ້ວລອງໃໝ່. ຕ.ຢ. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">ວິທີການຮັບເຄື່ອງ</translation>
 <translation id="3399952811970034796">ທີ່ຢູ່ການຈັດສົ່ງ</translation>
 <translation id="3402261774528610252">ການເຊື່ອມຕໍ່ທີ່ໃຊ້ເພື່ອໂຫຼດເວັບໄຊນີ້ໃຊ້ TLS 1.0 ຫຼື TLS 1.1, ເຊິ່ງເຊົາຮອງຮັບແລ້ວ ແລະ ຈະຖືກປິດການນຳໃຊ້ໃນອະນາຄົດ. ເມື່ອປິດການນຳໃຊ້ແລ້ວ, ລະບົບຈະປ້ອງກັນບໍ່ໃຫ້ຜູ້ໃຊ້ໂຫຼດເວັບໄຊນີ້. ເຊີບເວີຄວນເປີດການນຳໃຊ້ TLS 1.2 ຫຼື ໃໝ່ກວ່າ.</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">ບັນທຶກໄປໃສ່ບັນຊີ Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">ແອັບພລິເຄຊັນ:</translation>
+<translation id="3647286794400715637">ສະຕຣິງ URL ແຕ່ລະອັນຕ້ອງມີ URL ຈຳນວນ 1 ຫາ 2 ອັນ.</translation>
 <translation id="3650584904733503804">ການຮັບຮອງສໍາ​ເລັດ</translation>
 <translation id="3653033846669030038">ສວນສະໜຸກ</translation>
 <translation id="3655241534245626312">ໄປຫາການຕັ້ງຄ່າການອະນຸຍາດ</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">ໂປຣແກຣມທ່ອງເວັບຂອງທ່ານຖືກຈັດການໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ.</translation>
 <translation id="3740319564441798148">ລົດເມ ແລະ ລົດໄຟທາງໄກ</translation>
 <translation id="3744111561329211289">ການຊິ້ງຂໍ້ມູນໃນພື້ນຫຼັງ</translation>
+<translation id="3744286742364977428">ໄຟລ໌ທີ່ທ່ານດາວໂຫຼດຈະຖືກສົ່ງໃຫ້ Google Cloud ຫຼື ພາກສ່ວນທີສາມເພື່ອວິເຄາະ. ຕົວຢ່າງ: ພວກມັນອາດຖືກສະແກນເພື່ອຊອກຫາຂໍ້ມູນທີ່ລະອຽດອ່ອນ ຫຼື ເມົາແວ ແລະ ອາດຖືກຈັດເກັບໄວ້ໂດຍອ້າງອີງໃສ່ນະໂຍບາຍບໍລິສັດ.</translation>
 <translation id="3744899669254331632">ທ່ານ​ບໍ່​ສາ​ມາດ​ເຂົ້າ​ເບິ່ງ <ph name="SITE" /> ໄດ້​ດຽວ​ນີ້ ເພາະ​ວ່າ​ເວັບ​ໄຊ​ທ໌​ສົ່ງ​​ໃບຢັ້ງ​ຢືນທີ່​ຖືກ​ລົບ​ກວນ​ທີ່ Chromium ບໍ່​ສາ​ມາດ​ດຳ​ເນີນ​ການ​ໄດ້​ແລ້ວ. ປົກ​ກະ​ຕິນັ້ນ ຄວາມ​ຜິດ​ພາດ ແລະ​ການ​ໂຈມ​ຕີ​ເຄືອ​ຂ່າຍ​ຈະ​ມີ​ຊົ່ວ​ຄາວ, ດັ່ງ​ນັ້ນ ໜ້າ​ນີ້​ອາດ​ຈະ​ເຮັດ​ວຽກ​ໄດ້​ພາຍ​ຫຼັງ.</translation>
 <translation id="3745099705178523657">ຫຼັງຈາກທີ່ທ່ານຢືນຢັນ, ລະບົບຈະແບ່ງປັນລາຍລະອຽດບັດຈາກບັນຊີ Google ຂອງທ່ານກັບເວັບໄຊນີ້.</translation>
 <translation id="3748148204939282805">ຜູ້ໂຈມຕີໃນ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ອາດຈະຫຼອກໃຫ້ທ່ານເຮັດບາງຢ່າງທີ່ອັນຕະລາຍ ເຊັ່ນວ່າ ຕິດຕັ້ງຊອບແວ ຫຼື ເປີດເຜີຍຂໍ້ມູນສ່ວນຕົວຂອງທ່ານ (ຕົວຢ່າງ: ລະຫັດຜ່ານ, ເບີໂທລະສັບ ຫຼື ບັດເຄຣດິດ). <ph name="BEGIN_LEARN_MORE_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">ປຸ່ມສ້າງນັດໝາຍ, ກົດ Enter ເພື່ອສ້າງນັດໝາຍໃໝ່ໃນ Google ປະຕິທິນໄດ້ຢ່າງວ່ອງໄວ</translation>
 <translation id="4088981014127559358">ປ່ຽນຕຳແໜ່ງຮູບພາບດ້ານ 1 ຕາມແກນ Y</translation>
 <translation id="4089152113577680600">ຖາດ 14</translation>
+<translation id="4097288585054919042">ປິດການແຈ້ງເຕືອນ</translation>
 <translation id="4098354747657067197">ເວັບ​ໄຊ​ທ໌​ຫຼອກ​ລວງ​ຢູ່​ຂ້າງ​ໜ້າ</translation>
 <translation id="4099048595830172239">ນະໂຍບາຍຜູ້ເບິ່ງແຍງລະບົບບໍ່ແນະນຳໃຫ້ແບ່ງປັນໜ້າຈໍຂອງທ່ານກັບ <ph name="APPLICATION_TITLE" /> ເມື່ອປາກົດມີເນື້ອຫາທີ່ເປັນຄວາມລັບ:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, ກົດ tab ຈາກນັ້ນກົດ Enter ເພື່ອປັບແຕ່ງຂະໜາດຟອນ ແລະ ແບບອັກສອນໃນ Chrome</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">ປິດໃຊ້ງານແລ້ວ</translation>
 <translation id="4176535426287761656">ທີ່ພັກແບບແບ່ງເວລາ ແລະ ລາພັກ</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">ເຊົາຕິດຕາມລາຄາ</translation>
 <translation id="4194250254487269611">ຂໍອະໄພ, ບໍ່ສາມາດບັນທຶກບັດຂອງທ່ານໄວ້ໄດ້ໃນຕອນນີ້</translation>
 <translation id="4196861286325780578">ເຮັດຄືນຄໍາສັ່ງຍ້າຍ</translation>
 <translation id="4202554117186904723">ມ້ວນທີຫ້າ</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">ເລີ່ມຕົ້ນອຸປະກອນຂອງທ່ານໃໝ່</translation>
 <translation id="4277028893293644418">ຣີເຊັດລະຫັດຜ່ານ</translation>
 <translation id="4278390842282768270">ອະນຸຍາດແລ້ວ</translation>
+<translation id="4282346679996504092">ການແຈ້ງເຕືອນສຳລັບສິນຄ້ານີ້ໄດ້ຖືກປິດໄວ້ແລ້ວ ແລະ ລຶບບຸກມາກອອກແລ້ວ</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{ບັນທຶກບັດນີ້ໄວ້ໃນບັນຊີ Google ຂອງທ່ານແລ້ວ}other{ບັນທຶກບັດເຫຼົ່ານີ້ໄວ້ໃນບັນຊີ Google ຂອງທ່ານແລ້ວ}}</translation>
 <translation id="4287885627794386150">ມີສິດສຳລັບການທົດລອງໃຊ້ແຕ່ບໍ່ໄດ້ເປີດໃຊ້</translation>
 <translation id="4297502707443874121">ຮູບຕົວຢ່າງສຳລັບໜ້າ <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">ແມ່ແບບທີ່ທ່ານລະບຸອາດຈະນຳໃຊ້ບໍ່ໄດ້ຍ້ອນມີຂໍ້ຜິດພາດກັບນະໂຍບາຍ DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">ຈັດການວິທີການຈ່າຍເງິນ...</translation>
 <translation id="4359160567981085931">ທ່ານຫາກໍປ້ອນລະຫັດຜ່ານຂອງທ່ານໃສ່ເວັບໄຊຫຼອກລວງ. Chrome ສາມາດຊ່ວຍໄດ້. ເພື່ອປ່ຽນລະຫັດຜ່ານຂອງທ່ານ ແລະ ແຈ້ງບອກ Google ວ່າບັນຊີຂອງທ່ານອາດຈະມີຄວາມສ່ຽງ, ກະລຸນາຄລິກປົກປ້ອງບັນຊີ.</translation>
+<translation id="4363222835916186793">ການແຈ້ງເຕືອນສຳລັບສິນຄ້ານີ້ໄດ້ຖືກປິດໄວ້ແລ້ວ</translation>
 <translation id="4367563149485757821">Number-12 (ຊອງຈົດໝາຍ)</translation>
 <translation id="437040971055499437">ມີເຫດການຄວາມປອດໄພເກີດຂຶ້ນ</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">ຂໍມູນທີ່ທ່ານຈະສົ່ງບໍ່ປອດໄພ</translation>
 <translation id="4796594887379589189">ID ບັນຊີວຽກ</translation>
 <translation id="4798078619018708837">ປ້ອນວັນທີໝົດອາຍຸ ແລະ CVC ສຳລັບ <ph name="CREDIT_CARD" /> ເພື່ອອັບເດດລາຍລະອຽດບັດຂອງທ່ານ. ຫຼັງຈາກທີ່ທ່ານຢືນຢັນ, ລະບົບຈະແບ່ງປັນລາຍລະອຽດບັດຈາກບັນຊີ Google ຂອງທ່ານກັບເວັບໄຊນີ້.</translation>
+<translation id="4798269756263412078">ຮັບການແຈ້ງເຕືອນຫາກມີການຫຼຸດລາຄາຢູ່ເວັບໄຊໃດກໍຕາມ. ການແຈ້ງເຕືອນຈະຖືກສົ່ງໄປຫາອີເມວຂອງທ່ານ.</translation>
 <translation id="4800132727771399293">ກວດ​ເບິ່ງວັນ​ໝົດ​ອາ​ຍຸ ແລະ CVC ຂອງ​ທ່ານ ແລະ​ລອງ​ໃໝ່​ອີກ</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">ໃຊ້ TouchID</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">ຫຍິບຂອບເບື້ອງຂວາ</translation>
 <translation id="5398772614898833570">ບລັອກໂຄສະນາໄວ້ແລ້ວ</translation>
 <translation id="5400836586163650660">ສີເທົາ</translation>
+<translation id="540630185148148480">ເປີດໃຊ້ການແຈ້ງເຕືອນ</translation>
 <translation id="540969355065856584">ເຊີບເວີນີ້ບໍ່ສາມາດພິສູດໄດ້ວ່າ ມັນແມ່ນ <ph name="DOMAIN" />; ໃບຢັ້ງຢືນຄວາມປອດໄພຂອງມັນໃຊ້​ບໍ່​ໄດ້​ໃນ​ເວ​ລາ​ນີ້. ອັນນີ້ອາດຈະເຮັດໃຫ້ເກີດມີການປັບຕັ້ງຄ່າຜິດ ຫຼືຜູ້ໂຈມຕີອາດຈະດັກເອົາການເຊື່ອມຕໍ່ຂອງທ່ານ.</translation>
 <translation id="5412040515238827314">ຮູບແບບບໍ່ຖືກຕ້ອງ: ຕ້ອງການລາຍຊື່ຮູບແບບ.</translation>
 <translation id="5412236728747081950">ເວັບໄຊນີ້ໄດ້ຮັບຄວາມສົນໃຈຂອງທ່ານຈາກ Chrome ເພື່ອສະແດງໂຄສະນາທີ່ກ່ຽວຂ້ອງຫຼາຍຂຶ້ນໃຫ້ທ່ານເຫັນ</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">ກວດເບິ່ງເດືອນໝົດອາຍຸຂອງທ່ານ ແລະ ລອງອີກຄັ້ງ</translation>
 <translation id="558420943003240152">ຈັດການລະຫັດຜ່ານ ແລະ ກະແຈຜ່ານ…</translation>
 <translation id="5586446728396275693">ບໍ່ມີທີ່ຢູ່ທີ່ບັນທຶກໄວ້</translation>
+<translation id="5586831831248371458">ຊອກຫາ <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">ຜູ້ໃຊ້ແພລດຟອມ</translation>
 <translation id="5593349413089863479">ການເຊື່ອມຕໍ່ບໍ່ປອດໄພສົມບູນ</translation>
 <translation id="5595485650161345191">ແກ້ໄຂທີ່ຢູ່</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">ເພີ່ມບັດສະເໝືອນ</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">ກຳລັງເປີດ <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">ໄຟລ໌ທີ່ທ່ານອັບໂຫຼດ ຫຼື ແນບຈະຖືກສົ່ງໃຫ້ Google Cloud ຫຼື ພາກສ່ວນທີສາມເພື່ອວິເຄາະ. ຕົວຢ່າງ: ພວກມັນອາດຖືກສະແກນເພື່ອຊອກຫາຂໍ້ມູນທີ່ລະອຽດອ່ອນ ຫຼື ເມົາແວ ແລະ ອາດຖືກຈັດເກັບໄວ້ໂດຍອ້າງອີງໃສ່ນະໂຍບາຍບໍລິສັດ.</translation>
 <translation id="5951495562196540101">ບໍ່ສາມາດລົງທະບຽນດ້ວຍບັນຊີຜູ້ຊົມໃຊ້ໄດ້ (ມີໃບອະນຸຍາດແບບແພັກເກດ).</translation>
 <translation id="5953516610448771166">ບໍ່ສາມາດໃຊ້ຄຳບັນຍາຍສົດສຳລັບມີເດຍນີ້ໄດ້. ເພື່ອຮັບຄຳບັນຍາຍ, ໃຫ້ບລັອກ <ph name="CONTENT_SETTINGS" /> ສຳລັບເວັບໄຊນີ້.</translation>
 <translation id="5955063559762970069">ໂຮງແຮມ ແລະ ບ່ອນພັກເຊົາ</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">ການເຊື່ອມຕໍ່ຂອງທ່ານກັບເວັບໄຊນີ້ບໍ່ປອດໄພ</translation>
 <translation id="6180316780098470077">ຊ່ວງຫ່າງລະຫວ່າງການລອງໃໝ່ແຕ່ລະຄັ້ງ</translation>
 <translation id="61877208875190028">ເສື້ອຜ້າຜູ້ຍິງ</translation>
+<translation id="6194209731893739467">ເບິ່ງສິນຄ້າທີ່ທ່ານຕິດຕາມທັງໝົດຢູ່ບ່ອນນີ້</translation>
 <translation id="6195371403461054755">ທໍ​ລະ​ນີ​ສາດ</translation>
 <translation id="6196640612572343990">ບລັອກຄຸກກີ້ພາກສ່ວນທີສາມ</translation>
 <translation id="6203231073485539293">ກວດເບິ່ງການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງທ່ານ.</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{ຕອນນີ້ຈະຣີສະຕາດອຸປະກອນຂອງທ່ານແລ້ວ}=1{ອຸປະກອນຂອງທ່ານຈະຣີສະຕາດໃນ 1 ວິນາທີ}other{ອຸປະກອນຂອງທ່ານຈະຣີສະຕາດໃນ # ວິນາທີ}}</translation>
+<translation id="6301104306974789820">ຮັບການແຈ້ງເຕືອນການຕິດຕາມລາຄາ</translation>
 <translation id="6302269476990306341">ກຳລັງຢຸດຜູ້ຊ່ວຍ Google ໃນ Chrome</translation>
 <translation id="6305205051461490394"><ph name="URL" /> ບໍ່ສາມາດເຂົ້າເຖິງໄດ້</translation>
 <translation id="6311165245110979290">ບັດສະເໝືອນສາມາດໃຊ້ໄດ້</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">ຢືນຢັນການສົ່ງແບບຟອມຄືນໃໝ່</translation>
 <translation id="6456955391422100996">ລຶບໂຄສະນາອອກແລ້ວ.</translation>
 <translation id="6457206614190510200">ຫຍິບທີ່ສັນປຶ້ມ</translation>
+<translation id="6457455098507772300">ການແຈ້ງເຕືອນການຫຼຸດລາຄາຈະສະແດງຂຶ້ນເປັນການແຈ້ງເຕືອນປັອບອັບຢູ່ເດັສທັອບຂອງທ່ານ</translation>
 <translation id="6458606150257356946">ແນວໃດກໍວາງໃສ່</translation>
 <translation id="6464094930452079790">ຮູບ</translation>
 <translation id="6465306955648956876">ຈັດການລະຫັດຜ່ານ...</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">ລຶບ</translation>
 <translation id="6645291930348198241">ເຂົ້າເຖິງຄຸກກີ້ ແລະ ຂໍ້ມູນເວັບໄຊ.</translation>
+<translation id="6645478838938543427">ການແຈ້ງເຕືອນການຫຼຸດລາຄາຈະຖືກສົ່ງໄປໃຫ້ <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{ບໍ່ມີ}=1{ຈາກ 1 ເວັບໄຊ (ທ່ານຈະບໍ່ຖືກນຳອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ)}other{ຈາກ # ເວັບໄຊ (ທ່ານຈະບໍ່ຖືກນຳອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ)}}</translation>
 <translation id="6648459603387803038">ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານສາມາດປ່ຽນການຕັ້ງຄ່າໂປຣແກຣມທ່ອງເວັບຂອງທ່ານຈາກທາງໄກໄດ້. ການເຄື່ອນໄຫວໃນອຸປະກອນນີ້ອາດຈະຖືກຈັດການຢູ່ນອກ Chrome ໄດ້ເຊັ່ນກັນ.</translation>
 <translation id="6648524591329069940">ຟອນ Serif</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">ບໍ່ມີນະໂຍບາຍໃດຖືກຕັ້ງ</translation>
 <translation id="7186367841673660872">ໜ້ານີ້ຖືກໂອນຈາກ<ph name="ORIGINAL_LANGUAGE" />ຫາ<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">ເຊຍລີດເດີ</translation>
+<translation id="7192188280913829296">ຈະຕ້ອງລະບຸຄຸນສົມບັດ "vendor_id" ນຳ.</translation>
 <translation id="7192203810768312527">ຂະຫຍາຍ <ph name="SIZE" />. ບາງເວັບໄຊອາດຈະໂຫຼດຊ້າກວ່າໃນຄັ້ງຕໍ່ໄປທີ່ທ່ານເຂົ້າເບິ່ງ.</translation>
 <translation id="7193661028827781021">ການອ້າງອີງ</translation>
 <translation id="719464814642662924">ວີ​ຊາ</translation>
diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb
index a72b89a..3522d803 100644
--- a/components/strings/components_strings_lt.xtb
+++ b/components/strings/components_strings_lt.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Įrenginio atrakinimo funkcija</translation>
 <translation id="1269516672602708785">Greitai sukurkite naują svetainę „Google“ svetainėse</translation>
 <translation id="1270502636509132238">Paėmimo metodas</translation>
+<translation id="1273592791152866347">Kainų stebėjimas išjungtas</translation>
 <translation id="1281476433249504884">1 dėtuvė</translation>
 <translation id="1285320974508926690">Niekada neversti šios svetainės</translation>
 <translation id="1288548991597756084">Patikima kortelės duomenų apsauga</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Programinė įranga be mokesčio ar su laikinu mokesčiu</translation>
 <translation id="1553358976309200471">Atnaujinti „Chrome“</translation>
+<translation id="1554003749331233619">Dabar stebite šį produktą. Šis puslapis išsaugotas aplanke „<ph name="LAST_BOOKMARKS_FOLDER" />“</translation>
 <translation id="1555130319947370107">Mėlyna</translation>
 <translation id="1559447966090556585">Gauti pranešimus?</translation>
 <translation id="1559528461873125649">Nėra tokio failo ar katalogo</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Mygtukas „Tvarkyti „Google“ paskyrą“ – paspauskite klavišą „Enter“, jei norite tvarkyti savo informaciją, privatumo ir saugos nustatymus „Google“ paskyroje</translation>
 <translation id="2436186046335138073">Leisti „<ph name="HANDLER_HOSTNAME" />“ atidaryti visas <ph name="PROTOCOL" /> nuorodas?</translation>
 <translation id="2438874542388153331">Keturios skylės dešinėje</translation>
+<translation id="2443309680964448806">Kažkas ne taip. Pakeitimas neišsaugotas</translation>
 <translation id="2448295565072560657">Kai esate prisijungę, matomi išoriniai įrenginiai</translation>
 <translation id="2450021089947420533">Atlikti veiksmai</translation>
 <translation id="2463739503403862330">Užpildyti</translation>
@@ -820,6 +823,7 @@
 <translation id="317878711435188021">Žinoti, kada aktyviai naudojate šį įrenginį</translation>
 <translation id="3180358318770512945">Vaikų auklėjimas</translation>
 <translation id="3187306450550410410">Lanksčios darbo sąlygos</translation>
+<translation id="3190736958609431397">Nebestebėti</translation>
 <translation id="319282854780294203">Socialiniai tinklai</translation>
 <translation id="3194737229810486521"><ph name="URL" /> prašo leidimo nuolat saugoti duomenis jūsų įrenginyje</translation>
 <translation id="3195213714973468956">„<ph name="PRINTER_NAME" />“ serveryje „<ph name="SERVER_NAME" />“</translation>
@@ -905,6 +909,7 @@
 <translation id="3387261909427947069">Mokėjimo metodai</translation>
 <translation id="3391030046425686457">Pristatymo adresas</translation>
 <translation id="3391482648489541560">failo redagavimas</translation>
+<translation id="3392028486601120379">URL šablone „<ph name="URL_PATTERN" />“ nurodytas kelias. Keliai nepalaikomi naudojant šį raktą, pašalinkite kelią ir bandykite dar kartą, pvz., *://example.com/ =&gt; *://example.com</translation>
 <translation id="3395827396354264108">Paėmimo metodas</translation>
 <translation id="3399952811970034796">Pristatymo adresas</translation>
 <translation id="3402261774528610252">Šiai svetainei įkelti naudojamam ryšiui buvo naudojama 1.0 arba 1.1 versijos TLS, kuri nebenaudojama ir ateityje bus išjungta. Išjungus naudotojai nebegalės įkelti šios svetainės. Serveryje reikia įgalinti 1.2 arba naujesnės versijos TLS.</translation>
@@ -1000,6 +1005,7 @@
 <translation id="3637662659967048211">Išsaugojimas „Google“ paskyroje</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Programa:</translation>
+<translation id="3647286794400715637">Kiekviename URL eilutės įraše turi būti nuo vieno iki dviejų URL.</translation>
 <translation id="3650584904733503804">Tikrinimas sėkmingas</translation>
 <translation id="3653033846669030038">Pramogų parkai</translation>
 <translation id="3655241534245626312">Eiti į leidimo nustatymus</translation>
@@ -1038,6 +1044,7 @@
 <translation id="3738166223076830879">Jūsų naršyklę tvarko jūsų administratorius.</translation>
 <translation id="3740319564441798148">Tarpmiestiniai autobusai ir traukiniai</translation>
 <translation id="3744111561329211289">Fono sinchronizavimas</translation>
+<translation id="3744286742364977428">Failai, kuriuos atsisiunčiate, siunčiami „Google Cloud“ arba trečiosioms šalims, kad būtų atlikta analizė. Pavyzdžiui, jie gali būti nuskaityti tikrinant, ar juose nėra neskelbtinų duomenų arba kenkėjiškų programų, ir saugomi laikantis įmonės politikos nuostatų.</translation>
 <translation id="3744899669254331632">Negalite dabar apsilankyti svetainėje <ph name="SITE" />, nes ji atsiuntė užšifruotus prisijungimo duomenis, kurių „Chromium“ negali apdoroti. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
 <translation id="3745099705178523657">Kai patvirtinsite, „Google“ paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolikai gali bandyti apgaule priversti jus atlikti pavojingus veiksmus, pvz., įdiegti programinę įrangą ar atskleisti asmens informaciją (pvz., slaptažodžius, telefonų numerius ar kredito kortelių duomenis). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1145,6 +1152,7 @@
 <translation id="4087296516249690906">Mygtukas „Sukurti įvykį“ – paspauskite klavišą „Enter“, jei norite greitai sukurti naują „Google“ kalendoriaus įvykį</translation>
 <translation id="4088981014127559358">1 pusė: sukti vaizdą pagal Y ašį</translation>
 <translation id="4089152113577680600">Keturioliktas dėklas</translation>
+<translation id="4097288585054919042">Išjungti įspėjimus</translation>
 <translation id="4098354747657067197">Ketinate apsilankyti apgaulingoje svetainėje</translation>
 <translation id="4099048595830172239">Pagal administratoriaus politiką nerekomenduojama bendrinti ekrano su <ph name="APPLICATION_TITLE" />, kai matomas konfidencialus turinys.</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, paspauskite tabuliavimo klavišą, tada – „Enter“, kad galėtumėte tinkinti šriftų dydį ir šriftų šeimas naršyklėje „Chrome“.</translation>
@@ -1181,6 +1189,7 @@
 <translation id="4176463684765177261">Išjungta</translation>
 <translation id="4176535426287761656">Pakaitinio naudojimo ir atostogų būstai</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Nebestebėti kainų</translation>
 <translation id="4194250254487269611">Šiuo metu jūsų kortelės išsaugoti negalima</translation>
 <translation id="4196861286325780578">&amp;Perkelti dar kartą</translation>
 <translation id="4202554117186904723">Penktas ritinėlis</translation>
@@ -1227,6 +1236,7 @@
 <translation id="4275830172053184480">Iš naujo paleisti įrenginį</translation>
 <translation id="4277028893293644418">Iš naujo nustatyti slaptažodį</translation>
 <translation id="4278390842282768270">Leidžiama</translation>
+<translation id="4282346679996504092">Šio produkto įspėjimai išjungti ir žymė pašalinta</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Ši kortelė išsaugota jūsų „Google“ paskyroje}one{Šios kortelės išsaugotos jūsų „Google“ paskyroje}few{Šios kortelės išsaugotos jūsų „Google“ paskyroje}many{Šios kortelės išsaugotos jūsų „Google“ paskyroje}other{Šios kortelės išsaugotos jūsų „Google“ paskyroje}}</translation>
 <translation id="4287885627794386150">Galima naudoti bandomąją versiją, bet ji nėra aktyvi</translation>
 <translation id="4297502707443874121"><ph name="THUMBNAIL_PAGE" /> puslapio miniatiūra</translation>
@@ -1265,6 +1275,7 @@
 <translation id="4358059973562876591">Jūsų nurodyti šablonai gali būti netaikomi dėl klaidos, susijusios su „DnsOverHttpsMode“ politika.</translation>
 <translation id="4358461427845829800">Tvarkyti mokėjimo metodus...</translation>
 <translation id="4359160567981085931">Ką tik savo slaptažodį įvedėte apgaulingoje svetainėje. „Chrome“ gali padėti. Norėdami pakeisti slaptažodį ir pranešti „Google“, kad jūsų paskyrai gali grėsti pavojus, spustelėkite „Apsaugoti paskyrą“.</translation>
+<translation id="4363222835916186793">Šio produkto įspėjimai išjungti</translation>
 <translation id="4367563149485757821">„Number-12“ (vokas)</translation>
 <translation id="437040971055499437">Įvyksta saugos įvykis</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1417,6 +1428,7 @@
 <translation id="4792686369684665359">Informacija, kurią ketinate pateikti, nesaugi</translation>
 <translation id="4796594887379589189">Užduoties paskyros ID</translation>
 <translation id="4798078619018708837">Jei norite atnaujinti išsamią kortelės informaciją, įveskite „<ph name="CREDIT_CARD" />“ galiojimo laiko pabaigos datą ir kortelės saugos kodą (CVC). Kai patvirtinsite, „Google“ paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
+<translation id="4798269756263412078">Gaukite įspėjimus, jei kaina bus sumažinta bet kurioje svetainėje. Įspėjimai bus siunčiami jūsų el. pašto adresu.</translation>
 <translation id="4800132727771399293">Patikrinkite kortelės galiojimo pabaigos datą bei saugos kodą (CVC) ir bandykite dar kart</translation>
 <translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
 <translation id="4806051791961048632">Naudoti „Touch ID“</translation>
@@ -1660,6 +1672,7 @@
 <translation id="5396631636586785122">Kraštų sukabinimas dešinėje</translation>
 <translation id="5398772614898833570">Skelbimai užblokuoti</translation>
 <translation id="5400836586163650660">Pilka spalva</translation>
+<translation id="540630185148148480">Įjungti įspėjimus</translation>
 <translation id="540969355065856584">Šiam serveriui nepavyko patvirtinti, kad jis yra <ph name="DOMAIN" />; šiuo metu jo saugos sertifikatas negalioja. Tai gali būti dėl netinkamos konfigūracijos arba dėl ryšį pertraukusio užgrobėjo.</translation>
 <translation id="5412040515238827314">Netinkamas formatas: numatytas šablonų sąrašas.</translation>
 <translation id="5412236728747081950">Ši svetainė gauna informaciją apie jūsų pomėgius iš „Chrome“, kad galėtų rodyti jums aktualesnius skelbimus</translation>
@@ -1724,6 +1737,7 @@
 <translation id="5580958916614886209">Patikrinkite galiojimo pabaigos mėnesį ir bandykite dar kartą</translation>
 <translation id="558420943003240152">Tvarkyti slaptažodžius…</translation>
 <translation id="5586446728396275693">Nėra išsaugotų adresų</translation>
+<translation id="5586831831248371458">Ieškoti „<ph name="KEYWORD_SUFFIX" />“</translation>
 <translation id="5587987780934666589">Platformos naudotojas</translation>
 <translation id="5593349413089863479">Ryšys nevisiškai saugus</translation>
 <translation id="5595485650161345191">Adreso redagavimas</translation>
@@ -1843,6 +1857,7 @@
 <translation id="5938153366081463283">Pridėkite virtualią kortelę</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Atidaroma „<ph name="SITE_NAME" />“…</translation>
+<translation id="5947508410139465809">Failai, kuriuos įkeliate ar pridedate, siunčiami „Google Cloud“ arba trečiosioms šalims, kad būtų atlikta analizė. Pavyzdžiui, jie gali būti nuskaityti tikrinant, ar juose nėra neskelbtinų duomenų arba kenkėjiškų programų, ir saugomi laikantis įmonės politikos nuostatų.</translation>
 <translation id="5951495562196540101">Nepavyko prisiregistruoti su kliento paskyra (galima įsigyti licencijos paketą).</translation>
 <translation id="5953516610448771166">Subtitrų realiuoju laiku funkcija šioje medijoje nepasiekiama. Jei norite gauti subtitrų, užblokuokite šios svetainės <ph name="CONTENT_SETTINGS" />.</translation>
 <translation id="5955063559762970069">Viešbučiai ir apgyvendinimas</translation>
@@ -1931,6 +1946,7 @@
 <translation id="6177128806592000436">Ryšys su šia svetaine nėra saugus</translation>
 <translation id="6180316780098470077">Pakartotinio bandymo intervalas</translation>
 <translation id="61877208875190028">Moterų apranga</translation>
+<translation id="6194209731893739467">Peržiūrėkite visus stebimus produktus čia</translation>
 <translation id="6195371403461054755">Geologija</translation>
 <translation id="6196640612572343990">Blokuoti trečiosios šalies slapukus</translation>
 <translation id="6203231073485539293">Patikrinkite interneto ryšį</translation>
@@ -1966,6 +1982,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">Kortelės patvirtinimo kodas CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Jūsų įrenginys dabar bus paleistas iš naujo}=1{Jūsų įrenginys bus paleistas iš naujo po vienos sekundės}one{Jūsų įrenginys bus paleistas iš naujo po # sekundės}few{Jūsų įrenginys bus paleistas iš naujo po # sekundžių}many{Jūsų įrenginys bus paleistas iš naujo po # sekundės}other{Jūsų įrenginys bus paleistas iš naujo po # sekundžių}}</translation>
+<translation id="6301104306974789820">Gaukite kainų stebėjimo pranešimus</translation>
 <translation id="6302269476990306341">„Google“ padėjėjas sistemoje „Chrome“ sustabdomas</translation>
 <translation id="6305205051461490394"><ph name="URL" /> nepasiekiama.</translation>
 <translation id="6311165245110979290">Pasiekiama virtuali kortelė</translation>
@@ -2025,6 +2042,7 @@
 <translation id="6451458296329894277">Patvirtinkite pakartotiną formos pateikimą</translation>
 <translation id="6456955391422100996">Skelbimas pašalintas.</translation>
 <translation id="6457206614190510200">Sukabinimas perlenkimo vietoje</translation>
+<translation id="6457455098507772300">Įspėjimai apie sumažintas kainas rodomi kaip iššokančiojo lango pranešimai staliniame kompiuteryje</translation>
 <translation id="6458606150257356946">Vis tiek įklijuoti</translation>
 <translation id="6464094930452079790">vaizdai</translation>
 <translation id="6465306955648956876">Tvarkyti slaptažodžius...</translation>
@@ -2082,6 +2100,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Išvalyti</translation>
 <translation id="6645291930348198241">Pasiekti slapukus ir svetainės duomenis.</translation>
+<translation id="6645478838938543427">Įspėjimai apie sumažintas kainas bus siunčiami adresu <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Nėra}=1{Iš 1 svetainės (nebūsite atjungti nuo „Google“ paskyros)}one{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}few{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}many{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}other{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}}</translation>
 <translation id="6648459603387803038">Administratorius gali nuotoliniu būdu keisti naršyklės sąranką. Veiklą šiame įrenginyje taip pat galima tvarkyti ne naršyklėje „Chrome“.</translation>
 <translation id="6648524591329069940">Šriftas „Serif“</translation>
@@ -2275,6 +2294,7 @@
 <translation id="7182878459783632708">Nenustatyta jokia politika</translation>
 <translation id="7186367841673660872">Šis puslapis išverstas iš<ph name="ORIGINAL_LANGUAGE" />į<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Komandų palaikymas</translation>
+<translation id="7192188280913829296">Taip pat reikia nurodyti atributą „vendor_id“.</translation>
 <translation id="7192203810768312527">Atlaisvina <ph name="SIZE" />. Per kitą jūsų apsilankymą kai kurios svetainės gali būti įkeliamos lėčiau.</translation>
 <translation id="7193661028827781021">Žinių šaltiniai</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb
index 09363bc3..9eac47f7 100644
--- a/components/strings/components_strings_ms.xtb
+++ b/components/strings/components_strings_ms.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Buka kunci peranti</translation>
 <translation id="1269516672602708785">Buat laman baharu dalam Google Sites dengan pantas</translation>
 <translation id="1270502636509132238">Kaedah Pengambilan</translation>
+<translation id="1273592791152866347">Penjejakan harga dimatikan</translation>
 <translation id="1281476433249504884">Petak 1</translation>
 <translation id="1285320974508926690">Jangan sekali-kali menterjemahkan tapak ini</translation>
 <translation id="1288548991597756084">Simpan kad dengan selamat</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Kejuruteraan-D</translation>
 <translation id="1551884710160394169">Perisian percuma &amp; perisian kongsi</translation>
 <translation id="1553358976309200471">Kemas Kini Chrome</translation>
+<translation id="1554003749331233619">Kini anda menjejaki produk ini. Halaman ini disimpan dalam <ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">Biru</translation>
 <translation id="1559447966090556585">Dapatkan pemberitahuan?</translation>
 <translation id="1559528461873125649">Tiada fail atau direktori sedemikian</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Urus Google Account, tekan kekunci Enter untuk mengurus maklumat, privasi dan keselamatan anda dalam Google Account</translation>
 <translation id="2436186046335138073">Benarkan <ph name="HANDLER_HOSTNAME" /> untuk membuka semua <ph name="PROTOCOL" /> pautan?</translation>
 <translation id="2438874542388153331">Empat tebukan kanan</translation>
+<translation id="2443309680964448806">Ralat telah berlaku. Perubahan anda tidak disimpan.</translation>
 <translation id="2448295565072560657">Persisian yang dilampirkan pada peranti ini semasa anda log masuk</translation>
 <translation id="2450021089947420533">Perjalanan</translation>
 <translation id="2463739503403862330">Isi</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">Mengetahui waktu anda menggunakan peranti ini dengan aktif</translation>
 <translation id="3180358318770512945">Keibubapaan</translation>
 <translation id="3187306450550410410">Aturan kerja fleksibel</translation>
+<translation id="3190736958609431397">Nyahjejak</translation>
 <translation id="319282854780294203">Rangkaian sosial</translation>
 <translation id="3194737229810486521"><ph name="URL" /> mahu menyimpan data pada peranti anda secara kekal</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> pada <ph name="SERVER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">Kaedah Pembayaran</translation>
 <translation id="3391030046425686457">Alamat penghantaran</translation>
 <translation id="3391482648489541560">pengeditan fail</translation>
+<translation id="3392028486601120379">Corak "<ph name="URL_PATTERN" />" URL mempunyai laluan yang ditentukan. Laluan tidak disokong untuk kunci ini, sila alih keluar laluan dan cuba lagi. e.g. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Kaedah pengambilan</translation>
 <translation id="3399952811970034796">Alamat Penghantaran</translation>
 <translation id="3402261774528610252">Sambungan yang digunakan untuk memuatkan tapak ini menggunakan TLS 1.0 atau TLS 1.1, yang telah ditamatkan dan akan dilumpuhkan pada masa hadapan. Apabila dilumpuhkan, pengguna akan dihalang daripada memuatkan tapak ini. Pelayan harus mendayakan TLS 1.2 atau yang lebih baharu.</translation>
@@ -1000,6 +1005,7 @@
 <translation id="3637662659967048211">Simpan pada Akaun Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Aplikasi:</translation>
+<translation id="3647286794400715637">Setiap entri rentetan url mesti mengandungi antara 1 hingga 2 URL.</translation>
 <translation id="3650584904733503804">Pengesahan berjaya</translation>
 <translation id="3653033846669030038">Taman tema</translation>
 <translation id="3655241534245626312">Pergi ke tetapan kebenaran</translation>
@@ -1038,6 +1044,7 @@
 <translation id="3738166223076830879">Penyemak imbas anda diurus oleh pentadbir anda.</translation>
 <translation id="3740319564441798148">Bas &amp; kereta api jarak jauh</translation>
 <translation id="3744111561329211289">Penyegerakan latar belakang</translation>
+<translation id="3744286742364977428">Fail yang anda muat turun dihantar kepada Google Cloud atau pihak ketiga untuk dianalisis. Contohnya, fail itu mungkin diimbas untuk mencari data sensitif atau perisian hasad dan mungkin disimpan berdasarkan dasar syarikat.</translation>
 <translation id="3744899669254331632">Anda tidak boleh melawat <ph name="SITE" /> sekarang kerana laman web telah menghantar bukti kelayakan hancur yang tidak boleh diproses oleh Chromium. Ralat dan serangan rangkaian biasanya sementara. Oleh itu halaman ini mungkin akan berfungsi kemudian.</translation>
 <translation id="3745099705178523657">Setelah anda membuat pengesahan, butiran kad daripada Akaun Google anda akan dikongsi dengan tapak ini.</translation>
 <translation id="3748148204939282805">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin memperdaya anda agar melakukan sesuatu yang berbahaya seperti memasang perisian atau mendedahkan maklumat peribadi anda (contohnya, kata laluan, nombor telefon atau kad kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1145,6 +1152,7 @@
 <translation id="4087296516249690906">Butang buat acara, tekan kekunci Enter untuk membuat acara baharu dalam Google Calendar dengan pantas</translation>
 <translation id="4088981014127559358">Anjakan Y sisi 1 imej</translation>
 <translation id="4089152113577680600">Dulang 14</translation>
+<translation id="4097288585054919042">Matikan makluman</translation>
 <translation id="4098354747657067197">Tapak menipu di hadapan</translation>
 <translation id="4099048595830172239">Dasar pentadbir tidak mengesyorkan anda berkongsi skrin dengan <ph name="APPLICATION_TITLE" /> semasa kandungan sulit kelihatan:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tekan Tab kemudian Enter untuk menyesuaikan saiz fon dan rupa huruf dalam Chrome</translation>
@@ -1181,6 +1189,7 @@
 <translation id="4176463684765177261">Dilumpuhkan</translation>
 <translation id="4176535426287761656">Hartanah kongsi masa &amp; percutian</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Nyahjejak harga</translation>
 <translation id="4194250254487269611">Kad anda tidak dapat disimpan sekarang</translation>
 <translation id="4196861286325780578">&amp;Buat semula pindahkan</translation>
 <translation id="4202554117186904723">Gulungan Kelima</translation>
@@ -1227,6 +1236,7 @@
 <translation id="4275830172053184480">Mulakan semula peranti anda</translation>
 <translation id="4277028893293644418">Tetapkan semula kata laluan</translation>
 <translation id="4278390842282768270">Dibenarkan</translation>
+<translation id="4282346679996504092">Makluman untuk produk ini telah dimatikan dan penanda halaman dialih keluar</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Kad ini telah disimpan ke Akaun Google anda}other{Kad ini telah disimpan ke Akaun Google anda}}</translation>
 <translation id="4287885627794386150">Layak untuk percubaan tetapi tidak aktif</translation>
 <translation id="4297502707443874121">Lakaran kecil untuk halaman <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1265,6 +1275,7 @@
 <translation id="4358059973562876591">Templat yang anda nyatakan tidak dapat digunakan kerana terdapat ralat pada dasar DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Urus kaedah pembayaran...</translation>
 <translation id="4359160567981085931">Anda baru sahaja memasukkan kata laluan anda pada tapak yang menipu. Chrome boleh membantu. Untuk menukar kata laluan anda dan memaklumi Google bahawa akaun anda mungkin berisiko, klik Lindungi Akaun.</translation>
+<translation id="4363222835916186793">Makluman untuk produk ini telah dimatikan</translation>
 <translation id="4367563149485757821">Number-12 (Sampul Surat)</translation>
 <translation id="437040971055499437">Peristiwa keselamatan berlaku</translation>
 <translation id="4372516964750095882">Fanfold-AS</translation>
@@ -1417,6 +1428,7 @@
 <translation id="4792686369684665359">Maklumat yang hendak diserahkan adalah tidak selamat</translation>
 <translation id="4796594887379589189">ID akaun kerja</translation>
 <translation id="4798078619018708837">Masukkan tarikh tamat tempoh dan CVC <ph name="CREDIT_CARD" /> untuk mengemas kini butiran kad anda. Setelah anda mengesahkan maklumat, butiran kad daripada Akaun Google anda akan dikongsi dengan tapak ini.</translation>
+<translation id="4798269756263412078">Dapatkan makluman sekiranya harga jatuh pada mana-mana laman. Makluman akan dihantar ke e-mel anda.</translation>
 <translation id="4800132727771399293">Semak tarikh tamat tempoh serta CVC anda dan cuba lagi</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Gunakan Touch ID</translation>
@@ -1660,6 +1672,7 @@
 <translation id="5396631636586785122">Jahitan tepi kanan</translation>
 <translation id="5398772614898833570">Iklan disekat</translation>
 <translation id="5400836586163650660">Kelabu</translation>
+<translation id="540630185148148480">Hidupkan makluman</translation>
 <translation id="540969355065856584">Pelayan ini tidak dapat membuktikan bahawa pelayan adalah <ph name="DOMAIN" />; sijil keselamatan pelayan tidak sah pada masa ini. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang memintas sambungan anda.</translation>
 <translation id="5412040515238827314">Format tidak sah: Menjangkakan senarai pola.</translation>
 <translation id="5412236728747081950">Laman ini mendapat minat anda daripada Chrome untuk memaparkan iklan yang lebih berkaitan kepada anda</translation>
@@ -1724,6 +1737,7 @@
 <translation id="5580958916614886209">Semak bulan tamat tempoh anda dan cuba lagi</translation>
 <translation id="558420943003240152">Urus kata laluan dan kunci laluan…</translation>
 <translation id="5586446728396275693">Tiada alamat yang disimpan</translation>
+<translation id="5586831831248371458">Cari <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Pengguna platform</translation>
 <translation id="5593349413089863479">Sambungan tidak selamat sepenuhnya</translation>
 <translation id="5595485650161345191">Edit alamat</translation>
@@ -1843,6 +1857,7 @@
 <translation id="5938153366081463283">Tambah kad maya</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Membuka <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">Fail yang anda muat naik atau lampirkan dihantar kepada Google Cloud atau pihak ketiga untuk dianalisis. Contohnya, fail itu mungkin diimbas untuk mencari data sensitif atau perisian hasad dan mungkin disimpan berdasarkan dasar syarikat.</translation>
 <translation id="5951495562196540101">Tidak dapat mendaftar dengan akaun pengguna (lesen berpakej tersedia).</translation>
 <translation id="5953516610448771166">Sari Kata Langsung tidak tersedia untuk media ini. Untuk mendapatkan sari kata, sekat <ph name="CONTENT_SETTINGS" /> untuk laman ini.</translation>
 <translation id="5955063559762970069">Hotel &amp; penginapan</translation>
@@ -1931,6 +1946,7 @@
 <translation id="6177128806592000436">Sambungan anda ke tapak ini tidak selamat</translation>
 <translation id="6180316780098470077">Selang cubaan semula</translation>
 <translation id="61877208875190028">Pakaian wanita</translation>
+<translation id="6194209731893739467">Lihat semua produk yang dijejaki di sini</translation>
 <translation id="6195371403461054755">Geologi</translation>
 <translation id="6196640612572343990">Sekat kuki pihak ketiga</translation>
 <translation id="6203231073485539293">Semak sambungan Internet anda</translation>
@@ -1966,6 +1982,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Peranti anda akan dimulakan semula sekarang}=1{Peranti anda akan dimulakan semula dalam masa 1 saat}other{Peranti anda akan dimulakan semula dalam masa # saat}}</translation>
+<translation id="6301104306974789820">Dapatkan pemberitahuan penjejakan harga</translation>
 <translation id="6302269476990306341">Google Assistant dalam Chrome berhenti</translation>
 <translation id="6305205051461490394"><ph name="URL" /> tidak dapat dicapai.</translation>
 <translation id="6311165245110979290">Kad maya tersedia</translation>
@@ -2025,6 +2042,7 @@
 <translation id="6451458296329894277">Sahkan Penyerahan Semula Borang</translation>
 <translation id="6456955391422100996">Iklan dialih keluar.</translation>
 <translation id="6457206614190510200">Jahitan pelana</translation>
+<translation id="6457455098507772300">Pemakluman penurunan harga dipaparkan sebagai pemberitahuan pop timbul pada desktop anda</translation>
 <translation id="6458606150257356946">Tampal juga</translation>
 <translation id="6464094930452079790">imej</translation>
 <translation id="6465306955648956876">Urus kata laluan...</translation>
@@ -2082,6 +2100,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Kosongkan</translation>
 <translation id="6645291930348198241">Akses kuki dan data tapak.</translation>
+<translation id="6645478838938543427">Pemakluman penurunan harga akan dihantar ke <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Tiada}=1{Daripada 1 tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}other{Daripada # tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}}</translation>
 <translation id="6648459603387803038">Pentadbir anda boleh menukar persediaan penyemak imbas anda dari jauh. Aktiviti pada peranti ini mungkin turut diurus di luar Chrome.</translation>
 <translation id="6648524591329069940">Fon Serif</translation>
@@ -2275,6 +2294,7 @@
 <translation id="7182878459783632708">Tiada dasar ditetapkan</translation>
 <translation id="7186367841673660872">Halaman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Kumpulan Sorak</translation>
+<translation id="7192188280913829296">Atribut "vendor_id" mesti turut dinyatakan.</translation>
 <translation id="7192203810768312527">Mengosongkan <ph name="SIZE" />. Sesetengah tapak mungkin dimuatkan dengan perlahan pada lawatan anda yang seterusnya.</translation>
 <translation id="7193661028827781021">Rujukan</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_my.xtb b/components/strings/components_strings_my.xtb
index b945232..f38a7ed 100644
--- a/components/strings/components_strings_my.xtb
+++ b/components/strings/components_strings_my.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">စက်လော့ခ်ဖွင့်ခြင်း</translation>
 <translation id="1269516672602708785">Google Sites တွင် ဝဘ်ဆိုက်အသစ် အမြန်ပြုလုပ်ရန်</translation>
 <translation id="1270502636509132238">လာယူနည်း</translation>
+<translation id="1273592791152866347">ဈေးနှုန်းစောင့်ကြည့်မှု ပိတ်လိုက်သည်</translation>
 <translation id="1281476433249504884">စီထည့်သည့်ပုံး ၁</translation>
 <translation id="1285320974508926690">ဒီဆိုက်ကို ဘယ်တော့မှ ဘာသာမပြန်ပါနှင့်</translation>
 <translation id="1288548991597756084">ကတ်ကို လုံခြုံစွာသိမ်းရန်</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">အခမဲ့ဆော့ဖ်ဝဲနှင့် မျှဝေသည့်ဆော့ဖ်ဝဲ</translation>
 <translation id="1553358976309200471">Update Chrome</translation>
+<translation id="1554003749331233619">ဤထုတ်ကုန်ကို သင်ယခု စောင့်ကြည့်နေသည်။ ဤစာမျက်နှာကို <ph name="LAST_BOOKMARKS_FOLDER" /> တွင် သိမ်းထားသည်။</translation>
 <translation id="1555130319947370107">အပြာရောင်</translation>
 <translation id="1559447966090556585">အကြောင်းကြားချက်များကို ရယူမလား။</translation>
 <translation id="1559528461873125649">ကဲ့သို့သော ဖိုင် သို့မဟုတ် ဒါရိုက်ထရီ မရှိပါ</translation>
@@ -562,6 +564,7 @@
 <translation id="2430968933669123598">Google Account စီမံရန်၊ သင်၏ Google Account တွင် သင့်အချက်အလက်၊ ပုဂ္ဂိုလ်ရေးနှင့် လုံခြုံရေးဆိုင်ရာများကို စီမံရန် Enter ခလုတ် နှိပ်ပါ</translation>
 <translation id="2436186046335138073">လင့် <ph name="PROTOCOL" /> အားလုံးကို <ph name="HANDLER_HOSTNAME" />အား ဖွင့်ခွင့် ပြုမလား?</translation>
 <translation id="2438874542388153331">ညာဘက်တွင် လေးချက်ဖောက်ရန်</translation>
+<translation id="2443309680964448806">တစ်ခုခုမှားသွားသည်။ သင်၏အပြာင်းအလဲကို သိမ်းမထားပါ။</translation>
 <translation id="2448295565072560657">သင်အကောင့်ဝင်ချိန်တွင် ဤစက်သို့ ချိတ်ဆက်ပစ္စည်းများ တွဲချိတ်ထားသည်</translation>
 <translation id="2450021089947420533">ခရီးစဉ်များ</translation>
 <translation id="2463739503403862330">ဖြည့်သွင်းရန်</translation>
@@ -821,6 +824,7 @@
 <translation id="317878711435188021">ဤကိရိယာသုံးနေချိန်ကို သိလိုသည်</translation>
 <translation id="3180358318770512945">မိဘအုပ်ထိန်းမှု</translation>
 <translation id="3187306450550410410">လိုက်လျောညီထွေ အလုပ်စီစဉ်ပေးမှုများ</translation>
+<translation id="3190736958609431397">မစောင့်ကြည့်ရန်</translation>
 <translation id="319282854780294203">လူမှုကွန်ရက်များ</translation>
 <translation id="3194737229810486521"><ph name="URL" /> သည် ဒေတာများကို သင်၏စက်တွင် အမြဲတမ်းသိုလှောင်လိုသည်</translation>
 <translation id="3195213714973468956"><ph name="SERVER_NAME" /> ရှိ <ph name="PRINTER_NAME" /></translation>
@@ -906,6 +910,7 @@
 <translation id="3387261909427947069">ငွေပေးချေ နည်းလမ်းများ</translation>
 <translation id="3391030046425686457">ပို့ဆောင်ရန် လိပ်စာ</translation>
 <translation id="3391482648489541560">ဖိုင်တည်းဖြတ်ခြင်း</translation>
+<translation id="3392028486601120379">URL ပုံစံ "<ph name="URL_PATTERN" />" တွင် ဖိုင်တွဲလမ်းကြောင်း သတ်မှတ်ထားသည်။ ဖိုင်တွဲလမ်းကြောင်းများကို ဤကီးအတွက် ပံ့ပိုးမထားသဖြင့် ဖိုင်တွဲလမ်းကြောင်းဖယ်ရှားပြီး ထပ်စမ်းကြည့်ပါ။ ဥပမာ- *://example.com/ =&gt; *://example.com"၊</translation>
 <translation id="3395827396354264108">ပစ္စည်းထုတ်ယူရန် နည်းလမ်း</translation>
 <translation id="3399952811970034796">ပေးပို့ရန် လိပ်စာ</translation>
 <translation id="3402261774528610252">ဤဝဘ်ဆိုက်ဖွင့်ရန် အသုံးပြုသော ချိတ်ဆက်မှုက TLS 1.0 သို့မဟုတ် TLS 1.1 ကို သုံးထားသည်။ ၎င်းကို ရပ်ဆိုင်းထားပြီး နောင်တွင်ပိတ်လိုက်ပါမည်။ ပိတ်လိုက်သည့်အခါ အသုံးပြုသူများက ဤဝဘ်ဆိုက်ကို ဖွင့်နိုင်တော့မည်မဟုတ်ပါ။ ဆာဗာက TLS 1.2 နှင့်နောက်ပိုင်းကို ဖွင့်ပေးရပါမည်။</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">Google Account တွင် သိမ်းပါ</translation>
 <translation id="3640766068866876100">အညွှန်း-၄x၆-နောက်ဆက်တွဲ</translation>
 <translation id="3642638418806704195">အပလီကေးရှင်း-</translation>
+<translation id="3647286794400715637">URL လိုင်း တစ်ခုစီတွင် URL ၁ ခုမှ ၂ ခုအထိ ပါဝင်ရမည်။</translation>
 <translation id="3650584904733503804">အောင်မြင်စွာ အတည်ပြုပြီး</translation>
 <translation id="3653033846669030038">အစီအစဉ်များခင်းကျင်းရာ အပန်းဖြေဥယျာဉ်</translation>
 <translation id="3655241534245626312">ခွင့်ပြုချက် ဆက်တင်များသို့ သွားရန်</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">သင်၏ ဘရောင်ဇာကို သင့်ကြီးကြပ်သူက စီမံခန့်ခွဲထားပါသည်။</translation>
 <translation id="3740319564441798148">အဝေးပြေး ဘတ်စ်ကားနှင့် ရထား</translation>
 <translation id="3744111561329211289">နောက်ခံတွင် စင့်ခ်လုပ်ခြင်း</translation>
+<translation id="3744286742364977428">သင်ဒေါင်းလုဒ်လုပ်သည့် ဖိုင်များကို စိတ်ဖြာလေ့လာရန် Google Cloud (သို့) ပြင်ပအဖွဲ့များသို့ ပို့သည်။ ဥပမာအားဖြင့် ၎င်းတို့က သတိထားရမည့်ဒေတာ (သို့) မဲလ်ဝဲကို ရှာဖွေနိုင်ပြီး ကုမ္ပဏီမူဝါဒများအရ သိမ်းနိုင်သည်။</translation>
 <translation id="3744899669254331632">ဝက်ဘ်ဆိုက်က ဗလုံးဗထွေး ပို့လိုက်သည့် အထောက်အထားများကို Chromium ဖက်မှ စီမံဆောင်ရွက် မရနိုင်သောကြောင့် သင်သည် <ph name="SITE" /> ကို ယခုချက်ချင်း ဝင်မရနိုင်ပါ။ ကွန်ရက် အမှားများ နှင့် တိုက်ခိုက်မှုများမှာ ယာယီမျှသာ ဖြစ်ကြတာမို့လို့၊ ဒီစာမျက်နှာသည် နောက်ပိုင်းမှာ အလုပ်လုပ်နိုင်ပါမည်။</translation>
 <translation id="3745099705178523657">အတည်ပြုပြီးနောက် သင်၏ Google အကောင့်ရှိ ကဒ်အသေးစိတ် အချက်အလက်များကို ဤဆိုက်အား မျှဝေသွားပါမည်။</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ပေါ်ရှိ တိုက်ခိုက်သူများသည် သင့်အား သင့်စက်ပစ္စည်းကို ပျက်စီးစေနိုင်သည့် အန္တရာယ်ရှိသောဆော့ဖ်ဝဲများ ထည့်သွင်းခြင်း သို့မဟုတ် သင်၏ ကိုယ်ရေးကိုယ်တာ အချက်အလက်များ (ဥပမာ- စကားဝှက်များ၊ ဖုန်းနံပါတ်များ သို့မဟုတ် ခရက်ဒစ်ကတ် အချက်အလက်များ) ကို ဖော်ပြစေခြင်းတို့ကို ပြုလုပ်မိစေရန် လှည့်ဖြားနိုင်ပါသည်။ <ph name="BEGIN_LEARN_MORE_LINK" />ပိုမိုလေ့လာရန်<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">အစီအစဉ်ပြုလုပ်ရန် ခလုတ်၊ Google Calendar တွင် အစီအစဉ်အသစ် ပြုလုပ်ရန် Enter ခလုတ် နှိပ်ပါ</translation>
 <translation id="4088981014127559358">ဘေး ၁ ပုံ ဒေါင်လိုက် အရွှေ့</translation>
 <translation id="4089152113577680600">ဗန်း ၁၄</translation>
+<translation id="4097288585054919042">သတိပေးချက်များ ပိတ်ရန်</translation>
 <translation id="4098354747657067197">ရှေ့တွင် လှည့်ဖြားတတ်သော ဆိုက်ရှိနေသည်</translation>
 <translation id="4099048595830172239">လျှို့ဝှက်အကြောင်းအရာ မြင်ရချိန်တွင် သင်၏ဖန်သားပြင်အား <ph name="APPLICATION_TITLE" /> နှင့် မျှဝေခြင်းကို စီမံခန့်ခွဲသူမူဝါဒက အကြံပြုမထားပါ-</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />၊ Chrome တွင် ဖောင့် အရွယ်အစားများနှင့် စာလုံးပုံစံများကို စိတ်ကြိုက်လုပ်ရန် ‘တဘ်ခလုတ်’ ပြီးနောက် Enter နှိပ်ပါ</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">ပိတ်ထားသည်။</translation>
 <translation id="4176535426287761656">အချိန်ပိုင်းမျှသုံးသည့် နေစရာများနှင့် အားလပ်ရပ် တည်းခိုစရာများ</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">ဈေးနှုန်း မစောင့်ကြည့်ရန်</translation>
 <translation id="4194250254487269611">သင့်ကတ်ကို ယခု သိမ်း၍မရပါ</translation>
 <translation id="4196861286325780578">&amp;ရွေ့ရှားမှုကို ပြန်လုပ်ရန်</translation>
 <translation id="4202554117186904723">ငါးခုမြောက်အလိပ်</translation>
@@ -1227,6 +1236,7 @@
 <translation id="4275830172053184480">သင့်စက်ပစ္စည်းကို ပြန်လည် အစပြုပါ</translation>
 <translation id="4277028893293644418">စကားဝှက် ပြင်ဆင်သတ်မှတ်ရန်</translation>
 <translation id="4278390842282768270">ခွင့်ပြုထား</translation>
+<translation id="4282346679996504092">ဤထုတ်ကုန်အတွက် သတိပေးချက်များကို ပိတ်ထားပြီး လိပ်စာကို ဖယ်ရှားထားသည်</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{ဤကတ်ကို သင်၏ Google အကောင့်တွင် သိမ်းပြီးပါပြီ}other{ဤကတ်များကို သင်၏ Google အကောင့်တွင် သိမ်းပြီးပါပြီ}}</translation>
 <translation id="4287885627794386150">အစမ်းသုံးရန် အကျုံးဝင်သော်လည်း သုံးမနေပါ</translation>
 <translation id="4297502707443874121">စာမျက်နှာ <ph name="THUMBNAIL_PAGE" /> အတွက် ပုံသေး</translation>
@@ -1265,6 +1275,7 @@
 <translation id="4358059973562876591">DnsOverHttpsMode မူဝါဒတွင် အမှားဖြစ်သွားသောကြောင့် သင်သတ်မှတ်ထားသော နမူနာပုံစံများကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။</translation>
 <translation id="4358461427845829800">ငွေပေးချေနည်းလမ်းများကို စီမံရန်...</translation>
 <translation id="4359160567981085931">လှည့်ဖြားတတ်သော ဝဘ်ဆိုက်တစ်ခုတွင် သင့်စကားဝှက်ကို သင်က ယခုလေးတွင် ထည့်လိုက်သည်။ Chrome က ကူညီနိုင်ပါသည်။ သင်၏စကားဝှက် ပြောင်းရန်နှင့် သင့်အကောင့်အန္တရာယ်ရှိနိုင်ကြောင်း Google သို့ အသိပေးရန် 'အကောင့် ကာကွယ်ရေး' ကို နှိပ်ပါ။</translation>
+<translation id="4363222835916186793">ဤထုတ်ကုန်အတွက် သတိပေးချက်များကို ပိတ်ထားသည်</translation>
 <translation id="4367563149485757821">နံပါတ်-၁၂ (စာအိတ်)</translation>
 <translation id="437040971055499437">လုံခြုံရေးဆိုင်ရာ ဖြစ်ရပ် ရှိသည်</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1417,6 +1428,7 @@
 <translation id="4792686369684665359">သင်ပေးပို့တော့မည့်အချက်အလက်သည် မလုံခြုံပါ</translation>
 <translation id="4796594887379589189">အလုပ်အကောင့် ID</translation>
 <translation id="4798078619018708837">သင့်ကဒ်၏ အသေးစိတ်အချက်အလက်များကို အပ်ဒိတ်လုပ်ရန် <ph name="CREDIT_CARD" /> အတွက် ကုန်ဆုံးရက်နှင့် CVC ကို ထည့်ပါ။ အတည်ပြုပြီးသည်နှင့် Google အကောင့်မှ သင့်ကဒ်၏အသေးစိတ် အချက်အလက်များကို ဤဆိုက်အား မျှဝေသွားပါမည်။</translation>
+<translation id="4798269756263412078">ဝဘ်ဆိုက်တစ်ခုခုတွင် ဈေးကျပါက သတိပေးချက် ရယူနိုင်သည်။ သတိပေးချက်ကို သင့်အီးမေးလ်သို့ ပို့ပါမည်။</translation>
 <translation id="4800132727771399293">သင်၏ သက်တမ်းကုန်ဆုံးရက်နှင့် CVC အား စစ်ဆေးပြီး ထပ်မံကြိုးစားပါ</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">TouchID အသုံးပြုရန်</translation>
@@ -1660,6 +1672,7 @@
 <translation id="5396631636586785122">ညာဘက်အစွန်းတွင် အပ်ချည်ဖြင့်ချုပ်ရန်</translation>
 <translation id="5398772614898833570">ကြော်ငြာများကို ပိတ်လိုက်ပါပြီ</translation>
 <translation id="5400836586163650660">မီးခိုး</translation>
+<translation id="540630185148148480">သတိပေးချက်များ ဖွင့်ရန်</translation>
 <translation id="540969355065856584">ဤဆာဗာသည် <ph name="DOMAIN" /> ဖြစ်ကြောင်း သက်သေမပြနိုင်ပါ; ၎င်း၏လုံခြုံရေး အသိမှတ်ပြုလက်မှတ်သည် ယခုအချိန်တွင် တရားမဝင်ပါ။ ဖွဲ့စည်းမှု အမှားကြောင့် သို့မဟုတ် တိုက်ခိုက်လိုသူက သင်၏ချိတ်ဆက်မှုကို ကြားဖြတ်ယူနေ၍ ထိုသို့ဖြစ်လာနိုင်ခဲ့ပါသည်။</translation>
 <translation id="5412040515238827314">ပုံစံမမှန်ပါ- ပုံစံစာရင်း ဖြစ်ရမည်။</translation>
 <translation id="5412236728747081950">နောက်ထပ်သက်ဆိုင်ရာ ကြော်ငြာများ ပြရန် Chrome မှ သင့်စိတ်ဝင်စားမှုများကို ဤဝဘ်ဆိုက်က ရယူပါသည်</translation>
@@ -1724,6 +1737,7 @@
 <translation id="5580958916614886209">သင့်ကုန်ဆုံးမည့်လကို ကြည့်ပြီး ပြန်စမ်းကြည့်ပါ</translation>
 <translation id="558420943003240152">စကားဝှက်နှင့် လျှို့ဝှက်ကီးများ စီမံရန်…</translation>
 <translation id="5586446728396275693">သိမ်းဆည်းထားသည့် လိပ်စာများ မရှိပါ</translation>
+<translation id="5586831831248371458"><ph name="KEYWORD_SUFFIX" /> ကို ရှာရန်</translation>
 <translation id="5587987780934666589">စနစ်အသုံးပြုသူ</translation>
 <translation id="5593349413089863479">ချိတ်ဆက်မှုသည် အပြည့်အဝမလုံခြုံပါ</translation>
 <translation id="5595485650161345191">လိပ်စာ တည်းဖြတ်ရန်</translation>
@@ -1843,6 +1857,7 @@
 <translation id="5938153366081463283">ပကတိအသွင်ကတ် ထည့်ရန်</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> ကို ဖွင့်နေသည်…</translation>
+<translation id="5947508410139465809">သင်အပ်လုဒ်လုပ်သည့် (သို့) တွဲချိတ်သည့် ဖိုင်များကို စိတ်ဖြာလေ့လာရန် Google Cloud (သို့) ပြင်ပအဖွဲ့များသို့ ပို့သည်။ ဥပမာအားဖြင့် ၎င်းတို့က သတိထားရမည့်ဒေတာ (သို့) မဲလ်ဝဲကို ရှာဖွေနိုင်ပြီး ကုမ္ပဏီမူဝါဒများအရ သိမ်းနိုင်သည်။</translation>
 <translation id="5951495562196540101">အသုံးပြုသူ အကောင့်ဖြင့် စာရင်းသွင်း၍ မရပါ (ပက်ကေ့ချ်လုပ်ထားသော လိုင်စင်ကို ရနိုင်သည်)။</translation>
 <translation id="5953516610448771166">‘တိုက်ရိုက်စာတန်း’ ကို ဤမီဒီယာအတွက် မရနိုင်ပါ။ စာတန်းများရရှိရန် <ph name="CONTENT_SETTINGS" /> ကို ဤဝဘ်ဆိုက်အတွက် ပိတ်ထားနိုင်သည်။</translation>
 <translation id="5955063559762970069">ဟိုတယ်နှင့် တည်းခိုစရာများ</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">ဤဝဘ်ဆိုက်သို့ သင်၏ချိတ်ဆက်ထားမှုသည် လုံခြုံမှုမရှိပါ</translation>
 <translation id="6180316780098470077">ပြန်စမ်းချိန် ကြားကာလ</translation>
 <translation id="61877208875190028">အမျိုးသမီး အဝတ်အစား</translation>
+<translation id="6194209731893739467">စောင့်ကြည့်ထားသည့် ထုတ်ကုန်များကို ဤနေရာတွင် ကြည့်နိုင်သည်</translation>
 <translation id="6195371403461054755">ဘူမိဗေဒ</translation>
 <translation id="6196640612572343990">ပြင်ပကုမ္ပဏီကွတ်ကီးများကို ပိတ်ဆို့မည်</translation>
 <translation id="6203231073485539293">သင့်အင်တာနက် ချိတ်ဆက်မှုကို စစ်ပါ</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC-</translation>
 <translation id="6300452962057769623">{0,plural, =0{သင့်စက်ကို ယခုပြန်စမည်}=1{သင့်စက်ကို 1 စက္ကန့်အတွင်း ပြန်စမည်}other{သင့်စက်ကို # စက္ကန့်အတွင်း ပြန်စမည်}}</translation>
+<translation id="6301104306974789820">ဈေးနှုန်းစောင့်ကြည့်မှု အကြောင်းကြားချက်များ ရယူရန်</translation>
 <translation id="6302269476990306341">Chrome အတွင်းရှိ Google Assistant ရပ်တန့်နေသည်</translation>
 <translation id="6305205051461490394"><ph name="URL" /> ကိုဆက်သွယ်၍မရနိုင်ပါ။</translation>
 <translation id="6311165245110979290">ပကတိအသွင်ကတ် ရနိုင်သည်</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">ပုံစံ ပြန်လည်တင်မှုကို အတည်ပြုရန်</translation>
 <translation id="6456955391422100996">ကြော်ငြာကို ဖယ်ရှားလိုက်ပါပြီ။</translation>
 <translation id="6457206614190510200">အနှောင့်တွင် အပ်ချည်ဖြင့်ချုပ်ရန်</translation>
+<translation id="6457455098507772300">ဈေကျသည့် သတိပေးချက်များကို သင့်ဒက်စ်တော့တွင် ပေါ့ပ်အပ်အကြောင်းကြားချက်အနေဖြင့် ပြရန်</translation>
 <translation id="6458606150257356946">မည်သို့ပင်ဖြစ်စေ ကူးထည့်ရန်</translation>
 <translation id="6464094930452079790">ပုံများ</translation>
 <translation id="6465306955648956876">စကားဝှက်ကို စီမံရန်...</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">ရှင်းရန်</translation>
 <translation id="6645291930348198241">ကွတ်ကီးနှင့် ဝဘ်ဆိုက်ဒေတာများ သုံးခြင်း။</translation>
+<translation id="6645478838938543427">ဈေးကျသည့် သတိပေးချက်ကို <ph name="EMAIL_ADDRESS" /> သို့ ပို့ရန်</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{တစ်ခုမျှမရှိပါ}=1{ဝဘ်ဆိုက် ၁ ခုမှ (သင်၏ Google အကောင့်မှနေ၍ ထွက်သွားမည်မဟုတ်ပါ)}other{ဝဘ်ဆိုက် # ခုမှ (သင်၏ Google အကောင့်မှနေ၍ ထွက်သွားမည်မဟုတ်ပါ)}}</translation>
 <translation id="6648459603387803038">သင့်စီမံခန့်ခွဲသူက သင်၏ဘရောင်ဇာ စနစ်ထည့်သွင်းမှုကို အဝေးမှ ပြောင်းလဲနိုင်ပါသည်။ ဤစက်ပေါ်ရှိ လုပ်ဆောင်ချက်များကိုလည်း Chrome ပြင်ပမှ စီမံခန့်ခွဲထားခြင်း ဖြစ်နိုင်သည်။</translation>
 <translation id="6648524591329069940">Serif ဖောင့်</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">မည်သည့် ပေါ်လစီမှ သတ်မှတ်မထားပါ</translation>
 <translation id="7186367841673660872">ဤစာမျက်နှာကို <ph name="ORIGINAL_LANGUAGE" />မှ<ph name="LANGUAGE_LANGUAGE" /> သို့ဘာသာပြန်ထားသည်</translation>
 <translation id="718872491229180389">အားပေးရန် စည်းရုံးခြင်း</translation>
+<translation id="7192188280913829296">ရည်ညွှန်းချက် "vendor_id" ကိုလည်း သတ်မှတ်ရမည်။</translation>
 <translation id="7192203810768312527"><ph name="SIZE" /> နေရာလွတ်အောင်လုပ်ပါ။ နောက်တစ်ကြိမ် ဝင်ကြည့်သည့်အခါတွင် အချို့ဝဘ်ဆိုက်များက ပိုနှေးနေနိုင်ပါသည်။</translation>
 <translation id="7193661028827781021">အညွှန်း</translation>
 <translation id="719464814642662924">ဗီဇာ</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb
index 1557966bb..c355c1c 100644
--- a/components/strings/components_strings_nl.xtb
+++ b/components/strings/components_strings_nl.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Apparaatontgrendeling</translation>
 <translation id="1269516672602708785">Snel een nieuwe site in Google Sites maken</translation>
 <translation id="1270502636509132238">Ophaalmethode</translation>
+<translation id="1273592791152866347">Prijs volgen staat uit</translation>
 <translation id="1281476433249504884">Stapeleenheid 1</translation>
 <translation id="1285320974508926690">Deze site nooit vertalen</translation>
 <translation id="1288548991597756084">Kaart beveiligd opslaan</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Freeware en shareware</translation>
 <translation id="1553358976309200471">Chrome updaten</translation>
+<translation id="1554003749331233619">Je volgt dit product nu. Deze pagina is opgeslagen in <ph name="LAST_BOOKMARKS_FOLDER" />.</translation>
 <translation id="1555130319947370107">Blauw</translation>
 <translation id="1559447966090556585">Meldingen ontvangen?</translation>
 <translation id="1559528461873125649">Dit bestand of deze directory bestaat niet</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Google-account beheren, druk op Enter om je gegevens, privacy, en beveiliging te beheren in je Google-account</translation>
 <translation id="2436186046335138073"><ph name="HANDLER_HOSTNAME" /> toestaan alle links voor <ph name="PROTOCOL" /> te openen?</translation>
 <translation id="2438874542388153331">Vier perforaties rechts</translation>
+<translation id="2443309680964448806">Er is iets misgegaan. Je wijziging is niet opgeslagen.</translation>
 <translation id="2448295565072560657">Randapparaten die zijn aangesloten op dit apparaat als je bent ingelogd</translation>
 <translation id="2450021089947420533">Trajecten</translation>
 <translation id="2463739503403862330">Invullen</translation>
@@ -816,6 +819,7 @@
 <translation id="317878711435188021">Weten wanneer je dit apparaat actief gebruikt</translation>
 <translation id="3180358318770512945">Ouderschap</translation>
 <translation id="3187306450550410410">Flexibele werkopties</translation>
+<translation id="3190736958609431397">Niet meer volgen</translation>
 <translation id="319282854780294203">Sociale netwerken</translation>
 <translation id="3194737229810486521"><ph name="URL" /> vraagt toestemming om gegevens permanent op je apparaat op te slaan</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> op <ph name="SERVER_NAME" /></translation>
@@ -901,6 +905,7 @@
 <translation id="3387261909427947069">Betaalmethoden</translation>
 <translation id="3391030046425686457">Afleveradres</translation>
 <translation id="3391482648489541560">bestanden bewerken</translation>
+<translation id="3392028486601120379">Voor het URL-patroon <ph name="URL_PATTERN" /> is een pad opgegeven. Paden worden niet ondersteund voor deze sleutel. Verwijder het pad en probeer het opnieuw. Bijvoorbeeld: *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Ophaalmethode</translation>
 <translation id="3399952811970034796">Bezorgadres</translation>
 <translation id="3402261774528610252">De verbinding waarmee deze site is geladen, gebruikte TLS 1.0 of TLS 1.1. Deze versies zijn verouderd en worden in de toekomst niet meer gebruikt. Dan kunnen gebruikers deze site niet meer laden. Voor de server moet TLS 1.2 of hoger worden gebruikt.</translation>
@@ -994,6 +999,7 @@
 <translation id="3637662659967048211">Opslaan in Google-account</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">App:</translation>
+<translation id="3647286794400715637">Elke URL-tekenreeks moet 1 of 2 URL's bevatten.</translation>
 <translation id="3650584904733503804">Validatie geslaagd</translation>
 <translation id="3653033846669030038">Attractieparken</translation>
 <translation id="3655241534245626312">Naar de instellingen voor rechten</translation>
@@ -1032,6 +1038,7 @@
 <translation id="3738166223076830879">Je browser wordt beheerd door je beheerder.</translation>
 <translation id="3740319564441798148">Lange afstand bus- en treinvervoer</translation>
 <translation id="3744111561329211289">Synchronisatie op de achtergrond</translation>
+<translation id="3744286742364977428">Bestanden die je downloadt, worden voor analyse naar Google Cloud of naar derden gestuurd. Ze kunnen bijvoorbeeld worden gescand op gevoelige gegevens of malware en worden opgeslagen volgens het bedrijfsbeleid.</translation>
 <translation id="3744899669254331632">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gecodeerde inloggegevens heeft verstuurd die niet door Chromium kunnen worden verwerkt. Aangezien netwerkfouten en aanvallen doorgaans van tijdelijke aard zijn, zal deze pagina later waarschijnlijk wel werken.</translation>
 <translation id="3745099705178523657">Nadat je hebt bevestigd, worden de kaartgegevens uit je Google-account gedeeld met deze site.</translation>
 <translation id="3748148204939282805">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kunnen proberen om je te misleiden zodat je iets gevaarlijks doet, bijvoorbeeld software installeren of je persoonlijke informatie bekendmaken (zoals wachtwoorden, telefoonnummers of creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1139,6 +1146,7 @@
 <translation id="4087296516249690906">Knop Afspraak maken, druk op Enter om snel een nieuwe afspraak in Google Agenda te maken</translation>
 <translation id="4088981014127559358">Beeldverschuiving Y van zijde 1</translation>
 <translation id="4089152113577680600">Lade 14</translation>
+<translation id="4097288585054919042">Meldingen uitzetten</translation>
 <translation id="4098354747657067197">Misleidende site gedetecteerd</translation>
 <translation id="4099048595830172239">Op basis van het beheerdersbeleid wordt afgeraden dat je je scherm met <ph name="APPLICATION_TITLE" /> deelt als er vertrouwelijke content zichtbaar is:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, druk op Tab en daarna op Enter om je lettertypen en lettergrootten aan te passen in Chrome</translation>
@@ -1175,6 +1183,7 @@
 <translation id="4176463684765177261">Uitgezet</translation>
 <translation id="4176535426287761656">Timesharing en vakantiehuizen</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Prijs volgen</translation>
 <translation id="4194250254487269611">Je kaart kan op dit moment niet worden opgeslagen</translation>
 <translation id="4196861286325780578">&amp;Opnieuw verplaatsen</translation>
 <translation id="4202554117186904723">5e rol</translation>
@@ -1221,6 +1230,7 @@
 <translation id="4275830172053184480">Je apparaat opnieuw opstarten</translation>
 <translation id="4277028893293644418">Wachtwoord opnieuw instellen</translation>
 <translation id="4278390842282768270">Toegestaan</translation>
+<translation id="4282346679996504092">Meldingen voor dit product zijn uitgezet en de bookmark is verwijderd</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Deze pas is opgeslagen in je Google-account}other{Deze passen zijn opgeslagen in je Google-account}}</translation>
 <translation id="4287885627794386150">Komt in aanmerking voor proef maar is niet actief</translation>
 <translation id="4297502707443874121">Miniatuur voor pagina <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1259,6 +1269,7 @@
 <translation id="4358059973562876591">De gespecificeerde templates worden misschien niet toegepast door een fout met het beleid DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Betaalmethoden beheren...</translation>
 <translation id="4359160567981085931">Je hebt zojuist je wachtwoord opgegeven op een misleidende site. Chrome kan je laten zien wat je nu kunt doen. Klik op 'Account beschermen' om je wachtwoord te wijzigen en Google te laten weten dat je account mogelijk gevaar loopt.</translation>
+<translation id="4363222835916186793">Meldingen voor dit product zijn uitgezet</translation>
 <translation id="4367563149485757821">Number-12 (envelop)</translation>
 <translation id="437040971055499437">Beveiligingsgebeurtenis vindt plaats</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1411,6 +1422,7 @@
 <translation id="4792686369684665359">De gegevens die je wilt sturen, zijn niet beveiligd</translation>
 <translation id="4796594887379589189">Taakaccount-ID</translation>
 <translation id="4798078619018708837">Geef de vervaldatum en CVC-code voor <ph name="CREDIT_CARD" /> op om je creditcardgegevens te updaten. Nadat je hebt bevestigd, worden de creditcardgegevens uit je Google-account gedeeld met deze site.</translation>
+<translation id="4798269756263412078">Krijg meldingen bij een prijsdaling op een site. Meldingen worden naar je e-mailadres gestuurd.</translation>
 <translation id="4800132727771399293">Controleer je vervaldatum en CVC-code en probeer het opnieuw</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Touch ID gebruiken</translation>
@@ -1654,6 +1666,7 @@
 <translation id="5396631636586785122">Inbinden met nietjes rechts</translation>
 <translation id="5398772614898833570">Advertenties geblokkeerd</translation>
 <translation id="5400836586163650660">Grijs</translation>
+<translation id="540630185148148480">Meldingen aanzetten</translation>
 <translation id="540969355065856584">Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat is momenteel niet geldig. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
 <translation id="5412040515238827314">Ongeldige indeling: er wordt een lijst met patronen verwacht.</translation>
 <translation id="5412236728747081950">Deze site krijgt je interesses van Chrome zodat de site je relevantere advertenties kan laten zien</translation>
@@ -1718,6 +1731,7 @@
 <translation id="5580958916614886209">Controleer de vervalmaand en probeer het opnieuw</translation>
 <translation id="558420943003240152">Wachtwoorden en toegangscodes beheren…</translation>
 <translation id="5586446728396275693">Geen opgeslagen adressen</translation>
+<translation id="5586831831248371458"><ph name="KEYWORD_SUFFIX" /> zoeken</translation>
 <translation id="5587987780934666589">Platformgebruiker</translation>
 <translation id="5593349413089863479">Verbinding is niet volledig beveiligd</translation>
 <translation id="5595485650161345191">Adres bewerken</translation>
@@ -1837,6 +1851,7 @@
 <translation id="5938153366081463283">Virtuele kaart toevoegen</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> openen…</translation>
+<translation id="5947508410139465809">Bestanden die je uploadt of bijvoegt, worden voor analyse naar Google Cloud of derden gestuurd. Ze kunnen bijvoorbeeld worden gescand op gevoelige gegevens of malware en worden opgeslagen volgens het bedrijfsbeleid.</translation>
 <translation id="5951495562196540101">Kan consumentenaccount niet inschrijven (verpakte licentie beschikbaar).</translation>
 <translation id="5953516610448771166">Live ondertiteling is niet beschikbaar voor deze media. Blokkeer <ph name="CONTENT_SETTINGS" /> voor deze site als je ondertiteling wilt hebben.</translation>
 <translation id="5955063559762970069">Hotels en accommodaties</translation>
@@ -1924,6 +1939,7 @@
 <translation id="6177128806592000436">Je verbinding met deze site is niet beveiligd</translation>
 <translation id="6180316780098470077">Interval voor nieuwe poging</translation>
 <translation id="61877208875190028">Dameskleding</translation>
+<translation id="6194209731893739467">Bekijk hier al je gevolgde producten</translation>
 <translation id="6195371403461054755">Geologie</translation>
 <translation id="6196640612572343990">Cookies van derden blokkeren</translation>
 <translation id="6203231073485539293">Controleer je internetverbinding</translation>
@@ -1959,6 +1975,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Je apparaat wordt nu opnieuw opgestart}=1{Je apparaat wordt over 1 seconde opnieuw opgestart}other{Je apparaat wordt over # seconden opnieuw opgestart}}</translation>
+<translation id="6301104306974789820">Meldingen voor volgen van prijzen krijgen</translation>
 <translation id="6302269476990306341">De Google Assistent in Chrome wordt gestopt</translation>
 <translation id="6305205051461490394"><ph name="URL" /> is niet bereikbaar.</translation>
 <translation id="6311165245110979290">Virtuele kaart beschikbaar</translation>
@@ -2018,6 +2035,7 @@
 <translation id="6451458296329894277">Opnieuw indienen bevestigen</translation>
 <translation id="6456955391422100996">Advertentie verwijderd.</translation>
 <translation id="6457206614190510200">Zadelsteek</translation>
+<translation id="6457455098507772300">Je krijgt meldingen over prijsdalingen als pop-upmeldingen op je desktop</translation>
 <translation id="6458606150257356946">Toch plakken</translation>
 <translation id="6464094930452079790">afbeeldingen</translation>
 <translation id="6465306955648956876">Wachtwoorden beheren...</translation>
@@ -2075,6 +2093,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Wissen</translation>
 <translation id="6645291930348198241">Toegang krijgen tot cookies en sitegegevens.</translation>
+<translation id="6645478838938543427">Meldingen over prijsdalingen worden naar <ph name="EMAIL_ADDRESS" /> gestuurd</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Geen}=1{Van 1 site (je wordt niet uitgelogd bij je Google-account)}other{Van # sites (je wordt niet uitgelogd bij je Google-account)}}</translation>
 <translation id="6648459603387803038">Je beheerder kan je browserinstellingen op afstand wijzigen. Activiteit op dit apparaat kan ook buiten Chrome worden beheerd.</translation>
 <translation id="6648524591329069940">Serif-lettertype</translation>
@@ -2268,6 +2287,7 @@
 <translation id="7182878459783632708">Geen beleid ingesteld</translation>
 <translation id="7186367841673660872">Deze pagina is vertaald van het<ph name="ORIGINAL_LANGUAGE" />in het<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Cheerleaden</translation>
+<translation id="7192188280913829296">Het kenmerk 'vendor_id' moet ook worden opgegeven.</translation>
 <translation id="7192203810768312527">Hiermee wordt <ph name="SIZE" /> vrijgemaakt. Sommige sites kunnen langzamer worden geladen wanneer je ze weer bezoekt.</translation>
 <translation id="7193661028827781021">Naslagwerken</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_or.xtb b/components/strings/components_strings_or.xtb
index 27ecaa5c..7a3fc42 100644
--- a/components/strings/components_strings_or.xtb
+++ b/components/strings/components_strings_or.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">ଡିଭାଇସ ଅନଲକ</translation>
 <translation id="1269516672602708785">Google Sitesରେ ଶୀଘ୍ର ଏକ ନୂଆ ସାଇଟ୍ ତିଆରି କରନ୍ତୁ</translation>
 <translation id="1270502636509132238">ଉଠାଇବା ପଦ୍ଧତି</translation>
+<translation id="1273592791152866347">ମୂଲ୍ୟ ଟ୍ରାକିଂ ବନ୍ଦ କରନ୍ତୁ</translation>
 <translation id="1281476433249504884">ଷ୍ଟାକର୍ 1</translation>
 <translation id="1285320974508926690">ଏହି ସାଇଟ୍‍କୁ କଦାପି ଅନୁବାଦ କରନ୍ତୁ ନାହିଁ</translation>
 <translation id="1288548991597756084">ସୁରକ୍ଷିତ ଭାବେ କାର୍ଡକୁ ସେଭ କରନ୍ତୁ</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">ଇଞ୍ଜିନିୟରିଂ-D</translation>
 <translation id="1551884710160394169">ଫ୍ରିୱେର ଏବଂ ସେୟାରୱେର</translation>
 <translation id="1553358976309200471">Chrome ଅପ୍‍‍‍‍‍ଡେଟ୍‌</translation>
+<translation id="1554003749331233619">ଆପଣ ବର୍ତ୍ତମାନ ଏହି ପ୍ରଡକ୍ଟକୁ ଟ୍ରାକ କରୁଛନ୍ତି। ଏହି ପୃଷ୍ଠା <ph name="LAST_BOOKMARKS_FOLDER" />ରେ ସେଭ କରାଯାଇଛି</translation>
 <translation id="1555130319947370107">ନୀଳ</translation>
 <translation id="1559447966090556585">ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଇବେ?</translation>
 <translation id="1559528461873125649">ଏଭଳି କୌଣସି ଫାଇଲ୍ କିମ୍ବା ଡିରେକ୍ଟୋରୀ ନାହିଁ</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Google ଆକାଉଣ୍ଟ ପରିଚାଳନା କରନ୍ତୁ, ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟରେ ଆପଣଙ୍କର ସୂଚନା, ଗୋପନୀୟତା ଏବଂ ସୁରକ୍ଷାକୁ ପରିଚାଳନା କରିବା ପାଇଁ Enter ଦବାନ୍ତୁ</translation>
 <translation id="2436186046335138073">ସମସ୍ତ <ph name="PROTOCOL" /> ଲିଙ୍କ୍ ଖୋଲିବା ପାଇଁ <ph name="HANDLER_HOSTNAME" />କୁ ଅନୁମତି ଦେବେ?</translation>
 <translation id="2438874542388153331">ଡାହାଣ ପଟରେ ଚାରୋଟି ପଞ୍ଚ୍</translation>
+<translation id="2443309680964448806">କିଛି ତ୍ରୁଟି ହୋଇଛି। ଆପଣଙ୍କ ପରିବର୍ତ୍ତନ ସେଭ କରାଯାଇନାହିଁ।</translation>
 <translation id="2448295565072560657">ଆପଣ ଲଗ ଇନ କରିଥିବା ସମୟରେ ଏହି ଡିଭାଇସରେ ଆଟାଚ ହୋଇଥିବା ପେରିଫେରାଲଗୁଡ଼ିକ</translation>
 <translation id="2450021089947420533">ସନ୍ଧାନଗୁଡ଼ିକ</translation>
 <translation id="2463739503403862330">ପୂରଣ କରନ୍ତୁ</translation>
@@ -817,6 +820,7 @@
 <translation id="317878711435188021">ଆପଣ କେତେବେଳେ ଏହି ଡିଭାଇସକୁ ସକ୍ରିୟ ଭାବରେ ବ୍ୟବହାର କରୁଛନ୍ତି ତାହା ଜାଣିବାକୁ ଚାହୁଁଛି</translation>
 <translation id="3180358318770512945">ପ୍ୟାରେଣ୍ଟିଂ</translation>
 <translation id="3187306450550410410">ସୁବିଧାଜନକ କାର୍ଯ୍ୟ ବ୍ୟବସ୍ଥାଗୁଡ଼ିକ</translation>
+<translation id="3190736958609431397">ଅନଟ୍ରାକ କରନ୍ତୁ</translation>
 <translation id="319282854780294203">ସୋସିଆଲ ନେଟୱାର୍କଗୁଡ଼ିକ</translation>
 <translation id="3194737229810486521"><ph name="URL" /> ଆପଣଙ୍କର ଡିଭାଇସ୍‌ରେ ସ୍ଥାୟୀରୂପେ ଡାଟା ଷ୍ଟୋର୍ କରିବାକୁ ଚାହୁଁଛି</translation>
 <translation id="3195213714973468956"><ph name="SERVER_NAME" />ରେ <ph name="PRINTER_NAME" /></translation>
@@ -902,6 +906,7 @@
 <translation id="3387261909427947069">ପେମେଣ୍ଟ ପଦ୍ଧତି</translation>
 <translation id="3391030046425686457">ଡେଲିଭରୀ ଠିକଣା</translation>
 <translation id="3391482648489541560">ଫାଇଲ୍ ଏଡିଟିଂ</translation>
+<translation id="3392028486601120379">URL ପାଟର୍ନ "<ph name="URL_PATTERN" />"ର ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ ପାଥ ଅଛି। ଏହି କୀ ପାଇଁ ପାଥଗୁଡ଼ିକ ସମର୍ଥିତ ନୁହେଁ, ଦୟାକରି ପାଥକୁ କାଢ଼ି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ। ଉ.ଦା *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">ପିକ୍‌ଅପ୍‌ ପଦ୍ଧତି</translation>
 <translation id="3399952811970034796">ବିତରଣ ଠିକଣା</translation>
 <translation id="3402261774528610252">ଏହି ସାଇଟକୁ ଲୋଡ୍ କରିବା ପାଇଁ ବ୍ୟବହୃତ ସଂଯୋଗ TLS 1.0 କିମ୍ବା TLS 1.1ର ବ୍ୟବହାର କରିଛି, ଯେଉଁଗୁଡ଼ିକୁ ଅଗ୍ରାହ୍ୟ କରାଯାଇଛି ଏବଂ ଭବିଷ୍ୟତରେ ଏହା ଅକ୍ଷମ ହୋଇଯିବ। ଥରେ ଅକ୍ଷମ ହୋଇଗଲା ପରେ, ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ଏହି ସାଇଟ୍ ଲୋଡ୍ କରିବାରୁ ପ୍ରତିରୋଧ କରାଯିବ। TLS 1.2 କିମ୍ବା ତା'ପରର ସଂସ୍କରଣକୁ ସର୍ଭର ସକ୍ଷମ କରିବା ଉଚିତ।</translation>
@@ -996,6 +1001,7 @@
 <translation id="3637662659967048211">Google ଆକାଉଣ୍ଟରେ ସେଭ୍ କରନ୍ତୁ</translation>
 <translation id="3640766068866876100">ସୂଚୀ-4x6-Ext</translation>
 <translation id="3642638418806704195">ଆପ୍ଲିକେସନ୍:</translation>
+<translation id="3647286794400715637">ପ୍ରତ୍ୟେକ URL ଷ୍ଟ୍ରିଙ୍ଗ ଏଣ୍ଟ୍ରି 1ରୁ 2 URL ମଧ୍ୟରେ ରହିବା ଉଚିତ।</translation>
 <translation id="3650584904733503804">ବୈଧକରଣ ସଫଳ ହେଲା</translation>
 <translation id="3653033846669030038">ଥିମ ପାର୍କଗୁଡ଼ିକ</translation>
 <translation id="3655241534245626312">ଅନୁମତି ସେଟିଂସକୁ ଯାଆନ୍ତୁ</translation>
@@ -1034,6 +1040,7 @@
 <translation id="3738166223076830879">ଆପଣଙ୍କର ଆଡମିନିଷ୍ଟ୍ରେଟରଙ୍କ ଦ୍ୱାରା ଆପଣଙ୍କ ବ୍ରାଉଜର୍ ପରିଚାଳିତ ହେଉଛି।</translation>
 <translation id="3740319564441798148">ଦୂରଗାମୀ ବସ ଏବଂ ରେଳ</translation>
 <translation id="3744111561329211289">ପୃଷ୍ଠପଟ ସିଙ୍କ୍‌</translation>
+<translation id="3744286742364977428">ଆପଣ ଡାଉନଲୋଡ କରୁଥିବା ଫାଇଲଗୁଡ଼ିକୁ ବିଶ୍ଳେଷଣ ପାଇଁ Google Cloud କିମ୍ବା ତୃତୀୟ ପକ୍ଷଗୁଡ଼ିକୁ ପଠାଯାଏ। ଉଦାହରଣ ସ୍ଵରୂପ, ସେଗୁଡ଼ିକୁ ସମ୍ବେଦନଶୀଳ ଡାଟା କିମ୍ବା ମାଲୱେର ପାଇଁ ସ୍କାନ କରାଯାଇପାରେ ଏବଂ କମ୍ପାନୀ ନୀତିଗୁଡ଼ିକ ଆଧାରରେ ଷ୍ଟୋର କରାଯାଇପାରେ।</translation>
 <translation id="3744899669254331632">ଆପଣ ବର୍ତ୍ତମାନ <ph name="SITE" />କୁ ଯାଇପାରିବେ ନାହିଁ କାରଣ ୱେବ୍-ସାଇଟ୍ ଅସ୍ପଷ୍ଟ କ୍ରେଡେନ୍ସିଆଲ୍‍ଗୁଡ଼ିକୁ ପଠାଇଛି ଯାହାକୁ, Chromium କାର୍ଯ୍ୟକାରୀ କରିପାରିବ ନାହିଁ। ନେଟ୍‍ୱାର୍କ ତ୍ରୁଟି ଓ ଆକ୍ରମଣଗୁଡ଼ିକ ସାଧାରଣତଃ ଅସ୍ଥାୟୀ ଅଟେ ତେଣୁ ଏହି ପୃଷ୍ଠା ପରେ କାମ କରିପାରେ।</translation>
 <translation id="3745099705178523657">ଆପଣ ସୁନିଶ୍ଚିତ କରିବା ପରେ, ଆପଣଙ୍କର Google ଆକାଉଣ୍ଟରୁ ମିଳିଥିବା କାର୍ଡ ବିବରଣୀ ଏହି ସାଇଟ୍ ସହ ସେୟାର୍ କରାଯିବ।</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ରେ ଆକ୍ରମଣକାରୀ ଆପଣଙ୍କୁ ହୁଏତ କିଛି ବିପଜ୍ଜନକ କାର୍ଯ୍ୟ ଯେପରିକି, ସଫ୍ଟୱେର୍ ଇନ୍‌ଷ୍ଟଲେସନ୍ କିମ୍ବା ନିଜର ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ (ଉଦାହରଣସ୍ୱରୂପ ପାସ୍‌ୱର୍ଡ, ଫୋନ୍‌ ନମ୍ବର କିମ୍ବା କ୍ରେଡିଟ୍ କାର୍ଡ) ପ୍ରକାଶ କରିବା ପାଇଁ ପ୍ରତାରିତ କରିପାରନ୍ତି। <ph name="BEGIN_LEARN_MORE_LINK" />ଅଧିକ ଜାଣନ୍ତୁ<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1141,6 +1148,7 @@
 <translation id="4087296516249690906">"ଇଭେଣ୍ଟ ତିଆରି କରନ୍ତୁ" ବଟନ୍, Google Calendarରେ ଶୀଘ୍ର ଏକ ନୂଆ ଇଭେଣ୍ଟ ତିଆରି କରିବାକୁ Enter ଦବାନ୍ତୁ</translation>
 <translation id="4088981014127559358">ସାଇଡ୍ 1 ଇମେଜ୍ Y ସିଫ୍ଟ</translation>
 <translation id="4089152113577680600">ଟ୍ରେ 14</translation>
+<translation id="4097288585054919042">ଆଲର୍ଟଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ</translation>
 <translation id="4098354747657067197">ପ୍ରତାରଣାତ୍ମକ ସାଇଟ୍ ଆଗରେ ଅଛି</translation>
 <translation id="4099048595830172239">ଗୋପନୀୟ ବିଷୟବସ୍ତୁ ଦେଖାଯାଉଥିବା ବେଳେ ଆପଣଙ୍କ ସ୍କ୍ରିନ <ph name="APPLICATION_TITLE" /> ସହ ସେୟାର କରିବାକୁ ଆଡମିନିଷ୍ଟ୍ରେଟର ନୀତି ସୁପାରିଶ କରେ ନାହିଁ:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chromeରେ ଫଣ୍ଟ ଆକାର ଏବଂ ଟାଇପଫେସ୍ କଷ୍ଟମାଇଜ୍ କରିବାକୁ Tab କରି Enter ଦବାନ୍ତୁ</translation>
@@ -1177,6 +1185,7 @@
 <translation id="4176463684765177261">ଅକ୍ଷମ କରାଯାଇଛି</translation>
 <translation id="4176535426287761656">ଟାଇମସେୟାର ଏବଂ ଛୁଟି କାଟିବା ପାଇଁ ପ୍ରପର୍ଟିଗୁଡ଼ିକ</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /><ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">ମୂଲ୍ୟ ଅନଟ୍ରାକ କରନ୍ତୁ</translation>
 <translation id="4194250254487269611">ବର୍ତ୍ତମାନ ଆପଣଙ୍କର କାର୍ଡ ସେଭ୍ କରାଯାଇପାରିବ ନାହିଁ</translation>
 <translation id="4196861286325780578">&amp;ଘୁଞ୍ଚାଇବା କାର୍ଯ୍ୟଟି ପୁଣିଥରେ କରନ୍ତୁ</translation>
 <translation id="4202554117186904723">ପଞ୍ଚମ ରୋଲ୍</translation>
@@ -1223,6 +1232,7 @@
 <translation id="4275830172053184480">ଆପଣଙ୍କର ଡିଭାଇସ୍‌ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ</translation>
 <translation id="4277028893293644418">ପାସ୍‌ୱର୍ଡ ରିସେଟ୍ କରନ୍ତୁ</translation>
 <translation id="4278390842282768270">ଅନୁମୋଦିତ</translation>
+<translation id="4282346679996504092">ଏହି ପ୍ରଡକ୍ଟ ପାଇଁ ଆଲର୍ଟଗୁଡ଼ିକୁ ବନ୍ଦ କରିଦିଆଯାଇଛି ଏବଂ ବୁକମାର୍କକୁ କାଢ଼ି ଦିଆଯାଇଛି</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{ଏହି କାର୍ଡ ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟରେ ସେଭ୍ କରିଦିଆଯାଇଛି}other{ଏହି କାର୍ଡଗୁଡ଼ିକୁ ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟରେ ସେଭ୍ କରିଦିଆଯାଇଛି}}</translation>
 <translation id="4287885627794386150">ଟ୍ରାଏଲ୍ ପାଇଁ ଯୋଗ୍ୟ କିନ୍ତୁ ସକ୍ରିୟ ନୁହେଁ</translation>
 <translation id="4297502707443874121"><ph name="THUMBNAIL_PAGE" /> ପୃଷ୍ଠା ପାଇଁ ଥମ୍ବନେଲ୍</translation>
@@ -1261,6 +1271,7 @@
 <translation id="4358059973562876591">ଆପଣଙ୍କ ଦ୍ୱାରା ନିର୍ଦ୍ଦିଷ୍ଟ କରାଯାଇଥିବା ଟେମ୍ପଲେଟ୍‍ଗୁଡ଼ିକ DnsOverHttpsMode ନୀତିରେ କୌଣସି ତ୍ରୁଟି ଯୋଗୁଁ ଲାଗୁ ହୋଇନପାରେ।</translation>
 <translation id="4358461427845829800">ପେମେଣ୍ଟ ପଦ୍ଧତିକୁ ପରିଚାଳନା କରନ୍ତୁ...</translation>
 <translation id="4359160567981085931">ଆପଣ ଏକ ପ୍ରତାରଣାମୂଳକ ସାଇଟ୍‌ରେ ଏବେ ଆପଣଙ୍କର ପାସ୍‍ୱାର୍ଡ ଲେଖିଛନ୍ତି। Chrome ସାହାଯ୍ୟ କରିପାରିବ। ଆପଣଙ୍କର ପାସ୍‌ୱାର୍ଡ ପରିବର୍ତ୍ତନ କରିବାକୁ ଓ ଆପଣଙ୍କର ଆକାଉଣ୍ଟ ବିପଦରେ ପଡ଼ିପାରେ ବୋଲି Googleକୁ ସୂଚିତ କରିବା ପାଇଁ, ’ଆକାଉଣ୍ଟର ସୁରକ୍ଷା କରନ୍ତୁ’ରେ କ୍ଲିକ୍ କରନ୍ତୁ।</translation>
+<translation id="4363222835916186793">ଏହି ପ୍ରଡକ୍ଟ ପାଇଁ ଆଲର୍ଟଗୁଡ଼ିକୁ ବନ୍ଦ କରିଦିଆଯାଇଛି</translation>
 <translation id="4367563149485757821">ନମ୍ବର୍-12 (ଏନଭଲପ୍)</translation>
 <translation id="437040971055499437">ସୁରକ୍ଷା ସମ୍ବନ୍ଧିତ ଇଭେଣ୍ଟ ଘଟିଲେ</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1413,6 +1424,7 @@
 <translation id="4792686369684665359">ଆପଣ ଦାଖଲ କରିବାକୁ ଯାଉଥିବା ସୂଚନା ସୁରକ୍ଷିତ ନୁହେଁ</translation>
 <translation id="4796594887379589189">ଜବ୍ ଆକାଉଣ୍ଟ ID</translation>
 <translation id="4798078619018708837">ଆପଣଙ୍କର କ୍ରେଡିଟ୍ କାର୍ଡ ବିବରଣୀ ଅପ୍‌ଡେଟ୍ କରିବାକୁ <ph name="CREDIT_CARD" /> ପାଇଁ ମିଆଦ ସମାପ୍ତି ତାରିଖ ଏବଂ CVC ଲେଖନ୍ତୁ। ଆପଣ ସୁନିଶ୍ଚିତ କରିବା ପରେ, ଆପଣଙ୍କର Google ଆକାଉଣ୍ଟରୁ ମିଳିଥିବା କାର୍ଡ ବିବରଣୀ ଏହି ସାଇଟ୍ ସହ ସେୟାର୍ କରାଯିବ।</translation>
+<translation id="4798269756263412078">ଯଦି କୌଣସି ସାଇଟରେ ମୂଲ୍ୟ ହ୍ରାସ ପାଏ, ତେବେ ଆଲର୍ଟ ପାଆନ୍ତୁ। ଆପଣଙ୍କ ଇମେଲକୁ ଆଲର୍ଟ ପଠାଯିବ।</translation>
 <translation id="4800132727771399293">ସମୟ ସୀମା ସମାପ୍ତ ହେବାର ତାରିଖ ଏବଂ CVCକୁ ଯାଞ୍ଚ କରିବା ସହିତ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">TouchID ବ୍ୟବହାର କରନ୍ତୁ</translation>
@@ -1657,6 +1669,7 @@
 <translation id="5396631636586785122">ଡାହାଣ ପଟରେ ଏଜ୍ ଷ୍ଟିଚ୍</translation>
 <translation id="5398772614898833570">ବିଜ୍ଞାପନଗୁଡ଼ିକ ଅବରୋଧ ହୋ‍ଇଛି</translation>
 <translation id="5400836586163650660">ଧୂସର</translation>
+<translation id="540630185148148480">ଆଲର୍ଟ ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="540969355065856584">ଏହି ସର୍ଭର୍, ଏହା <ph name="DOMAIN" /> ବୋଲି ପ୍ରମାଣିତ କରିପାରିଲା ନାହିଁ; ଏହି ସମୟରେ ଏହାର ସୁରକ୍ଷା ସାର୍ଟିଫିକେଟ୍ ବୈଧ ନୁହେଁ। ଏହା ହୁଏତ ଏକ ଭୁଲ୍ କନଫିଗ୍‍‍ରେସନ୍ କିମ୍ବା ଜଣେ ଆକ୍ରମଣକାରୀ ଆପଣଙ୍କର ସଂଯୋଗକୁ ପ୍ରତିରୋଧ କରୁଥିବା କାରଣରୁ ହୋଇପାରେ।</translation>
 <translation id="5412040515238827314">ଅବୈଧ ଫର୍ମାଟ: ପାଟର୍ନଗୁଡ଼ିକର ଏକ ତାଲିକା ଆଶା କରାଯାଉଛି।</translation>
 <translation id="5412236728747081950">ଆପଣଙ୍କୁ ଅଧିକ ପ୍ରାସଙ୍ଗିକ ବିଜ୍ଞାପନ ଦେଖାଇବା ପାଇଁ ଏହି ସାଇଟ Chromeରୁ ଆପଣଙ୍କର ରୁଚିଗୁଡ଼ିକ ପାଇଥାଏ</translation>
@@ -1721,6 +1734,7 @@
 <translation id="5580958916614886209">ଆପଣଙ୍କର ମିଆଦ ଶେଷ ହେଉଥିବା ମାସ ଯାଞ୍ଚ କରନ୍ତୁ ଏବଂ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ</translation>
 <translation id="558420943003240152">ପାସୱାର୍ଡ ଏବଂ ପାସକୀଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ…</translation>
 <translation id="5586446728396275693">କୌଣସି ସେଭ୍ ହୋଇଥିବା ଠିକଣାଗୁଡ଼ିକ ନାହିଁ</translation>
+<translation id="5586831831248371458"><ph name="KEYWORD_SUFFIX" /> ସନ୍ଧାନ କରନ୍ତୁ</translation>
 <translation id="5587987780934666589">ପ୍ଲାଟଫର୍ମ ଉପଯୋଗକର୍ତ୍ତା</translation>
 <translation id="5593349413089863479">ସଂଯୋଗଟି ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ସୁରକ୍ଷିତ ନୁହେଁ</translation>
 <translation id="5595485650161345191">ଠିକଣା ଏଡିଟ୍ କରନ୍ତୁ</translation>
@@ -1840,6 +1854,7 @@
 <translation id="5938153366081463283">ଭର୍ଚୁଆଲ କାର୍ଡ ଯୋଗ କରନ୍ତୁ</translation>
 <translation id="5938793338444039872">ଟ୍ରୟ</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> ଖୋଲୁଛି…</translation>
+<translation id="5947508410139465809">ଆପଣ ଅପଲୋଡ କିମ୍ବା ଆଟାଚ କରୁଥିବା ଫାଇଲଗୁଡ଼ିକୁ ବିଶ୍ଳେଷଣ ପାଇଁ Google Cloud କିମ୍ବା ତୃତୀୟ ପକ୍ଷଗୁଡ଼ିକୁ ପଠାଯାଏ। ଉଦାହରଣ ସ୍ଵରୂପ, ସେଗୁଡ଼ିକୁ ସମ୍ବେଦନଶୀଳ ଡାଟା କିମ୍ବା ମାଲୱେର ପାଇଁ ସ୍କାନ କରାଯାଇପାରେ ଏବଂ କମ୍ପାନୀ ନୀତିଗୁଡ଼ିକ ଆଧାରରେ ଷ୍ଟୋର କରାଯାଇପାରେ।</translation>
 <translation id="5951495562196540101">ଉପଭୋକ୍ତାଙ୍କ ଆକାଉଣ୍ଟ (ପ୍ୟାକେଜ୍‌ ହୋ‍ଇଥିବା ଲାଇସେନ୍ସ ଉପଲବ୍ଧ ଅଛି ) ନାମାଙ୍କନ କରାଯାଇପାରିବ ନାହିଁ।</translation>
 <translation id="5953516610448771166">ଏହି ମିଡିଆ ପାଇଁ ଲାଇଭ କ୍ୟାପସନ ଉପଲବ୍ଧ ନାହିଁ। କ୍ୟାପସନଗୁଡ଼ିକ ପାଇବାକୁ, ଏହି ସାଇଟ ପାଇଁ <ph name="CONTENT_SETTINGS" />କୁ ବ୍ଲକ କରନ୍ତୁ।</translation>
 <translation id="5955063559762970069">ହୋଟେଲ ଏବଂ ରହିବା ପାଇଁ ସୁବିଧା</translation>
@@ -1927,6 +1942,7 @@
 <translation id="6177128806592000436">ଏହି ସାଇଟ୍‌ରେ ଆପଣଙ୍କର ସଂଯୋଗ ସୁରକ୍ଷିତ ନୁହେଁ</translation>
 <translation id="6180316780098470077">ପୁଣି ଚେଷ୍ଟା କରିବା ଇଣ୍ଟରଭାଲ୍</translation>
 <translation id="61877208875190028">ମହିଳାମାନଙ୍କର ପୋଷାକ</translation>
+<translation id="6194209731893739467">ଆପଣଙ୍କ ସମସ୍ତ ଟ୍ରାକ କରାଯାଇଥିବା ପ୍ରଡକ୍ଟଗୁଡ଼ିକୁ ଏଠାରେ ଦେଖନ୍ତୁ</translation>
 <translation id="6195371403461054755">ଜିଓଲୋଜି</translation>
 <translation id="6196640612572343990">ତୃତୀୟ ପକ୍ଷ କୁକୀଗୁଡ଼ିକୁ ବ୍ଲକ୍ କରନ୍ତୁ</translation>
 <translation id="6203231073485539293">ଆପଣଙ୍କର ଇଣ୍ଟର୍‌ନେଟ୍ ସଂଯୋଗକୁ ଯାଞ୍ଚ କରନ୍ତୁ</translation>
@@ -1962,6 +1978,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{ଆପଣଙ୍କ ଡିଭାଇସ ବର୍ତ୍ତମାନ ରିଷ୍ଟାର୍ଟ ହେବ}=1{ଆପଣଙ୍କ ଡିଭାଇସ 1 ସେକେଣ୍ଡରେ ରିଷ୍ଟାର୍ଟ ହେବ}other{ଆପଣଙ୍କ ଡିଭାଇସ # ସେକେଣ୍ଡରେ ରିଷ୍ଟାର୍ଟ ହେବ}}</translation>
+<translation id="6301104306974789820">ମୂଲ୍ୟ ଟ୍ରାକିଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଆନ୍ତୁ</translation>
 <translation id="6302269476990306341">Chromeରେ Google ଆସିଷ୍ଟାଣ୍ଟ ବନ୍ଦ କରାଯାଇଛି</translation>
 <translation id="6305205051461490394"><ph name="URL" />ରେ ପହଞ୍ଚି ହେଉନାହିଁ।</translation>
 <translation id="6311165245110979290">ଭର୍ଚୁଆଲ କାର୍ଡ ଉପଲବ୍ଧ</translation>
@@ -2021,6 +2038,7 @@
 <translation id="6451458296329894277">ଫର୍ମ ପୁନଃଦାଖଲକରଣ ସୁନିଶ୍ଚିତ କରନ୍ତୁ</translation>
 <translation id="6456955391422100996">ବିଜ୍ଞାପନକୁ କାଢ଼ି ଦିଆଯାଇଛି।</translation>
 <translation id="6457206614190510200">ସାଡାଲ୍ ଷ୍ଟିଚ୍</translation>
+<translation id="6457455098507772300">ମୂଲ୍ୟ ହ୍ରାସ ଆଲର୍ଟ ଆପଣଙ୍କ ଡେସ୍କଟପରେ ପପଅପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାବେ ଦେଖାଯିବ</translation>
 <translation id="6458606150257356946">ଯେ କୌଣସି ମତେ ପେଷ୍ଟ କରନ୍ତୁ</translation>
 <translation id="6464094930452079790">ଛବିଗୁଡ଼ିକ</translation>
 <translation id="6465306955648956876">ପାସ୍‌ୱାର୍ଡଗୁଡ଼ିକୁ ପରିଚାଳିତ କରନ୍ତୁ…</translation>
@@ -2078,6 +2096,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">ଖାଲି କରନ୍ତୁ</translation>
 <translation id="6645291930348198241">କୁକୀ ଏବଂ ସାଇଟ୍ ଡାଟା ଆକ୍ସେସ୍ କରନ୍ତୁ।</translation>
+<translation id="6645478838938543427">ମୂଲ୍ୟ ହ୍ରାସ ଆଲର୍ଟ <ph name="EMAIL_ADDRESS" />କୁ ପଠାଯିବ</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{କୌଣସିଟି ନୁହେଁ}=1{1ଟି ସାଇଟ୍‌ରୁ (ଆପଣ ନିଜ Google Accountରୁ ସାଇନ୍ ଆଉଟ୍ ହେବେ ନାହିଁ)}other{#ଟି ସାଇଟ୍‌ରୁ (ଆପଣ ନିଜ Google Accountରୁ ସାଇନ୍ ଆଉଟ୍ ହେବେ ନାହିଁ)}}</translation>
 <translation id="6648459603387803038">ଆପଣଙ୍କର ଆଡମିନିଷ୍ଟ୍ରେଟର୍ ଆପଣଙ୍କ ବ୍ରାଉଜର୍ ସେଟଅପକୁ ରିମୋଟ୍ ଭାବରେ ବଦଳାଇପାରିବେ। ଏହି ଡିଭାଇସରେ କରାଯାଉଥିବା କାର୍ଯ୍ୟକଳାପ Chrome ବାହାରେ ମଧ୍ୟ ପରିଚାଳନା କରାଯାଇପାରେ।</translation>
 <translation id="6648524591329069940">Serif ଫଣ୍ଟ</translation>
@@ -2271,6 +2290,7 @@
 <translation id="7182878459783632708">କୌଣସି ନୀତି ସେଟ୍ କରାଯାଇ ନାହିଁ</translation>
 <translation id="7186367841673660872">ଏହି ପୃଷ୍ଠା <ph name="ORIGINAL_LANGUAGE" />ରୁ<ph name="LANGUAGE_LANGUAGE" />ରେ ଅନୁବାଦ କରାଯାଇଛି</translation>
 <translation id="718872491229180389">ଚିଅରଲିଡିଂ</translation>
+<translation id="7192188280913829296">"vendor_id" ଆଟ୍ରିବ୍ୟୁଟ ମଧ୍ୟ ନିର୍ଦ୍ଦିଷ୍ଟ କରିବା ଉଚିତ।</translation>
 <translation id="7192203810768312527"><ph name="SIZE" /> ଜାଗା ଖାଲି କରିଥାଏ। କିଛି ସାଇଟ୍‍ ଆପଣଙ୍କର ପରବର୍ତ୍ତୀ ଭ୍ରମଣ ସମୟରେ ଆହୁରି ଧୀରେ ଲୋଡ୍ ହୋଇପାରନ୍ତି।</translation>
 <translation id="7193661028827781021">ରେଫରେନ୍ସ</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb
index 568912e..b954487 100644
--- a/components/strings/components_strings_pl.xtb
+++ b/components/strings/components_strings_pl.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Odblokowywanie urządzenia</translation>
 <translation id="1269516672602708785">Szybko utwórz nową witrynę w Witrynach Google</translation>
 <translation id="1270502636509132238">Metoda odbioru</translation>
+<translation id="1273592791152866347">Śledzenie cen zostało wyłączone</translation>
 <translation id="1281476433249504884">Układarka 1</translation>
 <translation id="1285320974508926690">Nigdy nie tłumacz tej witryny</translation>
 <translation id="1288548991597756084">Zapisz bezpiecznie kartę</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Oprogramowanie freeware i shareware</translation>
 <translation id="1553358976309200471">Zaktualizuj Chrome</translation>
+<translation id="1554003749331233619">Obserwujesz teraz ten produkt. Ta strona jest zapisana w folderze <ph name="LAST_BOOKMARKS_FOLDER" /></translation>
 <translation id="1555130319947370107">Niebieski</translation>
 <translation id="1559447966090556585">Wyświetlać powiadomienia?</translation>
 <translation id="1559528461873125649">Brak takiego pliku lub katalogu</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Zarządzaj kontem Google; naciśnij Enter, aby zarządzać swoimi danymi, prywatnością i bezpieczeństwem na koncie Google</translation>
 <translation id="2436186046335138073">Zezwolić usłudze <ph name="HANDLER_HOSTNAME" /> na otwieranie wszystkich linków <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Cztery otwory po prawej</translation>
+<translation id="2443309680964448806">Coś poszło nie tak. Zmiana nie została zapisana.</translation>
 <translation id="2448295565072560657">Urządzenia peryferyjne podłączone do tego urządzenia, gdy jesteś zalogowany(-a)</translation>
 <translation id="2450021089947420533">Serie czynności</translation>
 <translation id="2463739503403862330">Wpisz</translation>
@@ -688,6 +691,7 @@
 <translation id="2740531572673183784">OK</translation>
 <translation id="2742511345840685325">Tenis stołowy</translation>
 <translation id="2742870351467570537">Usuń wybrane elementy</translation>
+<translation id="2759825833388495838">wypełnić hasło na <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Komiksy</translation>
 <translation id="2765217105034171413">Mały</translation>
 <translation id="277133753123645258">Metoda wysyłki</translation>
@@ -819,6 +823,7 @@
 <translation id="317878711435188021">Wiedzieć, kiedy używasz urządzenia</translation>
 <translation id="3180358318770512945">Rodzicielstwo</translation>
 <translation id="3187306450550410410">Elastyczne zarządzanie pracą</translation>
+<translation id="3190736958609431397">Wyłącz śledzenie</translation>
 <translation id="319282854780294203">Sieci społecznościowe</translation>
 <translation id="3194737229810486521"><ph name="URL" /> chce na stałe przechowywać dane na Twoim urządzeniu</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na serwerze <ph name="SERVER_NAME" /></translation>
@@ -904,6 +909,7 @@
 <translation id="3387261909427947069">Formy płatności</translation>
 <translation id="3391030046425686457">Adres dostawy</translation>
 <translation id="3391482648489541560">edytowanie plików</translation>
+<translation id="3392028486601120379">Wzorzec adresu URL „<ph name="URL_PATTERN" />” ma określoną ścieżkę. W przypadku tego klucza ścieżki nie są obsługiwane. Usuń ścieżkę i spróbuj ponownie, np. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Metoda odbioru</translation>
 <translation id="3399952811970034796">Adres dostawy</translation>
 <translation id="3402261774528610252">Do połączenia z tą stroną użyto protokołu TLS 1.0 lub 1.1. Obie te wersje zostały wycofane, a w przyszłości zostaną wyłączone. Po ich wyłączeniu użytkownicy nie będą mogli otwierać tej strony. Serwer powinien korzystać z protokołu TLS w wersji 1.2 lub nowszej.</translation>
@@ -999,6 +1005,7 @@
 <translation id="3637662659967048211">Zapisz na koncie Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Aplikacja:</translation>
+<translation id="3647286794400715637">Każda pozycja z adresami URL musi zawierać od 1 do 2 takich adresów.</translation>
 <translation id="3650584904733503804">Weryfikacja powiodła się</translation>
 <translation id="3653033846669030038">Wesołe miasteczka</translation>
 <translation id="3655241534245626312">Otwórz ustawienia uprawnień</translation>
@@ -1037,6 +1044,7 @@
 <translation id="3738166223076830879">Przeglądarką zarządza administrator.</translation>
 <translation id="3740319564441798148">Międzymiastowe połączenia autobusowe i kolejowe</translation>
 <translation id="3744111561329211289">Synchronizacja w tle</translation>
+<translation id="3744286742364977428">Pobierane pliki są wysyłane do Google Cloud lub innych firm w celu przeanalizowania. Na przykład mogą być skanowane pod kątem danych wrażliwych lub złośliwego oprogramowania i przechowywane zgodnie z zasadami firmy.</translation>
 <translation id="3744899669254331632">Nie możesz teraz odwiedzić strony <ph name="SITE" />, ponieważ wysłała ona zaszyfrowane dane logowania, których Chromium nie może przetworzyć. Błędy sieciowe i ataki są zazwyczaj tymczasowe, więc prawdopodobnie strona będzie dostępna później.</translation>
 <translation id="3745099705178523657">Po potwierdzeniu dane karty z Twojego konta Google zostaną udostępnione tej stronie.</translation>
 <translation id="3748148204939282805">Osoby atakujące na stronie <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą podstępem nakłonić Cię do wykonania czynności niebezpiecznych takich jak zainstalowanie oprogramowania czy ujawnienie danych osobowych (na przykład haseł, numerów telefonów lub danych kart kredytowych). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1152,7 @@
 <translation id="4087296516249690906">Przycisk Utwórz wydarzenie; naciśnij Enter, aby szybko utworzyć nowe wydarzenie w Kalendarzu Google</translation>
 <translation id="4088981014127559358">Strona 1 – przesunięcie obrazu wzdłuż osi Y</translation>
 <translation id="4089152113577680600">Taca 14</translation>
+<translation id="4097288585054919042">Wyłącz alerty</translation>
 <translation id="4098354747657067197">Wchodzisz na stronę wprowadzającą w błąd</translation>
 <translation id="4099048595830172239">Zgodnie z zasadą administratora nie zaleca się udostępniania ekranu za pomocą aplikacji <ph name="APPLICATION_TITLE" />, gdy są widoczne treści poufne:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />; aby dostosować rozmiary i kroje czcionek w Chrome, naciśnij Tab, a potem Enter</translation>
@@ -1180,6 +1189,7 @@
 <translation id="4176463684765177261">Wyłączone</translation>
 <translation id="4176535426287761656">Rezydencje i domki letniskowe</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Wyłącz śledzenie ceny</translation>
 <translation id="4194250254487269611">W tej chwili nie można zapisać karty</translation>
 <translation id="4196861286325780578">&amp;Ponów przeniesienie</translation>
 <translation id="4202554117186904723">Rolka 5</translation>
@@ -1226,6 +1236,7 @@
 <translation id="4275830172053184480">Zrestartuj urządzenie</translation>
 <translation id="4277028893293644418">Resetuj hasło</translation>
 <translation id="4278390842282768270">Dopuszczone</translation>
+<translation id="4282346679996504092">Alerty dotyczące tego produktu zostały wyłączone, a zakładka usunięta</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Ta karta została zapisana na Twoim koncie Google}few{Te karty zostały zapisane na Twoim koncie Google}many{Te karty zostały zapisane na Twoim koncie Google}other{Te karty zostały zapisane na Twoim koncie Google}}</translation>
 <translation id="4287885627794386150">Kwalifikuje się do wersji próbnej, ale nie jest ona aktywna</translation>
 <translation id="4297502707443874121">Miniatura strony <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1264,6 +1275,7 @@
 <translation id="4358059973562876591">Nie można zastosować wybranych szablonów z powodu błędu związanego z zasadą DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Zarządzaj formami płatności…</translation>
 <translation id="4359160567981085931">Przed chwilą wpisano hasło na stronie wprowadzającej w błąd. Chrome może pomóc. Aby zmienić hasło i powiadomić Google, że Twoje konto może być zagrożone, kliknij Chroń konto.</translation>
+<translation id="4363222835916186793">Alerty dotyczące tego produktu zostały wyłączone</translation>
 <translation id="4367563149485757821">Number-12 (koperta)</translation>
 <translation id="437040971055499437">Wystąpiło zdarzenie związane z bezpieczeństwem</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1428,7 @@
 <translation id="4792686369684665359">Dane, które chcesz przesłać, nie są zabezpieczone</translation>
 <translation id="4796594887379589189">Identyfikator konta zadania</translation>
 <translation id="4798078619018708837">Wpisz datę ważności i kod CVC karty <ph name="CREDIT_CARD" />, by zaktualizować jej dane. Po potwierdzeniu dane karty z Twojego konta Google zostaną udostępnione tej stronie.</translation>
+<translation id="4798269756263412078">Jeśli na którejkolwiek stronie produkt stanieje, otrzymasz alert. Alerty będą wysyłane na Twój adres e-mail.</translation>
 <translation id="4800132727771399293">Sprawdź datę ważności i kod CVC, a potem spróbuj ponownie</translation>
 <translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
 <translation id="4806051791961048632">Użyj funkcji Touch ID</translation>
@@ -1659,6 +1672,7 @@
 <translation id="5396631636586785122">Zszywanie przy prawej krawędzi</translation>
 <translation id="5398772614898833570">Reklamy zostały zablokowane</translation>
 <translation id="5400836586163650660">Szary</translation>
+<translation id="540630185148148480">Włącz alerty</translation>
 <translation id="540969355065856584">Ten serwer nie może udowodnić, że należy do domeny <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest obecnie ważny. Może to być spowodowane nieprawidłową konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
 <translation id="5412040515238827314">Nieprawidłowy format: oczekiwana jest lista wzorców.</translation>
 <translation id="5412236728747081950">Witryna korzysta z gromadzonych przez Chrome informacji o Twoich zainteresowaniach, aby wyświetlać trafniejsze reklamy</translation>
@@ -1723,6 +1737,7 @@
 <translation id="5580958916614886209">Sprawdź miesiąc ważności i spróbuj ponownie</translation>
 <translation id="558420943003240152">Zarządzaj hasłami i kluczami…</translation>
 <translation id="5586446728396275693">Brak zapisanych adresów</translation>
+<translation id="5586831831248371458">Szukaj: <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Platforma – użytkownik</translation>
 <translation id="5593349413089863479">Połączenie nie jest całkiem bezpieczne</translation>
 <translation id="5595485650161345191">Edytuj adres</translation>
@@ -1842,6 +1857,7 @@
 <translation id="5938153366081463283">Dodaj kartę wirtualną</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Otwieram <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">Przesyłane lub dołączone pliki są wysyłane do Google Cloud lub innych firm w celu przeanalizowania. Na przykład mogą być skanowane pod kątem danych wrażliwych lub złośliwego oprogramowania i przechowywane zgodnie z zasadami firmy.</translation>
 <translation id="5951495562196540101">Nie można zarejestrować się przy użyciu konta klienta (w pakiecie dostępna jest licencja).</translation>
 <translation id="5953516610448771166">Dla tej treści multimedialnej napisy na żywo nie są dostępne. Aby wyświetlać napisy, zablokuj w tej witrynie <ph name="CONTENT_SETTINGS" />.</translation>
 <translation id="5955063559762970069">Hotele i noclegi</translation>
@@ -1930,6 +1946,7 @@
 <translation id="6177128806592000436">Twoje połączenie z tą witryną nie jest bezpieczne</translation>
 <translation id="6180316780098470077">Interwał ponawiania</translation>
 <translation id="61877208875190028">Odzież damska</translation>
+<translation id="6194209731893739467">Tu zobaczysz wszystkie obserwowane produkty</translation>
 <translation id="6195371403461054755">Geologia</translation>
 <translation id="6196640612572343990">Blokuj pliki cookie innych firm</translation>
 <translation id="6203231073485539293">Sprawdź połączenie z internetem</translation>
@@ -1965,6 +1982,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">Kod CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Twoje urządzenie uruchomi się ponownie teraz}=1{Twoje urządzenie uruchomi się ponownie za 1 sekundę}few{Twoje urządzenie uruchomi się ponownie za # sekundy}many{Twoje urządzenie uruchomi się ponownie za # sekund}other{Twoje urządzenie uruchomi się ponownie za # sekundy}}</translation>
+<translation id="6301104306974789820">Otrzymuj powiadomienia ze śledzenia cen</translation>
 <translation id="6302269476990306341">Wyłączam Asystenta Google w Chrome</translation>
 <translation id="6305205051461490394">Strona <ph name="URL" /> jest nieosiągalna.</translation>
 <translation id="6311165245110979290">Dostępna jest karta wirtualna</translation>
@@ -2024,6 +2042,7 @@
 <translation id="6451458296329894277">Potwierdź ponowne przesłanie formularza</translation>
 <translation id="6456955391422100996">Reklama została usunięta.</translation>
 <translation id="6457206614190510200">Zszywanie grzbietowe</translation>
+<translation id="6457455098507772300">Alerty o obniżkach cen wyświetlają się jako wyskakujące powiadomienia na pulpicie</translation>
 <translation id="6458606150257356946">Wklej mimo to</translation>
 <translation id="6464094930452079790">obrazy</translation>
 <translation id="6465306955648956876">Zarządzaj hasłami…</translation>
@@ -2081,6 +2100,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Wyczyść</translation>
 <translation id="6645291930348198241">Dostęp do plików cookie i danych witryn.</translation>
+<translation id="6645478838938543427">Alerty o obniżkach cen będą wysyłane na adres <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Brak}=1{Z 1 witryny (nie spowoduje to wylogowania z konta Google)}few{Z # witryn (nie spowoduje to wylogowania z konta Google)}many{Z # witryn (nie spowoduje to wylogowania z konta Google)}other{Z # witryny (nie spowoduje to wylogowania z konta Google)}}</translation>
 <translation id="6648459603387803038">Administrator może zdalnie zmienić konfigurację przeglądarki. Aktywność na tym urządzeniu może być zarządzana również poza Chrome.</translation>
 <translation id="6648524591329069940">Czcionka szeryfowa</translation>
@@ -2274,6 +2294,7 @@
 <translation id="7182878459783632708">Brak ustawionych zasad</translation>
 <translation id="7186367841673660872">Ta strona została przetłumaczona z języka<ph name="ORIGINAL_LANGUAGE" />na język<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Cheerleading</translation>
+<translation id="7192188280913829296">Musisz też określić atrybut „vendor_id”.</translation>
 <translation id="7192203810768312527">Zwolni się <ph name="SIZE" />. Podczas następnej wizyty niektóre strony mogą ładować się wolniej.</translation>
 <translation id="7193661028827781021">Źródła wiedzy</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb
index 965dbbc..341afa3 100644
--- a/components/strings/components_strings_pt-PT.xtb
+++ b/components/strings/components_strings_pt-PT.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">OK</translation>
 <translation id="2742511345840685325">Ténis de mesa</translation>
 <translation id="2742870351467570537">Remover itens seleccionados</translation>
+<translation id="2759825833388495838">preencher a sua palavra-passe na app <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Banda desenhada</translation>
 <translation id="2765217105034171413">Pequeno</translation>
 <translation id="277133753123645258">Método de envio</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb
index dcffa8ce..fc045d6d 100644
--- a/components/strings/components_strings_ru.xtb
+++ b/components/strings/components_strings_ru.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Разблокировка устройства</translation>
 <translation id="1269516672602708785">Быстро создать сайт в Google Сайтах</translation>
 <translation id="1270502636509132238">Способ получения</translation>
+<translation id="1273592791152866347">Цена больше не отслеживается.</translation>
 <translation id="1281476433249504884">Укладчик 1</translation>
 <translation id="1285320974508926690">Никогда не переводить этот сайт</translation>
 <translation id="1288548991597756084">Храните данные карты в безопасности</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Бесплатное и условно-бесплатное ПО</translation>
 <translation id="1553358976309200471">Обновить Chrome</translation>
+<translation id="1554003749331233619">Теперь вы отслеживаете этот товар. Эта страница сохранена в разделе "<ph name="LAST_BOOKMARKS_FOLDER" />".</translation>
 <translation id="1555130319947370107">Синий</translation>
 <translation id="1559447966090556585">Получать уведомления?</translation>
 <translation id="1559528461873125649">Данный файл или каталог не существует</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Параметры аккаунта Google. Чтобы управлять своими данными, конфиденциальностью и безопасностью в аккаунте Google, нажмите Ввод.</translation>
 <translation id="2436186046335138073">Использовать <ph name="HANDLER_HOSTNAME" /> для обработки ссылок типа "<ph name="PROTOCOL" />"?</translation>
 <translation id="2438874542388153331">Четыре отверстия справа</translation>
+<translation id="2443309680964448806">Произошла ошибка. Изменение не сохранено.</translation>
 <translation id="2448295565072560657">Когда вы вошли в систему, к этому устройству были подключены следующие периферийные устройства.</translation>
 <translation id="2450021089947420533">Сеансы</translation>
 <translation id="2463739503403862330">Заполнить</translation>
@@ -818,6 +821,7 @@
 <translation id="317878711435188021">доступ к информации об использовании устройства</translation>
 <translation id="3180358318770512945">Воспитание детей</translation>
 <translation id="3187306450550410410">Гибкие условия работы</translation>
+<translation id="3190736958609431397">Перестать отслеживать</translation>
 <translation id="319282854780294203">Социальные сети</translation>
 <translation id="3194737229810486521">Сайт <ph name="URL" /> запрашивает разрешение на постоянное хранение данных на вашем устройстве.</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> на <ph name="SERVER_NAME" /></translation>
@@ -903,6 +907,7 @@
 <translation id="3387261909427947069">Способы оплаты</translation>
 <translation id="3391030046425686457">Адрес доставки</translation>
 <translation id="3391482648489541560">Редактирование файлов</translation>
+<translation id="3392028486601120379">Задан путь для шаблона URL "<ph name="URL_PATTERN" />". Пути для этого ключа не поддерживаются. Удалите путь и попробуйте снова. Например, вместо *://example.com/ введите *://example.com.</translation>
 <translation id="3395827396354264108">Способ выдачи</translation>
 <translation id="3399952811970034796">Адрес доставки</translation>
 <translation id="3402261774528610252">Сайт использует устаревший протокол TLS 1.0 или TLS 1.1. В будущем эти протоколы будут отключены, из-за чего пользователи не смогут зайти на сайт. На сервере нужно включить протокол TLS 1.2 или более поздней версии.</translation>
@@ -998,6 +1003,7 @@
 <translation id="3637662659967048211">Сохранить в аккаунте Google?</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Приложение:</translation>
+<translation id="3647286794400715637">Каждая запись должна содержать 1–2 URL.</translation>
 <translation id="3650584904733503804">Проверка выполнена успешно</translation>
 <translation id="3653033846669030038">Тематические парки</translation>
 <translation id="3655241534245626312">Перейти в настройки разрешений</translation>
@@ -1036,6 +1042,7 @@
 <translation id="3738166223076830879">Этим браузером управляет администратор.</translation>
 <translation id="3740319564441798148">Автобусы и поезда дальнего следования</translation>
 <translation id="3744111561329211289">Фоновая синхронизация</translation>
+<translation id="3744286742364977428">Скачанные вами файлы передаются на проверку в Google Cloud или сторонние сервисы. В частности, файлы могут быть просканированы на наличие конфиденциальных данных или вредоносного ПО, а также храниться на основании правил компании.</translation>
 <translation id="3744899669254331632">Перейти на сайт <ph name="SITE" /> невозможно, так как его идентификационные данные зашифрованы, и Chrome не может их обработать. Это могло произойти из-за ошибки сети или атаки на сайт. Скорее всего, он заработает через некоторое время.</translation>
 <translation id="3745099705178523657">После подтверждения реквизиты карты из аккаунта Google будут переданы этому сайту.</translation>
 <translation id="3748148204939282805">Посещение сайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может привести к установке вредоносного ПО или хищению личной информации (например, паролей, телефонных номеров и данных банковских карт). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1143,6 +1150,7 @@
 <translation id="4087296516249690906">Кнопка "Создать мероприятие". Чтобы быстро создать мероприятие в Google Календаре, нажмите Ввод.</translation>
 <translation id="4088981014127559358">Смещение изображений на лицевой стороне по оси Y</translation>
 <translation id="4089152113577680600">Лоток 14</translation>
+<translation id="4097288585054919042">Отключить оповещения</translation>
 <translation id="4098354747657067197">Осторожно, поддельный сайт!</translation>
 <translation id="4099048595830172239">Администратор не рекомендует предоставлять доступ к экрану для приложения "<ph name="APPLICATION_TITLE" />", когда видны конфиденциальные данные:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />. Нажмите Tab, а затем Ввод, чтобы настроить шрифты и их размеры в Chrome.</translation>
@@ -1179,6 +1187,7 @@
 <translation id="4176463684765177261">Отключено</translation>
 <translation id="4176535426287761656">Таймшер и недвижимость для отдыха</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Перестать отслеживать цену</translation>
 <translation id="4194250254487269611">Сейчас сохранить эту карту нельзя.</translation>
 <translation id="4196861286325780578">&amp;Повторить перемещение</translation>
 <translation id="4202554117186904723">Пятый рулон</translation>
@@ -1225,6 +1234,7 @@
 <translation id="4275830172053184480">Перезапуск устройства</translation>
 <translation id="4277028893293644418">Сбросить пароль</translation>
 <translation id="4278390842282768270">Разрешено</translation>
+<translation id="4282346679996504092">Оповещения об этом товаре отключены, а закладка удалена.</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Карта сохранена в аккаунте Google.}one{Карты сохранены в аккаунте Google.}few{Карты сохранены в аккаунте Google.}many{Карты сохранены в аккаунте Google.}other{Карты сохранены в аккаунте Google.}}</translation>
 <translation id="4287885627794386150">Пробная функция доступна, но не активирована</translation>
 <translation id="4297502707443874121">Уменьшенное изображение страницы <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1263,6 +1273,7 @@
 <translation id="4358059973562876591">Указанные вами шаблоны нельзя применить из-за ошибки в настройке правила DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Управление способами оплаты…</translation>
 <translation id="4359160567981085931">Вы только что ввели пароль на поддельном сайте. Чтобы изменить пароль и сообщить Google о возможной угрозе безопасности, нажмите "Защитить аккаунт".</translation>
+<translation id="4363222835916186793">Оповещения об этом товаре отключены.</translation>
 <translation id="4367563149485757821">Number-12 (конверт)</translation>
 <translation id="437040971055499437">Зарегистрировано событие безопасности</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1415,6 +1426,7 @@
 <translation id="4792686369684665359">Отправляемая вами информация не защищена</translation>
 <translation id="4796594887379589189">Идентификатор аккаунта, в котором выполняется задание</translation>
 <translation id="4798078619018708837">Введите срок действия и CVC-код карты <ph name="CREDIT_CARD" />. После этого ее реквизиты из аккаунта Google будут переданы сайту.</translation>
+<translation id="4798269756263412078">Если на каком-нибудь сайте появится скидка, вы получите оповещение на электронную почту.</translation>
 <translation id="4800132727771399293">Проверьте срок действия и CVC-код, а затем повторите попытку</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Использовать Touch ID</translation>
@@ -1658,6 +1670,7 @@
 <translation id="5396631636586785122">Скобы по правому краю</translation>
 <translation id="5398772614898833570">Реклама заблокирована</translation>
 <translation id="5400836586163650660">Серый</translation>
+<translation id="540630185148148480">Включить оповещения</translation>
 <translation id="540969355065856584">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности может быть недействителен в настоящее время. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
 <translation id="5412040515238827314">Недействительный формат. Необходимо указать список шаблонов.</translation>
 <translation id="5412236728747081950">Этот сайт использует информацию из Chrome о ваших интересах, чтобы показывать более подходящие рекламные объявления.</translation>
@@ -1722,6 +1735,7 @@
 <translation id="5580958916614886209">Проверьте месяц в сроке действия карты и повторите попытку</translation>
 <translation id="558420943003240152">Управление паролями и ключами доступа</translation>
 <translation id="5586446728396275693">Нет сохраненных адресов</translation>
+<translation id="5586831831248371458">Искать: <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Пользователь платформы</translation>
 <translation id="5593349413089863479">Подключение недостаточно защищено</translation>
 <translation id="5595485650161345191">Изменить адрес</translation>
@@ -1841,6 +1855,7 @@
 <translation id="5938153366081463283">Добавить виртуальную карту</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Загрузка <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">Загруженные или прикрепленные вами файлы передаются на проверку в Google Cloud или сторонние сервисы. В частности, файлы могут быть просканированы на наличие конфиденциальных данных или вредоносного ПО, а также храниться на основании правил компании.</translation>
 <translation id="5951495562196540101">Регистрация невозможна, так как тип аккаунта не соответствует лицензии на устройстве.</translation>
 <translation id="5953516610448771166">Автоматические субтитры недоступны для этого медиафайла. Чтобы получить их, заблокируйте <ph name="CONTENT_SETTINGS" /> для этого сайта.</translation>
 <translation id="5955063559762970069">Гостиницы и другие места размещения</translation>
@@ -1929,6 +1944,7 @@
 <translation id="6177128806592000436">Подключение к сайту не защищено</translation>
 <translation id="6180316780098470077">Интервал повтора</translation>
 <translation id="61877208875190028">Одежда для женщин</translation>
+<translation id="6194209731893739467">Здесь вы найдете все отслеживаемые товары</translation>
 <translation id="6195371403461054755">Геология</translation>
 <translation id="6196640612572343990">Блокировать сторонние файлы cookie</translation>
 <translation id="6203231073485539293">Проверьте подключение к Интернету</translation>
@@ -1964,6 +1980,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">Код CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Устройство сейчас перезапустится}=1{Устройство перезапустится через 1 секунду}one{Устройство перезапустится через # секунду}few{Устройство перезапустится через # секунды}many{Устройство перезапустится через # секунд}other{Устройство перезапустится через # секунды}}</translation>
+<translation id="6301104306974789820">Получать уведомления об изменении цены</translation>
 <translation id="6302269476990306341">Google Ассистент в Chrome отключится</translation>
 <translation id="6305205051461490394">Сайт <ph name="URL" /> недоступен.</translation>
 <translation id="6311165245110979290">Виртуальная карта доступна</translation>
@@ -2023,6 +2040,7 @@
 <translation id="6451458296329894277">Подтвердите повторную отправку формы</translation>
 <translation id="6456955391422100996">Объявление удалено.</translation>
 <translation id="6457206614190510200">Скрепление внакидку</translation>
+<translation id="6457455098507772300">Оповещения о скидках будут появляться на рабочем столе</translation>
 <translation id="6458606150257356946">Все равно вставить</translation>
 <translation id="6464094930452079790">Изображения</translation>
 <translation id="6465306955648956876">Управление паролями…</translation>
@@ -2080,6 +2098,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Удалить</translation>
 <translation id="6645291930348198241">доступ к файлам cookie и данным сайта.</translation>
+<translation id="6645478838938543427">Оповещения о скидках будут отправляться на адрес <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Нет}=1{С 1 сайта (вы останетесь в аккаунте Google)}one{С # сайта (вы останетесь в аккаунте Google)}few{С # сайтов (вы останетесь в аккаунте Google)}many{С # сайтов (вы останетесь в аккаунте Google)}other{С # сайта (вы останетесь в аккаунте Google)}}</translation>
 <translation id="6648459603387803038">Администратор может удаленно менять настройки браузера и управлять действиями вне браузера Chrome на этом устройстве.</translation>
 <translation id="6648524591329069940">Шрифты с засечками</translation>
@@ -2273,6 +2292,7 @@
 <translation id="7182878459783632708">Правила не заданы</translation>
 <translation id="7186367841673660872">Эта страница была переведена автоматически<ph name="ORIGINAL_LANGUAGE" />&gt;<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Чирлидинг</translation>
+<translation id="7192188280913829296">Необходимо заполнить поле "vendor_id".</translation>
 <translation id="7192203810768312527">Освободится <ph name="SIZE" /> пространства. После этого некоторые веб-страницы могут загружаться дольше обычного.</translation>
 <translation id="7193661028827781021">Справочные ресурсы</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_si.xtb b/components/strings/components_strings_si.xtb
index 727bda1..0771cc2 100644
--- a/components/strings/components_strings_si.xtb
+++ b/components/strings/components_strings_si.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">උපාංග අගුලු හැරීම</translation>
 <translation id="1269516672602708785">ඉක්මනින් Google Sites තුළ නව අඩවියක් තනන්න</translation>
 <translation id="1270502636509132238">නංවා ගැනීමේ ක්‍රමය</translation>
+<translation id="1273592791152866347">මිල නිරීක්ෂණය කිරීම අක්‍රියයි</translation>
 <translation id="1281476433249504884">අට්ටිය 1</translation>
 <translation id="1285320974508926690">මෙම අඩවිය කිසිවිට පරිවර්තනය නොකරන්න</translation>
 <translation id="1288548991597756084">කාඩ්පත ආරක්ෂිතව සුරකින්න</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">නොමිලේ මෘදුකාංග සහ බෙදා ගන්නා මෘදුකාංග</translation>
 <translation id="1553358976309200471">Chrome යාවත් කරන්න</translation>
+<translation id="1554003749331233619">ඔබ දැන් මෙම නිෂ්පාදනය නිරීක්ෂණය කරමින් සිටී. මෙම පිටුව <ph name="LAST_BOOKMARKS_FOLDER" /> හි සුරකින ලදි</translation>
 <translation id="1555130319947370107">නිල්</translation>
 <translation id="1559447966090556585">දැනුම් දීම් ලබා ගන්නද?</translation>
 <translation id="1559528461873125649">එවන් ගොනුවක් හෝ නාමාවලියක් නොමැත</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Google ගිණුම කළමනාකරණය කරන්න, ඔබගේ තොරතුරු, පෞද්ගලිකත්වය සහ ආරක්ෂාව කළමනාකරණය කිරීමට Enter ඔබන්න</translation>
 <translation id="2436186046335138073"><ph name="HANDLER_HOSTNAME" /> හට සියලු <ph name="PROTOCOL" /> සබැඳීන් විවෘත කිරීමට ඉඩ දෙන්නද?</translation>
 <translation id="2438874542388153331">දකුණට සිවු වරක් අනින්න</translation>
+<translation id="2443309680964448806">යමක් වැරදිණි. ඔබේ වෙනස් කිරීම සුරැකුණේ නැත.</translation>
 <translation id="2448295565072560657">ඔබ පුරා සිටින අතරතුර මෙම උපාංගයට පර්යන්ත උපාංග අමුණා ඇත</translation>
 <translation id="2450021089947420533">සංචාර</translation>
 <translation id="2463739503403862330">සම්පූර්ණ කරන්න</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">ඔබ මෙම උපාංගය සක්‍රියව භාවිත කරන අවස්ථාව දැන ගන්න</translation>
 <translation id="3180358318770512945">මාපිය කටයුතු</translation>
 <translation id="3187306450550410410">නම්‍යශීලී වැඩ සැලසුම්</translation>
+<translation id="3190736958609431397">හඹා නොයන්න</translation>
 <translation id="319282854780294203">සමාජ ජාල</translation>
 <translation id="3194737229810486521"><ph name="URL" /> හට ඔබේ උපාංගයේ දත්ත ස්ථිරව ගබඩා කිරීමට අවශ්‍යයි</translation>
 <translation id="3195213714973468956"><ph name="SERVER_NAME" /> මත <ph name="PRINTER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">ගෙවීමේ ක්‍රම</translation>
 <translation id="3391030046425686457">බෙදා හැරීමේ ලිපිනය</translation>
 <translation id="3391482648489541560">ගොනු සංස්කරණය</translation>
+<translation id="3392028486601120379">URL රටාව "<ph name="URL_PATTERN" />" හි නිශ්චිත මාර්ගයක් ඇත. මෙම යතුර සඳහා මාර්ග සහය නොදක්වයි, මාර්ගය ඉවත් කර නැවත උත්සාහ කරන්න. උදා. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">භාර ගැනීමේ ක්‍රමය</translation>
 <translation id="3399952811970034796">බෙදා හැරීමේ ලිපිනය</translation>
 <translation id="3402261774528610252">මෙම වෙබ් අඩවිය පූරණ කිරීමට භාවිත කළ සම්බන්ධතාව TLS 1.0 හෝ TLS 1.1 භාවිත කළා, ඒවා අත හැර තිබෙන අතර අනාගතයේදී අබල කෙරේ. වරක් අබල කළ විට, පරිශීලකයින් මෙම වෙබ් අඩවිය පූරණ කිරීම වළක්වනු ලැබේ. සේවාදායකය TLS 1.2 හෝ පසු අනුවාදය සබල කළ යුතුය.</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">Google ගිණුමට සුරකින්න</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">යෙදුම:</translation>
+<translation id="3647286794400715637">සෑම url තන්තු ප්‍රවේශයකම URL 1ක් 2ක් අඩංගු විය යුතුය.</translation>
 <translation id="3650584904733503804">වලංගුකරණය සාර්ථකයි</translation>
 <translation id="3653033846669030038">තේමා උද්‍යාන</translation>
 <translation id="3655241534245626312">අවසර සැකසීම් වෙත යන්න</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">ඔබේ බ්‍රවුසරය ඔබේ පරිපාලක විසින් කළමනාකරණය කරයි.</translation>
 <translation id="3740319564441798148">දුර ගමන් බස් සහ දුම්රිය</translation>
 <translation id="3744111561329211289">පසුබිමෙහි සමමුහුර්තකරණය</translation>
+<translation id="3744286742364977428">ඔබ බාගත කරන ගොනු විශ්ලේෂණය සඳහා Google Cloud හෝ තෙවන පාර්ශව වෙත යවනු ලැබේ. උදාහරණයක් ලෙස, ඒවා සංවේදී දත්ත හෝ අනිෂ්ට මෘදුකාංග තිබේදැයි ස්කෑන් කළ හැකි අතර සමාගම් ප්‍රතිපත්තිවලට අනුව ගබඩා කළ හැක.</translation>
 <translation id="3744899669254331632">Chromium වලට ක්‍රියාවලිය කළ නොහැකි අවුල් අක්තපත්‍ර වෙබ් අඩවියට යැවූ නිසා ඔබට දැන් <ph name="SITE" /> වෙත පැමිණිය නොහැක. ජාල දෝෂ සහ ප්‍රහාර සාමාන්‍යයෙන් තාවකාලිකය, පෙනෙන හැටියට මෙම පිටුව පසුව වැඩ කරයි.</translation>
 <translation id="3745099705178523657">ඔබ තහවුරු කළ පසු, ඔබේ Google ගිණුමෙන් කාඩ්පත් විස්තර මෙම අඩවිය සමඟ බෙදා ගනු ලැබේ.</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> හි ප්‍රහාරකයන් මෘදුකාංගයක් ස්ථාපනය හෝ ඔබේ පුද්ගලික තොරතුරු (උදාහරණ ලෙස, මුරපද, දුරකථන අංක, හෝ ණයපත්) හෙළිදරව් කිරීම වැනි අවදානම් සහගත දේවල්වලට ඔබව පෙළඹවිය හැකිය. <ph name="BEGIN_LEARN_MORE_LINK" />තව දැන ගන්න<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">සිදුවීම තනන්න බොත්තම, Google දින දර්ශනයේ නව සිදුවීමක් ඉක්මනින් තැනීමට Enter ඔබන්න</translation>
 <translation id="4088981014127559358">පැත්ත 1 රූප Y වැඩ මුරය</translation>
 <translation id="4089152113577680600">Tray 14</translation>
+<translation id="4097288585054919042">ඇඟවීම් අක්‍රිය කරන්න</translation>
 <translation id="4098354747657067197">රැවටිලිකාර අඩවියක් ඉදිරියෙනි</translation>
 <translation id="4099048595830172239">රහසිගත අන්තර්ගතය දෘශ්‍යමාන වන විට <ph name="APPLICATION_TITLE" /> සමග ඔබගේ තිරය බෙදා ගැනීමට පරිපාලක ප්‍රතිපත්තිය නිර්දේශ නොකරයි:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome තුළ අකුරු වර්ග තරම සහ මුහුණත අභිරුචිකරණය කිරීමට Tab ඔබා අනතුරුව Enter ඔබන්න</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">අබල කරන ලද</translation>
 <translation id="4176535426287761656">කාල බෙදීම් සහ නිවාඩු දේපළ</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">මිල හඹා නොයන්න</translation>
 <translation id="4194250254487269611">ඔබේ කාඩ්පත දැනට සුරැකිය නොහැක</translation>
 <translation id="4196861286325780578">&amp;ගෙන යාම යළි කරන්න</translation>
 <translation id="4202554117186904723">Fifth Roll</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">ඔබේ උපාංගය නැවත අරඹන්න</translation>
 <translation id="4277028893293644418">මුරපදය යළි සකසන්න</translation>
 <translation id="4278390842282768270">ඉඩ දුන්</translation>
+<translation id="4282346679996504092">මෙම නිෂ්පාදනය සඳහා ඇඟවීම් අක්‍රිය කර ඇති අතර පිටුසන ඉවත් කර ඇත</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{මෙම කාඩ්පත ඔබගේ Google ගිණුම තුළ සුරැකී ඇත}one{මෙම කාඩ්පත් ඔබගේ Google ගිණුම තුළ සුරැකී ඇත}other{මෙම කාඩ්පත් ඔබගේ Google ගිණුම තුළ සුරැකී ඇත}}</translation>
 <translation id="4287885627794386150">අත්හදා බැලීම සඳහා සුදුසු නමුත් සක්‍රිය නැත</translation>
 <translation id="4297502707443874121"><ph name="THUMBNAIL_PAGE" /> පිටුව සඳහා සිඟිති රුව</translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">ඔබ සඳහන් කර ඇති අච්චු DnsOverHttpsMode ප්‍රතිපත්තියේ දෝෂයක් හේතුවෙන් නොයෙදිය හැක.</translation>
 <translation id="4358461427845829800">ගෙවීම් ක්‍රම කළමනාකරණය කරන්න...</translation>
 <translation id="4359160567981085931">ඔබ මේ දැන් වංචනික වෙබ් අඩවියක් මත ඔබේ මුරපදය ඇතුළත් කළා. Chrome උදවු කළ හැක. ඔබේ මුරපදය වෙනස් කිරීමටත් ඔබේ ගිණුම අවදානමේ තිබිය හැකි බව Google වෙත දැනුම් දිමටත්, ගිණුම ආරක්‍ෂා කරන්න ක්ලික් කරන්න.</translation>
+<translation id="4363222835916186793">මෙම නිෂ්පාදනය සඳහා ඇඟවීම් අක්‍රියයි</translation>
 <translation id="4367563149485757821">Number-12 (ලියුම් කවරය)</translation>
 <translation id="437040971055499437">ආරක්ෂක සිදුවීම සිදු වේ</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">ඔබ ඉදිරිපත් කිරීමට යන තොරතුරු ආරක්ෂිත නොවේ</translation>
 <translation id="4796594887379589189">වැඩ ගිණුම් හැඳුනුම</translation>
 <translation id="4798078619018708837">ඔබේ කාඩ්පත් විස්තර යාවත්කාලීන කිරීමට <ph name="CREDIT_CARD" /> සඳහා කල් ඉකුත් වීමේ දිනය සහ CVC ඇතුළත් කරන්න. ඔබ තහවුරු කළ පසු, ඔබේ Google ගිණුමෙන් කාඩ්පත් විස්තර මෙම අඩවිය සමඟ බෙදා ගනු ලැබේ.</translation>
+<translation id="4798269756263412078">ඕනෑම අඩවියක මිල අඩු වුවහොත් ඇඟවීම් ලබා ගන්න. ඇඟවීම් ඔබේ ඉ-තැපෑලට යවනු ලැබේ.</translation>
 <translation id="4800132727771399293">ඔබේ කල් ඉකුත් වූ දිනය සහ CVC, පරික්ෂා කර යළි උත්සාහ කරන්න</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">TouchID භාවිතා කරන්න</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">දකුණු දාරය මසන්න</translation>
 <translation id="5398772614898833570">වෙළඳ දැන්වීම් අවහිරයි</translation>
 <translation id="5400836586163650660">අළු</translation>
+<translation id="540630185148148480">ඇඟවීම් සක්‍රීය කරන්න</translation>
 <translation id="540969355065856584">මෙම සේවාදායකයට එය <ph name="DOMAIN" /> බව සනාථ කිරීමට නොහැකි විය; එහි ආරක්ෂණ සහතිකය මෙම අවස්ථවේ වලංගු නැත. මෙය වැරදි වින්‍යාස කිරීමක් හෝ ප්‍රහාරකයකු ඔබගේ සබැඳුමට බාධා කිරීමක් නිසා විය හැකිය.</translation>
 <translation id="5412040515238827314">අවලංගු ආකෘතියකි: රටා ලැයිස්තුවක් බලාපොරොත්තු විය.</translation>
 <translation id="5412236728747081950">මෙම අඩවිය ඔබට වඩාත් අදාළ වෙළඳ දැන්වීම් පෙන්වීමට Chrome වෙතින් ඔබගේ ලැදිකම් ලබා ගනී</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">ඔබේ කල් ඉකුත් වීමේ මාසය පරික්ෂා කර නැවත උත්සාහ කරන්න</translation>
 <translation id="558420943003240152">මුරපද සහ මුරයතුරු කළමනාකරණය කරන්න…</translation>
 <translation id="5586446728396275693">සුරැකූ ලිපින නැත</translation>
+<translation id="5586831831248371458"><ph name="KEYWORD_SUFFIX" /> සොයන්න</translation>
 <translation id="5587987780934666589">වේදිකා පරිශීලක</translation>
 <translation id="5593349413089863479">සබැඳුම පූර්ණ වශයෙන් ආරක්ෂිත නැත</translation>
 <translation id="5595485650161345191">ලිපිනය සංස්කරණය</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">අතථ්‍ය කාඩ්පත එක් කරන්න</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347"><ph name="SITE_NAME" /> විවෘත කරමින්…</translation>
+<translation id="5947508410139465809">ඔබ උඩුගත කරන හෝ අමුණන ගොනු විශ්ලේෂණය සඳහා Google Cloud හෝ තෙවන පාර්ශව වෙත යවයි. උදාහරණයක් ලෙස, ඒවා සංවේදී දත්ත හෝ අනිෂ්ට මෘදුකාංග තිබේදැයි ස්කෑන් කළ හැකි අතර සමාගම් ප්‍රතිපත්තිවලට අනුව ගබඩා කළ හැක.</translation>
 <translation id="5951495562196540101">පාරිභෝගික ගිණුම සමඟ ලියාපදිංචි විය නොහැක (ඇසුරුම් කළ බලපත්‍රයක් ලබාගත හැක).</translation>
 <translation id="5953516610448771166">සජීවී සිරස්තල මෙම මාධ්‍ය සඳහා ලබා ගත නොහැකිය. සිරස්තල ලබා ගැනීමට, මෙම අඩවිය සඳහා <ph name="CONTENT_SETTINGS" /> අවහිර කරන්න.</translation>
 <translation id="5955063559762970069">හෝටල් සහ නවාතැන්</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">මෙම අඩවිය වෙත ඔබගේ සම්බන්ධතාවය සුරක්ෂිත නොවේ</translation>
 <translation id="6180316780098470077">යළි උත්සාහ කිරීමේ විරාමය</translation>
 <translation id="61877208875190028">කාන්තා ඇඳුම්</translation>
+<translation id="6194209731893739467">ඔබ නිරීක්ෂණය කළ නිෂ්පාදන සියල්ල මෙතැනින් බලන්න</translation>
 <translation id="6195371403461054755">භූ විද්‍යාව</translation>
 <translation id="6196640612572343990">තෙවන-පාර්ශ්ව කුකී අවහිර කරන්න</translation>
 <translation id="6203231073485539293">ඔබගේ අන්තර්ජාල සබැඳුම පරික්ෂා කරන්න</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{ඔබගේ උපාංගය දැන් යළි ආරම්භ වනු ඇත}=1{ඔබගේ උපාංගය තත්පර 1කින් යළි ආරම්භ වනු ඇත}one{ඔබගේ උපාංගය තත්පර #කින් යළි ආරම්භ වනු ඇත}other{ඔබගේ උපාංගය තත්පර #කින් යළි ආරම්භ වනු ඇත}}</translation>
+<translation id="6301104306974789820">මිල නිරීක්ෂණ දැනුම්දීම් ලබා ගන්න</translation>
 <translation id="6302269476990306341">Chrome හි Google සහායක නැවතෙයි</translation>
 <translation id="6305205051461490394"><ph name="URL" /> වෙත ළඟා විය නොහැකිය.</translation>
 <translation id="6311165245110979290">අතථ්‍ය කාඩ්පත තිබේ</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">පෝරමය යළි ඉදිරිපත් කිරීම තහවුරු කරන්න</translation>
 <translation id="6456955391422100996">දැන්වීම ඉවත් කළා.</translation>
 <translation id="6457206614190510200">සෑදල මැසීම</translation>
+<translation id="6457455098507772300">මිල පහත වැටීමේ ඇඟවීම් ඔබේ ඩෙස්ක්ටොපයේ උත්පතන දැනුම්දීම් ලෙස පෙනෙයි</translation>
 <translation id="6458606150257356946">කෙසේ වෙතත් අලවන්න</translation>
 <translation id="6464094930452079790">රූප</translation>
 <translation id="6465306955648956876">මුරපද කළමනාකරණය කරන්න...</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">මකන්න</translation>
 <translation id="6645291930348198241">කුකී සහ වෙබ් අඩවි දත්ත වෙත ප්‍රවේශ වන්න.</translation>
+<translation id="6645478838938543427">මිල පහත වැටීමේ ඇඟවීම් යවන්නේ <ph name="EMAIL_ADDRESS" /> වෙතයි</translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{කිසිවක් නැත}=1{අඩවි 1කින් (ඔබව ඔබේ Google ගිණුමෙන් වරනය නොවනු ඇත)}one{අඩවි #කින් (ඔබව ඔබේ Google ගිණුමෙන් වරනය නොවනු ඇත)}other{අඩවි #කින් (ඔබව ඔබේ Google ගිණුමෙන් වරනය නොවනු ඇත)}}</translation>
 <translation id="6648459603387803038">ඔබේ පරිපාලකට දුරස්ථව ඔබේ බ්‍රවුසර සැකසීම වෙනස් කළ හැකිය. මෙම උපාංගය මත ක්‍රියාකාරකම Chrome හට පිටතින් ද කළමනා කරනු ලැබිය හැක.</translation>
 <translation id="6648524591329069940">Serif ෆොන්ට</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">ප්‍රතිපත්ති සකසා නැත</translation>
 <translation id="7186367841673660872">මෙම පිටුව <ph name="ORIGINAL_LANGUAGE" />වෙතින්<ph name="LANGUAGE_LANGUAGE" />වෙත පරිවර්තනය කර ඇත</translation>
 <translation id="718872491229180389">ඔල්වරසන් නැඟීම</translation>
+<translation id="7192188280913829296">"vendor_id" යන උපලක්ෂණය ද සඳහන් කළ යුතුය.</translation>
 <translation id="7192203810768312527"><ph name="SIZE" /> හිස් කරයි. ඔබේ ඊළඟ පිවිසීමේදී සමහර අඩවි වඩාත් සෙමින් පූරණය විය හැකිය.</translation>
 <translation id="7193661028827781021">යොමුව</translation>
 <translation id="719464814642662924">වීසා</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb
index 670fa7c8..dab514a 100644
--- a/components/strings/components_strings_sk.xtb
+++ b/components/strings/components_strings_sk.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">Odomknutie zariadením</translation>
 <translation id="1269516672602708785">Rýchlo vytvoriť nový web vo Weboch Google</translation>
 <translation id="1270502636509132238">Spôsob vyzdvihnutia</translation>
+<translation id="1273592791152866347">Sledovanie ceny je vypnuté</translation>
 <translation id="1281476433249504884">Odkladač č. 1</translation>
 <translation id="1285320974508926690">Nikdy neprekladať tieto webové stránky</translation>
 <translation id="1288548991597756084">Kartu bezpečne uložte</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">Freeware a shareware</translation>
 <translation id="1553358976309200471">Aktualizovať Chrome</translation>
+<translation id="1554003749331233619">Začali ste sledovať tento výrobok. Táto stránka je uložená v priečinku <ph name="LAST_BOOKMARKS_FOLDER" />.</translation>
 <translation id="1555130319947370107">Modrá</translation>
 <translation id="1559447966090556585">Chcete dostávať upozornenia?</translation>
 <translation id="1559528461873125649">Neexistuje žiadny takýto súbor ani priečinok</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">Spravovať účet Google, stlačením klávesa Enter môžete spravovať informácie, ochranu súkromia a zabezpečenie v účte Google</translation>
 <translation id="2436186046335138073">Chcete povoliť obslužnému programu <ph name="HANDLER_HOSTNAME" /> otvárať všetky odkazy protokolu <ph name="PROTOCOL" />?</translation>
 <translation id="2438874542388153331">Štyri dierky vpravo</translation>
+<translation id="2443309680964448806">Niečo sa pokazilo. Zmena nebola uložená.</translation>
 <translation id="2448295565072560657">Periférie pripojené k tomuto zariadeniu počas vášho prihlásenia</translation>
 <translation id="2450021089947420533">Journeys</translation>
 <translation id="2463739503403862330">Vyplniť</translation>
@@ -816,6 +819,7 @@
 <translation id="317878711435188021">Zistiť, kedy aktívne používate toto zariadenie</translation>
 <translation id="3180358318770512945">Rodičovstvo</translation>
 <translation id="3187306450550410410">Práca s flexibilným pracovným časom</translation>
+<translation id="3190736958609431397">Prestať sledovať</translation>
 <translation id="319282854780294203">Sociálne siete</translation>
 <translation id="3194737229810486521"><ph name="URL" /> chce natrvalo ukladať dáta vo vašom zariadení</translation>
 <translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na serveri <ph name="SERVER_NAME" /></translation>
@@ -901,6 +905,7 @@
 <translation id="3387261909427947069">Spôsoby platby</translation>
 <translation id="3391030046425686457">Doručovacia adresa</translation>
 <translation id="3391482648489541560">úprava súborov</translation>
+<translation id="3392028486601120379">Vzor webovej adresy <ph name="URL_PATTERN" /> má špecifikovanú cestu. Pre tento kľúč nie sú cesty podporované. Odstráňte cestu a skúste to znova. Napr. *://example.com/ =&gt; *://example.com",</translation>
 <translation id="3395827396354264108">Spôsob vyzdvihnutia</translation>
 <translation id="3399952811970034796">Doručovacia adresa</translation>
 <translation id="3402261774528610252">Pripojenie, pomocou ktorého bol načítaný tento web, používa protokol TLS 1.0 alebo TLS 1.1, ktorého podpora je zastaraná a ktorý bude v budúcnosti zakázaný. Po jeho zakázaní už používatelia nebudú môcť tento web načítať. Daný server by mal aktivovať protokol TLS verzie 1.2 alebo novšej.</translation>
@@ -995,6 +1000,7 @@
 <translation id="3637662659967048211">Uloženie do účtu Google</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">Aplikácia:</translation>
+<translation id="3647286794400715637">Každý záznam reťazca webovej adresy musí obsahovať jednu až dve webové adresy.</translation>
 <translation id="3650584904733503804">Overenie bolo úspešné</translation>
 <translation id="3653033846669030038">Zábavné parky</translation>
 <translation id="3655241534245626312">Prejsť do nastavení povolenia</translation>
@@ -1033,6 +1039,7 @@
 <translation id="3738166223076830879">Prehliadač je ovládaný vaším správcom.</translation>
 <translation id="3740319564441798148">Diaľkové autobusy a vlaky</translation>
 <translation id="3744111561329211289">Synchronizácia na pozadí</translation>
+<translation id="3744286742364977428">Súbory, ktoré si stiahnete, sa odosielajú na analýzu do služby Google Cloud alebo tretím stranám. V rámci toho môžu byť napríklad podrobené kontrole prítomnosti citlivých údajov alebo malvéru a podľa firemných pravidiel môžu byť uložené.</translation>
 <translation id="3744899669254331632">Webové stránky <ph name="SITE" /> momentálne nemôžete navštíviť, pretože odoslali zakódované poverenia, ktoré Chromium neodkáže spracovať. Chyby siete a útoky sú zvyčajne dočasné, takže táto stránka by mala pravdepodobne neskôr fungovať.</translation>
 <translation id="3745099705178523657">Po potvrdení sa budú údaje o karte z vášho účtu Google zdieľať s týmto webom.</translation>
 <translation id="3748148204939282805">Útočníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vás môžu oklamať, aby ste urobili niečo nebezpečné, napríklad nainštalovali softvér alebo odhalili svoje osobné informácie (napríklad heslá, telefónne čísla a kreditné karty). <ph name="BEGIN_LEARN_MORE_LINK" />Ďalšie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1140,6 +1147,7 @@
 <translation id="4087296516249690906">Tlačidlo na vytvorenie udalosti, stlačením klávesa Enter vytvoríte rýchlym spôsobom novú udalosť v Kalendári Google</translation>
 <translation id="4088981014127559358">Posun obrázka strany č. 1 na osi Y</translation>
 <translation id="4089152113577680600">Zásobník č. 14</translation>
+<translation id="4097288585054919042">Vypnúť upozornenia</translation>
 <translation id="4098354747657067197">Podvodné webové stránky</translation>
 <translation id="4099048595830172239">Pravidlá správcu neodporúčajú zdieľanie obrazovky s aplikáciou <ph name="APPLICATION_TITLE" />, keď je viditeľný dôverný obsah:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, po stlačení klávesov Tab a Enter môžete prispôsobiť veľkosť a typ písma v Chrome</translation>
@@ -1176,6 +1184,7 @@
 <translation id="4176463684765177261">Deaktivované</translation>
 <translation id="4176535426287761656">Ubytovacie zariadenia na časovo vymedzené využívanie a dovolenkové nehnuteľnosti</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">Prestať sledovať cenu</translation>
 <translation id="4194250254487269611">Vašu kartu momentálne nie je možné uložiť</translation>
 <translation id="4196861286325780578">&amp;Znova presunúť</translation>
 <translation id="4202554117186904723">Piaty kotúč</translation>
@@ -1222,6 +1231,7 @@
 <translation id="4275830172053184480">Reštart zariadenia</translation>
 <translation id="4277028893293644418">Obnoviť heslo</translation>
 <translation id="4278390842282768270">Povolené</translation>
+<translation id="4282346679996504092">Upozornenia na tento výrobok boli vypnuté a záložka bola odstránená</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{Táto karta sa uložila do vášho účtu Google}few{Tieto karty sa uložili do vášho účtu Google}many{Tieto karty sa uložili do vášho účtu Google}other{Tieto karty sa uložili do vášho účtu Google}}</translation>
 <translation id="4287885627794386150">Vhodné pre skúšobné obdobie, ale neaktívne</translation>
 <translation id="4297502707443874121">Miniatúra stránky <ph name="THUMBNAIL_PAGE" /></translation>
@@ -1260,6 +1270,7 @@
 <translation id="4358059973562876591">Špecifikované šablóny nemusia byť uplatnené pre chybu, ku ktorej došlo v súvislosti s pravidlom DnsOverHttpsMode.</translation>
 <translation id="4358461427845829800">Spravovať spôsoby platby…</translation>
 <translation id="4359160567981085931">Práve ste zadali svoje heslo na podvodnom webe. Chrome vám s tým pomôže. Ak chcete zmeniť heslo a upozorniť Google, že váš účet môže byť ohrozený, kliknite na Ochrániť účet.</translation>
+<translation id="4363222835916186793">Upozornenia na tento výrobok boli vypnuté</translation>
 <translation id="4367563149485757821">Number-12 (obálka)</translation>
 <translation id="437040971055499437">Vyskytne sa bezpečnostná udalosť</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1412,6 +1423,7 @@
 <translation id="4792686369684665359">Informácie, ktoré sa chystáte odoslať, nie sú zabezpečené</translation>
 <translation id="4796594887379589189">Číslo účtu úlohy</translation>
 <translation id="4798078619018708837">Ak chcete aktualizovať údaje o karte <ph name="CREDIT_CARD" />, zadajte dátum vypršania platnosti a kód CVC. Po potvrdení sa budú údaje o karte z vášho účtu Google zdieľať s týmto webom.</translation>
+<translation id="4798269756263412078">Dostávajte upozornenia, keď na ľubovoľnom webe poklesne cena. Upozornenia budú odosielané na váš e‑mail.</translation>
 <translation id="4800132727771399293">Skontrolujte dátum vypršania platnosti aj kód CVC a skúste to znova</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">Použiť TouchID</translation>
@@ -1655,6 +1667,7 @@
 <translation id="5396631636586785122">Zošiť hrebeňovou väzbou vpravo</translation>
 <translation id="5398772614898833570">Reklamy sú blokované</translation>
 <translation id="5400836586163650660">Sivá</translation>
+<translation id="540630185148148480">Zapnúť upozornenia</translation>
 <translation id="540969355065856584">Server nedokáže overiť, či ide o doménu <ph name="DOMAIN" /> – jej bezpečnostný certifikát je momentálne neplatný. Môže to byť spôsobené nesprávnou konfiguráciou alebo tým, že vaše pripojenie napadol útočník.</translation>
 <translation id="5412040515238827314">Neplatný formát: očakáva sa zoznam vzorov.</translation>
 <translation id="5412236728747081950">Chrome upozorní tento web na to, že sa oň zaujímate, a budú sa vám zobrazovať relevantné reklamy</translation>
@@ -1719,6 +1732,7 @@
 <translation id="5580958916614886209">Skontrolujte mesiac vypršania platnosti a skúste to znova</translation>
 <translation id="558420943003240152">Spravovať heslá a prístupové kľúče…</translation>
 <translation id="5586446728396275693">Žiadne uložené adresy</translation>
+<translation id="5586831831248371458">Hľadajte v službe <ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">Používateľ platformy</translation>
 <translation id="5593349413089863479">Pripojenie nie je úplne zabezpečené</translation>
 <translation id="5595485650161345191">Upraviť adresu</translation>
@@ -1838,6 +1852,7 @@
 <translation id="5938153366081463283">Pridajte si virtuálnu kartu</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">Otvára sa web <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">Súbory, ktoré nahráte alebo priložíte, sa odošlú na analýzu do služby Google Cloud alebo tretím stranám. V rámci toho môžu byť napríklad podrobené kontrole prítomnosti citlivých údajov alebo malvéru a podľa firemných pravidiel môžu byť uložené.</translation>
 <translation id="5951495562196540101">Nemôžete sa zaregistrovať spotrebiteľským účtom (k dispozícii je licencia v balíčku).</translation>
 <translation id="5953516610448771166">Živý prepis nie je pre toto médium k dispozícii. Ak si chcete zobrazovať titulky, zablokujte <ph name="CONTENT_SETTINGS" /> pre tento web.</translation>
 <translation id="5955063559762970069">Hotely a ubytovanie</translation>
@@ -1925,6 +1940,7 @@
 <translation id="6177128806592000436">Spojenie s týmto webom nie je zabezpečené</translation>
 <translation id="6180316780098470077">Interval opakovania pokusov</translation>
 <translation id="61877208875190028">Dámska móda</translation>
+<translation id="6194209731893739467">Tu nájdete všetky svoje sledované výrobky</translation>
 <translation id="6195371403461054755">Geológia</translation>
 <translation id="6196640612572343990">Blokovať súbory cookie tretích strán</translation>
 <translation id="6203231073485539293">Skontrolujte internetové pripojenie</translation>
@@ -1960,6 +1976,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{Vaše zariadenie sa reštartuje teraz}=1{Vaše zariadenie sa reštartuje o 1 sekundu}few{Vaše zariadenie sa reštartuje o # sekundy}many{Vaše zariadenie sa reštartuje o # sekundy}other{Vaše zariadenie sa reštartuje o # sekúnd}}</translation>
+<translation id="6301104306974789820">Dostávať upozornenia sledovania cien</translation>
 <translation id="6302269476990306341">Zastavuje sa Asistent Google v Chrome</translation>
 <translation id="6305205051461490394">Web <ph name="URL" /> je nedostupný.</translation>
 <translation id="6311165245110979290">K dispozícii je virtuálna karta</translation>
@@ -2019,6 +2036,7 @@
 <translation id="6451458296329894277">Potvrdiť opakované odoslanie formulára</translation>
 <translation id="6456955391422100996">Reklama bola odstránená.</translation>
 <translation id="6457206614190510200">Sedlová väzba</translation>
+<translation id="6457455098507772300">Upozornenia na pokles ceny sa zobrazujú ako vyskakovacie upozornenia na pracovnej ploche</translation>
 <translation id="6458606150257356946">Aj tak prilepiť</translation>
 <translation id="6464094930452079790">obrázky</translation>
 <translation id="6465306955648956876">Spravovať heslá…</translation>
@@ -2076,6 +2094,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">Vymazať</translation>
 <translation id="6645291930348198241">Používať súbory cookie a údaje webov.</translation>
+<translation id="6645478838938543427">Upozornenia na pokles ceny sa budú odosielať na <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{Žiadne}=1{Z 1 webu (neodhlásime vás z účtu Google)}few{Z # webov (neodhlásime vás z účtu Google)}many{From # sites (you won't be signed out of your Google Account)}other{Z # webov (neodhlásime vás z účtu Google)}}</translation>
 <translation id="6648459603387803038">Nastavenia prehliadača môže vzdialene zmeniť správca. Aktivita v tomto zariadení môže byť tiež spravovaná mimo Chromu.</translation>
 <translation id="6648524591329069940">Písmo Serif</translation>
@@ -2269,6 +2288,7 @@
 <translation id="7182878459783632708">Nie sú nastavené žiadne pravidlá</translation>
 <translation id="7186367841673660872">Táto stránka bola preložená z jazyka<ph name="ORIGINAL_LANGUAGE" />do jazyka<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">Roztlieskavanie</translation>
+<translation id="7192188280913829296">Musí byť zadaný aj atribút vendor_id.</translation>
 <translation id="7192203810768312527">Uvoľní <ph name="SIZE" />. Niektoré weby sa môžu pri ďalšej návšteve načítať pomalšie.</translation>
 <translation id="7193661028827781021">Referencie</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb
index 0d506e6b..1c5d791 100644
--- a/components/strings/components_strings_sl.xtb
+++ b/components/strings/components_strings_sl.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">V redu</translation>
 <translation id="2742511345840685325">Namizni tenis</translation>
 <translation id="2742870351467570537">Odstrani izbrane elemente</translation>
+<translation id="2759825833388495838">vnesti geslo v aplikaciji <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Stripi</translation>
 <translation id="2765217105034171413">Majhna</translation>
 <translation id="277133753123645258">Način pošiljanja</translation>
diff --git a/components/strings/components_strings_sr-Latn.xtb b/components/strings/components_strings_sr-Latn.xtb
index e0b2748..601771b 100644
--- a/components/strings/components_strings_sr-Latn.xtb
+++ b/components/strings/components_strings_sr-Latn.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">Potvrdi</translation>
 <translation id="2742511345840685325">Stoni tenis</translation>
 <translation id="2742870351467570537">Ukloni izabrane stavke</translation>
+<translation id="2759825833388495838">unese lozinku na <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Stripovi</translation>
 <translation id="2765217105034171413">Mala</translation>
 <translation id="277133753123645258">Način slanja</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb
index 242a49b3..c38e0f90 100644
--- a/components/strings/components_strings_sr.xtb
+++ b/components/strings/components_strings_sr.xtb
@@ -691,6 +691,7 @@
 <translation id="2740531572673183784">Потврди</translation>
 <translation id="2742511345840685325">Стони тенис</translation>
 <translation id="2742870351467570537">Уклони изабране ставке</translation>
+<translation id="2759825833388495838">унесе лозинку на <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">Стрипови</translation>
 <translation id="2765217105034171413">Мала</translation>
 <translation id="277133753123645258">Начин слања</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb
index 54f5bbc2..7941527f1 100644
--- a/components/strings/components_strings_zh-CN.xtb
+++ b/components/strings/components_strings_zh-CN.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">设备解锁</translation>
 <translation id="1269516672602708785">在 Google 协作平台中快速创建新网站</translation>
 <translation id="1270502636509132238">取货方式</translation>
+<translation id="1273592791152866347">价格跟踪功能已关闭</translation>
 <translation id="1281476433249504884">堆叠出纸器 1</translation>
 <translation id="1285320974508926690">一律不翻译此网站</translation>
 <translation id="1288548991597756084">妥善保存银行卡信息</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">免费软件与共享软件</translation>
 <translation id="1553358976309200471">更新 Chrome</translation>
+<translation id="1554003749331233619">您正在跟踪此商品。该网页保存在“<ph name="LAST_BOOKMARKS_FOLDER" />”中</translation>
 <translation id="1555130319947370107">蓝色</translation>
 <translation id="1559447966090556585">接收通知?</translation>
 <translation id="1559528461873125649">不存在此类文件或目录</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">“管理 Google 帐号”,按 Enter 键即可在您的 Google 帐号中管理自己的信息、隐私和安全</translation>
 <translation id="2436186046335138073">允许<ph name="HANDLER_HOSTNAME" />打开所有<ph name="PROTOCOL" />链接?</translation>
 <translation id="2438874542388153331">四孔(右侧)</translation>
+<translation id="2443309680964448806">出了点问题。未能保存您的更改。</translation>
 <translation id="2448295565072560657">登录时连接至该设备的外围设备</translation>
 <translation id="2450021089947420533">历程</translation>
 <translation id="2463739503403862330">填充</translation>
@@ -817,6 +820,7 @@
 <translation id="317878711435188021">了解您何时在主动使用此设备</translation>
 <translation id="3180358318770512945">育儿</translation>
 <translation id="3187306450550410410">弹性工作安排</translation>
+<translation id="3190736958609431397">取消跟踪</translation>
 <translation id="319282854780294203">社交网络</translation>
 <translation id="3194737229810486521"><ph name="URL" /> 想在您的设备上永久存储数据</translation>
 <translation id="3195213714973468956">“<ph name="SERVER_NAME" />”上的“<ph name="PRINTER_NAME" />”</translation>
@@ -902,6 +906,7 @@
 <translation id="3387261909427947069">付款方式</translation>
 <translation id="3391030046425686457">递送地址</translation>
 <translation id="3391482648489541560">文件修改</translation>
+<translation id="3392028486601120379">网址格式“<ph name="URL_PATTERN" />”中指定了路径。此键不支持路径。请移除该路径,然后重试。例如 *://example.com/ =&gt; *://example.com</translation>
 <translation id="3395827396354264108">取货方式</translation>
 <translation id="3399952811970034796">递送地址</translation>
 <translation id="3402261774528610252">用于加载此网站的连接使用的是 TLS 1.0 或 TLS 1.1,这两个 TLS 版本都已过时,将在不久后完全停用。届时,用户将无法再加载此网站。服务器应启用 TLS 1.2 或更高版本。</translation>
@@ -995,6 +1000,7 @@
 <translation id="3637662659967048211">保存到 Google 帐号</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">应用:</translation>
+<translation id="3647286794400715637">每个网址字符串条目都必须包含 1-2 个网址。</translation>
 <translation id="3650584904733503804">验证成功</translation>
 <translation id="3653033846669030038">主题公园</translation>
 <translation id="3655241534245626312">转到权限设置</translation>
@@ -1033,6 +1039,7 @@
 <translation id="3738166223076830879">您的浏览器由管理员管理。</translation>
 <translation id="3740319564441798148">长途大巴与铁路</translation>
 <translation id="3744111561329211289">后台同步</translation>
+<translation id="3744286742364977428">系统会将您下载的文件发送给 Google Cloud 或第三方以供分析。例如,可能会通过扫描来确定文件是否包含敏感数据或恶意软件,并且可能会根据公司政策存储这些文件。</translation>
 <translation id="3744899669254331632">您目前无法访问 <ph name="SITE" />,因为此网站发送了 Chromium 无法处理的杂乱凭据。网络错误和攻击通常是暂时的,因此,此网页稍后可能会恢复正常。</translation>
 <translation id="3745099705178523657">待您确认后,系统便会将您 Google 帐号中的信用卡详细信息共享给该网站。</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者可能会诱骗您做一些危险的事情,例如安装软件或泄露您的个人信息(如密码、电话号码或信用卡信息)。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1140,6 +1147,7 @@
 <translation id="4087296516249690906">“创建活动”按钮,按 Enter 键即可在 Google 日历中快速创建新活动</translation>
 <translation id="4088981014127559358">侧边 1,图片沿 Y 轴位移</translation>
 <translation id="4089152113577680600">纸匣 14</translation>
+<translation id="4097288585054919042">关闭提醒</translation>
 <translation id="4098354747657067197">您要访问的是诈骗网站</translation>
 <translation id="4099048595830172239">管理员政策不建议在屏幕显示机密内容时与 <ph name="APPLICATION_TITLE" /> 共享屏幕:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />,依次按 Tab 键和 Enter 键即可自定义 Chrome 中的字号和字型</translation>
@@ -1176,6 +1184,7 @@
 <translation id="4176463684765177261">已停用</translation>
 <translation id="4176535426287761656">分时度假房产与一般度假房产</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> - <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">取消跟踪价格</translation>
 <translation id="4194250254487269611">此刻无法保存您的信用卡信息</translation>
 <translation id="4196861286325780578">恢复移动(&amp;R)</translation>
 <translation id="4202554117186904723">第 5 卷</translation>
@@ -1222,6 +1231,7 @@
 <translation id="4275830172053184480">重启您的设备</translation>
 <translation id="4277028893293644418">重置密码</translation>
 <translation id="4278390842282768270">允许</translation>
+<translation id="4282346679996504092">针对此商品的提醒已被关闭,相应书签已被移除</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{这张卡已保存到您的 Google 帐号中}other{这些卡已保存到您的 Google 帐号中}}</translation>
 <translation id="4287885627794386150">符合试用条件但处于无效状态</translation>
 <translation id="4297502707443874121">第 <ph name="THUMBNAIL_PAGE" /> 页的缩略图</translation>
@@ -1260,6 +1270,7 @@
 <translation id="4358059973562876591">您指定的模板未必会被应用,因为 DnsOverHttpsMode 政策出错了。</translation>
 <translation id="4358461427845829800">管理付款方式…</translation>
 <translation id="4359160567981085931">您刚刚在一个诈骗网站中输入了密码。Chrome 可以为您提供帮助。若要更改密码并让 Google 知晓您的帐号可能处于危险状态,请点击“保护帐号”。</translation>
+<translation id="4363222835916186793">针对此商品的提醒已被关闭</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">发生了安全性事件</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1412,6 +1423,7 @@
 <translation id="4792686369684665359">您即将提交的信息不安全</translation>
 <translation id="4796594887379589189">工作帐号 ID</translation>
 <translation id="4798078619018708837">请输入 <ph name="CREDIT_CARD" /> 的失效日期和银行卡验证码 (CVC),以更新您的信用卡详细信息。待您确认后,系统便会将您 Google 帐号中的信用卡详细信息共享给该网站。</translation>
+<translation id="4798269756263412078">当任一网站上的商品降价时,您会收到提醒。系统会将提醒发送到您的电子邮件地址。</translation>
 <translation id="4800132727771399293">请检查您的到期日期和银行卡验证码 (CVC),然后重试</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">使用触控 ID</translation>
@@ -1655,6 +1667,7 @@
 <translation id="5396631636586785122">边缘装订(右侧)</translation>
 <translation id="5398772614898833570">广告已被拦截</translation>
 <translation id="5400836586163650660">灰色</translation>
+<translation id="540630185148148480">开启提醒</translation>
 <translation id="540969355065856584">此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书目前无效。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
 <translation id="5412040515238827314">格式无效:本应为模式列表。</translation>
 <translation id="5412236728747081950">此网站会从 Chrome 中了解您的兴趣,从而向您展示与您的需求更相符的广告</translation>
@@ -1719,6 +1732,7 @@
 <translation id="5580958916614886209">请检查您的信用卡到期月份,然后重试</translation>
 <translation id="558420943003240152">管理密码和密钥…</translation>
 <translation id="5586446728396275693">没有已保存的地址</translation>
+<translation id="5586831831248371458">搜索<ph name="KEYWORD_SUFFIX" /></translation>
 <translation id="5587987780934666589">平台用户</translation>
 <translation id="5593349413089863479">连接不够安全</translation>
 <translation id="5595485650161345191">修改地址</translation>
@@ -1838,6 +1852,7 @@
 <translation id="5938153366081463283">添加虚拟卡</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">正在打开 <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">系统会将您上传或附加的文件发送给 Google Cloud 或第三方以供分析。例如,可能会通过扫描来确定文件是否包含敏感数据或恶意软件,并且可能会根据公司政策存储这些文件。</translation>
 <translation id="5951495562196540101">无法通过消费者帐号注册(有封装的许可)。</translation>
 <translation id="5953516610448771166">此媒体无法使用实时字幕功能。如需获取字幕,请屏蔽该网站的<ph name="CONTENT_SETTINGS" />。</translation>
 <translation id="5955063559762970069">酒店与住宿</translation>
@@ -1925,6 +1940,7 @@
 <translation id="6177128806592000436">您与此网站之间建立的连接不安全</translation>
 <translation id="6180316780098470077">重试间隔</translation>
 <translation id="61877208875190028">女装</translation>
+<translation id="6194209731893739467">您跟踪的所有商品都会显示在此处</translation>
 <translation id="6195371403461054755">地质学</translation>
 <translation id="6196640612572343990">阻止第三方 Cookie</translation>
 <translation id="6203231073485539293">请检查您的互联网连接是否正常</translation>
@@ -1960,6 +1976,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{您的设备将立即重启}=1{您的设备将在 1 秒后重启}other{您的设备将在 # 秒后重启}}</translation>
+<translation id="6301104306974789820">接收价格跟踪通知</translation>
 <translation id="6302269476990306341">Chrome 中的 Google 助理即将停止工作</translation>
 <translation id="6305205051461490394">无法访问 <ph name="URL" />。</translation>
 <translation id="6311165245110979290">有可用的虚拟卡</translation>
@@ -2019,6 +2036,7 @@
 <translation id="6451458296329894277">确认重新提交表单</translation>
 <translation id="6456955391422100996">已移除广告。</translation>
 <translation id="6457206614190510200">鞍式装订</translation>
+<translation id="6457455098507772300">降价提醒在桌面设备上显示为弹出式通知</translation>
 <translation id="6458606150257356946">仍然粘贴</translation>
 <translation id="6464094930452079790">图片</translation>
 <translation id="6465306955648956876">管理密码…</translation>
@@ -2076,6 +2094,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6645291930348198241">访问 Cookie 和网站数据。</translation>
+<translation id="6645478838938543427">系统会将降价提醒发送到 <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{无}=1{来自 1 个网站(这不会致使您退出自己的 Google 帐号)}other{来自 # 个网站(这不会致使您退出自己的 Google 帐号)}}</translation>
 <translation id="6648459603387803038">您的管理员可以远程更改您的浏览器设置。此设备上的活动可能也在接受 Chrome 外部的管理。</translation>
 <translation id="6648524591329069940">Serif 字体</translation>
@@ -2269,6 +2288,7 @@
 <translation id="7182878459783632708">未设置任何政策</translation>
 <translation id="7186367841673660872">已将此网页从<ph name="ORIGINAL_LANGUAGE" />翻译成<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">啦啦队</translation>
+<translation id="7192188280913829296">还必须指定“vendor_id”属性。</translation>
 <translation id="7192203810768312527">释放了 <ph name="SIZE" />。当您下次访问时,某些网站的加载速度可能会更慢。</translation>
 <translation id="7193661028827781021">参考资料</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_zh-HK.xtb b/components/strings/components_strings_zh-HK.xtb
index 2f9141c..7db50ed 100644
--- a/components/strings/components_strings_zh-HK.xtb
+++ b/components/strings/components_strings_zh-HK.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">裝置解鎖</translation>
 <translation id="1269516672602708785">在「Google 協作平台」中快速建立新版網站</translation>
 <translation id="1270502636509132238">取貨方式</translation>
+<translation id="1273592791152866347">已關閉價格追蹤</translation>
 <translation id="1281476433249504884">堆疊器 1</translation>
 <translation id="1285320974508926690">永不翻譯此網站</translation>
 <translation id="1288548991597756084">安全地儲存信用卡</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">免費軟件和共用軟件</translation>
 <translation id="1553358976309200471">更新 Chrome</translation>
+<translation id="1554003749331233619">你正在追蹤這項產品,這個網頁已儲存到「<ph name="LAST_BOOKMARKS_FOLDER" />」中</translation>
 <translation id="1555130319947370107">藍色</translation>
 <translation id="1559447966090556585">要接收通知嗎?</translation>
 <translation id="1559528461873125649">找不到您所指定的檔案或目錄</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">管理 Google 帳戶,㩒一下 Enter 鍵就可以喺 Google 帳戶度管理你嘅資料、私隱權同埋安全設定</translation>
 <translation id="2436186046335138073">要允許 <ph name="HANDLER_HOSTNAME" /> 開啟所有 <ph name="PROTOCOL" /> 連結嗎?</translation>
 <translation id="2438874542388153331">四孔 (右側)</translation>
+<translation id="2443309680964448806">發生錯誤,系統未儲存你所做的變更。</translation>
 <translation id="2448295565072560657">登入時連接至此裝置的周邊裝置</translation>
 <translation id="2450021089947420533">瀏覽過程</translation>
 <translation id="2463739503403862330">填寫</translation>
@@ -820,6 +823,7 @@
 <translation id="317878711435188021">知道您是否正在使用此裝置</translation>
 <translation id="3180358318770512945">育兒</translation>
 <translation id="3187306450550410410">彈性工作安排</translation>
+<translation id="3190736958609431397">取消追蹤</translation>
 <translation id="319282854780294203">社交網絡</translation>
 <translation id="3194737229810486521"><ph name="URL" /> 要求在您的裝置上永久儲存數據</translation>
 <translation id="3195213714973468956">「<ph name="SERVER_NAME" />」上的 <ph name="PRINTER_NAME" /></translation>
@@ -905,6 +909,7 @@
 <translation id="3387261909427947069">付款方法</translation>
 <translation id="3391030046425686457">送貨地址</translation>
 <translation id="3391482648489541560">編輯檔案</translation>
+<translation id="3392028486601120379">網址模式「<ph name="URL_PATTERN" />」已指定路徑。這個金鑰不支援路徑,請移除路徑然後再試一次。例如 *://example.com/ =&gt; *://example.com"。</translation>
 <translation id="3395827396354264108">取貨方式</translation>
 <translation id="3399952811970034796">送貨地址</translation>
 <translation id="3402261774528610252">用於載入此網站的連線使用 TLS 1.0 或 TLS 1.1 版本現已被淘汰,並會於日後停用。停用後,使用者將無法載入此網站。伺服器應啟用 TLS 1.2 或以上版本。</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">儲存至 Google 帳戶</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">應用程式:</translation>
+<translation id="3647286794400715637">每個網址字串項目都必須包含 1 到 2 個網址。</translation>
 <translation id="3650584904733503804">驗證成功</translation>
 <translation id="3653033846669030038">主題公園</translation>
 <translation id="3655241534245626312">前往權限設定</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">您的瀏覽器由管理員管理。</translation>
 <translation id="3740319564441798148">長途巴士和鐵路</translation>
 <translation id="3744111561329211289">背景同步處理</translation>
+<translation id="3744286742364977428">你下載的檔案會傳送到 Google Cloud 或第三方進行分析。舉例來說,Google Cloud 或第三方可能會掃描檔案,檢查是否含有機密資料或惡意軟體,並可能會根據公司政策儲存這些檔案。</translation>
 <translation id="3744899669254331632">您目前無法瀏覽 <ph name="SITE" />,因為該網站傳送了 Chromium 無法處理的干擾憑證。網絡錯誤及攻擊行為通常是短暫性問題,因此這個網頁稍後應可正常運作。</translation>
 <translation id="3745099705178523657">確認後,您的 Google 帳戶會與這個網站共用您的信用卡資料。</translation>
 <translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻擊者可能會誘使您採取一些危險的行動,例如安裝軟件或洩漏您的個人資料 (包括密碼、電話號碼或信用卡資料)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">建立活動掣,㩒一下 Enter 鍵就可以喺 Google 日曆度快速建立新活動</translation>
 <translation id="4088981014127559358">側邊 1 圖片 Y 軸移動</translation>
 <translation id="4089152113577680600">紙匣 14</translation>
+<translation id="4097288585054919042">關閉快訊</translation>
 <translation id="4098354747657067197">前往的是欺詐網站</translation>
 <translation id="4099048595830172239">當螢幕上出現機密內容時,管理員政策不建議您與 <ph name="APPLICATION_TITLE" /> 分享螢幕畫面:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />,㩒一下 Tab 鍵,然後㩒一下 Enter 鍵就可以自訂 Chrome 嘅字型大小同字體</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">已停用</translation>
 <translation id="4176535426287761656">分時度假屋和度假物業</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">取消追蹤價格</translation>
 <translation id="4194250254487269611">目前無法儲存您的信用卡</translation>
 <translation id="4196861286325780578">重做移動(&amp;R)</translation>
 <translation id="4202554117186904723">第五卷</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">重新啟動裝置</translation>
 <translation id="4277028893293644418">重設密碼</translation>
 <translation id="4278390842282768270">已允許</translation>
+<translation id="4282346679996504092">這項產品的快訊已關閉,這個網頁也已從書籤中移除</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{此卡已儲存至您的 Google 帳戶}other{這些卡已儲存至您的 Google 帳戶}}</translation>
 <translation id="4287885627794386150">符合適用條件但尚未啟用</translation>
 <translation id="4297502707443874121">第 <ph name="THUMBNAIL_PAGE" /> 頁嘅縮圖</translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">DnsOverHttpsMode 政策發生錯誤,因此系統無法套用您指定的範本。</translation>
 <translation id="4358461427845829800">管理付款方法…</translation>
 <translation id="4359160567981085931">您剛才在欺詐網站上輸入了密碼。Chrome 可以就此提供協助。如需變更密碼或通知 Google 您的帳戶可能面臨風險,請按 [保護帳戶]。</translation>
+<translation id="4363222835916186793">這項產品的快訊已關閉</translation>
 <translation id="4367563149485757821">Number-12 (信封)</translation>
 <translation id="437040971055499437">發生安全性事件</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">您即將提交的資料不安全</translation>
 <translation id="4796594887379589189">工作帳戶 ID</translation>
 <translation id="4798078619018708837">請輸入 <ph name="CREDIT_CARD" /> 的到期日和信用卡驗證碼 (CVC),以更新您的信用卡詳細資料。確認後,您的 Google 帳戶會與這個網站共用您的信用卡資料。</translation>
+<translation id="4798269756263412078">如果產品在任何網站上降價,你會收到通知。我們會傳送快訊到你的電子郵件地址。</translation>
 <translation id="4800132727771399293">請檢查您的到期日和卡片驗證碼 (CVC),然後再試一次</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">使用 Touch ID</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">邊緣釘裝 (右側)</translation>
 <translation id="5398772614898833570">已封鎖廣告</translation>
 <translation id="5400836586163650660">灰色</translation>
+<translation id="540630185148148480">開啟快訊</translation>
 <translation id="540969355065856584">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證目前無效。這可能是因為設定錯誤,或有攻擊者攔截您的連線。</translation>
 <translation id="5412040515238827314">格式無效:輸入的值需要是模式清單。</translation>
 <translation id="5412236728747081950">此網站會從 Chrome 取得您的喜好,為您顯示更相關的廣告</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">請檢查您的到期月份,然後再試一次</translation>
 <translation id="558420943003240152">管理密碼和密鑰…</translation>
 <translation id="5586446728396275693">沒有已儲存的地址</translation>
+<translation id="5586831831248371458">搜尋「<ph name="KEYWORD_SUFFIX" />」</translation>
 <translation id="5587987780934666589">平台使用者</translation>
 <translation id="5593349413089863479">連線可能有安全漏洞</translation>
 <translation id="5595485650161345191">編輯地址</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">新增虛擬卡</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">正在開啟 <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">你上傳或附加的檔案會傳送到 Google Cloud 或第三方進行分析。舉例來說,Google Cloud 或第三方可能會掃描檔案,檢查是否含有機密資料或惡意軟體,並可能會根據公司政策儲存這些檔案。</translation>
 <translation id="5951495562196540101">無法使用消費者帳戶註冊 (有可用套裝授權)。</translation>
 <translation id="5953516610448771166">此媒體無法使用即時字幕功能。如要取得字幕,請封鎖此網站的 <ph name="CONTENT_SETTINGS" />。</translation>
 <translation id="5955063559762970069">酒店和住宿</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">您與此網站的連線並非完全安全</translation>
 <translation id="6180316780098470077">重試間隔</translation>
 <translation id="61877208875190028">女裝</translation>
+<translation id="6194209731893739467">在這裡查看所有追蹤的產品</translation>
 <translation id="6195371403461054755">地質學</translation>
 <translation id="6196640612572343990">封鎖第三方 Cookie</translation>
 <translation id="6203231073485539293">檢查互聯網連線</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{裝置會立即重新啟動}=1{裝置將於 1 秒後重新啟動}other{裝置將於 # 秒後重新啟動}}</translation>
+<translation id="6301104306974789820">接收價格追蹤通知</translation>
 <translation id="6302269476990306341">正在停止 Chrome 的「Google 助理」</translation>
 <translation id="6305205051461490394">無法存取 <ph name="URL" />。</translation>
 <translation id="6311165245110979290">可使用虛擬片</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">確認重新提交表格</translation>
 <translation id="6456955391422100996">已移除廣告。</translation>
 <translation id="6457206614190510200">騎馬釘</translation>
+<translation id="6457455098507772300">系統會以彈出式通知形式在電腦上顯示降價快訊</translation>
 <translation id="6458606150257356946">仍要貼上</translation>
 <translation id="6464094930452079790">圖片</translation>
 <translation id="6465306955648956876">管理密碼…</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6645291930348198241">存取 Cookie 和網站資料。</translation>
+<translation id="6645478838938543427">系統會將降價快訊將傳送到 <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{無}=1{1 個網站 (您不會登出 Google 帳戶)}other{# 個網站 (您不會登出 Google 帳戶)}}</translation>
 <translation id="6648459603387803038">您的管理員可遠端變更瀏覽器設定。此裝置上的活動也可透過 Chrome 以外的服務管理。</translation>
 <translation id="6648524591329069940">Serif 字型</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">未設定政策</translation>
 <translation id="7186367841673660872">此網頁內容已由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">啦啦隊</translation>
+<translation id="7192188280913829296">必須一併指定「vendor_id」屬性。</translation>
 <translation id="7192203810768312527">釋出 <ph name="SIZE" />。在您下次瀏覽部分網站時,載入速度可能會變慢。</translation>
 <translation id="7193661028827781021">參考資料</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb
index 07ead27..b425022 100644
--- a/components/strings/components_strings_zh-TW.xtb
+++ b/components/strings/components_strings_zh-TW.xtb
@@ -120,6 +120,7 @@
 <translation id="1266469291454105242">裝置解鎖</translation>
 <translation id="1269516672602708785">在 Google 協作平台中快速建立新網站</translation>
 <translation id="1270502636509132238">取件方式</translation>
+<translation id="1273592791152866347">已關閉價格追蹤</translation>
 <translation id="1281476433249504884">堆疊出紙器 1</translation>
 <translation id="1285320974508926690">一律不翻譯此網站</translation>
 <translation id="1288548991597756084">安全地儲存卡片</translation>
@@ -248,6 +249,7 @@
 <translation id="155039086686388498">Engineering-D</translation>
 <translation id="1551884710160394169">免費軟體與共享軟體</translation>
 <translation id="1553358976309200471">更新 Chrome</translation>
+<translation id="1554003749331233619">你正在追蹤這項產品,這個網頁已儲存到「<ph name="LAST_BOOKMARKS_FOLDER" />」中</translation>
 <translation id="1555130319947370107">藍色</translation>
 <translation id="1559447966090556585">要接收通知嗎?</translation>
 <translation id="1559528461873125649">找不到你所指定的檔案或目錄</translation>
@@ -561,6 +563,7 @@
 <translation id="2430968933669123598">管理 Google 帳戶;按下 Enter 鍵即可管理 Google 帳戶的資訊、隱私權和安全性</translation>
 <translation id="2436186046335138073">要允許 <ph name="HANDLER_HOSTNAME" /> 開啟所有<ph name="PROTOCOL" />連結嗎?</translation>
 <translation id="2438874542388153331">四孔 (右側)</translation>
+<translation id="2443309680964448806">發生錯誤,系統未儲存你所做的變更。</translation>
 <translation id="2448295565072560657">登入時連接至這部裝置的周邊裝置</translation>
 <translation id="2450021089947420533">瀏覽歷程</translation>
 <translation id="2463739503403862330">填入</translation>
@@ -819,6 +822,7 @@
 <translation id="317878711435188021">知道你使用這部裝置的時間</translation>
 <translation id="3180358318770512945">子女教養</translation>
 <translation id="3187306450550410410">彈性工作安排</translation>
+<translation id="3190736958609431397">取消追蹤</translation>
 <translation id="319282854780294203">社群網路</translation>
 <translation id="3194737229810486521"><ph name="URL" /> 要求在你的裝置上永久儲存資料</translation>
 <translation id="3195213714973468956"><ph name="SERVER_NAME" /> 上的 <ph name="PRINTER_NAME" /></translation>
@@ -904,6 +908,7 @@
 <translation id="3387261909427947069">付款方式</translation>
 <translation id="3391030046425686457">快遞地址</translation>
 <translation id="3391482648489541560">檔案編輯</translation>
+<translation id="3392028486601120379">網址模式「<ph name="URL_PATTERN" />」已指定路徑。這個金鑰不支援路徑,請移除路徑然後再試一次。例如 *://example.com/ =&gt; *://example.com"。</translation>
 <translation id="3395827396354264108">取件方式</translation>
 <translation id="3399952811970034796">快遞地址</translation>
 <translation id="3402261774528610252">用來載入這個網站的連線使用傳輸層安全標準 (TLS) 1.0 或 1.1,現已不適用,並將在日後遭到停用。一旦停用,使用者將無法載入這個網站。伺服器應啟用傳輸層安全標準 (TLS) 1.2 以上版本。</translation>
@@ -999,6 +1004,7 @@
 <translation id="3637662659967048211">儲存至 Google 帳戶</translation>
 <translation id="3640766068866876100">Index-4x6-Ext</translation>
 <translation id="3642638418806704195">應用程式:</translation>
+<translation id="3647286794400715637">每個網址字串項目都必須包含 1 到 2 個網址。</translation>
 <translation id="3650584904733503804">驗證成功</translation>
 <translation id="3653033846669030038">主題樂園</translation>
 <translation id="3655241534245626312">前往權限設定</translation>
@@ -1037,6 +1043,7 @@
 <translation id="3738166223076830879">你的瀏覽器是由系統管理員管理。</translation>
 <translation id="3740319564441798148">長途公車與鐵路</translation>
 <translation id="3744111561329211289">背景同步處理</translation>
+<translation id="3744286742364977428">你下載的檔案會傳送到 Google Cloud 或第三方進行分析。舉例來說,Google Cloud 或第三方可能會掃描檔案,檢查是否含有機密資料或惡意軟體,並可能會根據公司政策儲存這些檔案。</translation>
 <translation id="3744899669254331632"><ph name="SITE" /> 傳送的憑證受到干擾,造成 Chromium 無法處理,因此你目前無法造訪該網站。網路錯誤和攻擊通常是暫時性狀態,因此這個網頁可能稍後就會恢復正常運作。</translation>
 <translation id="3745099705178523657">經你確認後,這個網站就會取得你的 Google 帳戶中的信用卡詳細資料。</translation>
 <translation id="3748148204939282805">攻擊者可能會試圖透過 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 誘使你做一些危險行為,例如安裝軟體或提供個人資訊 (包括密碼、電話號碼或信用卡資料)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -1144,6 +1151,7 @@
 <translation id="4087296516249690906">建立活動的按鈕;按下 Enter 鍵即可在 Google 日曆中快速建立新活動</translation>
 <translation id="4088981014127559358">側邊 1 圖片 Y 批次</translation>
 <translation id="4089152113577680600">紙匣 14</translation>
+<translation id="4097288585054919042">關閉快訊</translation>
 <translation id="4098354747657067197">你要瀏覽的是詐騙網站</translation>
 <translation id="4099048595830172239">根據管理員政策,當畫面上有機密內容時,不建議你與「<ph name="APPLICATION_TITLE" />」分享螢幕畫面:</translation>
 <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />;按下 Tab 鍵再按下 Enter 鍵即可自訂 Chrome 中的字型大小和字體</translation>
@@ -1180,6 +1188,7 @@
 <translation id="4176463684765177261">已停用</translation>
 <translation id="4176535426287761656">分時度假與度假房產</translation>
 <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
+<translation id="4186035307311647330">取消追蹤價格</translation>
 <translation id="4194250254487269611">目前無法儲存你的信用卡</translation>
 <translation id="4196861286325780578">重做移動(&amp;R)</translation>
 <translation id="4202554117186904723">第五卷</translation>
@@ -1226,6 +1235,7 @@
 <translation id="4275830172053184480">重新啟動裝置</translation>
 <translation id="4277028893293644418">重設密碼</translation>
 <translation id="4278390842282768270">允許</translation>
+<translation id="4282346679996504092">這項產品的快訊已關閉,這個網頁也已從書籤中移除</translation>
 <translation id="428639260510061158">{NUM_CARDS,plural, =1{這張卡片已儲存到你的 Google 帳戶}other{這些卡片已儲存到你的 Google 帳戶}}</translation>
 <translation id="4287885627794386150">符合適用條件但尚未啟用</translation>
 <translation id="4297502707443874121">第 <ph name="THUMBNAIL_PAGE" /> 頁的縮圖</translation>
@@ -1264,6 +1274,7 @@
 <translation id="4358059973562876591">DnsOverHttpsMode 政策發生錯誤,因此系統無法套用你指定的範本。</translation>
 <translation id="4358461427845829800">管理付款方式...</translation>
 <translation id="4359160567981085931">你剛才在詐騙網站上輸入了密碼。Chrome 能夠幫助你。如要變更密碼並通知 Google 你的帳戶可能面臨風險,請按一下 [保護帳戶]。</translation>
+<translation id="4363222835916186793">這項產品的快訊已關閉</translation>
 <translation id="4367563149485757821">Number-12 (Envelope)</translation>
 <translation id="437040971055499437">發生安全性事件</translation>
 <translation id="4372516964750095882">Fanfold-Us</translation>
@@ -1416,6 +1427,7 @@
 <translation id="4792686369684665359">你要提交的資訊未受到保護</translation>
 <translation id="4796594887379589189">工作帳戶 ID</translation>
 <translation id="4798078619018708837">請輸入 <ph name="CREDIT_CARD" /> 的到期日和信用卡驗證碼,以更新信用卡詳細資料。你確認後,這個網站就會取得你 Google 帳戶中的信用卡詳細資料。</translation>
+<translation id="4798269756263412078">如果產品在任何網站上降價,你會收到通知。我們會傳送快訊到你的電子郵件地址。</translation>
 <translation id="4800132727771399293">請檢查您的有效期限和信用卡驗證碼,然後再試一次</translation>
 <translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
 <translation id="4806051791961048632">使用 TouchID</translation>
@@ -1659,6 +1671,7 @@
 <translation id="5396631636586785122">邊緣裝訂 (右側)</translation>
 <translation id="5398772614898833570">已封鎖廣告</translation>
 <translation id="5400836586163650660">灰</translation>
+<translation id="540630185148148480">開啟快訊</translation>
 <translation id="540969355065856584">這個伺服器無法證明所屬網域為 <ph name="DOMAIN" />;其安全性憑證目前無效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線所致。</translation>
 <translation id="5412040515238827314">格式無效:輸入的值必須是模式清單。</translation>
 <translation id="5412236728747081950">這個網站會取得你在 Chrome 設定的興趣喜好,為你顯示更貼近需求的廣告</translation>
@@ -1723,6 +1736,7 @@
 <translation id="5580958916614886209">請檢查信用卡到期月份,然後再試一次</translation>
 <translation id="558420943003240152">管理密碼和密碼金鑰…</translation>
 <translation id="5586446728396275693">沒有已儲存的地址</translation>
+<translation id="5586831831248371458">搜尋「<ph name="KEYWORD_SUFFIX" />」</translation>
 <translation id="5587987780934666589">平台使用者</translation>
 <translation id="5593349413089863479">連線可能有安全漏洞</translation>
 <translation id="5595485650161345191">編輯地址</translation>
@@ -1842,6 +1856,7 @@
 <translation id="5938153366081463283">新增虛擬卡片</translation>
 <translation id="5938793338444039872">Troy</translation>
 <translation id="5946937721014915347">正在開啟 <ph name="SITE_NAME" />…</translation>
+<translation id="5947508410139465809">你上傳或附加的檔案會傳送到 Google Cloud 或第三方進行分析。舉例來說,Google Cloud 或第三方可能會掃描檔案,檢查是否含有機密資料或惡意軟體,並可能會根據公司政策儲存這些檔案。</translation>
 <translation id="5951495562196540101">無法透過個人帳戶註冊 (有封裝授權)。</translation>
 <translation id="5953516610448771166">這個媒體無法使用即時字幕功能。如要取得字幕,請封鎖這個網站的 <ph name="CONTENT_SETTINGS" />。</translation>
 <translation id="5955063559762970069">飯店與住宿</translation>
@@ -1930,6 +1945,7 @@
 <translation id="6177128806592000436">你與這個網站的連線不安全</translation>
 <translation id="6180316780098470077">重試間隔</translation>
 <translation id="61877208875190028">女裝</translation>
+<translation id="6194209731893739467">在這裡查看所有追蹤的產品</translation>
 <translation id="6195371403461054755">地質學</translation>
 <translation id="6196640612572343990">封鎖第三方 Cookie</translation>
 <translation id="6203231073485539293">檢查網際網路連線</translation>
@@ -1965,6 +1981,7 @@
 <translation id="6293309776179964942">JIS B5</translation>
 <translation id="6295618774959045776">CVC:</translation>
 <translation id="6300452962057769623">{0,plural, =0{裝置會立即重新啟動}=1{裝置將於 1 秒後重新啟動}other{裝置將於 # 秒後重新啟動}}</translation>
+<translation id="6301104306974789820">接收價格追蹤通知</translation>
 <translation id="6302269476990306341">正在停止 Chrome 版 Google 助理</translation>
 <translation id="6305205051461490394">無法連上 <ph name="URL" />。</translation>
 <translation id="6311165245110979290">可使用虛擬卡片</translation>
@@ -2024,6 +2041,7 @@
 <translation id="6451458296329894277">確認重新提交表單</translation>
 <translation id="6456955391422100996">已移除廣告。</translation>
 <translation id="6457206614190510200">騎馬訂</translation>
+<translation id="6457455098507772300">系統會以彈出式通知形式在電腦上顯示降價快訊</translation>
 <translation id="6458606150257356946">仍要貼上</translation>
 <translation id="6464094930452079790">圖片</translation>
 <translation id="6465306955648956876">管理密碼...</translation>
@@ -2081,6 +2099,7 @@
 <translation id="663260587451432563">JIS B4</translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6645291930348198241">存取 Cookie 和網站資料。</translation>
+<translation id="6645478838938543427">系統會將降價快訊將傳送到 <ph name="EMAIL_ADDRESS" /></translation>
 <translation id="6646269444027925224">{COUNT,plural, =0{無}=1{1 個網站 (你不會因此登出 Google 帳戶)}other{# 個網站 (你不會因此登出 Google 帳戶)}}</translation>
 <translation id="6648459603387803038">你的系統管理員可以遠端變更瀏覽器設定。這部裝置上的活動也可以透過 Chrome 以外的服務管理。</translation>
 <translation id="6648524591329069940">Serif 字型</translation>
@@ -2274,6 +2293,7 @@
 <translation id="7182878459783632708">沒有設定任何政策</translation>
 <translation id="7186367841673660872">此網頁內容已由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation>
 <translation id="718872491229180389">啦啦隊</translation>
+<translation id="7192188280913829296">必須一併指定「vendor_id」屬性。</translation>
 <translation id="7192203810768312527">釋出 <ph name="SIZE" />。下次造訪部分網站時,載入速度可能會變慢。</translation>
 <translation id="7193661028827781021">參考資料</translation>
 <translation id="719464814642662924">Visa</translation>
diff --git a/components/sync/protocol/entity_specifics.proto b/components/sync/protocol/entity_specifics.proto
index 3aa5e07..aa412ea 100644
--- a/components/sync/protocol/entity_specifics.proto
+++ b/components/sync/protocol/entity_specifics.proto
@@ -47,6 +47,7 @@
 import "components/sync/protocol/search_engine_specifics.proto";
 import "components/sync/protocol/security_event_specifics.proto";
 import "components/sync/protocol/send_tab_to_self_specifics.proto";
+import "components/sync/protocol/segmentation_specifics.proto";
 import "components/sync/protocol/session_specifics.proto";
 import "components/sync/protocol/sharing_message_specifics.proto";
 import "components/sync/protocol/synced_notification_app_info_specifics.proto";
@@ -163,6 +164,7 @@
     SavedTabGroupSpecifics saved_tab_group = 1004874;
     AutofillWalletUsageSpecifics autofill_wallet_usage = 1033580;
     ContactInfoSpecifics contact_info = 1034378;
+    SegmentationSpecifics segmentation = 1026052;
   }
   reserved 218175;
   reserved "wifi_credential";
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc
index d3e3abb..c2bf4450 100644
--- a/components/sync/protocol/proto_enum_conversions.cc
+++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -206,6 +206,29 @@
   return "";
 }
 
+const char* ProtoEnumToString(
+    sync_pb::SegmentationSpecifics::DeviceMetadata::PlatformType
+        platform_type) {
+  ASSERT_ENUM_BOUNDS(sync_pb::SegmentationSpecifics::DeviceMetadata,
+                     PlatformType, PLATFORM_TYPE_UNSPECIFIED,
+                     PLATFORM_CHROMEOS_LACROS);
+  switch (platform_type) {
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata,
+              PLATFORM_TYPE_UNSPECIFIED);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata, PLATFORM_WINDOWS);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata, PLATFORM_MAC);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata, PLATFORM_LINUX);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata,
+              PLATFORM_CHROMEOS_ASH);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata, PLATFORM_ANDROID);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata, PLATFORM_IOS);
+    ENUM_CASE(sync_pb::SegmentationSpecifics::DeviceMetadata,
+              PLATFORM_CHROMEOS_LACROS);
+  }
+  NOTREACHED();
+  return "";
+}
+
 const char* ProtoEnumToString(sync_pb::SessionTab::FaviconType favicon_type) {
   ASSERT_ENUM_BOUNDS(sync_pb::SessionTab, FaviconType, TYPE_WEB_FAVICON,
                      TYPE_WEB_FAVICON);
diff --git a/components/sync/protocol/proto_enum_conversions.h b/components/sync/protocol/proto_enum_conversions.h
index a59beb8d..0b55ea8 100644
--- a/components/sync/protocol/proto_enum_conversions.h
+++ b/components/sync/protocol/proto_enum_conversions.h
@@ -14,6 +14,7 @@
 #include "components/sync/protocol/nigori_specifics.pb.h"
 #include "components/sync/protocol/reading_list_specifics.pb.h"
 #include "components/sync/protocol/saved_tab_group_specifics.pb.h"
+#include "components/sync/protocol/segmentation_specifics.pb.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "components/sync/protocol/sync_enums.pb.h"
@@ -108,6 +109,9 @@
     sync_pb::GaiaPasswordReuse::PasswordCaptured::EventTrigger trigger);
 
 const char* ProtoEnumToString(
+    sync_pb::SegmentationSpecifics::DeviceMetadata::PlatformType platform_type);
+
+const char* ProtoEnumToString(
     sync_pb::UserEventSpecifics::GaiaPasswordCaptured::EventTrigger trigger);
 
 const char* ProtoEnumToString(
diff --git a/components/sync/protocol/proto_enum_conversions_unittest.cc b/components/sync/protocol/proto_enum_conversions_unittest.cc
index 8f445e3..c1a52ea 100644
--- a/components/sync/protocol/proto_enum_conversions_unittest.cc
+++ b/components/sync/protocol/proto_enum_conversions_unittest.cc
@@ -31,6 +31,11 @@
   TestEnumStringsNonEmpty(sync_pb::AppListSpecifics::AppListItemType);
 }
 
+TEST(ProtoEnumConversionsTest, GetSegmentationPlatformTypeTypeString) {
+  TestEnumStringsNonEmpty(
+      sync_pb::SegmentationSpecifics::DeviceMetadata::PlatformType);
+}
+
 TEST(ProtoEnumConversionsTest, GetBrowserTypeString) {
   TestEnumStringsNonEmpty(sync_pb::SyncEnums::BrowserType);
 }
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc
index eb578183..57a3ec5 100644
--- a/components/sync/protocol/proto_value_conversions.cc
+++ b/components/sync/protocol/proto_value_conversions.cc
@@ -40,6 +40,7 @@
 #include "components/sync/protocol/proto_visitors.h"
 #include "components/sync/protocol/reading_list_specifics.pb.h"
 #include "components/sync/protocol/search_engine_specifics.pb.h"
+#include "components/sync/protocol/segmentation_specifics.pb.h"
 #include "components/sync/protocol/send_tab_to_self_specifics.pb.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync/protocol/sharing_message_specifics.pb.h"
@@ -366,6 +367,7 @@
 IMPLEMENT_PROTO_TO_VALUE(SearchEngineSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SecurityEventSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SendTabToSelfSpecifics)
+IMPLEMENT_PROTO_TO_VALUE(SegmentationSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SessionHeader)
 IMPLEMENT_PROTO_TO_VALUE(SessionSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SessionTab)
diff --git a/components/sync/protocol/proto_value_conversions.h b/components/sync/protocol/proto_value_conversions.h
index 2a6f0cf..4350693 100644
--- a/components/sync/protocol/proto_value_conversions.h
+++ b/components/sync/protocol/proto_value_conversions.h
@@ -54,6 +54,7 @@
 class ReadingListSpecifics;
 class SearchEngineSpecifics;
 class SecurityEventSpecifics;
+class SegmentationSpecifics;
 class SendTabToSelfSpecifics;
 class SessionHeader;
 class SessionSpecifics;
@@ -208,6 +209,9 @@
 std::unique_ptr<base::DictionaryValue> SearchEngineSpecificsToValue(
     const sync_pb::SearchEngineSpecifics& search_engine_specifics);
 
+std::unique_ptr<base::DictionaryValue> SegmentationSpecificsToValue(
+    const sync_pb::SegmentationSpecifics& segmentation_specifics);
+
 std::unique_ptr<base::DictionaryValue> SendTabToSelfSpecificsToValue(
     const sync_pb::SendTabToSelfSpecifics& send_tab_specifics);
 
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc
index 3320986..e4e1c5a5 100644
--- a/components/sync/protocol/proto_value_conversions_unittest.cc
+++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -30,6 +30,7 @@
 #include "components/sync/protocol/preference_specifics.pb.h"
 #include "components/sync/protocol/priority_preference_specifics.pb.h"
 #include "components/sync/protocol/search_engine_specifics.pb.h"
+#include "components/sync/protocol/segmentation_specifics.pb.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync/protocol/sharing_message_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -96,6 +97,7 @@
 DEFINE_SPECIFICS_TO_VALUE_TEST(reading_list)
 DEFINE_SPECIFICS_TO_VALUE_TEST(search_engine)
 DEFINE_SPECIFICS_TO_VALUE_TEST(security_event)
+DEFINE_SPECIFICS_TO_VALUE_TEST(segmentation)
 DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self)
 DEFINE_SPECIFICS_TO_VALUE_TEST(session)
 DEFINE_SPECIFICS_TO_VALUE_TEST(sharing_message)
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index 54a026c..b2cb206 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -39,6 +39,7 @@
 #include "components/sync/protocol/reading_list_specifics.pb.h"
 #include "components/sync/protocol/saved_tab_group_specifics.pb.h"
 #include "components/sync/protocol/search_engine_specifics.pb.h"
+#include "components/sync/protocol/segmentation_specifics.pb.h"
 #include "components/sync/protocol/send_tab_to_self_specifics.pb.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync/protocol/sharing_message_specifics.pb.h"
@@ -567,6 +568,7 @@
   VISIT(reading_list);
   VISIT(search_engine);
   VISIT(security_event);
+  VISIT(segmentation);
   VISIT(send_tab_to_self);
   VISIT(session);
   VISIT(sharing_message);
@@ -972,6 +974,43 @@
   VISIT(notification_dismissed);
 }
 
+VISIT_PROTO_FIELDS(const sync_pb::SegmentationSpecifics& proto) {
+  VISIT(segmentation_key);
+  VISIT(segment_selection_result);
+  VISIT(device_metadata);
+  VISIT_REP(model_execution_data);
+}
+
+VISIT_PROTO_FIELDS(
+    const sync_pb::SegmentationSpecifics::SegmentSelectionResult& proto) {
+  VISIT(selected_segment);
+  VISIT(expiry_time_windows_epoch_seconds);
+  VISIT(last_updated_time_windows_epoch_seconds);
+}
+
+VISIT_PROTO_FIELDS(
+    const sync_pb::SegmentationSpecifics::DeviceMetadata& proto) {
+  VISIT(cache_guid);
+  VISIT_ENUM(platform_type);
+}
+
+VISIT_PROTO_FIELDS(
+    const sync_pb::SegmentationSpecifics::ModelExecutionData& proto) {
+  VISIT(model_id);
+  VISIT_REP(model_outputs);
+  VISIT(execution_time_windows_epoch_seconds);
+  VISIT(score_expiry_time_windows_epoch_seconds);
+  VISIT(model_version);
+}
+
+VISIT_PROTO_FIELDS(
+    const sync_pb::SegmentationSpecifics::ModelExecutionData::ModelOutput&
+        proto) {
+  VISIT(label);
+  VISIT(score);
+  VISIT(rank);
+}
+
 VISIT_PROTO_FIELDS(const sync_pb::SessionHeader& proto) {
   VISIT_REP(window);
   VISIT(client_name);
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni
index ad4c341..fde666f9c 100644
--- a/components/sync/protocol/protocol_sources.gni
+++ b/components/sync/protocol/protocol_sources.gni
@@ -53,6 +53,7 @@
   "saved_tab_group_specifics.proto",
   "search_engine_specifics.proto",
   "security_event_specifics.proto",
+  "segmentation_specifics.proto",
   "send_tab_to_self_specifics.proto",
   "session_specifics.proto",
   "sharing_message_specifics.proto",
diff --git a/components/sync/protocol/segmentation_specifics.proto b/components/sync/protocol/segmentation_specifics.proto
new file mode 100644
index 0000000..c314ba3
--- /dev/null
+++ b/components/sync/protocol/segmentation_specifics.proto
@@ -0,0 +1,111 @@
+// 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.
+//
+// Sync protocol datatype extension for segmentations.
+
+// If you change or add any fields in this file, update proto_visitors.h and
+// potentially proto_enum_conversions.{h, cc}.
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "org.chromium.components.sync.protocol";
+
+option optimize_for = LITE_RUNTIME;
+
+package sync_pb;
+
+// Sync data proto for storing segmentation data. Keyed by the combination of
+// cache_guid (a Sync client id) and segmentation key.
+//
+// The segmentation platform is a platform that uses intelligence and machine
+// learning to guide developers for building purpose-built user experience for
+// specific segments of users. See go/chrome-segmentation for more details.
+message SegmentationSpecifics {
+  // The selected segment by the segmentation scheme.
+  message SegmentSelectionResult {
+    // The string ID that refers to the segment the user was assigned to, e.g.,
+    // 'highly_engaged_user'.
+    optional string selected_segment = 1;
+
+    // Expiry time of selection result. Represents time from windows epoch in
+    // seconds. Expired results are ignored by clients.
+    optional int64 expiry_time_windows_epoch_seconds = 2;
+
+    // Time when the segmentation data is updated. Used to weigh results by
+    // recency. Represents time from windows epoch in seconds.
+    optional int64 last_updated_time_windows_epoch_seconds = 3;
+  }
+
+  // Metadata about the client device as used by the segmentation platform.
+  message DeviceMetadata {
+    // The cache_guid created to identify a sync client on this device.
+    // Reuses the same Sync guid.
+    optional string cache_guid = 1;
+
+    enum PlatformType {
+      PLATFORM_TYPE_UNSPECIFIED = 0;
+      PLATFORM_WINDOWS = 1;
+      PLATFORM_MAC = 2;
+      PLATFORM_LINUX = 3;
+      PLATFORM_CHROMEOS_ASH = 4;
+      PLATFORM_ANDROID = 5;
+      PLATFORM_IOS = 6;
+      PLATFORM_CHROMEOS_LACROS = 7;
+    }
+
+    // The OS platform of the device.
+    optional PlatformType platform_type = 2;
+  }
+
+  // Model execution data including segment scores and related metadata, e.g.,
+  // model version.
+  message ModelExecutionData {
+    // Output of model.
+    message ModelOutput {
+      // When outputting multiple scores from a single model, this is the
+      // segment label for each output.
+      optional string label = 1;
+
+      // Raw segment scores provided by the ML model or the heuristic model.
+      // The score is derived based on a combination of UMA histograms,
+      // user actions or UKM and URLs visited. The score can be treated as a
+      // probability of the user liking a feature, like feed, or NTP.
+      optional float score = 2;
+
+      // A rank defined by the segmentation scheme.
+      optional int32 rank = 3;
+    }
+
+    // A string ID that identifies a model.
+    optional string model_id = 1;
+
+    // A model may output one or multiple scores, one score for each segment
+    // label.
+    repeated ModelOutput model_outputs = 2;
+
+    // Timestamp when the ML model was executed.
+    // Represents time from windows epoch in seconds.
+    optional int64 execution_time_windows_epoch_seconds = 3;
+
+    // Expiry timestamp for the model scores.
+    // Represents time from windows epoch in seconds.
+    optional int64 score_expiry_time_windows_epoch_seconds = 4;
+
+    // The version of the ML model that was run.
+    optional int32 model_version = 5;
+  }
+
+  // The key used to identify the type of segmentation associated with a
+  // feature, e.g. 'user_engagement'.
+  optional string segmentation_key = 1;
+
+  optional SegmentSelectionResult segment_selection_result = 2;
+
+  optional DeviceMetadata device_metadata = 3;
+
+  // One or more model execution data associated with each segment for the
+  // segmentation key.
+  repeated ModelExecutionData model_execution_data = 4;
+}
diff --git a/components/url_rewrite/common/url_loader_throttle.cc b/components/url_rewrite/common/url_loader_throttle.cc
index 443b4da..7f0f6384 100644
--- a/components/url_rewrite/common/url_loader_throttle.cc
+++ b/components/url_rewrite/common/url_loader_throttle.cc
@@ -112,12 +112,9 @@
   return base::CompareCaseInsensitiveASCII(url_host, rule_host) == 0;
 }
 
-// Returns true if the host and scheme filters defined in |rule| match
-// |request|.
-bool RuleFiltersMatchRequest(network::ResourceRequest* request,
-                             const mojom::UrlRequestRulePtr& rule) {
-  const GURL& url = request->url;
-
+// Returns true if the host and scheme filters defined in |rule| match |url|.
+bool RuleFiltersMatchUrl(const GURL& url,
+                         const mojom::UrlRequestRulePtr& rule) {
   if (rule->hosts_filter) {
     bool found = false;
     for (const base::StringPiece host : rule->hosts_filter.value()) {
@@ -153,7 +150,7 @@
     if (rule->actions[0]->which() != mojom::UrlRequestAction::Tag::kPolicy)
       continue;
 
-    if (!RuleFiltersMatchRequest(request, rule))
+    if (!RuleFiltersMatchUrl(request->url, rule))
       continue;
 
     switch (rule->actions[0]->get_policy()) {
@@ -203,9 +200,20 @@
 
 void URLLoaderThrottle::ApplyRule(network::ResourceRequest* request,
                                   const mojom::UrlRequestRulePtr& rule) {
-  if (!RuleFiltersMatchRequest(request, rule))
+  if (!RuleFiltersMatchUrl(request->url, rule))
     return;
 
+  // Prevent applying rules more than once when redirected.
+  for (const auto& url : request->navigation_redirect_chain) {
+    // Last element in redirect chain is the current navigation.
+    if (&url == &request->navigation_redirect_chain.back()) {
+      continue;
+    }
+    if (RuleFiltersMatchUrl(url, rule)) {
+      return;
+    }
+  }
+
   for (const auto& rewrite : rule->actions)
     ApplyRewrite(request, rewrite);
 }
diff --git a/components/url_rewrite/common/url_loader_throttle_unittest.cc b/components/url_rewrite/common/url_loader_throttle_unittest.cc
index 7ce47c0..82f5ef7f 100644
--- a/components/url_rewrite/common/url_loader_throttle_unittest.cc
+++ b/components/url_rewrite/common/url_loader_throttle_unittest.cc
@@ -146,7 +146,7 @@
 // Tests URL replacement rules that replace to a data URL do not append query or
 // ref from the original URL.
 TEST_F(URLLoaderThrottleTest, DataReplacementUrl) {
-  const char kCssDataURI[] = "data:text/css,";
+  constexpr char kCssDataURI[] = "data:text/css,";
 
   mojom::UrlRequestRewriteReplaceUrlPtr replace_url =
       mojom::UrlRequestRewriteReplaceUrl::New();
@@ -174,6 +174,164 @@
   EXPECT_EQ(request.url, base::StringPiece(kCssDataURI));
 }
 
+// Tests URL replacement rules do not apply more than once in a redirect chain
+// on the same host.
+TEST_F(URLLoaderThrottleTest, RedirectsToSameHost) {
+  constexpr char kAppendQueryString[] = "foo=1&bar=2";
+  constexpr char kBaseUrl[] = "http://test.net";
+  constexpr char kUrlWithQueryString[] = "http://test.net?foo=1&bar=2";
+
+  mojom::UrlRequestRewriteAppendToQueryPtr append_query =
+      mojom::UrlRequestRewriteAppendToQuery::New(kAppendQueryString);
+  std::vector<mojom::UrlRequestActionPtr> actions;
+  actions.push_back(
+      mojom::UrlRequestAction::NewAppendToQuery(std::move(append_query)));
+
+  mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
+  rule->hosts_filter = absl::optional<std::vector<std::string>>({"*.test.net"});
+  rule->actions = std::move(actions);
+
+  mojom::UrlRequestRewriteRulesPtr rules = mojom::UrlRequestRewriteRules::New();
+  rules->rules.push_back(std::move(rule));
+
+  URLLoaderThrottle throttle(
+      base::MakeRefCounted<UrlRequestRewriteRules>(std::move(rules)),
+      CreateCorsExemptHeadersCallback({}));
+  bool defer = false;
+
+  network::ResourceRequest request;
+  request.url = GURL(kBaseUrl);
+  request.navigation_redirect_chain = {GURL(kBaseUrl)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kUrlWithQueryString));
+
+  request.url = GURL(kUrlWithQueryString);
+  request.navigation_redirect_chain = {GURL(kBaseUrl),
+                                       GURL(kUrlWithQueryString)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kUrlWithQueryString));
+}
+
+// Tests URL replacement rules applies when redirecting from a different host.
+TEST_F(URLLoaderThrottleTest, RedirectsFromDifferentHost) {
+  constexpr char kAppendQueryString[] = "foo=1&bar=2";
+  constexpr char kBaseUrl1[] = "http://a.com";
+  constexpr char kBaseUrl2[] = "http://b.com";
+  constexpr char kUrl2WithQueryString[] = "http://b.com?foo=1&bar=2";
+
+  mojom::UrlRequestRewriteAppendToQueryPtr append_query =
+      mojom::UrlRequestRewriteAppendToQuery::New(kAppendQueryString);
+  std::vector<mojom::UrlRequestActionPtr> actions;
+  actions.push_back(
+      mojom::UrlRequestAction::NewAppendToQuery(std::move(append_query)));
+
+  mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
+  rule->hosts_filter = absl::optional<std::vector<std::string>>({"*.b.com"});
+  rule->actions = std::move(actions);
+
+  mojom::UrlRequestRewriteRulesPtr rules = mojom::UrlRequestRewriteRules::New();
+  rules->rules.push_back(std::move(rule));
+
+  URLLoaderThrottle throttle(
+      base::MakeRefCounted<UrlRequestRewriteRules>(std::move(rules)),
+      CreateCorsExemptHeadersCallback({}));
+  bool defer = false;
+
+  network::ResourceRequest request;
+  request.url = GURL(kBaseUrl1);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kBaseUrl1));
+
+  request.url = GURL(kBaseUrl2);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1), GURL(kBaseUrl2)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kUrl2WithQueryString));
+}
+
+// Tests URL replacement rules do not apply more than once when redirecting to a
+// different host that the rule applies to.
+TEST_F(URLLoaderThrottleTest, RedirectsToDifferentHost) {
+  constexpr char kAppendQueryString[] = "foo=1&bar=2";
+  constexpr char kBaseUrl1[] = "http://a.com";
+  constexpr char kBaseUrl2[] = "http://b.com";
+  constexpr char kUrl1WithQueryString[] = "http://a.com?foo=1&bar=2";
+
+  mojom::UrlRequestRewriteAppendToQueryPtr append_query =
+      mojom::UrlRequestRewriteAppendToQuery::New(kAppendQueryString);
+  std::vector<mojom::UrlRequestActionPtr> actions;
+  actions.push_back(
+      mojom::UrlRequestAction::NewAppendToQuery(std::move(append_query)));
+
+  mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
+  rule->hosts_filter =
+      absl::optional<std::vector<std::string>>({"*.a.com", "*.b.com"});
+  rule->actions = std::move(actions);
+
+  mojom::UrlRequestRewriteRulesPtr rules = mojom::UrlRequestRewriteRules::New();
+  rules->rules.push_back(std::move(rule));
+
+  URLLoaderThrottle throttle(
+      base::MakeRefCounted<UrlRequestRewriteRules>(std::move(rules)),
+      CreateCorsExemptHeadersCallback({}));
+  bool defer = false;
+
+  network::ResourceRequest request;
+  request.url = GURL(kBaseUrl1);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kUrl1WithQueryString));
+
+  request.url = GURL(kBaseUrl2);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1), GURL(kBaseUrl2)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kBaseUrl2));
+}
+
+// Tests URL replacement rules do not apply more than once when redirecting to a
+// different host then back to the same host.
+TEST_F(URLLoaderThrottleTest, RedirectsToDifferentHostThenBack) {
+  constexpr char kAppendQueryString[] = "foo=1&bar=2";
+  constexpr char kBaseUrl1[] = "http://a.com";
+  constexpr char kBaseUrl2[] = "http://b.com";
+  constexpr char kUrl1WithQueryString[] = "http://a.com?foo=1&bar=2";
+
+  mojom::UrlRequestRewriteAppendToQueryPtr append_query =
+      mojom::UrlRequestRewriteAppendToQuery::New(kAppendQueryString);
+  std::vector<mojom::UrlRequestActionPtr> actions;
+  actions.push_back(
+      mojom::UrlRequestAction::NewAppendToQuery(std::move(append_query)));
+
+  mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
+  rule->hosts_filter = absl::optional<std::vector<std::string>>({"*.a.com"});
+  rule->actions = std::move(actions);
+
+  mojom::UrlRequestRewriteRulesPtr rules = mojom::UrlRequestRewriteRules::New();
+  rules->rules.push_back(std::move(rule));
+
+  URLLoaderThrottle throttle(
+      base::MakeRefCounted<UrlRequestRewriteRules>(std::move(rules)),
+      CreateCorsExemptHeadersCallback({}));
+  bool defer = false;
+
+  network::ResourceRequest request;
+  request.url = GURL(kBaseUrl1);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kUrl1WithQueryString));
+
+  request.url = GURL(kBaseUrl2);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1), GURL(kBaseUrl2)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kBaseUrl2));
+
+  request.url = GURL(kBaseUrl1);
+  request.navigation_redirect_chain = {GURL(kBaseUrl1), GURL(kBaseUrl2),
+                                       GURL(kBaseUrl1)};
+  throttle.WillStartRequest(&request, &defer);
+  EXPECT_EQ(request.url, GURL(kBaseUrl1));
+}
+
 class TestThrottleDelegate : public blink::URLLoaderThrottle::Delegate {
  public:
   TestThrottleDelegate() = default;
diff --git a/components/user_manager/OWNERS b/components/user_manager/OWNERS
index 7d71337f..1e3e2653 100644
--- a/components/user_manager/OWNERS
+++ b/components/user_manager/OWNERS
@@ -1,5 +1,5 @@
 achuith@chromium.org
 alemate@chromium.org
 antrim@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 xiyuan@chromium.org
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc
index b1d74bc..940b02e 100644
--- a/components/user_manager/fake_user_manager.cc
+++ b/components/user_manager/fake_user_manager.cc
@@ -48,6 +48,17 @@
 FakeUserManager::~FakeUserManager() {
 }
 
+std::string FakeUserManager::GetFakeUsernameHash(const AccountId& account_id) {
+  // Consistent with the
+  // kUserDataDirNameSuffix in fake_userdataauth_client.cc and
+  // UserDataAuthClient::GetStubSanitizedUsername.
+  // TODO(crbug.com/1347837): After resolving the dependent code,
+  // consolidate the all implementation to cryptohome utilities,
+  // and remove this.
+  DCHECK(account_id.is_valid());
+  return account_id.GetUserEmail() + "-hash";
+}
+
 const User* FakeUserManager::AddUser(const AccountId& account_id) {
   return AddUserWithAffiliation(account_id, false);
 }
@@ -66,8 +77,7 @@
 
 const User* FakeUserManager::AddKioskAppUser(const AccountId& account_id) {
   User* user = User::CreateKioskAppUser(account_id);
-  // TODO: Merge with ProfileHelper::GetUserIdHashByUserIdForTesting.
-  user->set_username_hash(account_id.GetUserEmail() + "-hash");
+  user->set_username_hash(GetFakeUsernameHash(account_id));
   users_.push_back(user);
   return user;
 }
@@ -76,8 +86,7 @@
                                                     bool is_affiliated) {
   User* user = User::CreateRegularUser(account_id, USER_TYPE_REGULAR);
   user->SetAffiliation(is_affiliated);
-  // TODO: Merge with ProfileHelper::GetUserIdHashByUserIdForTesting.
-  user->set_username_hash(account_id.GetUserEmail() + "-hash");
+  user->set_username_hash(GetFakeUsernameHash(account_id));
   users_.push_back(user);
   return user;
 }
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h
index 8016122..690d3bfe 100644
--- a/components/user_manager/fake_user_manager.h
+++ b/components/user_manager/fake_user_manager.h
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "base/memory/raw_ptr.h"
+#include "base/strings/string_piece.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager_base.h"
@@ -27,6 +28,10 @@
 
   ~FakeUserManager() override;
 
+  // Returns the fake username hash for testing.
+  // Valid AccountId must be used, otherwise DCHECKed.
+  static std::string GetFakeUsernameHash(const AccountId& account_id);
+
   // Create and add a new user. Created user is not affiliated with the domain,
   // that owns the device.
   const User* AddUser(const AccountId& account_id);
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn
index b2e1ce3..6169ab1 100644
--- a/components/variations/BUILD.gn
+++ b/components/variations/BUILD.gn
@@ -284,4 +284,13 @@
       "//third_party/libprotobuf-mutator",
     ]
   }
+  fuzzer_test("create_trials_from_seed_fuzzer") {
+    sources = [ "fuzzers/create_trials_from_seed_fuzzer.cc" ]
+    deps = [
+      ":variations",
+      "proto",
+      "//base/test:test_support",
+      "//third_party/libprotobuf-mutator",
+    ]
+  }
 }
diff --git a/components/variations/fuzzers/create_trials_from_seed_fuzzer.cc b/components/variations/fuzzers/create_trials_from_seed_fuzzer.cc
new file mode 100644
index 0000000..d371588
--- /dev/null
+++ b/components/variations/fuzzers/create_trials_from_seed_fuzzer.cc
@@ -0,0 +1,91 @@
+// 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/variations/variations_seed_processor.h"
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/test/mock_entropy_provider.h"
+#include "base/test/scoped_command_line.h"
+#include "components/variations/entropy_provider.h"
+#include "components/variations/processed_study.h"
+#include "components/variations/proto/study.pb.h"
+#include "components/variations/study_filtering.h"
+#include "testing/libfuzzer/proto/lpm_interface.h"
+
+namespace variations {
+namespace {
+
+class TestOverrideStringCallback {
+ public:
+  typedef std::map<uint32_t, std::u16string> OverrideMap;
+
+  TestOverrideStringCallback()
+      : callback_(base::BindRepeating(&TestOverrideStringCallback::Override,
+                                      base::Unretained(this))) {}
+  TestOverrideStringCallback(const TestOverrideStringCallback&) = delete;
+  TestOverrideStringCallback& operator=(const TestOverrideStringCallback&) =
+      delete;
+
+  virtual ~TestOverrideStringCallback() {}
+
+  const VariationsSeedProcessor::UIStringOverrideCallback& callback() const {
+    return callback_;
+  }
+
+  const OverrideMap& overrides() const { return overrides_; }
+
+ private:
+  void Override(uint32_t hash, const std::u16string& string) {
+    overrides_[hash] = string;
+  }
+
+  VariationsSeedProcessor::UIStringOverrideCallback callback_;
+  OverrideMap overrides_;
+};
+
+struct Environment {
+  Environment() { base::CommandLine::Init(0, nullptr); }
+
+  base::AtExitManager at_exit_manager;
+};
+
+std::unique_ptr<ClientFilterableState> MockChromeClientFilterableState() {
+  auto client_state = std::make_unique<ClientFilterableState>(
+      base::BindOnce([] { return false; }));
+  client_state->locale = "en-CA";
+  client_state->reference_date = base::Time::Now();
+  client_state->version = base::Version("20.0.0.0");
+  client_state->channel = Study::STABLE;
+  client_state->form_factor = Study::PHONE;
+  client_state->platform = Study::PLATFORM_ANDROID;
+  return client_state;
+}
+
+}  // namespace
+
+void CreateTrialsFromStudyFuzzer(const VariationsSeed& seed) {
+  base::FieldTrialList field_trial_list(
+      std::make_unique<SHA1EntropyProvider>("client_id"));
+  base::FeatureList feature_list;
+
+  TestOverrideStringCallback override_callback;
+  // TODO(b/244252663): Add more coverage of client_state and entropy
+  // provider arguments.
+  auto client_state = MockChromeClientFilterableState();
+  base::MockEntropyProvider mock_low_entropy_provider(0.9);
+
+  VariationsSeedProcessor().CreateTrialsFromSeed(
+      seed, *client_state, override_callback.callback(),
+      &mock_low_entropy_provider, &feature_list);
+}
+
+DEFINE_PROTO_FUZZER(const VariationsSeed& seed) {
+  static Environment env;
+  CreateTrialsFromStudyFuzzer(seed);
+}
+
+}  // namespace variations
diff --git a/components/variations/variations_seed_processor.cc b/components/variations/variations_seed_processor.cc
index f9851e25d..4dc28ca1 100644
--- a/components/variations/variations_seed_processor.cc
+++ b/components/variations/variations_seed_processor.cc
@@ -24,6 +24,10 @@
 
 namespace variations {
 
+namespace internal {
+const char kFeatureConflictGroupName[] = "ClientSideFeatureConflict";
+}  // namespace internal
+
 namespace {
 
 // Associates the variations params of |experiment|, if present.
@@ -187,6 +191,21 @@
   return false;
 }
 
+// Creates a trial with the name |trial_name|, and forcibly selects the
+// |kFeatureConflictGroupName| group, which specifies no feature, params, or
+// variation IDs. This group is used to indicate that there was a feature
+// conflict. For example, toggling a flag with params in chrome://flags, which
+// will associate the feature with a trial. If the variations seed specifies a
+// different trial with the same feature, then there is a conflict.
+void CreateTrialWithFeatureConflictGroup(const std::string& trial_name) {
+  base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
+      trial_name, internal::kFeatureConflictGroupName);
+  DCHECK(trial);
+  // Query the trial's group in order to immediately activate it. This way,
+  // from the metrics logs, it will be obvious that there was a conflict.
+  trial->group();
+}
+
 }  // namespace
 
 VariationsSeedProcessor::VariationsSeedProcessor() = default;
@@ -232,6 +251,11 @@
     const UIStringOverrideCallback& override_callback,
     const base::FieldTrial::EntropyProvider* low_entropy_provider,
     base::FeatureList* feature_list) {
+  // Since trials and features can come from many different sources (variations
+  // seed, about://flags, and command line), there are special cases for when
+  // they conflict with each other. See the following doc:
+  // https://docs.google.com/document/d/1PAlx0KyjRwLJsmkIWlZMgZ-R422Oetgxa3ZPq0Q98aQ
+
   const Study& study = *processed_study.study();
 
   // If the trial already exists, check if the selected group exists in the
@@ -242,6 +266,39 @@
         existing_trial->GetGroupNameWithoutActivation());
     if (experiment_index == -1)
       return;
+    // If the selected group exists in |processed_study|, then there may be some
+    // variation ids, params, and features to pick up, so do not return early.
+    // For example, if a user specifies the command line flag
+    // "--force-fieldtrials=Study/Enabled" and the variations seed includes
+    // a "Study" trial with an "Enabled" group that specifies features or other
+    // details, then use those details, even though they were not directly
+    // specified on the command line.
+  } else {
+    // If an experiment group in the study specifies a feature that is already
+    // associated with another trial, forcibly select the
+    // |kFeatureConflictGroupName| group to indicate a conflict. Usually, the
+    // server-side enforces that no two studies enable/disable the same feature,
+    // but this might happen from the client-side, such as through flags or
+    // through the command line.
+    //
+    // Only check for this if the trial does not already exist. If it already
+    // exists, then we cannot create the |kFeatureConflictGroupName| group for
+    // it.
+    for (const Study::Experiment& experiment : study.experiment()) {
+      const auto& features = experiment.feature_association();
+      for (const std::string& feature_name : features.enable_feature()) {
+        if (feature_list->HasAssociatedFieldTrialByFeatureName(feature_name)) {
+          CreateTrialWithFeatureConflictGroup(study.name());
+          return;
+        }
+      }
+      for (const std::string& feature_name : features.disable_feature()) {
+        if (feature_list->HasAssociatedFieldTrialByFeatureName(feature_name)) {
+          CreateTrialWithFeatureConflictGroup(study.name());
+          return;
+        }
+      }
+    }
   }
 
   // Check if any experiments need to be forced due to a command line
diff --git a/components/variations/variations_seed_processor.h b/components/variations/variations_seed_processor.h
index 624eb446..3c9a29a 100644
--- a/components/variations/variations_seed_processor.h
+++ b/components/variations/variations_seed_processor.h
@@ -24,6 +24,12 @@
 
 namespace variations {
 
+namespace internal {
+// The trial group selected when a study specifies a feature that is already
+// associated with another trial. Exposed in the header file for testing.
+COMPONENT_EXPORT(VARIATIONS) extern const char kFeatureConflictGroupName[];
+}  // namespace internal
+
 class ProcessedStudy;
 struct ClientFilterableState;
 
diff --git a/components/variations/variations_seed_processor_unittest.cc b/components/variations/variations_seed_processor_unittest.cc
index 5b473bf..1ae7b0bd 100644
--- a/components/variations/variations_seed_processor_unittest.cc
+++ b/components/variations/variations_seed_processor_unittest.cc
@@ -1374,4 +1374,88 @@
   EXPECT_FALSE(base::FieldTrialList::IsTrialActive(study->name()));
 }
 
+TYPED_TEST(VariationsSeedProcessorTest, StudiesWithOverlappingEnabledFeatures) {
+  static struct base::Feature kFeature {
+    "FeatureName", base::FEATURE_ENABLED_BY_DEFAULT
+  };
+
+  VariationsSeed seed;
+
+  // Create two studies that enable |kFeature|.
+  Study* flags_study = seed.add_study();
+  flags_study->set_name("FlagsStudy");
+  flags_study->set_default_experiment_name("A");
+  flags_study->set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
+  Study::Experiment* experiment =
+      AddExperiment("A", /*probability=*/1, flags_study);
+  experiment->mutable_feature_association()->add_enable_feature(kFeature.name);
+
+  Study* server_side_study = seed.add_study();
+  server_side_study->set_name("ServerSideStudy");
+  server_side_study->set_default_experiment_name("A");
+  server_side_study->set_activation_type(
+      Study_ActivationType_ACTIVATE_ON_STARTUP);
+  Study::Experiment* experiment2 =
+      AddExperiment("A", /*probability=*/1, server_side_study);
+  experiment2->mutable_feature_association()->add_enable_feature(kFeature.name);
+
+  this->CreateTrialsFromSeed(seed);
+
+  // Verify that FlagsStudy was created and activated, and that the "A"
+  // experiment group was selected.
+  ASSERT_TRUE(base::FieldTrialList::IsTrialActive(flags_study->name()));
+  EXPECT_EQ(base::FieldTrialList::Find(flags_study->name())->group_name(), "A");
+
+  // Verify that ServerSideStudy was created and activated, but that the
+  // |kFeatureConflictGroupName| experiment group was forcibly selected due to
+  // the study being associated with |kFeature| (which is already associated
+  // with trial FlagsStudy).
+  ASSERT_TRUE(base::FieldTrialList::IsTrialActive(server_side_study->name()));
+  EXPECT_EQ(base::FieldTrialList::Find(server_side_study->name())->group_name(),
+            internal::kFeatureConflictGroupName);
+}
+
+TYPED_TEST(VariationsSeedProcessorTest,
+           StudiesWithOverlappingDisabledFeatures) {
+  static struct base::Feature kFeature {
+    "FeatureName", base::FEATURE_ENABLED_BY_DEFAULT
+  };
+
+  VariationsSeed seed;
+
+  // Create two studies that disable |kFeature|.
+  Study* flags_study = seed.add_study();
+  flags_study->set_name("FlagsStudy");
+  flags_study->set_default_experiment_name("A");
+  flags_study->set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
+  Study::Experiment* experiment =
+      AddExperiment("A", /*probability=*/1, flags_study);
+  experiment->mutable_feature_association()->add_disable_feature(kFeature.name);
+
+  Study* server_side_study = seed.add_study();
+  server_side_study->set_name("ServerSideStudy");
+  server_side_study->set_default_experiment_name("A");
+  server_side_study->set_activation_type(
+      Study_ActivationType_ACTIVATE_ON_STARTUP);
+  Study::Experiment* experiment2 =
+      AddExperiment("A", /*probability=*/1, server_side_study);
+  experiment2->mutable_feature_association()->add_disable_feature(
+      kFeature.name);
+
+  this->CreateTrialsFromSeed(seed);
+
+  // Verify that FlagsStudy was created and activated, and that the "A"
+  // experiment group was selected.
+  ASSERT_TRUE(base::FieldTrialList::IsTrialActive(flags_study->name()));
+  EXPECT_EQ(base::FieldTrialList::Find(flags_study->name())->group_name(), "A");
+
+  // Verify that ServerSideStudy was created and activated, but that the
+  // |kFeatureConflictGroupName| experiment group was forcibly selected due to
+  // the study being associated with |kFeature| (which is already associated
+  // with trial FlagsStudy).
+  ASSERT_TRUE(base::FieldTrialList::IsTrialActive(server_side_study->name()));
+  EXPECT_EQ(base::FieldTrialList::Find(server_side_study->name())->group_name(),
+            internal::kFeatureConflictGroupName);
+}
+
 }  // namespace variations
diff --git a/components/viz/host/host_gpu_memory_buffer_manager.cc b/components/viz/host/host_gpu_memory_buffer_manager.cc
index 4722098a..dbe7b11 100644
--- a/components/viz/host/host_gpu_memory_buffer_manager.cc
+++ b/components/viz/host/host_gpu_memory_buffer_manager.cc
@@ -56,7 +56,12 @@
 HostGpuMemoryBufferManager::PendingBufferInfo::PendingBufferInfo() = default;
 HostGpuMemoryBufferManager::PendingBufferInfo::PendingBufferInfo(
     PendingBufferInfo&&) = default;
-HostGpuMemoryBufferManager::PendingBufferInfo::~PendingBufferInfo() = default;
+HostGpuMemoryBufferManager::PendingBufferInfo::~PendingBufferInfo() {
+  // Another thread may be blocked on WaitableEvent that is signalled by
+  // `callback` so ensure it gets run.
+  if (callback)
+    std::move(callback).Run(gfx::GpuMemoryBufferHandle());
+}
 
 HostGpuMemoryBufferManager::HostGpuMemoryBufferManager(
     GpuServiceProvider gpu_service_provider,
diff --git a/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_multithread_unittest.cc b/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_multithread_unittest.cc
index 3d48c2c..97c8237 100644
--- a/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_multithread_unittest.cc
+++ b/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_multithread_unittest.cc
@@ -86,7 +86,7 @@
          static_cast<uint32_t>(i) < thread_test_config_.dbg_commands[0].size();
          ++i) {
       // Spin to allow writer to jump in once in a while.
-      for (uint32_t _ = 0; _ < spin_amount_; ++_) {
+      for (uint32_t spinner = 0; spinner < spin_amount_; ++spinner) {
         ++spin_inc_var_;
       }
       // The position of the rect is used as a unique identifier
@@ -140,9 +140,10 @@
   }
 
   void ThreadMain() override {
-    for (uint32_t _ = 0; _ < num_writer_tries_; ++_) {
+    for (uint32_t writer_try = 0; writer_try < num_writer_tries_;
+         ++writer_try) {
       // Spin to add delays before writer tries again.
-      for (uint32_t _ = 0; _ < spin_amount_; ++_) {
+      for (uint32_t spinner = 0; spinner < spin_amount_; ++spinner) {
         ++spin_inc_var_;
       }
       test_fixture_ptr_->GetFrameData(false);
diff --git a/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_rwlock_unittest.cc b/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_rwlock_unittest.cc
index 29124f8..8c93a596 100644
--- a/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_rwlock_unittest.cc
+++ b/components/viz/service/debugger/viz_debugger_unittests/viz_debugger_rwlock_unittest.cc
@@ -35,7 +35,7 @@
   WriterThread() = default;
 
   void ThreadMain() override {
-    for (uint32_t _ = 0; _ < kNumWriterTries; ++_) {
+    for (uint32_t writer_try = 0; writer_try < kNumWriterTries; ++writer_try) {
       RWLockTest::test_rwlock.WriteLock();
 
       for (int i = 0; i < size_; ++i) {
@@ -81,7 +81,7 @@
   ReaderThread& operator=(const ReaderThread&) = delete;
 
   void ThreadMain() override {
-    for (uint32_t _ = 0; _ < kNumCounts; ++_) {
+    for (uint32_t count = 0; count < kNumCounts; ++count) {
       RWLockTest::test_rwlock.ReadLock();
       ++(*array_)[array_index];
       RWLockTest::test_rwlock.ReadUnlock();
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc
index 8ea9e8f2..589fd71 100644
--- a/components/viz/service/display/direct_renderer.cc
+++ b/components/viz/service/display/direct_renderer.cc
@@ -414,6 +414,7 @@
   current_frame()->render_passes_in_draw_order = nullptr;
   current_frame()->root_render_pass = nullptr;
 
+  skipped_render_pass_ids_.clear();
   render_passes_in_draw_order->clear();
   render_pass_filters_.clear();
   render_pass_backdrop_filters_.clear();
@@ -602,8 +603,11 @@
 
 void DirectRenderer::DrawRenderPass(const AggregatedRenderPass* render_pass) {
   TRACE_EVENT0("viz", "DirectRenderer::DrawRenderPass");
-  if (CanSkipRenderPass(render_pass))
+  if (CanSkipRenderPass(render_pass)) {
+    skipped_render_pass_ids_.insert(render_pass->id);
     return;
+  }
+
   UseRenderPass(render_pass);
 
   // TODO(crbug.com/582554): This change applies only when Vulkan is enabled and
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h
index 1df3c4d..d8df093 100644
--- a/components/viz/service/display/direct_renderer.h
+++ b/components/viz/service/display/direct_renderer.h
@@ -346,6 +346,9 @@
   // this frame.
   bool has_pixel_moving_foreground_filters_ = false;
 
+  // Track skipped non-root render passes in DrawRenderPass.
+  base::flat_set<AggregatedRenderPassId> skipped_render_pass_ids_;
+
   bool visible_ = false;
   bool disable_color_checks_for_testing_ = false;
 
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 45e5dcf..7baee9b 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -560,6 +560,17 @@
   }
 }
 
+#if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
+struct SkiaRenderer::RenderPassOverlayParams {
+  AggregatedRenderPassId render_pass_id;
+  RenderPassBacking render_pass_backing;
+  AggregatedRenderPassDrawQuad rpdq;
+  SharedQuadState shared_quad_state;
+  cc::FilterOperations filters;
+  cc::FilterOperations backdrop_filters;
+};
+#endif
+
 enum class SkiaRenderer::BypassMode {
   // The RenderPass's contents' blendmode would have made a transparent black
   // image and the RenderPass's own blend mode does not effect transparent black
@@ -919,8 +930,9 @@
 #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
   // Delete render pass overlay backings from the previous frame that will not
   // be used again.
-  for (auto& backing : available_render_pass_overlay_backings_) {
-    skia_output_surface_->DestroySharedImage(backing.mailbox);
+  for (auto& overlay : available_render_pass_overlay_backings_) {
+    skia_output_surface_->DestroySharedImage(
+        overlay.render_pass_backing.mailbox);
   }
   available_render_pass_overlay_backings_.clear();
 #endif  // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
@@ -995,16 +1007,15 @@
   for (const auto& mailbox : released_overlays) {
     // If this mailbox is for render pass overlay, mark the released render pass
     // overlay backing as available to be re-used.
-    auto backing_iter =
+    auto it =
         std::find_if(in_flight_render_pass_overlay_backings_.begin(),
                      in_flight_render_pass_overlay_backings_.end(),
-                     [&mailbox](const RenderPassBacking& backing) {
-                       return backing.mailbox == mailbox;
+                     [&mailbox](const RenderPassOverlayParams& overlay) {
+                       return overlay.render_pass_backing.mailbox == mailbox;
                      });
-    if (backing_iter != in_flight_render_pass_overlay_backings_.end()) {
-      available_render_pass_overlay_backings_.push_back(
-          std::move(*backing_iter));
-      in_flight_render_pass_overlay_backings_.erase(backing_iter);
+    if (it != in_flight_render_pass_overlay_backings_.end()) {
+      available_render_pass_overlay_backings_.push_back(*it);
+      in_flight_render_pass_overlay_backings_.erase(it);
     }
 
     auto iter = std::find_if(awaiting_release_overlay_locks_.begin(),
@@ -1609,6 +1620,11 @@
   // draw calls into the canvas.
   if (quad->material == DrawQuad::Material::kPictureContent)
     return;
+
+  // DebugBorderDrawQuads draw a path so they must be explicitly clipped.
+  if (quad->material == DrawQuad::Material::kDebugBorder)
+    return;
+
   // Intersection with scissor and a quadrilateral is not necessarily a quad,
   // so don't complicate things
   if (draw_region.has_value())
@@ -2947,7 +2963,9 @@
 
   // A real render pass that was turned into an image
   auto iter = render_pass_backings_.find(quad->render_pass_id);
-  DCHECK(render_pass_backings_.end() != iter);
+  DCHECK(render_pass_backings_.end() != iter)
+      << "Could not find render pass id # " << quad->render_pass_id
+      << " in the render pass overlay backings";
   // This function is called after AllocateRenderPassResourceIfNeeded, so
   // there should be backing ready.
   RenderPassBacking& backing = iter->second;
@@ -3147,42 +3165,139 @@
 }
 
 #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
-SkiaRenderer::RenderPassBacking&
+bool SkiaRenderer::CanSkipRenderPassOverlay(
+    AggregatedRenderPassId render_pass_id,
+    const AggregatedRenderPassDrawQuad* rpdq,
+    RenderPassOverlayParams** output_render_pass_overlay) {
+  // The render pass draw quad can be skipped if (1) the render pass has no
+  // damage and is skipped in DirectRender and (2) the parameters of drawing the
+  // render pass has not changed.
+
+  // Check if the render pass has been re-drawn.
+  if (skipped_render_pass_ids_.count(render_pass_id) == 0)
+    return false;
+
+  // Every time a new render_pass_overlay is allocated, it's added to the back
+  // of the list. In order to get the render_pass_overlay of the previous frame,
+  // loop through the list in a reverse order since there might be multiple
+  // render pass overlays with the same render pass id.
+  RenderPassOverlayParams* overlay_found = nullptr;
+  bool Found_in_available_backings = false;
+  for (auto rit = in_flight_render_pass_overlay_backings_.rbegin();
+       rit != in_flight_render_pass_overlay_backings_.rend(); ++rit) {
+    if (rit->render_pass_id == render_pass_id) {
+      overlay_found = &*rit;
+      break;
+    }
+  }
+
+  // The backing of the previous frame might be complete and moved to
+  // available_render_pass_overlay_backings_ when this frame starts.
+  std::vector<RenderPassOverlayParams>::iterator it_to_delete;
+  if (!overlay_found) {
+    int index = 0;
+    for (auto rit = available_render_pass_overlay_backings_.rbegin();
+         rit != available_render_pass_overlay_backings_.rend();
+         ++rit, ++index) {
+      if (rit->render_pass_id == render_pass_id) {
+        Found_in_available_backings = true;
+        // Cannot use reverse_iterator. Convert it to const_iterator.
+        it_to_delete =
+            available_render_pass_overlay_backings_.begin() +
+            (available_render_pass_overlay_backings_.size() - index - 1);
+        overlay_found = &*rit;
+        break;
+      }
+    }
+  }
+
+  if (!overlay_found) {
+    return false;
+  }
+
+  // Compare RenderPassDrawQuads of the previous frame and the current frame.
+  const cc::FilterOperations* filters = FiltersForPass(render_pass_id);
+  const cc::FilterOperations* backdrop_filters =
+      BackdropFiltersForPass(render_pass_id);
+  overlay_found->rpdq.shared_quad_state = &(overlay_found->shared_quad_state);
+
+  bool no_change_in_rpdq = overlay_found->rpdq.Equals(*rpdq);
+  bool no_change_in_filters =
+      filters ? (overlay_found->filters == *filters)
+              : (overlay_found->filters == cc::FilterOperations());
+  bool no_change_in_backdrop_filters =
+      backdrop_filters
+          ? (overlay_found->backdrop_filters == *backdrop_filters)
+          : (overlay_found->backdrop_filters == cc::FilterOperations());
+
+  if (no_change_in_rpdq && no_change_in_filters &&
+      no_change_in_backdrop_filters) {
+    if (Found_in_available_backings) {
+      in_flight_render_pass_overlay_backings_.push_back(*overlay_found);
+      available_render_pass_overlay_backings_.erase(it_to_delete);
+      *output_render_pass_overlay =
+          &in_flight_render_pass_overlay_backings_.back();
+    } else {
+      *output_render_pass_overlay = overlay_found;
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+SkiaRenderer::RenderPassOverlayParams*
 SkiaRenderer::GetOrCreateRenderPassOverlayBacking(
     AggregatedRenderPassId render_pass_id,
     const AggregatedRenderPassDrawQuad* rpdq,
     ResourceFormat buffer_format,
     gfx::ColorSpace color_space,
     gfx::Size buffer_size) {
+  RenderPassOverlayParams overlay_params;
   auto it = std::find_if(available_render_pass_overlay_backings_.begin(),
                          available_render_pass_overlay_backings_.end(),
-                         [&buffer_format, &buffer_size,
-                          &color_space](const RenderPassBacking& backing) {
+                         [&buffer_format, &buffer_size, &color_space](
+                             const RenderPassOverlayParams& overlay) {
+                           auto& backing = overlay.render_pass_backing;
                            return backing.format == buffer_format &&
                                   backing.size == buffer_size &&
                                   backing.color_space == color_space;
                          });
-
-  gpu::Mailbox mailbox;
   if (it == available_render_pass_overlay_backings_.end()) {
     // Allocate the image for render pass overlay if there is no existing
     // available one.
     constexpr auto kOverlayUsage = gpu::SHARED_IMAGE_USAGE_SCANOUT |
                                    gpu::SHARED_IMAGE_USAGE_DISPLAY |
                                    gpu::SHARED_IMAGE_USAGE_RASTER;
-    mailbox = skia_output_surface_->CreateSharedImage(
+    auto mailbox = skia_output_surface_->CreateSharedImage(
         buffer_format, buffer_size, color_space, kOverlayUsage,
         gpu::kNullSurfaceHandle);
-    in_flight_render_pass_overlay_backings_.push_back(
-        RenderPassBacking{buffer_size, /*generate_mipmap=*/false, color_space,
-                          buffer_format, mailbox, /*is_root=*/false});
+    overlay_params.render_pass_backing = {
+        buffer_size, /*generate_mipmap=*/false, color_space, buffer_format,
+        mailbox,     /*is_root=*/false};
   } else {
-    mailbox = it->mailbox;
-    in_flight_render_pass_overlay_backings_.push_back(std::move(*it));
+    overlay_params = *it;
     available_render_pass_overlay_backings_.erase(it);
   }
 
-  return in_flight_render_pass_overlay_backings_.back();
+  // Add current rpdq to RenderPassOverlayParams.
+  overlay_params.render_pass_id = render_pass_id;
+  overlay_params.shared_quad_state.SetAll(*rpdq->shared_quad_state);
+  overlay_params.rpdq.SetAll(*rpdq);
+
+  if (const cc::FilterOperations* filters = FiltersForPass(render_pass_id);
+      filters) {
+    overlay_params.filters = *filters;
+  }
+  if (const cc::FilterOperations* backdrop_filters =
+          BackdropFiltersForPass(render_pass_id);
+      backdrop_filters) {
+    overlay_params.backdrop_filters = *backdrop_filters;
+  }
+
+  in_flight_render_pass_overlay_backings_.push_back(overlay_params);
+
+  return &in_flight_render_pass_overlay_backings_.back();
 }
 
 void SkiaRenderer::PrepareRenderPassOverlay(
@@ -3327,12 +3442,22 @@
       cc::MathUtil::CheckedRoundUp(filter_bounds.width(), kBufferMultiple),
       cc::MathUtil::CheckedRoundUp(filter_bounds.height(), kBufferMultiple));
 
-  const RenderPassBacking& dst_overlay_backing =
-      GetOrCreateRenderPassOverlayBacking(
-          quad->render_pass_id, quad, buffer_format, color_space, buffer_size);
+  RenderPassOverlayParams* overlay_params = nullptr;
+  bool can_skip_render_pass =
+      CanSkipRenderPassOverlay(quad->render_pass_id, quad, &overlay_params);
+  if (!can_skip_render_pass) {
+    overlay_params = GetOrCreateRenderPassOverlayBacking(
+        quad->render_pass_id, quad, buffer_format, color_space, buffer_size);
+  }
+  DCHECK(overlay_params);
 
+  const RenderPassBacking& dst_overlay_backing =
+      overlay_params->render_pass_backing;
   overlay->mailbox = dst_overlay_backing.mailbox;
 
+  // Still call BeginPaintRenderPass/EndPaint when skipping the render pass, so
+  // we get the notification (DidReceiveReleasedOverlays) for releaseing the
+  // mailbox of the skipped rendering.
   current_canvas_ = skia_output_surface_->BeginPaintRenderPass(
       quad->render_pass_id, dst_overlay_backing.size,
       dst_overlay_backing.format, /*mipmap=*/false,
@@ -3344,55 +3469,60 @@
     return;
   }
 
-  // Clear the backing to ARGB(0,0,0,0).
-  current_canvas_->clear(SkColorSetARGB(0, 0, 0, 0));
+  if (!can_skip_render_pass) {
+    // Clear the backing to ARGB(0,0,0,0).
+    current_canvas_->clear(SkColorSetARGB(0, 0, 0, 0));
 
-  // Adjust the |content_device_transform| to make sure filter extends are drawn
-  // inside of the buffer.
-  params.content_device_transform.Translate(-filter_bounds.x(),
-                                            -filter_bounds.y());
+    // Adjust the |content_device_transform| to make sure filter extends are
+    // drawn inside of the buffer.
+    params.content_device_transform.Translate(-filter_bounds.x(),
+                                              -filter_bounds.y());
 
-  // Also adjust the |rounded_corner_bounds| to the new location.
-  if (params.mask_filter_info) {
-    params.mask_filter_info->Transform(params.content_device_transform);
-  }
+    // Also adjust the |rounded_corner_bounds| to the new location.
+    if (params.mask_filter_info) {
+      params.mask_filter_info->Transform(params.content_device_transform);
+    }
 
-  // When Render Pass has a single quad inside we would draw that directly.
-  if (bypass != render_pass_bypass_quads_.end()) {
-    if (bypass_mode == BypassMode::kDrawTransparentQuad) {
-      DrawColoredQuad(SkColors::kTransparent, &rpdq_params, &params);
-    } else if (bypass_mode == BypassMode::kDrawBypassQuad) {
-      DrawQuadInternal(bypass->second, &rpdq_params, &params);
+    // When Render Pass has a single quad inside we would draw that directly.
+    if (bypass != render_pass_bypass_quads_.end()) {
+      if (bypass_mode == BypassMode::kDrawTransparentQuad) {
+        DrawColoredQuad(SkColors::kTransparent, &rpdq_params, &params);
+      } else if (bypass_mode == BypassMode::kDrawBypassQuad) {
+        DrawQuadInternal(bypass->second, &rpdq_params, &params);
+      } else {
+        NOTREACHED();
+      }
     } else {
-      NOTREACHED();
-    }
-  } else {
-    DCHECK(src_quad_backing);
-    auto content_image = skia_output_surface_->MakePromiseSkImageFromRenderPass(
-        quad->render_pass_id, src_quad_backing->size, src_quad_backing->format,
-        src_quad_backing->generate_mipmap,
-        RenderPassBackingSkColorSpace(*src_quad_backing),
-        src_quad_backing->mailbox);
-    if (!content_image) {
-      DLOG(ERROR) << "MakePromiseSkImageFromRenderPass() in "
-                     "PrepareRenderPassOverlay() failed.";
-      EndPaint(/*failed=*/true);
-      return;
-    }
+      DCHECK(src_quad_backing);
+      auto content_image =
+          skia_output_surface_->MakePromiseSkImageFromRenderPass(
+              quad->render_pass_id, src_quad_backing->size,
+              src_quad_backing->format, src_quad_backing->generate_mipmap,
+              RenderPassBackingSkColorSpace(*src_quad_backing),
+              src_quad_backing->mailbox);
+      if (!content_image) {
+        DLOG(ERROR) << "MakePromiseSkImageFromRenderPass() in "
+                       "PrepareRenderPassOverlay() failed.";
+        EndPaint(/*failed=*/true);
+        return;
+      }
 
-    if (src_quad_backing->generate_mipmap) {
-      params.sampling =
-          SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
+      if (src_quad_backing->generate_mipmap) {
+        params.sampling =
+            SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
+      }
+
+      params.vis_tex_coords = cc::MathUtil::ScaleRectProportional(
+          quad->tex_coord_rect, gfx::RectF(quad->rect), params.visible_rect);
+
+      gfx::RectF valid_texel_bounds(content_image->width(),
+                                    content_image->height());
+
+      SkPaint paint = params.paint(GetContentColorFilter());
+
+      DrawSingleImage(content_image.get(), valid_texel_bounds, &rpdq_params,
+                      &paint, &params);
     }
-
-    params.vis_tex_coords = cc::MathUtil::ScaleRectProportional(
-        quad->tex_coord_rect, gfx::RectF(quad->rect), params.visible_rect);
-    gfx::RectF valid_texel_bounds(content_image->width(),
-                                  content_image->height());
-
-    SkPaint paint = params.paint(GetContentColorFilter());
-    DrawSingleImage(content_image.get(), valid_texel_bounds, &rpdq_params,
-                    &paint, &params);
   }
   current_canvas_ = nullptr;
 
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index 5fbb87b..0d5a08e 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -115,6 +115,7 @@
   enum class BypassMode;
   struct DrawQuadParams;
   struct DrawRPDQParams;
+  struct RenderPassOverlayParams;
   class ScopedSkImageBuilder;
   class ScopedYUVSkImageBuilder;
 
@@ -276,7 +277,12 @@
   };
 
 #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
-  RenderPassBacking& GetOrCreateRenderPassOverlayBacking(
+  bool CanSkipRenderPassOverlay(
+      AggregatedRenderPassId render_pass_id,
+      const AggregatedRenderPassDrawQuad* rpdq,
+      RenderPassOverlayParams** output_render_pass_overlay);
+
+  RenderPassOverlayParams* GetOrCreateRenderPassOverlayBacking(
       AggregatedRenderPassId render_pass_id,
       const AggregatedRenderPassDrawQuad* rpdq,
       ResourceFormat buffer_format,
@@ -429,10 +435,11 @@
   base::flat_set<OverlayLock, OverlayLockComparator>
       awaiting_release_overlay_locks_;
 
-  // Tracks render pass overlay backings that are currently in use and available
-  // for re-using via mailboxes. RenderPassBacking.generate_mipmap is not used.
-  std::vector<RenderPassBacking> in_flight_render_pass_overlay_backings_;
-  std::vector<RenderPassBacking> available_render_pass_overlay_backings_;
+  // Tracks RenderPassDrawQuad and render pass overlay backings that are
+  // currently in use and available for re-using via mailboxes.
+  // RenderPassBacking.generate_mipmap is not used.
+  std::vector<RenderPassOverlayParams> in_flight_render_pass_overlay_backings_;
+  std::vector<RenderPassOverlayParams> available_render_pass_overlay_backings_;
 #endif  // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
 
   gfx::ColorConversionSkFilterCache color_filter_cache_;
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc
index 26ced15..ad48aac 100644
--- a/components/viz/service/display/surface_aggregator.cc
+++ b/components/viz/service/display/surface_aggregator.cc
@@ -1707,11 +1707,11 @@
       // same frame as last aggregation and there is no damage OR there is
       // already full damage for the surface.
       if (resolved_frame.IsNextFrameSinceLastAggregation()) {
-        auto& damage_rect = GetOptionalDamageRectFromQuad(quad);
-        DCHECK(damage_rect.has_value());
-        // The DrawQuad `damage_rect` is already in the render pass coordinate
-        // space instead of quad rect coordinate space.
-        quad_target_space_damage_rect = damage_rect.value();
+        auto& per_quad_damage_rect = GetOptionalDamageRectFromQuad(quad);
+        DCHECK(per_quad_damage_rect.has_value());
+        // The DrawQuad `per_quad_damage_rect` is already in the render pass
+        // coordinate space instead of quad rect coordinate space.
+        quad_target_space_damage_rect = per_quad_damage_rect.value();
       }
     }
 
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 3c44c3bd..410779d4 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -6607,13 +6607,13 @@
   // Both CompositorRenderPass are built with
   // has_damage_from_contributing_content set to true.
   {
-    CompositorFrame root_frame = MakeEmptyCompositorFrame();
+    CompositorFrame root_frame_2 = MakeEmptyCompositorFrame();
     root_passes[0].has_damage_from_contributing_content = true;
-    AddPasses(&root_frame.render_pass_list, root_passes,
-              &root_frame.metadata.referenced_surfaces);
+    AddPasses(&root_frame_2.render_pass_list, root_passes,
+              &root_frame_2.metadata.referenced_surfaces);
 
     root_sink_->SubmitCompositorFrame(root_surface_id_.local_surface_id(),
-                                      std::move(root_frame));
+                                      std::move(root_frame_2));
 
     CompositorFrame child_frame = MakeEmptyCompositorFrame();
     child_passes[0].has_damage_from_contributing_content = true;
diff --git a/components/viz/service/display_embedder/compositor_gpu_thread.cc b/components/viz/service/display_embedder/compositor_gpu_thread.cc
index 68b9aff..5c6e89c 100644
--- a/components/viz/service/display_embedder/compositor_gpu_thread.cc
+++ b/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -68,8 +68,7 @@
         device_queue->GetVulkanPhysicalDevice(),
         device_queue->GetVulkanDevice(), device_queue->GetVulkanQueue(),
         device_queue->GetVulkanQueueIndex(), device_queue->enabled_extensions(),
-        device_queue->enabled_device_features_2(),
-        device_queue->vma_allocator());
+        device_queue->enabled_device_features_2());
     vulkan_context_provider =
         VulkanInProcessContextProvider::CreateForCompositorGpuThread(
             vulkan_implementation, std::move(compositor_thread_device_queue),
@@ -227,7 +226,6 @@
   // Context should be current for cache/memory cleanup.
   if (shared_context_state_ &&
       shared_context_state_->MakeCurrent(nullptr, /*needs_gl=*/true)) {
-    LOG(ERROR) << "vikas: purging drdc context";
     shared_context_state_->PurgeMemory(memory_pressure_level);
   }
 }
diff --git a/components/viz/service/hit_test/hit_test_manager_fuzzer.cc b/components/viz/service/hit_test/hit_test_manager_fuzzer.cc
index e6147e6..72cac93 100644
--- a/components/viz/service/hit_test/hit_test_manager_fuzzer.cc
+++ b/components/viz/service/hit_test/hit_test_manager_fuzzer.cc
@@ -168,12 +168,12 @@
 
   viz::SurfaceId aggregate_surface_id = surface_id;
   if (fuzz.ConsumeBool() && fuzz.remaining_bytes() >= sizeof(viz::SurfaceId)) {
-    viz::FrameSinkId frame_sink_id(GetNextUInt32NonZero(&fuzz),
-                                   GetNextUInt32NonZero(&fuzz));
-    viz::LocalSurfaceId local_surface_id(GetNextUInt32NonZero(&fuzz),
-                                         GetNextUInt32NonZero(&fuzz),
-                                         base::UnguessableToken::Create());
-    aggregate_surface_id = viz::SurfaceId(frame_sink_id, local_surface_id);
+    aggregate_surface_id =
+        viz::SurfaceId(viz::FrameSinkId(GetNextUInt32NonZero(&fuzz),
+                                        GetNextUInt32NonZero(&fuzz)),
+                       viz::LocalSurfaceId(GetNextUInt32NonZero(&fuzz),
+                                           GetNextUInt32NonZero(&fuzz),
+                                           base::UnguessableToken::Create()));
   }
   aggregator.Aggregate(aggregate_surface_id);
   viz::Surface* surface = frame_sink_manager.surface_manager()->GetSurfaceForId(
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_id.cc b/components/web_package/signed_web_bundles/signed_web_bundle_id.cc
index 73359ca..59f7c0b 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_id.cc
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_id.cc
@@ -14,18 +14,7 @@
 
 namespace web_package {
 
-namespace {
-
-constexpr uint8_t kTypeSuffixLength = 3;
-
-constexpr uint8_t kTypeDevelopment[] = {0x00, 0x00, 0x02};
-constexpr uint8_t kTypeEd25519PublicKey[] = {0x00, 0x01, 0x02};
-
-static_assert(std::size(kTypeDevelopment) == kTypeSuffixLength);
-static_assert(std::size(kTypeEd25519PublicKey) == kTypeSuffixLength);
-
-}  // namespace
-
+// static
 base::expected<SignedWebBundleId, std::string> SignedWebBundleId::Create(
     base::StringPiece encoded_id) {
   if (encoded_id.size() != kEncodedIdLength) {
@@ -66,6 +55,35 @@
   return base::unexpected("The signed web bundle ID has an unknown type.");
 }
 
+// static
+SignedWebBundleId SignedWebBundleId::CreateForEd25519PublicKey(
+    Ed25519PublicKey public_key) {
+  std::array<uint8_t, kDecodedIdLength> decoded_id;
+  base::ranges::copy(public_key.bytes(), decoded_id.begin());
+  base::ranges::copy(kTypeEd25519PublicKey,
+                     decoded_id.end() - kTypeSuffixLength);
+
+  auto encoded_id_uppercase =
+      base32::Base32Encode(std::string(decoded_id.begin(), decoded_id.end()),
+                           base32::Base32EncodePolicy::OMIT_PADDING);
+  auto encoded_id = base::ToLowerASCII(encoded_id_uppercase);
+  return SignedWebBundleId(Type::kEd25519PublicKey, encoded_id, decoded_id);
+}
+
+// static
+SignedWebBundleId SignedWebBundleId::CreateForDevelopment(
+    base::span<const uint8_t, kDecodedIdLength - kTypeSuffixLength> data) {
+  std::array<uint8_t, kDecodedIdLength> decoded_id;
+  base::ranges::copy(data, decoded_id.begin());
+  base::ranges::copy(kTypeDevelopment, decoded_id.end() - kTypeSuffixLength);
+
+  auto encoded_id_uppercase =
+      base32::Base32Encode(std::string(decoded_id.begin(), decoded_id.end()),
+                           base32::Base32EncodePolicy::OMIT_PADDING);
+  auto encoded_id = base::ToLowerASCII(encoded_id_uppercase);
+  return SignedWebBundleId(Type::kDevelopment, encoded_id, decoded_id);
+}
+
 SignedWebBundleId::SignedWebBundleId(
     Type type,
     base::StringPiece encoded_id,
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_id.h b/components/web_package/signed_web_bundles/signed_web_bundle_id.h
index 99e8e428..04a4744 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_id.h
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_id.h
@@ -20,6 +20,19 @@
 // function, which will validate the format of the given ID. This means that you
 // can assume that every instance of this class wraps a correctly formatted ID.
 class SignedWebBundleId {
+ private:
+  static constexpr size_t kEncodedIdLength = 56;
+  static constexpr size_t kDecodedIdLength = 35;
+  static constexpr uint8_t kTypeSuffixLength = 3;
+
+  static constexpr uint8_t kTypeDevelopment[] = {0x00, 0x00, 0x02};
+  static constexpr uint8_t kTypeEd25519PublicKey[] = {0x00, 0x01, 0x02};
+
+  static_assert(std::size(kTypeDevelopment) ==
+                SignedWebBundleId::kTypeSuffixLength);
+  static_assert(std::size(kTypeEd25519PublicKey) ==
+                SignedWebBundleId::kTypeSuffixLength);
+
  public:
   enum class Type {
     // This is intended for use during development, where a web bundle might not
@@ -34,6 +47,12 @@
   static base::expected<SignedWebBundleId, std::string> Create(
       base::StringPiece base32_encoded_id);
 
+  static SignedWebBundleId CreateForEd25519PublicKey(
+      Ed25519PublicKey public_key);
+
+  static SignedWebBundleId CreateForDevelopment(
+      base::span<const uint8_t, kDecodedIdLength - kTypeSuffixLength> data);
+
   SignedWebBundleId(const SignedWebBundleId& other);
 
   ~SignedWebBundleId();
@@ -55,9 +74,6 @@
   }
 
  private:
-  static constexpr size_t kEncodedIdLength = 56;
-  static constexpr size_t kDecodedIdLength = 35;
-
   SignedWebBundleId(Type type,
                     base::StringPiece encoded_id,
                     std::array<uint8_t, kDecodedIdLength> decoded_id);
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_id_unittest.cc b/components/web_package/signed_web_bundles/signed_web_bundle_id_unittest.cc
index fb9162f..af50964 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_id_unittest.cc
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_id_unittest.cc
@@ -8,12 +8,36 @@
 #include <tuple>
 #include <utility>
 
+#include "base/containers/span.h"
 #include "base/strings/string_piece.h"
+#include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_package {
 
+namespace {
+
+// Some random bytes that are treated as an Ed25519 public key.
+const std::array<uint8_t, 32> kEd25519PublicKeyBytes(
+    {0x01, 0x23, 0x43, 0x43, 0x33, 0x42, 0x7A, 0x14, 0x42, 0x14, 0xa2,
+     0xb6, 0xc2, 0xd9, 0xf2, 0x02, 0x03, 0x42, 0x18, 0x10, 0x12, 0x26,
+     0x62, 0x88, 0xf6, 0xa3, 0xa5, 0x47, 0x14, 0x69, 0x00, 0x73});
+
+constexpr char kEd25519SignedWebBundleId[] =
+    "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic";
+
+// Some random bytes to use as a development-only key.
+const std::array<uint8_t, 32> kDevelopmentBytes(
+    {0x02, 0x23, 0x43, 0x43, 0x33, 0x42, 0x7a, 0x14, 0x42, 0x14, 0xa2,
+     0xb6, 0xc2, 0xd9, 0xf2, 0x02, 0x03, 0x42, 0x18, 0x10, 0x12, 0x26,
+     0x62, 0x88, 0xf6, 0xa3, 0xa5, 0x47, 0x14, 0x69, 0x00, 0x73});
+
+constexpr char kDevelopmentSignedWebBundleId[] =
+    "airugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac";
+
+}  // namespace
+
 class SignedWebBundleIdValidTest
     : public ::testing::TestWithParam<
           std::tuple<std::string,
@@ -31,7 +55,7 @@
   absl::optional<std::array<uint8_t, 32>> public_key_;
 };
 
-TEST_P(SignedWebBundleIdValidTest, ValidIDs) {
+TEST_P(SignedWebBundleIdValidTest, ParseValidIDs) {
   const auto parsed_id = SignedWebBundleId::Create(raw_id_);
   EXPECT_TRUE(parsed_id.has_value());
   EXPECT_EQ(parsed_id->type(), type_);
@@ -45,26 +69,20 @@
     SignedWebBundleIdValidTest,
     ::testing::Values(
         // Development-only key suffix
-        std::make_tuple(
-            "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaac",
-            SignedWebBundleId::Type::kDevelopment,
-            absl::nullopt),
+        std::make_tuple(kDevelopmentSignedWebBundleId,
+                        SignedWebBundleId::Type::kDevelopment,
+                        absl::nullopt),
         // Ed25519 key suffix
-        std::make_tuple(
-            "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic",
-            SignedWebBundleId::Type::kEd25519PublicKey,
-            std::array<uint8_t, 32>({0x01, 0x23, 0x43, 0x43, 0x33, 0x42, 0x7A,
-                                     0x14, 0x42, 0x14, 0xa2, 0xb6, 0xc2, 0xd9,
-                                     0xf2, 0x02, 0x03, 0x42, 0x18, 0x10, 0x12,
-                                     0x26, 0x62, 0x88, 0xf6, 0xa3, 0xa5, 0x47,
-                                     0x14, 0x69, 0x00, 0x73}))),
+        std::make_tuple(kEd25519SignedWebBundleId,
+                        SignedWebBundleId::Type::kEd25519PublicKey,
+                        kEd25519PublicKeyBytes)),
     [](const testing::TestParamInfo<SignedWebBundleIdValidTest::ParamType>&
            info) { return std::get<0>(info.param); });
 
 class SignedWebBundleIdInvalidTest
     : public ::testing::TestWithParam<std::pair<std::string, std::string>> {};
 
-TEST_P(SignedWebBundleIdInvalidTest, InvalidIDs) {
+TEST_P(SignedWebBundleIdInvalidTest, ParseInvalidIDs) {
   EXPECT_FALSE(SignedWebBundleId::Create(GetParam().second).has_value());
 }
 
@@ -106,4 +124,21 @@
   EXPECT_FALSE(b < a2);
 }
 
+TEST(SignedWebBundleIdTest, CreateForEd25519PublicKey) {
+  auto public_key =
+      Ed25519PublicKey::Create(base::make_span(kEd25519PublicKeyBytes));
+
+  auto id = SignedWebBundleId::CreateForEd25519PublicKey(public_key);
+  EXPECT_EQ(id.type(), SignedWebBundleId::Type::kEd25519PublicKey);
+  EXPECT_EQ(id.GetEd25519PublicKey().bytes(), public_key.bytes());
+  EXPECT_EQ(id.id(), kEd25519SignedWebBundleId);
+}
+
+TEST(SignedWebBundleIdTest, CreateForDevelopment) {
+  auto id = SignedWebBundleId::CreateForDevelopment(
+      base::make_span(kDevelopmentBytes));
+  EXPECT_EQ(id.type(), SignedWebBundleId::Type::kDevelopment);
+  EXPECT_EQ(id.id(), kDevelopmentSignedWebBundleId);
+}
+
 }  // namespace web_package
diff --git a/components/web_package/web_bundle_url_loader_factory.cc b/components/web_package/web_bundle_url_loader_factory.cc
index 92c86d5..c6ada21 100644
--- a/components/web_package/web_bundle_url_loader_factory.cc
+++ b/components/web_package/web_bundle_url_loader_factory.cc
@@ -103,8 +103,10 @@
     wrapped_->OnReceiveEarlyHints(std::move(early_hints));
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     std::string error_message;
     if (!CheckWebBundleServingConstraints(*response_head, error_message)) {
       if (factory_) {
@@ -123,7 +125,8 @@
     mojo::ScopedDataPipeConsumerHandle consumer;
     if (body)
       consumer = HandleReceiveBody(std::move(body));
-    wrapped_->OnReceiveResponse(std::move(response_head), std::move(consumer));
+    wrapped_->OnReceiveResponse(std::move(response_head), std::move(consumer),
+                                std::move(cached_metadata));
   }
 
   void OnReceiveRedirect(
@@ -150,10 +153,6 @@
                                std::move(ack_callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    wrapped_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     wrapped_->OnTransferSizeUpdated(transfer_size_diff);
   }
@@ -231,7 +230,8 @@
 
   void OnResponse(network::mojom::URLResponseHeadPtr response,
                   mojo::ScopedDataPipeConsumerHandle consumer) {
-    client_->OnReceiveResponse(std::move(response), std::move(consumer));
+    client_->OnReceiveResponse(std::move(response), std::move(consumer),
+                               absl::nullopt);
   }
 
   void OnFail(net::Error error) {
@@ -268,7 +268,8 @@
       return;
     }
     producer.reset();
-    client_->OnReceiveResponse(std::move(response_head), std::move(consumer));
+    client_->OnReceiveResponse(std::move(response_head), std::move(consumer),
+                               absl::nullopt);
 
     // CORB responses are reported as a success.
     CompleteBlockedResponse(net::OK, absl::nullopt);
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index fb4af33..ed2baca 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -153,7 +153,7 @@
 
 #if BUILDFLAG(ENABLE_PPAPI)
 #include "content/common/pepper_plugin_list.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #endif
 
 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -367,7 +367,7 @@
 // call PPP_InitializeModule). This is needed by the zygote on Linux to get
 // access to the plugins before entering the sandbox.
 void PreloadPepperPlugins() {
-  std::vector<PepperPluginInfo> plugins;
+  std::vector<ContentPluginInfo> plugins;
   ComputePepperPluginList(&plugins);
   for (const auto& plugin : plugins) {
     if (!plugin.is_internal) {
diff --git a/content/browser/about_url_loader_factory.cc b/content/browser/about_url_loader_factory.cc
index 27dd584..717e8576 100644
--- a/content/browser/about_url_loader_factory.cc
+++ b/content/browser/about_url_loader_factory.cc
@@ -39,7 +39,7 @@
   }
 
   client_remote->OnReceiveResponse(std::move(response_head),
-                                   std::move(consumer));
+                                   std::move(consumer), absl::nullopt);
   client_remote->OnComplete(network::URLLoaderCompletionStatus(net::OK));
 }
 
diff --git a/content/browser/aggregation_service/aggregatable_report_scheduler.cc b/content/browser/aggregation_service/aggregatable_report_scheduler.cc
index 9aa433b3..76ef332c 100644
--- a/content/browser/aggregation_service/aggregatable_report_scheduler.cc
+++ b/content/browser/aggregation_service/aggregatable_report_scheduler.cc
@@ -19,6 +19,7 @@
 #include "base/threading/sequence_bound.h"
 #include "base/time/time.h"
 #include "content/browser/aggregation_service/aggregatable_report.h"
+#include "content/browser/aggregation_service/aggregation_service.h"
 #include "content/browser/aggregation_service/aggregation_service_storage.h"
 #include "content/browser/aggregation_service/aggregation_service_storage_context.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc b/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc
index f1bd3f9..b6eea08 100644
--- a/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc
+++ b/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
 #include "content/browser/aggregation_service/aggregatable_report.h"
+#include "content/browser/aggregation_service/aggregation_service.h"
 #include "content/browser/aggregation_service/aggregation_service_storage.h"
 #include "content/browser/aggregation_service/aggregation_service_test_utils.h"
 #include "services/network/public/mojom/network_change_manager.mojom.h"
@@ -31,6 +32,7 @@
 
 using testing::_;
 using testing::Invoke;
+using testing::Property;
 
 // Will be used to verify the sequence of expected function calls.
 using Checkpoint = ::testing::MockFunction<void(int)>;
@@ -491,4 +493,30 @@
   task_environment_.FastForwardBy(base::TimeDelta());
 }
 
+TEST_F(AggregatableReportSchedulerTest,
+       StorageLimitReached_ReportSilentlyDropped) {
+  // Attempt to schedule one too many reports.
+  for (int i = 0;
+       i < AggregationService::kMaxStoredReportsPerReportingOrigin + 1; ++i) {
+    AggregatableReportRequest example_request =
+        aggregation_service::CreateExampleRequest();
+
+    AggregatableReportSharedInfo expected_shared_info =
+        example_request.shared_info().Clone();
+    expected_shared_info.scheduled_report_time = kExampleTime;
+
+    scheduler_.ScheduleRequest(
+        AggregatableReportRequest::Create(example_request.payload_contents(),
+                                          std::move(expected_shared_info))
+            .value());
+  }
+
+  // One report has been silently dropped.
+  EXPECT_CALL(
+      mock_callback_,
+      Run(Property(&std::vector<AggregationServiceStorage::RequestAndId>::size,
+                   AggregationService::kMaxStoredReportsPerReportingOrigin)));
+  task_environment_.FastForwardBy(kExampleTime - base::Time::Now());
+}
+
 }  // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service.h b/content/browser/aggregation_service/aggregation_service.h
index 02cde2f5..84d46b1a 100644
--- a/content/browser/aggregation_service/aggregation_service.h
+++ b/content/browser/aggregation_service/aggregation_service.h
@@ -36,6 +36,11 @@
   using SendStatus = AggregatableReportSender::RequestStatus;
   using SendCallback = AggregatableReportSender::ReportSentCallback;
 
+  // No more report requests can be scheduled and not yet sent than this. Any
+  // additional requests will silently be dropped until there is more capacity.
+  // This ensures malicious actors cannot use unbounded memory or disk space.
+  static constexpr int kMaxStoredReportsPerReportingOrigin = 1000;
+
   virtual ~AggregationService() = default;
 
   // Gets the AggregationService that should be used for handling aggregations
diff --git a/content/browser/aggregation_service/aggregation_service_storage.h b/content/browser/aggregation_service/aggregation_service_storage.h
index f91c569c..9f9572d 100644
--- a/content/browser/aggregation_service/aggregation_service_storage.h
+++ b/content/browser/aggregation_service/aggregation_service_storage.h
@@ -57,8 +57,8 @@
 
   // == Aggregatable report request methods =====
 
-  // Persists the `request` with a report time of `*report_time_override`. If
-  // the optional has no value, the `request`'s scheduled report time is used.
+  // Persists the `request` (unless it would exceed a limit on the number of
+  // stored reports).
   virtual void StoreRequest(AggregatableReportRequest request) = 0;
 
   // Deletes the report request with the given `request_id`, if any.
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql.cc b/content/browser/aggregation_service/aggregation_service_storage_sql.cc
index 7b2953c..8a722d0 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql.cc
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql.cc
@@ -19,6 +19,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/sequence_checker.h"
+#include "base/strings/string_piece.h"
 #include "base/time/clock.h"
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
@@ -41,25 +42,26 @@
 
 namespace content {
 
-namespace {
-
-constexpr base::FilePath::CharType kDatabasePath[] =
-    FILE_PATH_LITERAL("AggregationService");
-
 // Version number of the database.
 //
 // Version 1 - https://crrev.com/c/3038364
 //             https://crrev.com/c/3462368
 // Version 2 - https://crrev.com/c/3733377 (adding report_requests table)
-constexpr int kCurrentVersionNumber = 2;
+// Version 3 - https://crrev.com/c/3842459 (adding reporting_origin index)
+constexpr int AggregationServiceStorageSql::kCurrentVersionNumber = 3;
 
 // Earliest version which can use a `kCurrentVersionNumber` database
 // without failing.
-constexpr int kCompatibleVersionNumber = 2;
+constexpr int AggregationServiceStorageSql::kCompatibleVersionNumber = 3;
 
 // Latest version of the database that cannot be upgraded to
 // `kCurrentVersionNumber` without razing the database.
-constexpr int kDeprecatedVersionNumber = 0;
+constexpr int AggregationServiceStorageSql::kDeprecatedVersionNumber = 0;
+
+namespace {
+
+constexpr base::FilePath::CharType kDatabasePath[] =
+    FILE_PATH_LITERAL("AggregationService");
 
 // All columns in this table except `report_time` are designed to be "const".
 // `request_id` uses AUTOINCREMENT to ensure that IDs aren't reused over the
@@ -91,28 +93,43 @@
     "CREATE INDEX IF NOT EXISTS creation_time_idx ON "
     "report_requests(creation_time)";
 
+// Used to optimize checking whether there is capacity for the reporting origin.
+static constexpr char kReportingOriginIndexSql[] =
+    "CREATE INDEX IF NOT EXISTS reporting_origin_idx ON "
+    "report_requests(reporting_origin)";
+
 bool UpgradeAggregationServiceStorageSqlSchema(sql::Database& db,
                                                sql::MetaTable& meta_table) {
-  if (meta_table.GetVersionNumber() != 1)
-    return false;  // Only one migration is supported.
-
-  // == Migrate from version 1 to 2 ==
-  // Simply create the new empty table.
+  if (meta_table.GetVersionNumber() != 1 && meta_table.GetVersionNumber() != 2)
+    return false;  // Migration is not supported.
 
   sql::Transaction transaction(&db);
+
   if (!transaction.Begin())
     return false;
 
-  if (!db.Execute(kReportRequestsCreateTableSql))
+  if (meta_table.GetVersionNumber() == 1) {
+    // == Migrate from version 1 to 2 ==
+    // Create the new empty table.
+
+    if (!db.Execute(kReportRequestsCreateTableSql))
+      return false;
+
+    if (!db.Execute(kReportTimeIndexSql))
+      return false;
+
+    if (!db.Execute(kCreationTimeIndexSql))
+      return false;
+  }
+
+  // == Migrate from version 2 to 3 ==
+  // Add the new index.
+  if (!db.Execute(kReportingOriginIndexSql))
     return false;
 
-  if (!db.Execute(kReportTimeIndexSql))
-    return false;
+  meta_table.SetVersionNumber(
+      AggregationServiceStorageSql::kCurrentVersionNumber);
 
-  if (!db.Execute(kCreationTimeIndexSql))
-    return false;
-
-  meta_table.SetVersionNumber(kCurrentVersionNumber);
   return transaction.Commit();
 }
 
@@ -127,12 +144,15 @@
 AggregationServiceStorageSql::AggregationServiceStorageSql(
     bool run_in_memory,
     const base::FilePath& path_to_database,
-    const base::Clock* clock)
+    const base::Clock* clock,
+    int max_stored_requests_per_reporting_origin)
     : run_in_memory_(run_in_memory),
       path_to_database_(run_in_memory_
                             ? base::FilePath()
                             : path_to_database.Append(kDatabasePath)),
       clock_(*clock),
+      max_stored_requests_per_reporting_origin_(
+          max_stored_requests_per_reporting_origin),
       db_(sql::DatabaseOptions{.exclusive_locking = true,
                                .page_size = 4096,
                                .cache_size = 32}) {
@@ -405,14 +425,46 @@
   transaction.Commit();
 }
 
+bool AggregationServiceStorageSql::ReportingOriginHasCapacity(
+    base::StringPiece serialized_reporting_origin) {
+  static constexpr char kCountRequestSql[] =
+      "SELECT COUNT(*)FROM report_requests WHERE reporting_origin = ?";
+  sql::Statement count_request_statement(
+      db_.GetCachedStatement(SQL_FROM_HERE, kCountRequestSql));
+  count_request_statement.BindString(0, serialized_reporting_origin);
+
+  if (!count_request_statement.Step())
+    return false;
+
+  int64_t count = count_request_statement.ColumnInt64(0);
+  return count < max_stored_requests_per_reporting_origin_;
+}
+
 void AggregationServiceStorageSql::StoreRequest(
     AggregatableReportRequest request) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Force the creation of the database if it doesn't exist, as we need to
-  // persist the public keys.
+  // persist the request.
   if (!EnsureDatabaseOpen(DbCreationPolicy::kCreateIfAbsent))
     return;
 
+  sql::Transaction transaction(&db_);
+  if (!transaction.Begin())
+    return;
+
+  const AggregatableReportSharedInfo& shared_info = request.shared_info();
+  std::string serialized_reporting_origin =
+      shared_info.reporting_origin.Serialize();
+
+  bool reporting_origin_has_capacity =
+      ReportingOriginHasCapacity(serialized_reporting_origin);
+  base::UmaHistogramBoolean(
+      "PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity",
+      reporting_origin_has_capacity);
+
+  if (!reporting_origin_has_capacity)
+    return;
+
   static constexpr char kStoreRequestSql[] =
       "INSERT INTO report_requests("
       "report_time,creation_time,reporting_origin,request_proto) "
@@ -421,12 +473,9 @@
   sql::Statement store_request_statement(
       db_.GetCachedStatement(SQL_FROM_HERE, kStoreRequestSql));
 
-  const AggregatableReportSharedInfo& shared_info = request.shared_info();
-
   store_request_statement.BindTime(0, shared_info.scheduled_report_time);
   store_request_statement.BindTime(1, clock_.Now());
-  store_request_statement.BindString(2,
-                                     shared_info.reporting_origin.Serialize());
+  store_request_statement.BindString(2, serialized_reporting_origin);
 
   std::vector<uint8_t> serialized_request = request.Serialize();
 
@@ -435,7 +484,10 @@
   DCHECK(!serialized_request.empty());
   store_request_statement.BindBlob(3, serialized_request);
 
-  store_request_statement.Run();
+  if (!store_request_statement.Run())
+    return;
+
+  transaction.Commit();
 }
 
 void AggregationServiceStorageSql::DeleteRequest(
@@ -831,6 +883,9 @@
   if (!db_.Execute(kCreationTimeIndexSql))
     return false;
 
+  if (!db_.Execute(kReportingOriginIndexSql))
+    return false;
+
   if (!meta_table_.Init(&db_, kCurrentVersionNumber,
                         kCompatibleVersionNumber)) {
     return false;
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql.h b/content/browser/aggregation_service/aggregation_service_storage_sql.h
index 6edf2ec..0cb7d78 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql.h
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql.h
@@ -11,8 +11,10 @@
 
 #include "base/files/file_path.h"
 #include "base/sequence_checker.h"
+#include "base/strings/string_piece_forward.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service.h"
 #include "content/browser/aggregation_service/aggregation_service_storage.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/storage_partition.h"
@@ -44,10 +46,18 @@
 class CONTENT_EXPORT AggregationServiceStorageSql
     : public AggregationServiceStorage {
  public:
+  // Exposed for testing.
+  static const int kCurrentVersionNumber;
+  static const int kCompatibleVersionNumber;
+  static const int kDeprecatedVersionNumber;
+
   // `clock` must be a non-null pointer that is valid as long as this object.
-  AggregationServiceStorageSql(bool run_in_memory,
-                               const base::FilePath& path_to_database,
-                               const base::Clock* clock);
+  AggregationServiceStorageSql(
+      bool run_in_memory,
+      const base::FilePath& path_to_database,
+      const base::Clock* clock,
+      int max_stored_requests_per_reporting_origin =
+          AggregationService::kMaxStoredReportsPerReportingOrigin);
   AggregationServiceStorageSql(const AggregationServiceStorageSql& other) =
       delete;
   AggregationServiceStorageSql& operator=(
@@ -154,6 +164,11 @@
   // Clears all stored report requests;
   void ClearAllRequests() VALID_CONTEXT_REQUIRED(sequence_checker_);
 
+  // Whether the reporting origin has space for an extra report to be stored,
+  // i.e. has not reached the `max_stored_requests_per_reporting_origin_` limit.
+  bool ReportingOriginHasCapacity(base::StringPiece serialized_reporting_origin)
+      VALID_CONTEXT_REQUIRED(sequence_checker_);
+
   // Initializes the database if necessary, and returns whether the database is
   // open. `creation_policy` indicates whether the database should be created if
   // it is not already.
@@ -180,6 +195,11 @@
 
   const base::Clock& clock_;
 
+  // No more report requests with the same reporting origin can be stored in the
+  // database than this. Any additional requests attempted to be stored will
+  // silently be dropped until there is more capacity.
+  int max_stored_requests_per_reporting_origin_;
+
   // Current status of the database initialization. Tracks what stage `this` is
   // at for lazy initialization, and used as a signal for if the database is
   // closed. This is initialized in the first call to EnsureDatabaseOpen() to
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc b/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
index 69eb43b..aeebf85 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
@@ -5,6 +5,7 @@
 #include "content/browser/aggregation_service/aggregation_service_storage_sql.h"
 
 #include <memory>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -13,22 +14,29 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/path_service.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
 #include "content/browser/aggregation_service/aggregatable_report.h"
+#include "content/browser/aggregation_service/aggregation_service.h"
 #include "content/browser/aggregation_service/aggregation_service_storage.h"
 #include "content/browser/aggregation_service/aggregation_service_test_utils.h"
 #include "content/browser/aggregation_service/public_key.h"
+#include "content/public/common/content_paths.h"
 #include "sql/database.h"
 #include "sql/meta_table.h"
+#include "sql/statement.h"
 #include "sql/test/test_helpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 
@@ -45,6 +53,12 @@
 const std::vector<PublicKey> kExampleKeys{
     aggregation_service::GenerateKey("dummy_id").public_key};
 
+std::string RemoveQuotes(base::StringPiece input) {
+  std::string output;
+  base::RemoveChars(input, "\"", &output);
+  return output;
+}
+
 }  // namespace
 
 class AggregationServiceStorageSqlTest : public testing::Test {
@@ -56,9 +70,18 @@
     clock_.SetNow(base::Time::Now());
   }
 
-  void OpenDatabase() {
-    storage_ = std::make_unique<AggregationServiceStorageSql>(
-        /*run_in_memory=*/false, temp_directory_.GetPath(), &clock_);
+  // Use the default limit unless specified.
+  void OpenDatabase(
+      absl::optional<int> max_stored_requests_per_reporting_origin =
+          absl::nullopt) {
+    if (max_stored_requests_per_reporting_origin.has_value()) {
+      storage_ = std::make_unique<AggregationServiceStorageSql>(
+          /*run_in_memory=*/false, temp_directory_.GetPath(), &clock_,
+          max_stored_requests_per_reporting_origin.value());
+    } else {
+      storage_ = std::make_unique<AggregationServiceStorageSql>(
+          /*run_in_memory=*/false, temp_directory_.GetPath(), &clock_);
+    }
   }
 
   void CloseDatabase() { storage_.reset(); }
@@ -153,8 +176,9 @@
     EXPECT_EQ(sql::test::CountSQLTables(&raw_db), 5u);
 
     // [urls_by_url_idx], [fetch_time_idx], [expiry_time_idx],
-    // [report_time_idx], [creation_time_idx] and meta table index.
-    EXPECT_EQ(sql::test::CountSQLIndices(&raw_db), 6u);
+    // [report_time_idx], [creation_time_idx], [reporting_origin_idx] and meta
+    // table index.
+    EXPECT_EQ(sql::test::CountSQLIndices(&raw_db), 7u);
   }
 }
 
@@ -895,6 +919,101 @@
             kExampleTime + base::Hours(1));
 }
 
+TEST_F(AggregationServiceStorageSqlTest, StoreRequest_RespectsLimit) {
+  base::HistogramTester histograms;
+
+  size_t example_limit = 10;
+  OpenDatabase(example_limit);
+
+  for (size_t i = 0; i < example_limit; ++i) {
+    EXPECT_EQ(
+        storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(), i);
+
+    storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+  }
+
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  // Storing one more report will silently fail.
+  storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  // Deleting a request frees up space.
+  storage_->DeleteRequest(RequestId{5});
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit - 1);
+
+  // We can then store another request.
+  storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  histograms.ExpectBucketCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity",
+      true, example_limit + 1);
+  histograms.ExpectBucketCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity",
+      false, 1);
+}
+
+TEST_F(AggregationServiceStorageSqlTest, StoreRequest_LimitIsScopedCorrectly) {
+  base::HistogramTester histograms;
+
+  size_t example_limit = 10;
+  OpenDatabase(example_limit);
+
+  for (size_t i = 0; i < example_limit; ++i) {
+    EXPECT_EQ(
+        storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(), i);
+
+    storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+  }
+
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  // Storing one more report will silently fail.
+  storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  AggregatableReportRequest example_request =
+      aggregation_service::CreateExampleRequest();
+
+  // Different APIs using the same reporting origin share a limit so storage
+  // will silently fail.
+  AggregatableReportSharedInfo different_api_shared_info =
+      example_request.shared_info().Clone();
+  different_api_shared_info.api_identifier = "some-other-api";
+  storage_->StoreRequest(
+      AggregatableReportRequest::Create(example_request.payload_contents(),
+                                        std::move(different_api_shared_info))
+          .value());
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit);
+
+  // Different reporting origins have separate limits so storage will succeed.
+  AggregatableReportSharedInfo different_reporting_origin_shared_info =
+      example_request.shared_info().Clone();
+  different_reporting_origin_shared_info.reporting_origin =
+      url::Origin::Create(GURL("https://some-other-reporting-origin.example"));
+  storage_->StoreRequest(AggregatableReportRequest::Create(
+                             example_request.payload_contents(),
+                             std::move(different_reporting_origin_shared_info))
+                             .value());
+  EXPECT_EQ(storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).size(),
+            example_limit + 1);
+
+  histograms.ExpectBucketCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity",
+      true, example_limit + 1);
+  histograms.ExpectBucketCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity",
+      false, 2);
+}
+
 TEST_F(AggregationServiceStorageSqlInMemoryTest,
        DatabaseInMemoryReopened_RequestsNotPersisted) {
   OpenDatabase();
@@ -915,4 +1034,199 @@
       storage_->GetRequestsReportingOnOrBefore(base::Time::Max()).empty());
 }
 
+class AggregationServiceStorageSqlMigrationsTest
+    : public AggregationServiceStorageSqlTest {
+ public:
+  AggregationServiceStorageSqlMigrationsTest() = default;
+
+  void MigrateDatabase() {
+    AggregationServiceStorageSql storage(
+        /*run_in_memory=*/false, temp_directory_.GetPath(), &clock_);
+
+    // We need to run an operation on storage to force the lazy initialization.
+    std::ignore = storage.NextReportTimeAfter(base::Time::Min());
+  }
+
+  void LoadDatabase(int version_id, const base::FilePath* db_path = nullptr) {
+    std::string contents = GetDatabaseData(version_id);
+    ASSERT_FALSE(contents.empty());
+
+    sql::Database db;
+    // Use `db_path()` if none is specified.
+    ASSERT_TRUE(db.Open(db_path ? *db_path : this->db_path()));
+    ASSERT_TRUE(db.Execute(contents.data()));
+  }
+
+  std::string GetCurrentSchema() {
+    base::FilePath current_version_path = temp_directory_.GetPath().Append(
+        FILE_PATH_LITERAL("TestCurrentVersion.db"));
+    LoadDatabase(AggregationServiceStorageSql::kCurrentVersionNumber,
+                 &current_version_path);
+    sql::Database db;
+    EXPECT_TRUE(db.Open(current_version_path));
+    return db.GetSchema();
+  }
+
+  static int VersionFromDatabase(sql::Database* db) {
+    sql::Statement statement(
+        db->GetUniqueStatement("SELECT value FROM meta WHERE key='version'"));
+    if (!statement.Step())
+      return 0;
+    return statement.ColumnInt(0);
+  }
+
+ private:
+  // Returns empty string in case of an error.
+  std::string GetDatabaseData(int version_id) {
+    base::FilePath source_path;
+    base::PathService::Get(content::DIR_TEST_DATA, &source_path);
+    // Should be safe cross platform because StringPrintf has overloads for wide
+    // strings.
+    source_path = source_path.Append(base::FilePath(base::StringPrintf(
+        FILE_PATH_LITERAL("aggregation_service/databases/version_%d.sql"),
+        version_id)));
+
+    if (!base::PathExists(source_path))
+      return std::string();
+
+    std::string contents;
+    base::ReadFileToString(source_path, &contents);
+
+    return contents;
+  }
+};
+
+TEST_F(AggregationServiceStorageSqlMigrationsTest, MigrateEmptyToCurrent) {
+  base::HistogramTester histograms;
+  {
+    OpenDatabase();
+
+    // We need to perform an operation that is non-trivial on an empty database
+    // to force initialization.
+    storage_->StoreRequest(aggregation_service::CreateExampleRequest());
+
+    CloseDatabase();
+  }
+
+  // Verify schema is current.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+
+    EXPECT_EQ(VersionFromDatabase(&db),
+              AggregationServiceStorageSql::kCurrentVersionNumber);
+
+    EXPECT_TRUE(db.DoesTableExist("urls"));
+    EXPECT_TRUE(db.DoesTableExist("keys"));
+    EXPECT_TRUE(db.DoesTableExist("report_requests"));
+    EXPECT_TRUE(db.DoesTableExist("meta"));
+
+    EXPECT_EQ(db.GetSchema(), GetCurrentSchema());
+  }
+
+  histograms.ExpectTotalCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.CreationTime", 1);
+  histograms.ExpectUniqueSample(
+      "PrivacySandbox.AggregationService.Storage.Sql.InitStatus",
+      AggregationServiceStorageSql::InitStatus::kSuccess, 1);
+}
+
+// Note: We should add a MigrateLatestDeprecatedVersion test when we first
+// deprecate a version.
+
+TEST_F(AggregationServiceStorageSqlMigrationsTest, MigrateVersion1ToCurrent) {
+  base::HistogramTester histograms;
+  LoadDatabase(/*version_id=*/1);
+
+  // Verify pre-conditions.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+    ASSERT_FALSE(db.DoesTableExist("report_requests"));
+
+    sql::Statement s(db.GetUniqueStatement("SELECT * FROM urls"));
+
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ(s.ColumnString(1), "https://url.example/path");  // url
+    ASSERT_FALSE(s.Step());
+  }
+
+  MigrateDatabase();
+
+  // Verify schema is current.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+
+    EXPECT_EQ(VersionFromDatabase(&db),
+              AggregationServiceStorageSql::kCurrentVersionNumber);
+
+    // Compare without quotes as sometimes migrations cause table names to be
+    // string literals.
+    EXPECT_EQ(RemoveQuotes(db.GetSchema()), RemoveQuotes(GetCurrentSchema()));
+
+    // Verify that data is preserved across the migration.
+    sql::Statement s(db.GetUniqueStatement("SELECT * FROM urls"));
+
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ(s.ColumnString(1), "https://url.example/path");  // url
+    ASSERT_FALSE(s.Step());
+  }
+
+  histograms.ExpectTotalCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.CreationTime", 0);
+  histograms.ExpectUniqueSample(
+      "PrivacySandbox.AggregationService.Storage.Sql.InitStatus",
+      AggregationServiceStorageSql::InitStatus::kSuccess, 1);
+}
+
+TEST_F(AggregationServiceStorageSqlMigrationsTest, MigrateVersion2ToCurrent) {
+  base::HistogramTester histograms;
+  LoadDatabase(/*version_id=*/2);
+
+  // Verify pre-conditions.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+    ASSERT_TRUE(db.DoesTableExist("report_requests"));
+    ASSERT_FALSE(db.DoesIndexExist("reporting_origin_idx"));
+
+    sql::Statement s(db.GetUniqueStatement("SELECT * FROM report_requests"));
+
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ(s.ColumnString(3),
+              "https://reporting.example");  // reporting_origin
+    ASSERT_FALSE(s.Step());
+  }
+
+  MigrateDatabase();
+
+  // Verify schema is current.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+
+    EXPECT_EQ(VersionFromDatabase(&db),
+              AggregationServiceStorageSql::kCurrentVersionNumber);
+
+    // Compare without quotes as sometimes migrations cause table names to be
+    // string literals.
+    EXPECT_EQ(RemoveQuotes(db.GetSchema()), RemoveQuotes(GetCurrentSchema()));
+
+    // Verify that data is preserved across the migration.
+    sql::Statement s(db.GetUniqueStatement("SELECT * FROM report_requests"));
+
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ(s.ColumnString(3),
+              "https://reporting.example");  // reporting_origin
+    ASSERT_FALSE(s.Step());
+  }
+
+  histograms.ExpectTotalCount(
+      "PrivacySandbox.AggregationService.Storage.Sql.CreationTime", 0);
+  histograms.ExpectUniqueSample(
+      "PrivacySandbox.AggregationService.Storage.Sql.InitStatus",
+      AggregationServiceStorageSql::InitStatus::kSuccess, 1);
+}
+
 }  // namespace content
diff --git a/content/browser/android/content_url_loader_factory.cc b/content/browser/android/content_url_loader_factory.cc
index 140cc18..c51892b 100644
--- a/content/browser/android/content_url_loader_factory.cc
+++ b/content/browser/android/content_url_loader_factory.cc
@@ -229,7 +229,8 @@
                                head->mime_type);
     }
 
-    client->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                              absl::nullopt);
     client_ = std::move(client);
 
     if (total_bytes_to_send == 0) {
diff --git a/content/browser/attribution_reporting/aggregatable_attribution_utils.cc b/content/browser/attribution_reporting/aggregatable_attribution_utils.cc
index c2aa1358..858d420 100644
--- a/content/browser/attribution_reporting/aggregatable_attribution_utils.cc
+++ b/content/browser/attribution_reporting/aggregatable_attribution_utils.cc
@@ -150,7 +150,7 @@
   additional_fields.Set(
       "source_registration_time",
       SerializeTimeRoundedDownToWholeDayInSeconds(
-          attribution_info.source.common_info().impression_time()));
+          attribution_info.source.common_info().source_time()));
   additional_fields.Set(
       "attribution_destination",
       attribution_info.source.common_info().DestinationSite().Serialize());
diff --git a/content/browser/attribution_reporting/attribution_header_utils_unittest.cc b/content/browser/attribution_reporting/attribution_header_utils_unittest.cc
index 87d5aa7..7835445 100644
--- a/content/browser/attribution_reporting/attribution_header_utils_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_header_utils_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/values_test_util.h"
 #include "base/time/time.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "content/browser/attribution_reporting/attribution_aggregation_keys.h"
 #include "content/browser/attribution_reporting/attribution_filter_data.h"
@@ -58,7 +59,7 @@
 
   for (const auto& test_case : kTestCases) {
     EXPECT_EQ(AttributionAggregationKeys::FromJSON(
-                  base::OptionalOrNullptr(test_case.json)),
+                  base::OptionalToPtr(test_case.json)),
               test_case.expected)
         << test_case.description;
   }
@@ -228,7 +229,7 @@
 
   for (auto& test_case : kTestCases) {
     EXPECT_EQ(AttributionFilterData::FromSourceJSON(
-                  base::OptionalOrNullptr(test_case.json)),
+                  base::OptionalToPtr(test_case.json)),
               test_case.expected)
         << test_case.description;
   }
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
index 59a341e..3fa1fe9 100644
--- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
+++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -61,7 +61,7 @@
   return attribution_internals::mojom::WebUISource::New(
       source.source_event_id(), source.source_origin(),
       source.DestinationSite().Serialize(), source.reporting_origin(),
-      source.impression_time().ToJsTime(), source.expiry_time().ToJsTime(),
+      source.source_time().ToJsTime(), source.expiry_time().ToJsTime(),
       source.source_type(), source.priority(),
       WebUIDebugKey(source.debug_key()), dedup_keys,
       source.filter_data().filter_values(),
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
index 9e5620e..ae460807 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
@@ -34,11 +34,11 @@
 constexpr base::TimeDelta kDefaultExpiry = base::Days(30);
 
 AttributionReport GetReport(
-    base::Time impression_time,
+    base::Time source_time,
     base::Time trigger_time,
     base::TimeDelta expiry = kDefaultExpiry,
     AttributionSourceType source_type = AttributionSourceType::kNavigation) {
-  return ReportBuilder(AttributionInfoBuilder(SourceBuilder(impression_time)
+  return ReportBuilder(AttributionInfoBuilder(SourceBuilder(source_time)
                                                   .SetExpiry(expiry)
                                                   .SetSourceType(source_type)
                                                   .BuildStored())
@@ -108,10 +108,10 @@
 }  // namespace
 
 TEST(AttributionStorageDelegateImplTest, ImmediateConversion_FirstWindowUsed) {
-  base::Time impression_time = base::Time::Now();
+  base::Time source_time = base::Time::Now();
   const AttributionReport report =
-      GetReport(impression_time, /*trigger_time=*/impression_time);
-  EXPECT_EQ(impression_time + base::Days(2),
+      GetReport(source_time, /*trigger_time=*/source_time);
+  EXPECT_EQ(source_time + base::Days(2),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -119,10 +119,10 @@
 
 TEST(AttributionStorageDelegateImplTest,
      ConversionImmediatelyBeforeWindow_NextWindowUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Days(2) - base::Minutes(1);
-  const AttributionReport report = GetReport(impression_time, trigger_time);
-  EXPECT_EQ(impression_time + base::Days(7),
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Days(2) - base::Minutes(1);
+  const AttributionReport report = GetReport(source_time, trigger_time);
+  EXPECT_EQ(source_time + base::Days(7),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -130,13 +130,13 @@
 
 TEST(AttributionStorageDelegateImplTest,
      ConversionBeforeWindowDelay_WindowUsed) {
-  base::Time impression_time = base::Time::Now();
+  base::Time source_time = base::Time::Now();
 
   // The deadline for a window is 1 hour before the window. Use a time just
   // before the deadline.
-  base::Time trigger_time = impression_time + base::Days(2) - base::Minutes(61);
-  const AttributionReport report = GetReport(impression_time, trigger_time);
-  EXPECT_EQ(impression_time + base::Days(2),
+  base::Time trigger_time = source_time + base::Days(2) - base::Minutes(61);
+  const AttributionReport report = GetReport(source_time, trigger_time);
+  EXPECT_EQ(source_time + base::Days(2),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -144,13 +144,13 @@
 
 TEST(AttributionStorageDelegateImplTest,
      ImpressionExpiryBeforeTwoDayWindow_TwoDayWindowUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Hours(1);
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Hours(1);
 
   // Set the impression to expire before the two day window.
-  const AttributionReport report = GetReport(impression_time, trigger_time,
+  const AttributionReport report = GetReport(source_time, trigger_time,
                                              /*expiry=*/base::Hours(2));
-  EXPECT_EQ(impression_time + base::Days(2),
+  EXPECT_EQ(source_time + base::Days(2),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -158,15 +158,15 @@
 
 TEST(AttributionStorageDelegateImplTest,
      ImpressionExpiryBeforeSevenDayWindow_ExpiryWindowUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Days(3);
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Days(3);
 
   // Set the impression to expire before the two day window.
-  const AttributionReport report = GetReport(impression_time, trigger_time,
+  const AttributionReport report = GetReport(source_time, trigger_time,
                                              /*expiry=*/base::Days(4));
 
   // The expiry window is reported one hour after expiry time.
-  EXPECT_EQ(impression_time + base::Days(4) + base::Hours(1),
+  EXPECT_EQ(source_time + base::Days(4) + base::Hours(1),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -174,15 +174,15 @@
 
 TEST(AttributionStorageDelegateImplTest,
      ImpressionExpiryAfterSevenDayWindow_ExpiryWindowUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Days(7);
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Days(7);
 
   // Set the impression to expire before the two day window.
-  const AttributionReport report = GetReport(impression_time, trigger_time,
+  const AttributionReport report = GetReport(source_time, trigger_time,
                                              /*expiry=*/base::Days(9));
 
   // The expiry window is reported one hour after expiry time.
-  EXPECT_EQ(impression_time + base::Days(9) + base::Hours(1),
+  EXPECT_EQ(source_time + base::Days(9) + base::Hours(1),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -190,12 +190,12 @@
 
 TEST(AttributionStorageDelegateImplTest,
      SourceTypeEvent_ExpiryLessThanTwoDays_TwoDaysUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Days(3);
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Days(3);
   const AttributionReport report =
-      GetReport(impression_time, trigger_time,
+      GetReport(source_time, trigger_time,
                 /*expiry=*/base::Days(1), AttributionSourceType::kEvent);
-  EXPECT_EQ(impression_time + base::Days(2) + base::Hours(1),
+  EXPECT_EQ(source_time + base::Days(2) + base::Hours(1),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
@@ -203,12 +203,12 @@
 
 TEST(AttributionStorageDelegateImplTest,
      SourceTypeEvent_ExpiryGreaterThanTwoDays_ExpiryUsed) {
-  base::Time impression_time = base::Time::Now();
-  base::Time trigger_time = impression_time + base::Days(3);
+  base::Time source_time = base::Time::Now();
+  base::Time trigger_time = source_time + base::Days(3);
   const AttributionReport report =
-      GetReport(impression_time, trigger_time,
+      GetReport(source_time, trigger_time,
                 /*expiry=*/base::Days(4), AttributionSourceType::kEvent);
-  EXPECT_EQ(impression_time + base::Days(4) + base::Hours(1),
+  EXPECT_EQ(source_time + base::Days(4) + base::Hours(1),
             AttributionStorageDelegateImpl().GetEventLevelReportTime(
                 report.attribution_info().source.common_info(),
                 report.attribution_info().time));
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
index adfeb964..9198c37 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -308,7 +308,7 @@
       DeserializePotentiallyTrustworthyOrigin(statement.ColumnString(col++));
   url::Origin reporting_origin =
       DeserializePotentiallyTrustworthyOrigin(statement.ColumnString(col++));
-  base::Time impression_time = statement.ColumnTime(col++);
+  base::Time source_time = statement.ColumnTime(col++);
   base::Time expiry_time = statement.ColumnTime(col++);
   absl::optional<AttributionSourceType> source_type =
       DeserializeSourceType(statement.ColumnInt(col++));
@@ -346,7 +346,7 @@
           CommonSourceInfo(
               source_event_id, std::move(source_origin),
               std::move(destination_origin), std::move(reporting_origin),
-              impression_time, expiry_time, *source_type, priority,
+              source_time, expiry_time, *source_type, priority,
               std::move(*filter_data), debug_key, std::move(*aggregation_keys)),
           *attribution_logic, *active_state, source_id),
       .num_conversions = num_conversions,
@@ -637,7 +637,7 @@
                               common_info.destination_origin()));
   statement.BindString(3, serialized_conversion_destination);
   statement.BindString(4, serialized_reporting_origin);
-  statement.BindTime(5, common_info.impression_time());
+  statement.BindTime(5, common_info.source_time());
   statement.BindTime(6, common_info.expiry_time());
   statement.BindInt(7, SerializeSourceType(common_info.source_type()));
   statement.BindInt(8, SerializeAttributionLogic(attribution_logic));
@@ -669,7 +669,7 @@
   absl::optional<base::Time> min_fake_report_time;
 
   if (attribution_logic == StoredSource::AttributionLogic::kFalsely) {
-    const base::Time trigger_time = common_info.impression_time();
+    const base::Time trigger_time = common_info.source_time();
 
     for (const auto& fake_report : *randomized_response) {
       DCHECK_EQ(fake_report.trigger_data,
@@ -2368,7 +2368,7 @@
   statement.BindString(0, source.common_info().SourceSite().Serialize());
   statement.BindString(1, SerializePotentiallyTrustworthyOrigin(
                               source.common_info().reporting_origin()));
-  statement.BindTime(2, source.common_info().impression_time());
+  statement.BindTime(2, source.common_info().source_time());
 
   base::flat_set<std::string> destinations;
   while (statement.Step()) {
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc
index d82a1b86..c1ca12fe 100644
--- a/content/browser/attribution_reporting/attribution_storage_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -111,7 +111,7 @@
                              .SetTime(base::Time::Now())
                              .Build())
         .SetTriggerData(event_trigger->data)
-        .SetReportTime(source.common_info().impression_time() + kReportDelay)
+        .SetReportTime(source.common_info().source_time() + kReportDelay)
         .SetPriority(event_trigger->priority)
         .Build();
   }
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc
index 597d89bd..13653d0 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.cc
+++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -134,7 +134,7 @@
     const CommonSourceInfo& source,
     base::Time trigger_time) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return source.impression_time() + report_delay_;
+  return source.source_time() + report_delay_;
 }
 
 base::Time ConfigurableStorageDelegate::GetAggregatableReportTime(
@@ -467,7 +467,7 @@
 // Builds an impression with default values. This is done as a builder because
 // all values needed to be provided at construction time.
 SourceBuilder::SourceBuilder(base::Time time)
-    : impression_time_(time),
+    : source_time_(time),
       expiry_(base::Milliseconds(kExpiryTime)),
       source_origin_(url::Origin::Create(GURL(kDefaultSourceOrigin))),
       destination_origin_(url::Origin::Create(GURL(kDefaultDestinationOrigin))),
@@ -563,9 +563,9 @@
 
 CommonSourceInfo SourceBuilder::BuildCommonInfo() const {
   return CommonSourceInfo(source_event_id_, source_origin_, destination_origin_,
-                          reporting_origin_, impression_time_,
-                          /*expiry_time=*/impression_time_ + expiry_,
-                          source_type_, priority_, filter_data_, debug_key_,
+                          reporting_origin_, source_time_,
+                          /*expiry_time=*/source_time_ + expiry_, source_type_,
+                          priority_, filter_data_, debug_key_,
                           aggregation_keys_);
 }
 
@@ -785,7 +785,7 @@
   const auto tie = [](const CommonSourceInfo& source) {
     return std::make_tuple(source.source_event_id(), source.source_origin(),
                            source.destination_origin(),
-                           source.reporting_origin(), source.impression_time(),
+                           source.reporting_origin(), source.source_time(),
                            source.expiry_time(), source.source_type(),
                            source.priority(), source.filter_data(),
                            source.debug_key(), source.aggregation_keys());
@@ -1106,7 +1106,7 @@
              << ",source_origin=" << source.source_origin()
              << ",destination_origin=" << source.destination_origin()
              << ",reporting_origin=" << source.reporting_origin()
-             << ",impression_time=" << source.impression_time()
+             << ",source_time=" << source.source_time()
              << ",expiry_time=" << source.expiry_time()
              << ",source_type=" << source.source_type()
              << ",priority=" << source.priority()
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h
index 0c51420..7237838f 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.h
+++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -475,7 +475,7 @@
 
  private:
   uint64_t source_event_id_ = 123;
-  base::Time impression_time_;
+  base::Time source_time_;
   base::TimeDelta expiry_;
   url::Origin source_origin_;
   url::Origin destination_origin_;
@@ -756,11 +756,6 @@
                             result_listener);
 }
 
-MATCHER_P(ImpressionTimeIs, matcher, "") {
-  return ExplainMatchResult(matcher, arg.common_info().impression_time(),
-                            result_listener);
-}
-
 MATCHER_P(SourceDebugKeyIs, matcher, "") {
   return ExplainMatchResult(matcher, arg.common_info().debug_key(),
                             result_listener);
diff --git a/content/browser/attribution_reporting/attribution_utils.cc b/content/browser/attribution_reporting/attribution_utils.cc
index 13ba8f9..c2ffc221 100644
--- a/content/browser/attribution_reporting/attribution_utils.cc
+++ b/content/browser/attribution_reporting/attribution_utils.cc
@@ -36,8 +36,7 @@
 }
 
 base::TimeDelta ExpiryDeadline(const CommonSourceInfo& source) {
-  base::TimeDelta expiry_deadline =
-      source.expiry_time() - source.impression_time();
+  base::TimeDelta expiry_deadline = source.expiry_time() - source.source_time();
 
   constexpr base::TimeDelta kMinExpiryDeadline = base::Days(2);
   if (expiry_deadline < kMinExpiryDeadline)
@@ -46,11 +45,11 @@
   return expiry_deadline;
 }
 
-base::Time ReportTimeFromDeadline(base::Time impression_time,
+base::Time ReportTimeFromDeadline(base::Time source_time,
                                   base::TimeDelta deadline) {
   // Valid conversion reports should always have a valid reporting deadline.
   DCHECK(!deadline.is_zero());
-  return impression_time + deadline + kWindowDeadlineOffset;
+  return source_time + deadline + kWindowDeadlineOffset;
 }
 
 }  // namespace
@@ -83,14 +82,14 @@
   for (base::TimeDelta early_deadline : EarlyDeadlines(source.source_type())) {
     // If this window is valid for the conversion, use it.
     // |trigger_time| is roughly ~now.
-    if (source.impression_time() + early_deadline >= trigger_time &&
+    if (source.source_time() + early_deadline >= trigger_time &&
         early_deadline < deadline_to_use) {
       deadline_to_use = early_deadline;
       break;
     }
   }
 
-  return ReportTimeFromDeadline(source.impression_time(), deadline_to_use);
+  return ReportTimeFromDeadline(source.source_time(), deadline_to_use);
 }
 
 int NumReportWindows(AttributionSourceType source_type) {
@@ -111,7 +110,7 @@
           ? early_deadlines[window_index]
           : ExpiryDeadline(source);
 
-  return ReportTimeFromDeadline(source.impression_time(), deadline);
+  return ReportTimeFromDeadline(source.source_time(), deadline);
 }
 
 std::string SerializeAttributionJson(const base::Value::Dict& body,
diff --git a/content/browser/attribution_reporting/common_source_info.cc b/content/browser/attribution_reporting/common_source_info.cc
index 4b47a69b..275a72f 100644
--- a/content/browser/attribution_reporting/common_source_info.cc
+++ b/content/browser/attribution_reporting/common_source_info.cc
@@ -15,7 +15,7 @@
 
 base::Time CommonSourceInfo::GetExpiryTime(
     absl::optional<base::TimeDelta> declared_expiry,
-    base::Time impression_time,
+    base::Time source_time,
     AttributionSourceType source_type) {
   constexpr base::TimeDelta kMinImpressionExpiry = base::Days(1);
 
@@ -29,15 +29,15 @@
 
   // If the impression specified its own expiry, clamp it to the minimum and
   // maximum.
-  return impression_time + base::clamp(expiry, kMinImpressionExpiry,
-                                       kDefaultAttributionSourceExpiry);
+  return source_time + base::clamp(expiry, kMinImpressionExpiry,
+                                   kDefaultAttributionSourceExpiry);
 }
 
 CommonSourceInfo::CommonSourceInfo(uint64_t source_event_id,
                                    url::Origin source_origin,
                                    url::Origin destination_origin,
                                    url::Origin reporting_origin,
-                                   base::Time impression_time,
+                                   base::Time source_time,
                                    base::Time expiry_time,
                                    AttributionSourceType source_type,
                                    int64_t priority,
@@ -48,7 +48,7 @@
       source_origin_(std::move(source_origin)),
       destination_origin_(std::move(destination_origin)),
       reporting_origin_(std::move(reporting_origin)),
-      impression_time_(impression_time),
+      source_time_(source_time),
       expiry_time_(expiry_time),
       source_type_(source_type),
       priority_(priority),
@@ -56,9 +56,9 @@
       debug_key_(debug_key),
       aggregation_keys_(std::move(aggregation_keys)) {
   // 30 days is the max allowed expiry for an impression.
-  DCHECK_GE(base::Days(30), expiry_time - impression_time);
+  DCHECK_GE(base::Days(30), expiry_time - source_time);
   // The impression must expire strictly after it occurred.
-  DCHECK_GT(expiry_time, impression_time);
+  DCHECK_GT(expiry_time, source_time);
   DCHECK(network::IsOriginPotentiallyTrustworthy(source_origin_));
   DCHECK(network::IsOriginPotentiallyTrustworthy(reporting_origin_));
   DCHECK(network::IsOriginPotentiallyTrustworthy(destination_origin_));
diff --git a/content/browser/attribution_reporting/common_source_info.h b/content/browser/attribution_reporting/common_source_info.h
index d7a9df1..5239b7a6 100644
--- a/content/browser/attribution_reporting/common_source_info.h
+++ b/content/browser/attribution_reporting/common_source_info.h
@@ -28,14 +28,14 @@
  public:
   static base::Time GetExpiryTime(
       absl::optional<base::TimeDelta> declared_expiry,
-      base::Time impression_time,
+      base::Time source_time,
       AttributionSourceType source_type);
 
   CommonSourceInfo(uint64_t source_event_id,
                    url::Origin source_origin,
                    url::Origin destination_origin,
                    url::Origin reporting_origin,
-                   base::Time impression_time,
+                   base::Time source_time,
                    base::Time expiry_time,
                    AttributionSourceType source_type,
                    int64_t priority,
@@ -59,7 +59,7 @@
 
   const url::Origin& reporting_origin() const { return reporting_origin_; }
 
-  base::Time impression_time() const { return impression_time_; }
+  base::Time source_time() const { return source_time_; }
 
   base::Time expiry_time() const { return expiry_time_; }
 
@@ -94,7 +94,7 @@
   url::Origin source_origin_;
   url::Origin destination_origin_;
   url::Origin reporting_origin_;
-  base::Time impression_time_;
+  base::Time source_time_;
   base::Time expiry_time_;
   AttributionSourceType source_type_;
   int64_t priority_;
diff --git a/content/browser/attribution_reporting/common_source_info_unittest.cc b/content/browser/attribution_reporting/common_source_info_unittest.cc
index d125318..1a59864 100644
--- a/content/browser/attribution_reporting/common_source_info_unittest.cc
+++ b/content/browser/attribution_reporting/common_source_info_unittest.cc
@@ -13,23 +13,22 @@
 namespace content {
 
 TEST(CommonSourceInfoTest, NoExpiryForImpression_DefaultUsed) {
-  const base::Time impression_time = base::Time::Now();
+  const base::Time source_time = base::Time::Now();
 
   for (auto source_type : kSourceTypes) {
-    EXPECT_EQ(
-        impression_time + base::Days(30),
-        CommonSourceInfo::GetExpiryTime(
-            /*declared_expiry=*/absl::nullopt, impression_time, source_type));
+    EXPECT_EQ(source_time + base::Days(30),
+              CommonSourceInfo::GetExpiryTime(
+                  /*declared_expiry=*/absl::nullopt, source_time, source_type));
   }
 }
 
 TEST(CommonSourceInfoTest, LargeImpressionExpirySpecified_ClampedTo30Days) {
   constexpr base::TimeDelta declared_expiry = base::Days(60);
-  const base::Time impression_time = base::Time::Now();
+  const base::Time source_time = base::Time::Now();
 
   for (auto source_type : kSourceTypes) {
-    EXPECT_EQ(impression_time + base::Days(30),
-              CommonSourceInfo::GetExpiryTime(declared_expiry, impression_time,
+    EXPECT_EQ(source_time + base::Days(30),
+              CommonSourceInfo::GetExpiryTime(declared_expiry, source_time,
                                               source_type));
   }
 }
@@ -44,13 +43,13 @@
       {base::Days(1) - base::Milliseconds(1), base::Days(1)},
   };
 
-  const base::Time impression_time = base::Time::Now();
+  const base::Time source_time = base::Time::Now();
 
   for (auto source_type : kSourceTypes) {
     for (const auto& test_case : kTestCases) {
-      EXPECT_EQ(impression_time + test_case.want_expiry,
+      EXPECT_EQ(source_time + test_case.want_expiry,
                 CommonSourceInfo::GetExpiryTime(test_case.declared_expiry,
-                                                impression_time, source_type));
+                                                source_time, source_type));
     }
   }
 }
@@ -71,23 +70,23 @@
        base::Days(1)},
   };
 
-  const base::Time impression_time = base::Time::Now();
+  const base::Time source_time = base::Time::Now();
 
   for (const auto& test_case : kTestCases) {
     EXPECT_EQ(
-        impression_time + test_case.want_expiry,
-        CommonSourceInfo::GetExpiryTime(
-            test_case.declared_expiry, impression_time, test_case.source_type));
+        source_time + test_case.want_expiry,
+        CommonSourceInfo::GetExpiryTime(test_case.declared_expiry, source_time,
+                                        test_case.source_type));
   }
 }
 
 TEST(CommonSourceInfoTest, ImpressionExpirySpecified_ExpiryOverrideDefault) {
   constexpr base::TimeDelta declared_expiry = base::Days(10);
-  const base::Time impression_time = base::Time::Now();
+  const base::Time source_time = base::Time::Now();
 
   for (auto source_type : kSourceTypes) {
-    EXPECT_EQ(impression_time + base::Days(10),
-              CommonSourceInfo::GetExpiryTime(declared_expiry, impression_time,
+    EXPECT_EQ(source_time + base::Days(10),
+              CommonSourceInfo::GetExpiryTime(declared_expiry, source_time,
                                               source_type));
   }
 }
diff --git a/content/browser/attribution_reporting/rate_limit_table.cc b/content/browser/attribution_reporting/rate_limit_table.cc
index 9df03ce2..193a959 100644
--- a/content/browser/attribution_reporting/rate_limit_table.cc
+++ b/content/browser/attribution_reporting/rate_limit_table.cc
@@ -103,7 +103,7 @@
                                            const StoredSource& source) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return AddRateLimit(db, Scope::kSource, source,
-                      source.common_info().impression_time());
+                      source.common_info().source_time());
 }
 
 bool RateLimitTable::AddRateLimitForAttribution(
@@ -208,7 +208,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return AllowedForReportingOriginLimit(db, Scope::kSource,
                                         source.common_info(),
-                                        source.common_info().impression_time());
+                                        source.common_info().source_time());
 }
 
 RateLimitResult RateLimitTable::SourceAllowedForDestinationLimit(
@@ -234,7 +234,7 @@
   const CommonSourceInfo& common_info = source.common_info();
   statement.BindString(0, common_info.SourceSite().Serialize());
   statement.BindString(1, SerializeOrigin(common_info.reporting_origin()));
-  statement.BindTime(2, common_info.impression_time());
+  statement.BindTime(2, common_info.source_time());
 
   const std::string serialized_destination_site =
       common_info.DestinationSite().Serialize();
diff --git a/content/browser/blob_storage/blob_internals_url_loader.cc b/content/browser/blob_storage/blob_internals_url_loader.cc
index f447726..fb916e6 100644
--- a/content/browser/blob_storage/blob_internals_url_loader.cc
+++ b/content/browser/blob_storage/blob_internals_url_loader.cc
@@ -45,7 +45,7 @@
   CHECK_EQ(result, MOJO_RESULT_OK);
 
   client->OnReceiveResponse(std::move(resource_response),
-                            std::move(consumer_handle));
+                            std::move(consumer_handle), absl::nullopt);
   network::URLLoaderCompletionStatus status(net::OK);
   status.encoded_data_length = output.size();
   status.encoded_body_length = output.size();
diff --git a/content/browser/blob_storage/blob_url_unittest.cc b/content/browser/blob_storage/blob_url_unittest.cc
index 9a395b4..631264e 100644
--- a/content/browser/blob_storage/blob_url_unittest.cc
+++ b/content/browser/blob_storage/blob_url_unittest.cc
@@ -195,7 +195,7 @@
     expected_error_code_ = expected_error_code;
     expected_response_ = "";
     TestRequest("GET", net::HttpRequestHeaders());
-    EXPECT_TRUE(response_metadata_.empty());
+    EXPECT_FALSE(response_metadata_.has_value());
   }
 
   void TestRequest(const std::string& method,
@@ -349,7 +349,7 @@
   std::string response_;
   int response_error_code_;
   scoped_refptr<net::HttpResponseHeaders> response_headers_;
-  std::string response_metadata_;
+  absl::optional<std::string> response_metadata_;
 
   int expected_error_code_;
   int expected_status_code_;
@@ -495,7 +495,7 @@
   TestRequest("GET", extra_headers);
 
   EXPECT_EQ(6, response_headers_->GetContentLength());
-  EXPECT_TRUE(response_metadata_.empty());
+  EXPECT_FALSE(response_metadata_.has_value());
 
   int64_t first = 0, last = 0, length = 0;
   EXPECT_TRUE(response_headers_->GetContentRangeFor206(&first, &last, &length));
@@ -516,7 +516,7 @@
   TestRequest("GET", extra_headers);
 
   EXPECT_EQ(10, response_headers_->GetContentLength());
-  EXPECT_TRUE(response_metadata_.empty());
+  EXPECT_FALSE(response_metadata_.has_value());
 
   int64_t total = GetTotalBlobLength();
   int64_t first = 0, last = 0, length = 0;
@@ -538,7 +538,7 @@
   TestRequest("GET", extra_headers);
 
   EXPECT_EQ(3, response_headers_->GetContentLength());
-  EXPECT_TRUE(response_metadata_.empty());
+  EXPECT_FALSE(response_metadata_.has_value());
 
   int64_t first = 0, last = 0, length = 0;
   EXPECT_TRUE(response_headers_->GetContentRangeFor206(&first, &last, &length));
@@ -558,7 +558,7 @@
   std::string content_type;
   EXPECT_TRUE(response_headers_->GetMimeType(&content_type));
   EXPECT_EQ(kTestContentType, content_type);
-  EXPECT_TRUE(response_metadata_.empty());
+  EXPECT_FALSE(response_metadata_.has_value());
   size_t iter = 0;
   std::string content_disposition;
   EXPECT_TRUE(response_headers_->EnumerateHeader(&iter, "Content-Disposition",
@@ -576,7 +576,7 @@
   EXPECT_EQ(static_cast<int>(std::size(kTestDataHandleData2) - 1),
             response_headers_->GetContentLength());
 
-  EXPECT_EQ(std::string(kTestDiskCacheSideData), response_metadata_);
+  EXPECT_EQ(std::string(kTestDiskCacheSideData), *response_metadata_);
 }
 
 TEST_F(BlobURLTest, TestZeroSizeSideData) {
@@ -589,7 +589,7 @@
   EXPECT_EQ(static_cast<int>(std::size(kTestDataHandleData2) - 1),
             response_headers_->GetContentLength());
 
-  EXPECT_TRUE(response_metadata_.empty());
+  EXPECT_FALSE(response_metadata_.has_value());
 }
 
 TEST_F(BlobURLTest, BrokenBlob) {
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc
index 601a053..67e46b9 100644
--- a/content/browser/cache_storage/cache_storage.cc
+++ b/content/browser/cache_storage/cache_storage.cc
@@ -611,21 +611,21 @@
                                     scheduler_task_runner)),
       directory_path_(path),
       cache_task_runner_(cache_task_runner),
-      quota_manager_proxy_(quota_manager_proxy),
+      quota_manager_proxy_(std::move(quota_manager_proxy)),
       blob_storage_context_(std::move(blob_storage_context)),
       owner_(owner),
       cache_storage_manager_(cache_storage_manager) {
   if (memory_only) {
     cache_loader_ = base::WrapUnique<CacheLoader>(
         new MemoryLoader(cache_task_runner_.get(),
-                         std::move(scheduler_task_runner), quota_manager_proxy,
+                         std::move(scheduler_task_runner), quota_manager_proxy_,
                          blob_storage_context_, this, bucket_locator_, owner));
     return;
   }
 
   cache_loader_ = base::WrapUnique<CacheLoader>(new SimpleCacheLoader(
       directory_path_, cache_task_runner_.get(),
-      std::move(scheduler_task_runner), quota_manager_proxy,
+      std::move(scheduler_task_runner), quota_manager_proxy_,
       blob_storage_context_, this, bucket_locator_, owner));
 
 #if BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
index ab70c74..268e3f8f 100644
--- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -634,7 +634,6 @@
  public:
   CacheStorageImpl(
       CacheStorageDispatcherHost* host,
-      const blink::StorageKey& storage_key,
       const absl::optional<storage::BucketLocator>& bucket,
       bool incognito,
       const CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
@@ -642,7 +641,6 @@
           coep_reporter,
       storage::mojom::CacheStorageOwner owner)
       : host_(host),
-        storage_key_(storage_key),
         bucket_(bucket),
         cross_origin_embedder_policy_(cross_origin_embedder_policy),
         coep_reporter_(std::move(coep_reporter)),
@@ -679,12 +677,6 @@
         TRACE_ID_GLOBAL(trace_id),
         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
 
-    // Return error if failed to retrieve bucket from QuotaManager.
-    if (!bucket_.has_value()) {
-      std::move(callback).Run(std::vector<std::u16string>());
-      return;
-    }
-
     auto cb = base::BindOnce(
         [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorage::KeysCallback callback,
@@ -706,6 +698,12 @@
         },
         base::TimeTicks::Now(), trace_id, std::move(callback));
 
+    // Return error if failed to retrieve bucket from QuotaManager.
+    if (!bucket_.has_value()) {
+      std::move(cb).Run(std::vector<std::string>());
+      return;
+    }
+
     GetOrCreateCacheStorage(base::BindOnce(
         [](int64_t trace_id, content::CacheStorage::EnumerateCachesCallback cb,
            content::CacheStorage* cache_storage) {
@@ -868,6 +866,8 @@
                 blink::mojom::MatchResult::NewStatus(error));
             return;
           }
+          DCHECK(self->bucket_.has_value());
+
           TRACE_EVENT_WITH_FLOW1(
               "CacheStorage",
               "CacheStorageDispatchHost::CacheStorageImpl::Match::Callback",
@@ -879,7 +879,7 @@
           // against the requesting document's origin and
           // Cross-Origin-Embedder-Policy (COEP).
           if (ResponseBlockedByCrossOriginResourcePolicy(
-                  response.get(), self->storage_key_.origin(),
+                  response.get(), self->bucket_->storage_key.origin(),
                   self->cross_origin_embedder_policy_, self->coep_reporter_)) {
             std::move(callback).Run(blink::mojom::MatchResult::NewStatus(
                 CacheStorageError::kErrorCrossOriginResourcePolicy));
@@ -970,6 +970,7 @@
             std::move(callback).Run(blink::mojom::OpenResult::NewStatus(error));
             return;
           }
+          DCHECK(self->bucket_.has_value());
 
           mojo::PendingAssociatedRemote<blink::mojom::CacheStorageCache>
               pending_remote;
@@ -980,7 +981,7 @@
                 coep_reporter.InitWithNewPipeAndPassReceiver());
           }
           auto cache_impl = std::make_unique<CacheImpl>(
-              self->host_, std::move(cache_handle), self->storage_key_,
+              self->host_, std::move(cache_handle), self->bucket_->storage_key,
               self->cross_origin_embedder_policy_, std::move(coep_reporter),
               self->owner_);
           self->host_->AddCacheReceiver(
@@ -1059,7 +1060,7 @@
     // check in `CacheStorageManager::OpenCacheStorage()`.
     if (host_->WasNotifiedOfBucketDataDeletion(bucket_.value())) {
       host_->UpdateOrCreateBucket(
-          storage_key_,
+          bucket_->storage_key,
           base::BindOnce(&CacheStorageImpl::UpdateOrCreateBucketCallback,
                          weak_factory_.GetWeakPtr(), std::move(callback)));
       return;
@@ -1073,7 +1074,6 @@
   // Owns this.
   const raw_ptr<CacheStorageDispatcherHost> host_;
 
-  const blink::StorageKey storage_key_;
   // absl::nullopt when bucket retrieval has failed.
   absl::optional<storage::BucketLocator> bucket_;
   const CrossOriginEmbedderPolicy cross_origin_embedder_policy_;
@@ -1089,7 +1089,7 @@
 CacheStorageDispatcherHost::CacheStorageDispatcherHost(
     CacheStorageContextImpl* context,
     scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy)
-    : context_(context), quota_manager_proxy_(quota_manager_proxy) {
+    : context_(context), quota_manager_proxy_(std::move(quota_manager_proxy)) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
@@ -1106,19 +1106,22 @@
     storage::mojom::CacheStorageOwner owner,
     mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (bucket.has_value() && WasNotifiedOfBucketDataDeletion(bucket.value())) {
-    // The list of deleted buckets gets added to each time
-    // `CacheStorageManager::DeleteBucketData()` is called, but it's not
-    // guaranteed that this means the bucket was actually deleted. To avoid
-    // a bucket being mistakenly considered deleted forever, treat a
-    // call to `CacheStorageDispatcherHost::AddReceiver` with a given bucket
-    // locator to be a signal that the corresponding bucket has not actually
-    // been deleted.
-    deleted_buckets_.erase(bucket.value());
+  if (bucket.has_value()) {
+    DCHECK_EQ(bucket->storage_key, storage_key);
+    if (WasNotifiedOfBucketDataDeletion(bucket.value())) {
+      // The list of deleted buckets gets added to each time
+      // `CacheStorageManager::DeleteBucketData()` is called, but it's not
+      // guaranteed that this means the bucket was actually deleted. To avoid
+      // a bucket being mistakenly considered deleted forever, treat a
+      // call to `CacheStorageDispatcherHost::AddReceiver` with a given bucket
+      // locator to be a signal that the corresponding bucket has not actually
+      // been deleted.
+      deleted_buckets_.erase(bucket.value());
+    }
   }
   bool incognito = context_ ? context_->is_incognito() : false;
   auto impl = std::make_unique<CacheStorageImpl>(
-      this, storage_key, bucket, incognito, cross_origin_embedder_policy,
+      this, bucket, incognito, cross_origin_embedder_policy,
       std::move(coep_reporter), owner);
   receivers_.Add(std::move(impl), std::move(receiver));
 }
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc
index 1a339ba..9778a34 100644
--- a/content/browser/cross_origin_opener_policy_browsertest.cc
+++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -1301,11 +1301,9 @@
     if (features::GetBrowsingContextMode() ==
         features::BrowsingContextStateImplementationType::
             kLegacyOneToOneWithFrameTreeNode) {
-      // Navigate back. Isolated into non-isolated.
-      // This DCHECKs currently because of https://crbug.com/1264104,
-      // remove the death check and add a simple load wait when the
-      // bug is fixed.
-      EXPECT_DCHECK_DEATH(web_contents()->GetController().GoBack());
+      // TODO(https://crbug.com/1264104): Navigate back. Isolated into
+      // non-isolated. Add a simple load wait when the bug is fixed.
+      return;
     } else {
       // Swapping BrowsingContextState on cross-origin navigations resolves
       // https://crbug.com/1264104, as we store proxies for isolated pages
diff --git a/content/browser/data_url_loader_factory.cc b/content/browser/data_url_loader_factory.cc
index 708f4e3..49ce771 100644
--- a/content/browser/data_url_loader_factory.cc
+++ b/content/browser/data_url_loader_factory.cc
@@ -88,7 +88,8 @@
     return;
   }
 
-  client_remote->OnReceiveResponse(std::move(response), std::move(consumer));
+  client_remote->OnReceiveResponse(std::move(response), std::move(consumer),
+                                   absl::nullopt);
 
   auto write_data = std::make_unique<WriteData>();
   write_data->client = std::move(client_remote);
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc
index 5fe42f0..b6e99074 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -252,7 +252,7 @@
   network::mojom::URLResponseHeadPtr head =
       network::mojom::URLResponseHead::New();
   std::unique_ptr<net::RedirectInfo> redirect_info;
-  mojo_base::BigBuffer cached_metadata;
+  absl::optional<mojo_base::BigBuffer> cached_metadata;
   size_t encoded_length = 0;
   size_t transfer_size = 0;
   network::URLLoaderCompletionStatus status;
@@ -363,14 +363,15 @@
 
   // network::mojom::URLLoaderClient methods
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
@@ -1006,7 +1007,8 @@
     DCHECK_EQ(State::kResponseReceived, state_);
     DCHECK(!body_reader_);
     client_->OnReceiveResponse(std::move(response_metadata_->head),
-                               std::move(body_));
+                               std::move(body_),
+                               std::move(response_metadata_->cached_metadata));
     response_metadata_.reset();
     loader_->ResumeReadingBodyFromNet();
     client_receiver_.Resume();
@@ -1250,10 +1252,8 @@
     DCHECK_EQ(num_bytes, body_size);
   }
   client_->OnReceiveResponse(std::move(response_metadata_->head),
-                             std::move(consumer_handle));
-  if (response_metadata_->cached_metadata.size() != 0)
-    client_->OnReceiveCachedMetadata(
-        std::move(response_metadata_->cached_metadata));
+                             std::move(consumer_handle),
+                             std::move(response_metadata_->cached_metadata));
 
   if (response_metadata_->transfer_size)
     client_->OnTransferSizeUpdated(response_metadata_->transfer_size);
@@ -1482,11 +1482,13 @@
 
 void InterceptionJob::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   state_ = State::kResponseReceived;
   DCHECK(!response_metadata_);
   if (!(stage_ & InterceptionStage::RESPONSE)) {
-    client_->OnReceiveResponse(std::move(head), std::move(body));
+    client_->OnReceiveResponse(std::move(head), std::move(body),
+                               std::move(cached_metadata));
     return;
   }
   loader_->PauseReadingBodyFromNet();
@@ -1501,6 +1503,7 @@
                            request.url, head->headers.get(), head->mime_type));
 
   response_metadata_ = std::make_unique<ResponseMetadata>(std::move(head));
+  response_metadata_->cached_metadata = std::move(cached_metadata);
 
   NotifyClient(std::move(request_info));
 }
@@ -1532,13 +1535,6 @@
   client_->OnUploadProgress(current_position, total_size, std::move(callback));
 }
 
-void InterceptionJob::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  if (ShouldBypassForResponse())
-    client_->OnReceiveCachedMetadata(std::move(data));
-  else
-    response_metadata_->cached_metadata = std::move(data);
-}
-
 void InterceptionJob::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   if (ShouldBypassForResponse())
     client_->OnTransferSizeUpdated(transfer_size_diff);
diff --git a/content/browser/direct_sockets/direct_sockets_test_utils.cc b/content/browser/direct_sockets/direct_sockets_test_utils.cc
index a413419..bab5a01 100644
--- a/content/browser/direct_sockets/direct_sockets_test_utils.cc
+++ b/content/browser/direct_sockets/direct_sockets_test_utils.cc
@@ -28,7 +28,7 @@
 MockHostResolver::~MockHostResolver() = default;
 
 void MockHostResolver::ResolveHost(
-    const ::net::HostPortPair& host,
+    network::mojom::HostResolverHostPtr host,
     const ::net::NetworkIsolationKey& network_isolation_key,
     network::mojom::ResolveHostParametersPtr optional_parameters,
     ::mojo::PendingRemote<network::mojom::ResolveHostClient>
@@ -36,11 +36,19 @@
   DCHECK(!internal_request_);
   DCHECK(!response_client_.is_bound());
 
-  internal_request_ = internal_resolver_->CreateRequest(
-      host, network_isolation_key,
-      net::NetLogWithSource::Make(net::NetLog::Get(),
-                                  net::NetLogSourceType::NONE),
-      absl::nullopt);
+  internal_request_ =
+      host->is_host_port_pair()
+          ? internal_resolver_->CreateRequest(
+                host->get_host_port_pair(), network_isolation_key,
+                net::NetLogWithSource::Make(net::NetLog::Get(),
+                                            net::NetLogSourceType::NONE),
+                absl::nullopt)
+          : internal_resolver_->CreateRequest(
+                host->get_scheme_host_port(), network_isolation_key,
+                net::NetLogWithSource::Make(net::NetLog::Get(),
+                                            net::NetLogSourceType::NONE),
+                absl::nullopt);
+
   mojo::Remote<network::mojom::ResolveHostClient> response_client(
       std::move(pending_response_client));
 
diff --git a/content/browser/direct_sockets/direct_sockets_test_utils.h b/content/browser/direct_sockets/direct_sockets_test_utils.h
index d1b6498..1a5f414 100644
--- a/content/browser/direct_sockets/direct_sockets_test_utils.h
+++ b/content/browser/direct_sockets/direct_sockets_test_utils.h
@@ -43,7 +43,7 @@
   MockHostResolver(const MockHostResolver&) = delete;
   MockHostResolver& operator=(const MockHostResolver&) = delete;
 
-  void ResolveHost(const ::net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const ::net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    ::mojo::PendingRemote<network::mojom::ResolveHostClient>
diff --git a/content/browser/direct_sockets/resolve_host_and_open_socket.cc b/content/browser/direct_sockets/resolve_host_and_open_socket.cc
index 39415d0..1671db77 100644
--- a/content/browser/direct_sockets/resolve_host_and_open_socket.cc
+++ b/content/browser/direct_sockets/resolve_host_and_open_socket.cc
@@ -95,8 +95,10 @@
     is_mdns_name_ = true;
   }
 #endif  // !BUILDFLAG(ENABLE_MDNS)
+  // Intentionally using a HostPortPair because scheme isn't specified.
   resolver_->ResolveHost(
-      net::HostPortPair(*options_->remote_hostname, options_->remote_port),
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair(*options_->remote_hostname, options_->remote_port)),
       net::NetworkIsolationKey::CreateTransient(), std::move(parameters),
       receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(
diff --git a/content/browser/file_system/file_system_url_loader_factory.cc b/content/browser/file_system/file_system_url_loader_factory.cc
index d48bd6a..630061f 100644
--- a/content/browser/file_system/file_system_url_loader_factory.cc
+++ b/content/browser/file_system/file_system_url_loader_factory.cc
@@ -376,7 +376,8 @@
     head->content_length = data_.size();
     head->headers = CreateHttpResponseHeaders(200);
 
-    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                               absl::nullopt);
 
     data_producer_ =
         std::make_unique<mojo::DataPipeProducer>(std::move(producer_handle));
@@ -527,7 +528,7 @@
         // This was an empty file; make sure to call OnReceiveResponse
         // regardless.
         client_->OnReceiveResponse(std::move(head_),
-                                   std::move(consumer_handle_));
+                                   std::move(consumer_handle_), absl::nullopt);
       }
       OnFileWritten(net::OK);
       return;
@@ -570,7 +571,8 @@
         head_->did_mime_sniff = true;
       }
 
-      client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle_));
+      client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle_),
+                                 absl::nullopt);
     }
     remaining_bytes_ -= result;
     DCHECK_GE(remaining_bytes_, 0);
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
index 7e673f9..eaf87e79 100644
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
@@ -20,6 +20,7 @@
 #include "storage/browser/file_system/file_system_operation_runner.h"
 #include "storage/browser/file_system/file_system_url.h"
 #include "storage/common/file_system/file_system_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_error.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_transfer_token.mojom.h"
@@ -281,6 +282,19 @@
     return;
   }
 
+  // URLs from the sandboxed file system must include bucket info, while URLs
+  // from non-sandboxed file systems should not.
+  DCHECK_EQ(parent_url.type() == storage::kFileSystemTypeTemporary,
+            parent_url.bucket().has_value());
+  DCHECK_EQ(child_url.type() == storage::kFileSystemTypeTemporary,
+            child_url.bucket().has_value());
+
+  // Since the types match, either both or neither URL will have bucket info.
+  if (parent_url.bucket() != child_url.bucket()) {
+    std::move(callback).Run(file_system_access_error::Ok(), absl::nullopt);
+    return;
+  }
+
   // Otherwise compare path.
   const base::FilePath& parent_path = parent_url.path();
   const base::FilePath& child_path = child_url.path();
diff --git a/content/browser/file_system_access/file_system_access_file_handle_impl.cc b/content/browser/file_system_access/file_system_access_file_handle_impl.cc
index 505b993..961eaa9 100644
--- a/content/browser/file_system_access/file_system_access_file_handle_impl.cc
+++ b/content/browser/file_system_access/file_system_access_file_handle_impl.cc
@@ -373,6 +373,7 @@
 void FileSystemAccessFileHandleImpl::IsSameEntryImpl(
     IsSameEntryCallback callback,
     FileSystemAccessTransferTokenImpl* other) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!other) {
     std::move(callback).Run(
         file_system_access_error::FromStatus(
@@ -381,24 +382,13 @@
     return;
   }
 
-  if (other->type() != FileSystemAccessPermissionContext::HandleType::kFile) {
-    std::move(callback).Run(file_system_access_error::Ok(), false);
-    return;
-  }
-
-  const storage::FileSystemURL& url1 = url();
-  const storage::FileSystemURL& url2 = other->url();
-
-  // If two URLs are of a different type they are definitely not related.
-  if (url1.type() != url2.type()) {
-    std::move(callback).Run(file_system_access_error::Ok(), false);
-    return;
-  }
-
-  // Otherwise compare path.
-  const base::FilePath& path1 = url1.path();
-  const base::FilePath& path2 = url2.path();
-  std::move(callback).Run(file_system_access_error::Ok(), path1 == path2);
+  // The two handles are the same if they serialize to the same value.
+  auto serialization = manager()->SerializeURL(
+      url(), FileSystemAccessPermissionContext::HandleType::kFile);
+  auto other_serialization =
+      manager()->SerializeURL(other->url(), other->type());
+  std::move(callback).Run(file_system_access_error::Ok(),
+                          serialization == other_serialization);
 }
 
 void FileSystemAccessFileHandleImpl::Transfer(
diff --git a/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc b/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
index 56d98f7..dce5a0a 100644
--- a/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_file_handle_impl_unittest.cc
@@ -90,6 +90,18 @@
     return handle;
   }
 
+  storage::BucketLocator CreateBucketForTesting() {
+    base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>>
+        bucket_future;
+    quota_manager_proxy_->CreateBucketForTesting(
+        test_src_storage_key_, "custom_bucket",
+        blink::mojom::StorageType::kTemporary,
+        base::SequencedTaskRunnerHandle::Get(), bucket_future.GetCallback());
+    auto bucket = bucket_future.Take();
+    EXPECT_TRUE(bucket.ok());
+    return bucket->ToBucketLocator();
+  }
+
  protected:
   void SetupHelper(storage::FileSystemType type, bool is_incognito) {
     ASSERT_TRUE(dir_.CreateUniqueTempDir());
@@ -113,6 +125,8 @@
 
     test_file_url_ = file_system_context_->CreateCrackedFileSystemURL(
         test_src_storage_key_, type, base::FilePath::FromUTF8Unsafe("test"));
+    if (type == storage::kFileSystemTypeTemporary)
+      test_file_url_.SetBucket(CreateBucketForTesting());
 
     ASSERT_EQ(base::File::FILE_OK,
               storage::AsyncFileTestHelper::CreateFile(
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
index 4ccc12b..6d82695 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -25,6 +25,7 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/unguessable_token.h"
 #include "build/build_config.h"
 #include "components/services/storage/public/cpp/buckets/bucket_id.h"
 #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
@@ -54,6 +55,7 @@
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/file_system/file_system_types.h"
 #include "storage/common/file_system/file_system_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_capacity_allocation_host.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_data_transfer_token.mojom.h"
@@ -750,8 +752,80 @@
   return base::FilePath(s);
 }
 
+std::string SerializeURLImpl(const storage::FileSystemURL& url,
+                             FileSystemAccessPermissionContext::HandleType type,
+                             base::FilePath root_permission_path) {
+  FileSystemAccessHandleData data;
+  data.set_handle_type(type == HandleType::kFile
+                           ? FileSystemAccessHandleData::kFile
+                           : FileSystemAccessHandleData::kDirectory);
+
+  if (url.type() == storage::kFileSystemTypeLocal ||
+      url.mount_type() == storage::kFileSystemTypeExternal) {
+    // Files from non-sandboxed file systems should not include bucket info.
+    DCHECK(!url.bucket().has_value());
+
+    // A url can have mount_type = external and type = native local at the same
+    // time. In that case we want to still treat it as an external path.
+    const bool is_external =
+        url.mount_type() == storage::kFileSystemTypeExternal;
+    content::LocalFileData* file_data =
+        is_external ? data.mutable_external() : data.mutable_local();
+
+    base::FilePath url_path = is_external ? url.virtual_path() : url.path();
+    if (root_permission_path.empty())
+      root_permission_path = url_path;
+    file_data->set_root_path(SerializePath(root_permission_path));
+
+    base::FilePath relative_path;
+    // We want `relative_path` to be the path of the file or directory
+    // relative to `root_permission_path`. FilePath::AppendRelativePath gets us
+    // that, but fails if the path we're looking for is equal to the
+    // `root_permission_path`. So special case that case (in which case relative
+    // path would be empty anyway).
+    if (root_permission_path != url_path) {
+      bool relative_path_result =
+          root_permission_path.AppendRelativePath(url_path, &relative_path);
+      DCHECK(relative_path_result);
+    }
+
+    file_data->set_relative_path(SerializePath(relative_path));
+  } else if (url.type() == storage::kFileSystemTypeTemporary) {
+    base::FilePath virtual_path = url.virtual_path();
+    data.mutable_sandboxed()->set_virtual_path(SerializePath(virtual_path));
+    // Files in the sandboxed file system must include bucket info.
+    DCHECK(url.bucket().has_value());
+    if (!url.bucket()->is_default) {
+      data.mutable_sandboxed()->set_bucket_id(url.bucket()->id.value());
+    }
+  } else {
+    NOTREACHED();
+  }
+
+  std::string value;
+  bool success = data.SerializeToString(&value);
+  DCHECK(success);
+  return value;
+}
+
 }  // namespace
 
+std::string FileSystemAccessManagerImpl::SerializeURL(
+    const storage::FileSystemURL& url,
+    HandleType type) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return SerializeURLImpl(url, type,
+                          /*root_permission_path=*/base::FilePath());
+}
+
+std::string FileSystemAccessManagerImpl::SerializeURLWithPermissionRoot(
+    const storage::FileSystemURL& url,
+    HandleType type,
+    const base::FilePath& root_permission_path) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return SerializeURLImpl(url, type, root_permission_path);
+}
+
 void FileSystemAccessManagerImpl::DidResolveForSerializeHandle(
     SerializeHandleCallback callback,
     FileSystemAccessTransferTokenImpl* resolved_token) {
@@ -762,55 +836,9 @@
     return;
   }
 
-  const storage::FileSystemURL& url = resolved_token->url();
-
-  FileSystemAccessHandleData data;
-  data.set_handle_type(resolved_token->type() == HandleType::kFile
-                           ? FileSystemAccessHandleData::kFile
-                           : FileSystemAccessHandleData::kDirectory);
-
-  if (url.type() == storage::kFileSystemTypeLocal ||
-      url.mount_type() == storage::kFileSystemTypeExternal) {
-    // A url can have mount_type = external and type = native local at the same
-    // time. In that case we want to still treat it as an external path.
-    const bool is_external =
-        url.mount_type() == storage::kFileSystemTypeExternal;
-    content::LocalFileData* file_data =
-        is_external ? data.mutable_external() : data.mutable_local();
-
-    base::FilePath url_path = is_external ? url.virtual_path() : url.path();
-    base::FilePath root_path = resolved_token->GetWriteGrant()->GetPath();
-    if (root_path.empty())
-      root_path = url_path;
-
-    file_data->set_root_path(SerializePath(root_path));
-
-    base::FilePath relative_path;
-    // We want `relative_path` to be the path of the file or directory
-    // relative to `root_path`. FilePath::AppendRelativePath gets us that,
-    // but fails if the path we're looking for is equal to the `root_path`.
-    // So special case that case (in which case relative path would be empty
-    // anyway).
-    if (root_path != url_path) {
-      bool relative_path_result =
-          root_path.AppendRelativePath(url_path, &relative_path);
-      DCHECK(relative_path_result);
-    }
-
-    file_data->set_relative_path(SerializePath(relative_path));
-  } else if (url.type() == storage::kFileSystemTypeTemporary) {
-    base::FilePath virtual_path = url.virtual_path();
-    data.mutable_sandboxed()->set_virtual_path(SerializePath(virtual_path));
-    if (url.bucket().has_value() && !url.bucket()->is_default) {
-      data.mutable_sandboxed()->set_bucket_id(url.bucket()->id.value());
-    }
-  } else {
-    NOTREACHED();
-  }
-
-  std::string value;
-  bool success = data.SerializeToString(&value);
-  DCHECK(success);
+  auto value = SerializeURLWithPermissionRoot(
+      resolved_token->url(), resolved_token->type(),
+      resolved_token->GetWriteGrant()->GetPath());
   std::vector<uint8_t> result(value.begin(), value.end());
   std::move(callback).Run(result);
 }
@@ -851,26 +879,28 @@
           DeserializePath(data.sandboxed().virtual_path());
       storage::FileSystemURL url = context()->CreateCrackedFileSystemURL(
           storage_key, storage::kFileSystemTypeTemporary, virtual_path);
+      // Apply bucket information.
+      auto bucket_callback = base::BindOnce(
+          [](storage::FileSystemURL url,
+             base::OnceCallback<void(const storage::FileSystemURL&)> callback,
+             storage::QuotaErrorOr<storage::BucketInfo> result) {
+            if (!result.ok()) {
+              // Drop `token`, and directly return.
+              return;
+            }
+            url.SetBucket(result->ToBucketLocator());
+            std::move(callback).Run(url);
+          },
+          url,
+          base::BindOnce(&FileSystemAccessManagerImpl::
+                             DidGetSandboxedBucketForDeserializeHandle,
+                         weak_factory_.GetWeakPtr(), data, std::move(token)));
       if (!data.sandboxed().has_bucket_id()) {
         // Use the default storage bucket.
-        DidGetSandboxedBucketForDeserializeHandle(data, std::move(token), url);
+        context_->quota_manager_proxy()->UpdateOrCreateBucket(
+            storage::BucketInitParams::ForDefaultBucket(storage_key),
+            base::SequencedTaskRunnerHandle::Get(), std::move(bucket_callback));
       } else {
-        // Apply a custom bucket override.
-        auto bucket_callback = base::BindOnce(
-            [](storage::FileSystemURL url,
-               base::OnceCallback<void(const storage::FileSystemURL&)> callback,
-               storage::QuotaErrorOr<storage::BucketInfo> result) {
-              if (!result.ok()) {
-                // Drop `token`, and directly return.
-                return;
-              }
-              url.SetBucket(result->ToBucketLocator());
-              std::move(callback).Run(url);
-            },
-            url,
-            base::BindOnce(&FileSystemAccessManagerImpl::
-                               DidGetSandboxedBucketForDeserializeHandle,
-                           weak_factory_.GetWeakPtr(), data, std::move(token)));
         context_->quota_manager_proxy()->GetBucketById(
             storage::BucketId::FromUnsafeValue(data.sandboxed().bucket_id()),
             base::SequencedTaskRunnerHandle::Get(), std::move(bucket_callback));
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.h b/content/browser/file_system_access/file_system_access_manager_impl.h
index 111107a..aac2ce5d 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.h
+++ b/content/browser/file_system_access/file_system_access_manager_impl.h
@@ -15,6 +15,7 @@
 #include "base/thread_annotations.h"
 #include "base/threading/sequence_bound.h"
 #include "base/types/pass_key.h"
+#include "base/unguessable_token.h"
 #include "components/download/public/common/quarantine_connection.h"
 #include "components/services/storage/public/cpp/buckets/bucket_info.h"
 #include "components/services/storage/public/cpp/quota_error_or.h"
@@ -35,6 +36,7 @@
 #include "mojo/public/cpp/bindings/unique_receiver_set.h"
 #include "storage/browser/file_system/file_system_operation_runner.h"
 #include "storage/browser/file_system/file_system_url.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_access_handle_host.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_capacity_allocation_host.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_data_transfer_token.mojom.h"
@@ -252,6 +254,11 @@
       mojo::PendingRemote<blink::mojom::FileSystemAccessTransferToken> token,
       ResolvedTokenCallback callback);
 
+  // Generates a unique serialization of a URL, which can be used to check
+  // handles for equality. This is not cryptographically secure.
+  std::string SerializeURL(const storage::FileSystemURL& url,
+                           FileSystemAccessPermissionContext::HandleType type);
+
   base::WeakPtr<FileSystemAccessManagerImpl> AsWeakPtr();
 
   storage::FileSystemContext* context() {
@@ -504,6 +511,14 @@
       GetEntryFromDataTransferTokenCallback token_resolved_callback,
       FileSystemAccessPermissionContext::HandleType file_type);
 
+  // `root_permission_path` is path that the user selected in a file or
+  // directory picker which led to the site having access to this URL. All
+  // permissions related to the URL are based on this path.
+  std::string SerializeURLWithPermissionRoot(
+      const storage::FileSystemURL& url,
+      FileSystemAccessPermissionContext::HandleType type,
+      const base::FilePath& root_permission_path);
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   const scoped_refptr<storage::FileSystemContext> context_;
diff --git a/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc b/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
index 9e82b43..0bcdf465 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "components/services/storage/public/cpp/buckets/bucket_id.h"
 #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
+#include "components/services/storage/public/cpp/buckets/constants.h"
 #include "content/browser/file_system_access/file_system_access_data_transfer_token_impl.h"
 #include "content/browser/file_system_access/file_system_access_directory_handle_impl.h"
 #include "content/browser/file_system_access/file_system_access_file_handle_impl.h"
@@ -46,6 +47,7 @@
 #include "storage/browser/test/mock_special_storage_policy.h"
 #include "storage/browser/test/quota_manager_proxy_sync.h"
 #include "storage/browser/test/test_file_system_context.h"
+#include "storage/common/file_system/file_system_types.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/blob/blob.mojom.h"
@@ -334,11 +336,39 @@
         base::SequencedTaskRunnerHandle::Get(), bucket_future.GetCallback());
     auto bucket = bucket_future.Take();
     EXPECT_TRUE(bucket.ok());
-    LOG(INFO) << "Created bucket "
-              << bucket->ToBucketLocator().id.GetUnsafeValue();
     return bucket->ToBucketLocator();
   }
 
+  storage::BucketLocator CreateSandboxFileSystemAndGetDefaultBucket() {
+    base::test::TestFuture<
+        blink::mojom::FileSystemAccessErrorPtr,
+        mojo::PendingRemote<blink::mojom::FileSystemAccessDirectoryHandle>>
+        future;
+    manager_remote_->GetSandboxedFileSystem(future.GetCallback());
+    blink::mojom::FileSystemAccessErrorPtr get_fs_result;
+    mojo::PendingRemote<blink::mojom::FileSystemAccessDirectoryHandle>
+        directory_remote;
+    std::tie(get_fs_result, directory_remote) = future.Take();
+    EXPECT_EQ(get_fs_result->status, blink::mojom::FileSystemAccessStatus::kOk);
+    mojo::Remote<blink::mojom::FileSystemAccessDirectoryHandle> root(
+        std::move(directory_remote));
+    EXPECT_TRUE(root);
+
+    storage::QuotaManagerProxySync quota_manager_proxy_sync(
+        quota_manager_proxy_.get());
+
+    // Check default bucket exists.
+    storage::QuotaErrorOr<storage::BucketInfo> result =
+        quota_manager_proxy_sync.GetBucket(
+            kTestStorageKey, storage::kDefaultBucketName,
+            blink::mojom::StorageType::kTemporary);
+    EXPECT_TRUE(result.ok());
+    EXPECT_EQ(result->name, storage::kDefaultBucketName);
+    EXPECT_EQ(result->storage_key, kTestStorageKey);
+    EXPECT_GT(result->id.value(), 0);
+    return result->ToBucketLocator();
+  }
+
  protected:
   const GURL kTestURL = GURL("https://example.com/test");
   const blink::StorageKey kTestStorageKey =
@@ -384,32 +414,8 @@
 };
 
 TEST_F(FileSystemAccessManagerImplTest, GetSandboxedFileSystem_CreateBucket) {
-  base::test::TestFuture<
-      blink::mojom::FileSystemAccessErrorPtr,
-      mojo::PendingRemote<blink::mojom::FileSystemAccessDirectoryHandle>>
-      future;
-  manager_remote_->GetSandboxedFileSystem(future.GetCallback());
-  blink::mojom::FileSystemAccessErrorPtr get_fs_result;
-  mojo::PendingRemote<blink::mojom::FileSystemAccessDirectoryHandle>
-      directory_remote;
-  std::tie(get_fs_result, directory_remote) = future.Take();
-  EXPECT_EQ(get_fs_result->status, blink::mojom::FileSystemAccessStatus::kOk);
-  mojo::Remote<blink::mojom::FileSystemAccessDirectoryHandle> root(
-      std::move(directory_remote));
-  ASSERT_TRUE(root);
-
-  storage::QuotaManagerProxySync quota_manager_proxy_sync(
-      quota_manager_proxy_.get());
-
   // Check default bucket exists.
-  storage::QuotaErrorOr<storage::BucketInfo> result =
-      quota_manager_proxy_sync.GetBucket(kTestStorageKey,
-                                         storage::kDefaultBucketName,
-                                         blink::mojom::StorageType::kTemporary);
-  EXPECT_TRUE(result.ok());
-  EXPECT_EQ(result->name, storage::kDefaultBucketName);
-  EXPECT_EQ(result->storage_key, kTestStorageKey);
-  EXPECT_GT(result->id.value(), 0);
+  ASSERT_TRUE(CreateSandboxFileSystemAndGetDefaultBucket().is_default);
 }
 
 TEST_F(FileSystemAccessManagerImplTest, GetSandboxedFileSystem_CustomBucket) {
@@ -753,9 +759,11 @@
 
 TEST_F(FileSystemAccessManagerImplTest,
        SerializeHandle_SandboxedFile_DefaultBucket) {
+  auto default_bucket = CreateSandboxFileSystemAndGetDefaultBucket();
   auto test_file_url = file_system_context_->CreateCrackedFileSystemURL(
       kTestStorageKey, storage::kFileSystemTypeTemporary,
       base::FilePath::FromUTF8Unsafe("test/foo/bar"));
+  test_file_url.SetBucket(default_bucket);
   FileSystemAccessFileHandleImpl file(manager_.get(), kBindingContext,
                                       test_file_url, {ask_grant_, ask_grant_});
   mojo::PendingRemote<blink::mojom::FileSystemAccessTransferToken> token_remote;
@@ -765,7 +773,7 @@
   FileSystemAccessTransferTokenImpl* token =
       SerializeAndDeserializeToken(std::move(token_remote));
   ASSERT_TRUE(token);
-  ASSERT_FALSE(token->url().bucket().has_value());
+  ASSERT_TRUE(token->url().bucket().has_value());
   EXPECT_EQ(test_file_url, token->url());
   EXPECT_EQ(HandleType::kFile, token->type());
 
@@ -806,9 +814,11 @@
 
 TEST_F(FileSystemAccessManagerImplTest,
        SerializeHandle_SandboxedDirectory_DefaultBucket) {
+  auto default_bucket = CreateSandboxFileSystemAndGetDefaultBucket();
   auto test_file_url = file_system_context_->CreateCrackedFileSystemURL(
       kTestStorageKey, storage::kFileSystemTypeTemporary,
       base::FilePath::FromUTF8Unsafe("hello/world/"));
+  test_file_url.SetBucket(default_bucket);
   FileSystemAccessDirectoryHandleImpl directory(
       manager_.get(), kBindingContext, test_file_url, {ask_grant_, ask_grant_});
   mojo::PendingRemote<blink::mojom::FileSystemAccessTransferToken> token_remote;
@@ -818,7 +828,7 @@
   FileSystemAccessTransferTokenImpl* token =
       SerializeAndDeserializeToken(std::move(token_remote));
   ASSERT_TRUE(token);
-  ASSERT_FALSE(token->url().bucket().has_value());
+  ASSERT_TRUE(token->url().bucket().has_value());
   EXPECT_EQ(test_file_url, token->url());
   EXPECT_EQ(HandleType::kDirectory, token->type());
 
diff --git a/content/browser/file_system_access/file_system_access_write_lock_manager.cc b/content/browser/file_system_access/file_system_access_write_lock_manager.cc
index f8d7533..41a95cf0 100644
--- a/content/browser/file_system_access/file_system_access_write_lock_manager.cc
+++ b/content/browser/file_system_access/file_system_access_write_lock_manager.cc
@@ -18,42 +18,27 @@
 // static
 EntryLocator EntryLocator::FromFileSystemURL(
     const storage::FileSystemURL& url) {
+  absl::optional<storage::BucketLocator> maybe_bucket_locator = absl::nullopt;
   EntryPathType path_type;
   switch (url.type()) {
     case storage::kFileSystemTypeLocal:
     case storage::kFileSystemTypeTest:
+      DCHECK(!url.bucket());
       path_type = EntryPathType::kLocal;
       break;
     case storage::kFileSystemTypeTemporary:
+      // URLs from the sandboxed file system must include bucket information.
+      DCHECK(url.bucket());
+      maybe_bucket_locator = url.bucket().value();
       path_type = EntryPathType::kSandboxed;
       break;
     default:
+      DCHECK(!url.bucket());
       DCHECK_EQ(url.mount_type(),
                 storage::FileSystemType::kFileSystemTypeExternal);
       path_type = EntryPathType::kExternal;
   }
-  base::FilePath path =
-      path_type == EntryPathType::kLocal ? url.path() : url.virtual_path();
-  // Sandboxed file system URLs may or may not have a bucket locator. If they
-  // don't, construct a dummy bucket locator and populate it with the URL's
-  // storage key to ensure that files of the same relative path in different
-  // sandboxed file systems represent distinct locks. Note that files in the
-  // same file system can use different locks if one has bucket information and
-  // one does not, though we don't expect this to happen in practice...
-  //
-  // TODO(crbug.com/1329927): If/when we require all FileSystemURLs in sandboxed
-  // file systems to have a bucket locator, replace this logic with a DCHECK.
-  absl::optional<storage::BucketLocator> maybe_bucket_locator = absl::nullopt;
-  if (path_type == EntryPathType::kSandboxed) {
-    storage::BucketLocator bucket_locator;
-    if (url.bucket().has_value()) {
-      bucket_locator = url.bucket().value();
-    } else {
-      bucket_locator.storage_key = url.storage_key();
-    }
-    maybe_bucket_locator.emplace(std::move(bucket_locator));
-  }
-  return EntryLocator(path_type, path, maybe_bucket_locator);
+  return EntryLocator(path_type, url.path(), maybe_bucket_locator);
 }
 
 EntryLocator::EntryLocator(
@@ -64,7 +49,8 @@
   // Files in the sandboxed file system must have a `bucket_locator`. See the
   // comment in `EntryLocator::FromFileSystemURL()`. Files outside of the
   // sandboxed file system should not be keyed by StorageKey to ensure that
-  // separate sites cannot hold their own exclusive locks to the same file.
+  // locks apply across sites. i.e. separate sites cannot hold their own
+  // exclusive locks to the same file.
   DCHECK_EQ(type == EntryPathType::kSandboxed, bucket_locator.has_value());
 }
 EntryLocator::EntryLocator(const EntryLocator&) = default;
diff --git a/content/browser/file_system_access/file_system_access_write_lock_manager_unittest.cc b/content/browser/file_system_access/file_system_access_write_lock_manager_unittest.cc
index 06075cee..c165a3b 100644
--- a/content/browser/file_system_access/file_system_access_write_lock_manager_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_write_lock_manager_unittest.cc
@@ -7,9 +7,8 @@
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/test/task_environment.h"
-#include "base/test/test_future.h"
+#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
 #include "content/browser/file_system_access/file_system_access_manager_impl.h"
-#include "content/browser/file_system_access/file_system_access_transfer_token_impl.h"
 #include "content/public/test/browser_task_environment.h"
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/file_system/external_mount_points.h"
@@ -18,9 +17,6 @@
 #include "storage/browser/test/test_file_system_context.h"
 #include "storage/common/file_system/file_system_types.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/mojom/file_system_access/file_system_access_data_transfer_token.mojom.h"
-#include "third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom.h"
-#include "third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom.h"
 
 namespace content {
 
@@ -140,6 +136,11 @@
  protected:
   const blink::StorageKey kTestStorageKey =
       blink::StorageKey::CreateFromStringForTesting("https://example.com/test");
+  const storage::BucketLocator kTestBucketLocator =
+      storage::BucketLocator(storage::BucketId(1),
+                             kTestStorageKey,
+                             blink::mojom::StorageType::kTemporary,
+                             /*is_default=*/false);
 
   BrowserTaskEnvironment task_environment_;
 
@@ -192,6 +193,7 @@
   auto url = file_system_context_->CreateCrackedFileSystemURL(
       kTestStorageKey, storage::kFileSystemTypeTemporary,
       base::FilePath::FromUTF8Unsafe("test/foo/bar"));
+  url.SetBucket(kTestBucketLocator);
 
   {
     auto exclusive_lock =
@@ -213,12 +215,44 @@
   // BucketLocator is set.
   const blink::StorageKey kOtherStorageKey =
       blink::StorageKey::CreateFromStringForTesting("https://foo.com/test");
+  const auto path = base::FilePath::FromUTF8Unsafe("test/foo/bar");
   auto url1 = file_system_context_->CreateCrackedFileSystemURL(
-      kOtherStorageKey, storage::kFileSystemTypeTemporary,
-      base::FilePath::FromUTF8Unsafe("test/foo/bar"));
+      kOtherStorageKey, storage::kFileSystemTypeTemporary, path);
+  url1.SetBucket(kTestBucketLocator);
   auto url2 = file_system_context_->CreateCrackedFileSystemURL(
-      kTestStorageKey, storage::kFileSystemTypeTemporary,
-      base::FilePath::FromUTF8Unsafe("test/foo/bar"));
+      kTestStorageKey, storage::kFileSystemTypeTemporary, path);
+  const storage::BucketLocator kOtherBucketLocator(
+      storage::BucketId(2), kOtherStorageKey,
+      blink::mojom::StorageType::kTemporary,
+      /*is_default=*/false);
+  url2.SetBucket(kOtherBucketLocator);
+
+  // Take a lock on the file in the first file system.
+  auto exclusive_lock1 =
+      manager_->TakeWriteLock(url1, WriteLockType::kExclusive);
+  ASSERT_TRUE(exclusive_lock1);
+  ASSERT_FALSE(manager_->TakeWriteLock(url1, WriteLockType::kExclusive));
+
+  // Can still take a lock on the file in the second file system.
+  auto exclusive_lock2 =
+      manager_->TakeWriteLock(url2, WriteLockType::kExclusive);
+  ASSERT_TRUE(exclusive_lock2);
+  ASSERT_FALSE(manager_->TakeWriteLock(url2, WriteLockType::kExclusive));
+}
+
+TEST_F(FileSystemAccessWriteLockManagerTest, SandboxedFilesDifferentBucket) {
+  // Sandboxed files of the same relative path do not lock across buckets.
+  const auto path = base::FilePath::FromUTF8Unsafe("test/foo/bar");
+  auto url1 = file_system_context_->CreateCrackedFileSystemURL(
+      kTestStorageKey, storage::kFileSystemTypeTemporary, path);
+  url1.SetBucket(kTestBucketLocator);
+  auto url2 = file_system_context_->CreateCrackedFileSystemURL(
+      kTestStorageKey, storage::kFileSystemTypeTemporary, path);
+  const storage::BucketLocator kOtherBucketLocator(
+      storage::BucketId(2), kTestStorageKey,
+      blink::mojom::StorageType::kTemporary,
+      /*is_default=*/false);
+  url2.SetBucket(kOtherBucketLocator);
 
   // Take a lock on the file in the first file system.
   auto exclusive_lock1 =
@@ -317,9 +351,11 @@
   auto parent_path = base::FilePath::FromUTF8Unsafe("test/foo/bar");
   auto parent_url = file_system_context_->CreateCrackedFileSystemURL(
       kTestStorageKey, storage::kFileSystemTypeTemporary, parent_path);
+  parent_url.SetBucket(kTestBucketLocator);
   auto child_url = file_system_context_->CreateCrackedFileSystemURL(
       kTestStorageKey, storage::kFileSystemTypeTemporary,
       parent_path.Append(FILE_PATH_LITERAL("child")));
+  child_url.SetBucket(kTestBucketLocator);
 
   AssertAncestorLockBehavior(parent_url, child_url);
 }
diff --git a/content/browser/first_party_sets/database/first_party_sets_database.cc b/content/browser/first_party_sets/database/first_party_sets_database.cc
index 61e8098..9a2851d 100644
--- a/content/browser/first_party_sets/database/first_party_sets_database.cc
+++ b/content/browser/first_party_sets/database/first_party_sets_database.cc
@@ -15,7 +15,6 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "content/browser/first_party_sets/first_party_set_parser.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/first_party_set_entry.h"
 #include "sql/database.h"
@@ -35,6 +34,16 @@
 const char kRunCountKey[] = "run_count";
 
 [[nodiscard]] bool InitSchema(sql::Database& db) {
+  static constexpr char kPublicSetsSql[] =
+      "CREATE TABLE IF NOT EXISTS public_sets("
+      "site TEXT NOT NULL,"
+      "primary_site TEXT NOT NULL,"
+      "site_type INTEGER NOT NULL,"
+      "PRIMARY KEY(site)"
+      ")WITHOUT ROWID";
+  if (!db.Execute(kPublicSetsSql))
+    return false;
+
   static constexpr char kBrowserContextSitesToClearSql[] =
       "CREATE TABLE IF NOT EXISTS browser_context_sites_to_clear("
       "browser_context_id TEXT NOT NULL,"
@@ -82,6 +91,16 @@
   base::UmaHistogramEnumeration("FirstPartySets.Database.InitStatus", status);
 }
 
+absl::optional<net::SiteType> DeserializeSiteType(int value) {
+  switch (value) {
+    case static_cast<int>(net::SiteType::kPrimary):
+      return net::SiteType::kPrimary;
+    case static_cast<int>(net::SiteType::kAssociated):
+      return net::SiteType::kAssociated;
+  }
+  return absl::nullopt;
+}
+
 }  // namespace
 
 FirstPartySetsDatabase::FirstPartySetsDatabase(base::FilePath db_path)
@@ -93,6 +112,41 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
+bool FirstPartySetsDatabase::SetPublicSets(
+    const FirstPartySetsDatabase::FlattenedSets& sets) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!LazyInit())
+    return false;
+
+  sql::Transaction transaction(db_.get());
+  if (!transaction.Begin())
+    return false;
+
+  static constexpr char kDeleteSql[] = "DELETE FROM public_sets";
+  sql::Statement delete_statement(
+      db_->GetCachedStatement(SQL_FROM_HERE, kDeleteSql));
+  if (!delete_statement.Run())
+    return false;
+
+  for (const auto& [site, entry] : sets) {
+    DCHECK(!site.opaque());
+    DCHECK(!entry.primary().opaque());
+    static constexpr char kInsertSql[] =
+        "INSERT INTO public_sets(site,primary_site,site_type)"
+        "VALUES(?,?,?)";
+    sql::Statement insert_statement(
+        db_->GetCachedStatement(SQL_FROM_HERE, kInsertSql));
+    insert_statement.BindString(0, site.Serialize());
+    insert_statement.BindString(1, entry.primary().Serialize());
+    insert_statement.BindInt(2, static_cast<int>(entry.site_type()));
+
+    if (!insert_statement.Run())
+      return false;
+  }
+  return transaction.Commit();
+}
+
 bool FirstPartySetsDatabase::InsertSitesToClear(
     const std::string& browser_context_id,
     const base::flat_set<net::SchemefulSite>& sites) {
@@ -162,9 +216,10 @@
 
   static constexpr char kDeleteSql[] =
       "DELETE FROM policy_modifications WHERE browser_context_id=?";
-  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kDeleteSql));
-  statement.BindString(0, browser_context_id);
-  if (!statement.Run())
+  sql::Statement delete_statement(
+      db_->GetCachedStatement(SQL_FROM_HERE, kDeleteSql));
+  delete_statement.BindString(0, browser_context_id);
+  if (!delete_statement.Run())
     return false;
 
   for (const auto& [site, owner] : modificatons) {
@@ -172,22 +227,60 @@
     static constexpr char kInsertSql[] =
         "INSERT INTO policy_modifications(browser_context_id,site,site_owner)"
         "VALUES(?,?,?)";
-    sql::Statement statement(
+    sql::Statement insert_statement(
         db_->GetCachedStatement(SQL_FROM_HERE, kInsertSql));
-    statement.BindString(0, browser_context_id);
-    statement.BindString(1, site.Serialize());
+    insert_statement.BindString(0, browser_context_id);
+    insert_statement.BindString(1, site.Serialize());
     if (owner.has_value()) {
-      statement.BindString(2, owner.value().primary().Serialize());
+      insert_statement.BindString(2, owner.value().primary().Serialize());
     } else {
-      statement.BindNull(2);
+      insert_statement.BindNull(2);
     }
 
-    if (!statement.Run())
+    if (!insert_statement.Run())
       return false;
   }
   return transaction.Commit();
 }
 
+FirstPartySetsDatabase::FlattenedSets FirstPartySetsDatabase::GetPublicSets() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!LazyInit())
+    return {};
+
+  std::vector<std::pair<net::SchemefulSite, net::FirstPartySetEntry>> results;
+  static constexpr char kSelectSql[] =
+      "SELECT site,primary_site,site_type FROM public_sets";
+  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSelectSql));
+
+  while (statement.Step()) {
+    absl::optional<net::SchemefulSite> site =
+        FirstPartySetParser::CanonicalizeRegisteredDomain(
+            statement.ColumnString(0), /*emit_errors=*/false);
+
+    absl::optional<net::SchemefulSite> primary =
+        FirstPartySetParser::CanonicalizeRegisteredDomain(
+            statement.ColumnString(1), /*emit_errors=*/false);
+
+    absl::optional<net::SiteType> site_type =
+        DeserializeSiteType(statement.ColumnInt(2));
+
+    // TODO(crbug.com/1314039): Invalid entries should be rare case but
+    // possible. Consider deleting them from DB.
+    if (site.has_value() && primary.has_value() && site_type.has_value()) {
+      results.emplace_back(
+          std::move(site.value()),
+          net::FirstPartySetEntry(primary.value(), site_type.value(),
+                                  /*site_index=*/absl::nullopt));
+    }
+  }
+  if (!statement.Succeeded())
+    return {};
+
+  return results;
+}
+
 std::vector<net::SchemefulSite> FirstPartySetsDatabase::FetchSitesToClear(
     const std::string& browser_context_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/browser/first_party_sets/database/first_party_sets_database.h b/content/browser/first_party_sets/database/first_party_sets_database.h
index 9c1adf3..ee865dd7 100644
--- a/content/browser/first_party_sets/database/first_party_sets_database.h
+++ b/content/browser/first_party_sets/database/first_party_sets_database.h
@@ -13,6 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
+#include "content/browser/first_party_sets/first_party_set_parser.h"
 #include "content/common/content_export.h"
 #include "sql/meta_table.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -37,6 +38,8 @@
 // singleton only and is already sequence-safe.
 class CONTENT_EXPORT FirstPartySetsDatabase {
  public:
+  using FlattenedSets = FirstPartySetParser::SetsMap;
+
   // These values are persisted to logs. Entries should not be renumbered and
   // numeric values should never be reused.
   enum class InitStatus {
@@ -64,6 +67,11 @@
   FirstPartySetsDatabase& operator=(const FirstPartySetsDatabase&&) = delete;
   ~FirstPartySetsDatabase();
 
+  // Stores the public First-Party Sets into database, and returns true on
+  // success.  Note that calling this method will wipe out the pre-existing
+  // data in the table.
+  [[nodiscard]] bool SetPublicSets(const FlattenedSets& sets);
+
   // Stores the `sites` to be cleared for the `browser_context_id` into
   // database, and returns true on success.
   [[nodiscard]] bool InsertSitesToClear(
@@ -84,6 +92,11 @@
                            absl::optional<net::FirstPartySetEntry>>&
           modificatons);
 
+  // TODO(crbug.com/1219656): Consider returning absl::nullopt for all the
+  // fetching methods when having query errors
+
+  [[nodiscard]] FlattenedSets GetPublicSets();
+
   // Gets the list of sites to clear for the `browser_context_id`.
   [[nodiscard]] std::vector<net::SchemefulSite> FetchSitesToClear(
       const std::string& browser_context_id);
diff --git a/content/browser/first_party_sets/database/first_party_sets_database_unittest.cc b/content/browser/first_party_sets/database/first_party_sets_database_unittest.cc
index 44406dd..f9519e0 100644
--- a/content/browser/first_party_sets/database/first_party_sets_database_unittest.cc
+++ b/content/browser/first_party_sets/database/first_party_sets_database_unittest.cc
@@ -25,7 +25,7 @@
 
 namespace {
 
-static const size_t kTableCount = 4u;
+static const size_t kTableCount = 5u;
 
 int VersionFromMetaTable(sql::Database& db) {
   // Get version.
@@ -65,6 +65,12 @@
     return path;
   }
 
+  size_t CountPublicSetsEntries(sql::Database* db) {
+    size_t size = 0;
+    EXPECT_TRUE(sql::test::CountTableRows(db, "public_sets", &size));
+    return size;
+  }
+
   size_t CountBrowserContextSitesToClearEntries(sql::Database* db) {
     size_t size = 0;
     EXPECT_TRUE(
@@ -118,13 +124,15 @@
   // Create a db handle to the existing db file to verify schemas.
   sql::Database db;
   EXPECT_TRUE(db.Open(db_path()));
-  // [policy_modifications], [browser_context_sites_to_clear],
+  // [public_sets], [policy_modifications], [browser_context_sites_to_clear],
   // [browser_contexts_cleared], and [meta].
   EXPECT_EQ(kTableCount, sql::test::CountSQLTables(&db));
   EXPECT_EQ(1, VersionFromMetaTable(db));
   // [idx_marked_at_run_sites], [idx_cleared_at_run_browser_contexts], and
   // [sqlite_autoindex_meta_1].
   EXPECT_EQ(3u, sql::test::CountSQLIndices(&db));
+  // `site`, `primary`, `site_type`.
+  EXPECT_EQ(3u, sql::test::CountTableColumns(&db, "public_sets"));
   // `browser_context_id`, `site`, `marked_at_run`.
   EXPECT_EQ(
       3u, sql::test::CountTableColumns(&db, "browser_context_sites_to_clear"));
@@ -132,6 +140,7 @@
   EXPECT_EQ(2u, sql::test::CountTableColumns(&db, "browser_contexts_cleared"));
   // `browser_context_id`, `site`, `site_owner`.
   EXPECT_EQ(3u, sql::test::CountTableColumns(&db, "policy_modifications"));
+  EXPECT_EQ(0u, CountPublicSetsEntries(&db));
   EXPECT_EQ(0u, CountBrowserContextSitesToClearEntries(&db));
   EXPECT_EQ(0u, CountBrowserContextsClearedEntries(&db));
   EXPECT_EQ(0u, CountPolicyModificationsEntries(&db));
@@ -150,6 +159,7 @@
   sql::Database db;
   EXPECT_TRUE(db.Open(db_path()));
   EXPECT_EQ(kTableCount, sql::test::CountSQLTables(&db));
+  EXPECT_EQ(2u, CountPublicSetsEntries(&db));
   EXPECT_EQ(1, VersionFromMetaTable(db));
   EXPECT_EQ(2u, CountBrowserContextSitesToClearEntries(&db));
   EXPECT_EQ(1u, CountBrowserContextsClearedEntries(&db));
@@ -176,6 +186,7 @@
   EXPECT_TRUE(db.Open(db_path()));
   EXPECT_EQ(kTableCount, sql::test::CountSQLTables(&db));
   EXPECT_EQ(0, VersionFromMetaTable(db));
+  EXPECT_EQ(2u, CountPublicSetsEntries(&db));
   EXPECT_EQ(2u, CountBrowserContextSitesToClearEntries(&db));
   EXPECT_EQ(1u, CountBrowserContextsClearedEntries(&db));
   EXPECT_EQ(2u, CountPolicyModificationsEntries(&db));
@@ -200,6 +211,7 @@
   EXPECT_TRUE(db.Open(db_path()));
   EXPECT_EQ(kTableCount, sql::test::CountSQLTables(&db));
   EXPECT_EQ(2, VersionFromMetaTable(db));
+  EXPECT_EQ(2u, CountPublicSetsEntries(&db));
   EXPECT_EQ(2u, CountBrowserContextSitesToClearEntries(&db));
   EXPECT_EQ(1u, CountBrowserContextsClearedEntries(&db));
   EXPECT_EQ(2u, CountPolicyModificationsEntries(&db));
@@ -228,6 +240,105 @@
                                 1);
 }
 
+TEST_F(FirstPartySetsDatabaseTest, SetPublicSets_NoPreExistingDB) {
+  const std::string site = "https://aaa.test";
+  const std::string primary = "https://bbb.test";
+
+  FirstPartySetsDatabase::FlattenedSets input = {
+      {net::SchemefulSite(GURL(site)),
+       net::FirstPartySetEntry(net::SchemefulSite(GURL(primary)),
+                               net::SiteType::kAssociated, absl::nullopt)},
+      {net::SchemefulSite(GURL(primary)),
+       net::FirstPartySetEntry(net::SchemefulSite(GURL(primary)),
+                               net::SiteType::kPrimary, absl::nullopt)}};
+
+  OpenDatabase();
+  // Trigger the lazy-initialization.
+  EXPECT_TRUE(db()->SetPublicSets(input));
+  CloseDatabase();
+
+  sql::Database db;
+  EXPECT_TRUE(db.Open(db_path()));
+  EXPECT_EQ(2u, CountPublicSetsEntries(&db));
+
+  static constexpr char kSelectSql[] =
+      "SELECT site,primary_site,site_type FROM public_sets";
+  sql::Statement s(db.GetUniqueStatement(kSelectSql));
+  EXPECT_TRUE(s.Step());
+  EXPECT_EQ(site, s.ColumnString(0));
+  EXPECT_EQ(primary, s.ColumnString(1));
+  EXPECT_EQ(1, s.ColumnInt(2));
+
+  EXPECT_TRUE(s.Step());
+  EXPECT_EQ(primary, s.ColumnString(0));
+  EXPECT_EQ(primary, s.ColumnString(1));
+  EXPECT_EQ(0, s.ColumnInt(2));
+
+  EXPECT_FALSE(s.Step());
+}
+
+TEST_F(FirstPartySetsDatabaseTest, SetPublicSets_PreExistingDB) {
+  ASSERT_TRUE(
+      sql::test::CreateDatabaseFromSQL(db_path(), GetSqlFilePath("v1.sql")));
+
+  // Verify data in the pre-existing DB.
+  {
+    sql::Database db;
+    ASSERT_TRUE(db.Open(db_path()));
+    ASSERT_EQ(kTableCount, sql::test::CountSQLTables(&db));
+    ASSERT_EQ(2u, CountPublicSetsEntries(&db));
+
+    static constexpr char kSelectSql[] =
+        "SELECT site,primary_site,site_type FROM public_sets";
+    sql::Statement s(db.GetUniqueStatement(kSelectSql));
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ("https://aaa.test", s.ColumnString(0));
+    ASSERT_EQ("https://bbb.test", s.ColumnString(1));
+    ASSERT_EQ(1, s.ColumnInt(2));
+
+    ASSERT_TRUE(s.Step());
+    ASSERT_EQ("https://bbb.test", s.ColumnString(0));
+    ASSERT_EQ("https://bbb.test", s.ColumnString(1));
+    ASSERT_EQ(0, s.ColumnInt(2));
+  }
+
+  const std::string site = "https://site1.test";
+  const std::string primary = "https://site2.test";
+
+  FirstPartySetsDatabase::FlattenedSets input = {
+      {net::SchemefulSite(GURL(site)),
+       net::FirstPartySetEntry(net::SchemefulSite(GURL(primary)),
+                               net::SiteType::kAssociated, absl::nullopt)},
+      {net::SchemefulSite(GURL(primary)),
+       net::FirstPartySetEntry(net::SchemefulSite(GURL(primary)),
+                               net::SiteType::kPrimary, absl::nullopt)}};
+
+  OpenDatabase();
+  // Trigger the lazy-initialization.
+  EXPECT_TRUE(db()->SetPublicSets(input));
+  CloseDatabase();
+
+  // Verify the inserted data overwrote the pre-existing data.
+  sql::Database db;
+  EXPECT_TRUE(db.Open(db_path()));
+  EXPECT_EQ(2u, CountPublicSetsEntries(&db));
+
+  static constexpr char kSelectSql[] =
+      "SELECT site,primary_site,site_type FROM public_sets";
+  sql::Statement s(db.GetUniqueStatement(kSelectSql));
+  EXPECT_TRUE(s.Step());
+  EXPECT_EQ(site, s.ColumnString(0));
+  EXPECT_EQ(primary, s.ColumnString(1));
+  EXPECT_EQ(1, s.ColumnInt(2));
+
+  EXPECT_TRUE(s.Step());
+  EXPECT_EQ(primary, s.ColumnString(0));
+  EXPECT_EQ(primary, s.ColumnString(1));
+  EXPECT_EQ(0, s.ColumnInt(2));
+
+  EXPECT_FALSE(s.Step());
+}
+
 TEST_F(FirstPartySetsDatabaseTest, InsertSitesToClear_NoPreExistingDB) {
   std::vector<net::SchemefulSite> input = {
       net::SchemefulSite(GURL("https://example1.test")),
@@ -300,7 +411,7 @@
   // Verify the inserted data.
   sql::Database db;
   EXPECT_TRUE(db.Open(db_path()));
-  EXPECT_EQ(kTableCount, CountBrowserContextSitesToClearEntries(&db));
+  EXPECT_EQ(4u, CountBrowserContextSitesToClearEntries(&db));
 
   const char kSelectSql[] =
       "SELECT site, marked_at_run FROM browser_context_sites_to_clear "
@@ -649,4 +760,31 @@
   EXPECT_THAT(db()->FetchPolicyModifications("b2"), res);
 }
 
+TEST_F(FirstPartySetsDatabaseTest, GetPublicSets_NoPreExistingDB) {
+  OpenDatabase();
+  EXPECT_THAT(db()->GetPublicSets(), IsEmpty());
+}
+
+TEST_F(FirstPartySetsDatabaseTest, GetPublicSets) {
+  ASSERT_TRUE(
+      sql::test::CreateDatabaseFromSQL(db_path(), GetSqlFilePath("v1.sql")));
+
+  // Verify data in the pre-existing DB.
+  {
+    sql::Database db;
+    EXPECT_TRUE(db.Open(db_path()));
+    EXPECT_EQ(2u, CountPublicSetsEntries(&db));
+  }
+  FirstPartySetsDatabase::FlattenedSets res = {
+      {net::SchemefulSite(GURL("https://aaa.test")),
+       net::FirstPartySetEntry({net::SchemefulSite(GURL("https://bbb.test"))},
+                               net::SiteType::kAssociated, absl::nullopt)},
+      {net::SchemefulSite(GURL("https://bbb.test")),
+       net::FirstPartySetEntry({net::SchemefulSite(GURL("https://bbb.test"))},
+                               net::SiteType::kPrimary, absl::nullopt)},
+  };
+  OpenDatabase();
+  EXPECT_THAT(db()->GetPublicSets(), res);
+}
+
 }  // namespace content
\ No newline at end of file
diff --git a/content/browser/first_party_sets/first_party_set_parser_unittest.cc b/content/browser/first_party_sets/first_party_set_parser_unittest.cc
index 7b0383785..9b2b67d 100644
--- a/content/browser/first_party_sets/first_party_set_parser_unittest.cc
+++ b/content/browser/first_party_sets/first_party_set_parser_unittest.cc
@@ -6,9 +6,6 @@
 
 #include <sstream>
 
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/json/json_reader.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/first_party_set_entry.h"
@@ -437,6 +434,27 @@
               Pair(IsEmpty(), IsEmpty()));
 }
 
+TEST(FirstPartySetParser, Rejects_NondisjointCcTLDAliases) {
+  // These two sets overlap only via a ccTLD variant.
+  std::istringstream stream(
+      "{"                                         //
+      "\"owner\": \"https://example.test\","      //
+      "\"members\": [\"https://member.test1\"],"  //
+      "\"ccTLDs\": {"                             //
+      "\"https://member.test1\": [\"https://member.cctld\"],"
+      "}"                                                     //
+      "}\n"                                                   //
+      "{"                                                     //
+      "\"owner\": \"https://foo.test\","                      //
+      "\"members\": [\"https://member.test2\"],"              //
+      "\"ccTLDs\": {"                                         //
+      "\"https://member.test2\": [\"https://member.cctld\"]"  //
+      "}"                                                     //
+      "}");
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromStream(stream),
+              Pair(IsEmpty(), IsEmpty()));
+}
+
 TEST(FirstPartySetParser, SerializeFirstPartySets) {
   EXPECT_EQ(R"({"https://member1.test":"https://example1.test"})",
             FirstPartySetParser::SerializeFirstPartySets(
diff --git a/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc b/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
index b11b05e..b64e23b5 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_database_helper.cc
@@ -23,8 +23,9 @@
     const FirstPartySetsHandlerDatabaseHelper::PolicyCustomization&
         policy_sets) {
   absl::optional<net::FirstPartySetEntry> owner;
-  if (const auto it = policy_sets.find(site); it != policy_sets.end()) {
-    owner = it->second;
+  if (const auto policy_it = policy_sets.find(site);
+      policy_it != policy_sets.end()) {
+    owner = policy_it->second;
   } else if (const auto it = sets.find(site); it != sets.end()) {
     owner = it->second;
   }
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index 93733f0..ddf4fb4a 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -13,8 +13,10 @@
 #include <vector>
 
 #include "base/callback_helpers.h"
+#include "base/check.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
+#include "base/json/json_writer.h"
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
@@ -759,6 +761,38 @@
       kSellerDebugWinReportBaseUrl, kPostAuctionSignalsPlaceholder);
 }
 
+// Represents an entry in trusted bidding signal's `perInterestGroupData` field.
+struct BiddingSignalsPerInterestGroupData {
+  std::string interest_group_name;
+  absl::optional<base::flat_map<std::string, double>> priority_vector;
+};
+
+// Creates a trusted bidding signals response body with the provided data.
+std::string MakeBiddingSignalsWithPerInterestGroupData(
+    std::vector<BiddingSignalsPerInterestGroupData> per_interest_group_data) {
+  base::Value::Dict per_interest_group_dict;
+  for (const auto& data : per_interest_group_data) {
+    base::Value::Dict interest_group_dict;
+    if (data.priority_vector) {
+      base::Value::Dict priority_vector;
+      for (const auto& pair : *data.priority_vector) {
+        priority_vector.Set(pair.first, pair.second);
+      }
+      interest_group_dict.Set("priorityVector", std::move(priority_vector));
+    }
+    per_interest_group_dict.Set(data.interest_group_name,
+                                std::move(interest_group_dict));
+  }
+
+  base::Value::Dict bidding_signals_dict;
+  bidding_signals_dict.Set("perInterestGroupData",
+                           std::move(per_interest_group_dict));
+
+  std::string bidding_signals_string;
+  CHECK(base::JSONWriter::Write(bidding_signals_dict, &bidding_signals_string));
+  return bidding_signals_string;
+}
+
 // Returns a report URL with given parameters for reportWin(), with post auction
 // signals included in the URL
 const GURL ReportWinUrl(
@@ -967,6 +1001,11 @@
       PrivateAggregationRequests pa_requests = {}) {
     WaitForGenerateBid();
 
+    base::RunLoop run_loop;
+    generate_bid_client_->OnBiddingSignalsReceived(
+        /*priority_vector=*/{}, run_loop.QuitClosure());
+    run_loop.Run();
+
     if (!bid.has_value()) {
       generate_bid_client_->OnGenerateBidComplete(
           /*bid=*/nullptr,
@@ -1748,14 +1787,16 @@
       std::vector<std::string> trusted_bidding_signals_keys,
       absl::optional<GURL> ad_url,
       absl::optional<std::vector<GURL>> ad_component_urls = absl::nullopt) {
-    std::vector<blink::InterestGroup::Ad> ads;
+    absl::optional<std::vector<blink::InterestGroup::Ad>> ads;
     // Give only kBidder1 an InterestGroupAd ad with non-empty metadata, to
     // better test the `ad_metadata` output.
     if (ad_url) {
+      ads.emplace();
       if (owner == kBidder1) {
-        ads.emplace_back(blink::InterestGroup::Ad(*ad_url, R"({"ads": true})"));
+        ads->emplace_back(
+            blink::InterestGroup::Ad(*ad_url, R"({"ads": true})"));
       } else {
-        ads.emplace_back(blink::InterestGroup::Ad(*ad_url, absl::nullopt));
+        ads->emplace_back(blink::InterestGroup::Ad(*ad_url, absl::nullopt));
       }
     }
 
@@ -7980,6 +8021,638 @@
                   /*expected_sellers=*/1);
 }
 
+// Auction with only one interest group participating. The priority calculated
+// using the priority vector fetch in bidding signals is negative, so it should
+// be filtered out after the bidding signals fetch, and there should be no
+// winner.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorOnlyGroupFiltered) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullTrustedSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", -1}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_FALSE(result_.winning_group_id);
+  EXPECT_FALSE(result_.ad_url);
+
+  // The interest group is considered to have participated in the auction.
+  CheckHistograms(InterestGroupAuction::AuctionResult::kNoBids,
+                  /*expected_interest_groups=*/1,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with only one interest group participating. The priority calculated
+// using the priority vector fetch in bidding signals is zero, so it should
+// not be filtered out.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorOnlyGroupNotFiltered) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullTrustedSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 0}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/1,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner. The
+// priority calculated using the priority vector fetch in bidding signals is
+// negative for both groups. The group limit is 1 and
+// `enable_bidding_signals_prioritization` is set to true for one of the groups,
+// so the auction should be set up to filter only after all priority vectors
+// have been received, but then they eliminates both interest groups.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorBothGroupsFiltered) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullTrustedSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", -1}}}},
+           {"2", {{{"browserSignals.one", -2}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_FALSE(result_.winning_group_id);
+  EXPECT_FALSE(result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kNoBids,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// The priority calculated using the priority vector fetch in bidding signals is
+// negative for the first group to receive trusted signals (which is group 2).
+// The group limit is 1 and `enable_bidding_signals_prioritization` is set to
+// true for one of the groups, so the auction should be set up to filter only
+// after all priority vectors have been received.
+//
+// The two interest groups use different trusted signals URLs, so the order the
+// responses are received in can be controlled.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorFirstGroupFiltered) {
+  const GURL kFullTrustedSignalsUrl1 =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1");
+  const GURL kBidder1TrustedSignalsUrl2 =
+      GURL(kBidder1TrustedSignalsUrl.spec() + "2");
+  const GURL kFullTrustedSignalsUrl2 =
+      GURL(kBidder1TrustedSignalsUrl2.spec() +
+           "?hostname=publisher1.com&interestGroupNames=2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl2,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(2, url_loader_factory_.NumPending());
+
+  // Group 2 has a negative priority.
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl2,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"2", {{{"browserSignals.one", -2}}}}}));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl1,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 1}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// The priority calculated using the priority vector fetch in bidding signals is
+// negative for the second group to receive trusted signals (which is group 2).
+// The group limit is 1 and `enable_bidding_signals_prioritization` is set to
+// true for one of the groups, so the auction should be set up to filter only
+// after all priority vectors have been received.
+//
+// The two interest groups use different trusted signals URLs, so the order the
+// responses are received in can be controlled.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorSecondGroupFiltered) {
+  const GURL kFullTrustedSignalsUrl1 =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1");
+  const GURL kBidder1TrustedSignalsUrl2 =
+      GURL(kBidder1TrustedSignalsUrl.spec() + "2");
+  const GURL kFullTrustedSignalsUrl2 =
+      GURL(kBidder1TrustedSignalsUrl2.spec() +
+           "?hostname=publisher1.com&interestGroupNames=2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl2,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(2, url_loader_factory_.NumPending());
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl1,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 1}}}}}));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+
+  // Group 2 has a negative priority.
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl2,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"2", {{{"browserSignals.one", -2}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// The priority calculated using the priority vector fetch in bidding signals is
+// negative for both groups. The group limit is 1 and
+// `enable_bidding_signals_prioritization` is set to true for one of the groups,
+// so the auction should be set up to filter only after all priority vectors
+// have been received.
+//
+// In this test, the group with the lower priority is removed when enforcing the
+// per-bidder size limit. The other interest group goes on to win the auction.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorSizeLimitFiltersOneGroup) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullTrustedSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+
+  // Group 2 has a lower, but non-negative, priority.
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 1}}}},
+           {"2", {{{"browserSignals.one", 0.5}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// The priority calculated using the priority vector fetch in bidding signals is
+// negative for both groups. The group limit is 1 and
+// `enable_bidding_signals_prioritization` is set to true for one of the groups,
+// so the auction should be set up to filter only after all priority vectors
+// have been received.
+//
+// In this test, neither group is filtered due to having a negative priority,
+// however, the group that would otherwise bid higher is filtered out due to the
+// per buyer interest group limit.
+TEST_F(AuctionRunnerTest, TrustedBiddingSignalsPriorityVectorNoGroupFiltered) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullTrustedSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 2}}}},
+           {"2", {{{"browserSignals.one", 1}}}}}));
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Test that `basePriority` works as expected. Interest groups have one priority
+// order with base priorities, another with the priority vectors that are part
+// of the interest groups, and then the priority vectors downloaded as signals
+// echo the base priority values, which should be the order that takes effect,
+// when one group has `enable_bidding_signals_prioritization` set to true.
+TEST_F(AuctionRunnerTest, TrustedBiddingSignalsPriorityVectorBasePriority) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.priority = 2;
+  bidders[0].interest_group.priority_vector = {{"browserSignals.one", 1}};
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+  bidders[1].interest_group.priority = 1;
+  bidders[1].interest_group.priority_vector = {{"browserSignals.one", 2}};
+  bidders[1].interest_group.enable_bidding_signals_prioritization = true;
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.basePriority", 1}}}},
+           {"2", {{{"browserSignals.basePriority", 1}}}}}));
+
+  all_buyers_group_limit_ = 1;
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Test that `firstDotProductPriority` works as expected. Interest groups have
+// one priority order with base priorities, another with the priority vectors
+// that are part of the interest groups, and then the priority vectors
+// downloaded as signals echo the values of the previous priority vector dot
+// product, which should be the order that takes effect, when one group has
+// `enable_bidding_signals_prioritization` set to true.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorFirstDotProductPriority) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.priority = 1;
+  bidders[0].interest_group.priority_vector = {{"browserSignals.one", 2}};
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+  bidders[1].interest_group.priority = 2;
+  bidders[1].interest_group.priority_vector = {{"browserSignals.one", 1}};
+  bidders[1].interest_group.enable_bidding_signals_prioritization = true;
+
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.firstDotProductPriority", 1}}}},
+           {"2", {{{"browserSignals.firstDotProductPriority", 1}}}}}));
+
+  all_buyers_group_limit_ = 1;
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Test that when no priority vector is received, the result of the first
+// priority calculation using the interset group's priority vector is used, if
+// available, and if not, the base priority is used.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorNotreceivedMixPrioritySources) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+
+  url_loader_factory_.ClearResponses();
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         MakeBidScriptSupportsTie());
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         MakeAuctionScriptSupportsTie());
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.priority = 0;
+  bidders[0].interest_group.priority_vector = {{"browserSignals.one", 2}};
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+  bidders[1].interest_group.priority = 1;
+  bidders[1].interest_group.enable_bidding_signals_prioritization = true;
+
+  // Empty priority vector.
+  auction_worklet::AddBidderJsonResponse(&url_loader_factory_,
+                                         kFullTrustedSignalsUrl,
+                                         /*content=*/"{}");
+
+  all_buyers_group_limit_ = 1;
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
+
+  EXPECT_THAT(result_.errors, testing::UnorderedElementsAre());
+  EXPECT_EQ(InterestGroupKey(kBidder1, "1"), result_.winning_group_id);
+  EXPECT_EQ(GURL("https://ad1.com"), result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// `enable_bidding_signals_prioritization` is set to true and the size limit is
+// one, so the worklets wait until all other worklets have received signals
+// before proceeding. However, the worklets' Javascript fails to load before any
+// signals are received, which should safely fail the auction. This follows the
+// same path as if the worklet crashed, so no need to test crashing combined
+// with `enable_bidding_signals_prioritization`.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorSharedScriptLoadErrorAfterSignals) {
+  const GURL kFullTrustedSignalsUrl =
+      GURL(kBidder1TrustedSignalsUrl.spec() +
+           "?hostname=publisher1.com&interestGroupNames=1,2");
+  url_loader_factory_.ClearResponses();
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  // Seller script, bidder script, signals URL should all be pending.
+  EXPECT_EQ(3, url_loader_factory_.NumPending());
+
+  // Bidding signals received. Auction should still be pending.
+  auction_worklet::AddBidderJsonResponse(
+      &url_loader_factory_, kFullTrustedSignalsUrl,
+      MakeBiddingSignalsWithPerInterestGroupData(
+          {{"1", {{{"browserSignals.one", 1}}}},
+           {"2", {{{"browserSignals.one", 2}}}}}));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  // Seller script, bidder script should still be pending.
+  EXPECT_EQ(2, url_loader_factory_.NumPending());
+
+  // Script loads fail. The auction should safely fail.
+  url_loader_factory_.AddResponse(kBidder1Url.spec(), "", net::HTTP_NOT_FOUND);
+  auction_run_loop_->Run();
+
+  // Only get an error for one interest group - the other was filtered out due
+  // to having a lower priority.
+  EXPECT_THAT(
+      result_.errors,
+      testing::UnorderedElementsAre(
+          "Failed to load https://adplatform.com/offers.js HTTP status ="
+          " 404 Not Found."));
+  EXPECT_EQ(absl::nullopt, result_.winning_group_id);
+  EXPECT_EQ(absl::nullopt, result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kNoBids,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
+// Auction with two interest groups participating, both with the same owner.
+// `enable_bidding_signals_prioritization` is set to true and the size limit is
+// one, so the worklets wait until all other worklets have received signals
+// before proceeding. However, the worklet's Javascript fails to load after
+// signals are received, which should safely fail the auction. This follows the
+// same path as if the worklet crashed, so no need to test crashing combined
+// with `enable_bidding_signals_prioritization`.
+TEST_F(AuctionRunnerTest,
+       TrustedBiddingSignalsPriorityVectorSharedScriptLoadErrorBeforeSignals) {
+  url_loader_factory_.ClearResponses();
+
+  std::vector<StorageInterestGroup> bidders;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"1", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad1.com")));
+  bidders[0].interest_group.enable_bidding_signals_prioritization = true;
+  bidders.emplace_back(MakeInterestGroup(
+      kBidder1, /*name=*/"2", kBidder1Url, kBidder1TrustedSignalsUrl,
+      /*trusted_bidding_signals_keys=*/{}, GURL("https://ad2.com")));
+
+  all_buyers_group_limit_ = 1;
+  StartAuction(kSellerUrl, std::move(bidders));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(auction_complete_);
+  // Seller script, bidder script, signals URL should all be pending.
+  EXPECT_EQ(3, url_loader_factory_.NumPending());
+
+  // Script loads fail. The auction should safely fail.
+  url_loader_factory_.AddResponse(kBidder1Url.spec(), "", net::HTTP_NOT_FOUND);
+  auction_run_loop_->Run();
+
+  EXPECT_THAT(
+      result_.errors,
+      testing::UnorderedElementsAre(
+          "Failed to load https://adplatform.com/offers.js HTTP status ="
+          " 404 Not Found.",
+          "Failed to load https://adplatform.com/offers.js HTTP status ="
+          " 404 Not Found."));
+  EXPECT_EQ(absl::nullopt, result_.winning_group_id);
+  EXPECT_EQ(absl::nullopt, result_.ad_url);
+
+  CheckHistograms(InterestGroupAuction::AuctionResult::kNoBids,
+                  /*expected_interest_groups=*/2,
+                  /*expected_owners=*/1,
+                  /*expected_sellers=*/1);
+}
+
 // Enable and test forDebuggingOnly.reportAdAuctionLoss() and
 // forDebuggingOnly.reportAdAuctionWin() APIs.
 class AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc
index 05553be9..34af0413 100644
--- a/content/browser/interest_group/interest_group_auction.cc
+++ b/content/browser/interest_group/interest_group_auction.cc
@@ -224,7 +224,7 @@
       if (bidder.interest_group.priority_vector &&
           !bidder.interest_group.priority_vector->empty()) {
         priority = CalculateInterestGroupPriority(
-            *auction_->config_, bidder.interest_group,
+            *auction_->config_, bidder, auction_->auction_start_time_,
             *bidder.interest_group.priority_vector);
         // Only filter interest groups with priority < 0 if the negative
         // priority is the result of a `priority_vector` multiplication.
@@ -235,6 +235,9 @@
           continue;
       }
 
+      if (bidder.interest_group.enable_bidding_signals_prioritization)
+        enable_bidding_signals_prioritization_ = true;
+
       auto state = std::make_unique<BidState>();
       state->bidder = std::move(bidder);
       state->calculated_priority = priority;
@@ -255,7 +258,16 @@
       return;
     }
 
-    ApplySizeLimitAndSort();
+    if (!enable_bidding_signals_prioritization_) {
+      ApplySizeLimitAndSort();
+    } else {
+      // When not applying the size limit yet, still sort by priority, since
+      // worklets preserve the order they see requests in. This allows higher
+      // priority interest groups will get to bid first, and also groups
+      // interest groups by the origin they joined to potentially improve
+      // Javscript context reuse.
+      SortByPriorityAndGroupByJoinOrigin();
+    }
   }
 
   ~BuyerHelper() override = default;
@@ -268,6 +280,7 @@
     DCHECK(!bid_states_.empty());
     DCHECK_EQ(0, num_outstanding_bids_);
     num_outstanding_bids_ = bid_states_.size();
+    num_outstanding_bidding_signals_received_calls_ = num_outstanding_bids_;
 
     // Request processes for all bidder worklets.
     for (auto& bid_state : bid_states_) {
@@ -283,6 +296,26 @@
   }
 
   // auction_worklet::mojom::GenerateBidClient implementation:
+
+  void OnBiddingSignalsReceived(
+      const base::flat_map<std::string, double>& priority_vector,
+      base::OnceClosure resume_generate_bid_callback) override {
+    BidState* state = generate_bid_client_receiver_set_.current_context();
+    absl::optional<double> new_priority;
+    if (!priority_vector.empty()) {
+      const auto& interest_group = state->bidder.interest_group;
+      new_priority = CalculateInterestGroupPriority(
+          *auction_->config_, state->bidder, auction_->auction_start_time_,
+          priority_vector,
+          (interest_group.priority_vector &&
+           !interest_group.priority_vector->empty())
+              ? state->calculated_priority
+              : absl::optional<double>());
+    }
+    OnBiddingSignalsReceivedInternal(state, new_priority,
+                                     std::move(resume_generate_bid_callback));
+  }
+
   void OnGenerateBidComplete(
       auction_worklet::mojom::BidderWorkletBidPtr mojo_bid,
       uint32_t bidding_signals_data_version,
@@ -417,6 +450,12 @@
     auto rand_end = std::upper_bound(rand_begin, bid_states_.end(),
                                      min_priority, BidStatesDescByPriority());
     base::RandomShuffle(rand_begin, rand_end);
+    for (size_t i = size_limit_; i < bid_states_.size(); ++i) {
+      // Need to close pipes explicitly, as the state's GenerateBidClientPipe is
+      // owned by `generate_bid_client_receiver_set_`, deleting the bid isn't
+      // sufficient.
+      CloseBidStatePipes(*bid_states_[i]);
+    }
     bid_states_.resize(size_limit_);
 
     // Restore the origin grouping within lowest priority band among the
@@ -426,38 +465,51 @@
   }
 
   // Called when the `bid_state` BidderWorklet crashes or fails to load.
-  // Invokes OnGenerateBidComplete() for the worklet with a failure.
+  // Invokes OnGenerateBidCompleteInternal() for the worklet with a failure.
   void OnBidderWorkletGenerateBidFatalError(
       BidState* bid_state,
       AuctionWorkletManager::FatalErrorType fatal_error_type,
       const std::vector<std::string>& errors) {
+    // Add error(s) directly to error list.
     if (fatal_error_type ==
         AuctionWorkletManager::FatalErrorType::kWorkletCrash) {
       // Ignore default error message in case of crash. Instead, use a more
       // specific one.
-      OnGenerateBidCompleteInternal(
-          bid_state, auction_worklet::mojom::BidderWorkletBidPtr(),
-          /*bidding_signals_data_version=*/0,
-          /*has_bidding_signals_data_version=*/false,
-          /*debug_loss_report_url=*/absl::nullopt,
-          /*debug_win_report_url=*/absl::nullopt,
-          /*set_priority=*/0,
-          /*has_set_priority=*/false,
-          /*pa_requests=*/{},
-          {base::StrCat({bid_state->bidder.interest_group.bidding_url->spec(),
-                         " crashed while trying to run generateBid()."})});
+      auction_->errors_.push_back(
+          base::StrCat({bid_state->bidder.interest_group.bidding_url->spec(),
+                        " crashed while trying to run generateBid()."}));
+    } else {
+      auction_->errors_.insert(auction_->errors_.end(), errors.begin(),
+                               errors.end());
+    }
+
+    // If waiting on bidding signals, the bidder needs to be removed in the same
+    // way as if it had a new negative priority value, so reuse that logic. The
+    // bidder needs to be removed, and the remaining bidders potentially need to
+    // have the size limit applied and have their generate bid calls resumed, if
+    // they were waiting on this bidder. Therefore, can't just call
+    // OnGenerateBidCompleteInternal().
+    if (!bid_state->bidding_signals_received) {
+      OnBiddingSignalsReceivedInternal(bid_state,
+                                       /*new_priority=*/-1,
+                                       base::OnceClosure());
       return;
     }
 
-    // Otherwise, use error message from the worklet.
-    OnGenerateBidCompleteInternal(
-        bid_state, auction_worklet::mojom::BidderWorkletBidPtr(),
-        /*bidding_signals_data_version=*/0,
-        /*has_bidding_signals_data_version=*/false,
-        /*debug_loss_report_url=*/absl::nullopt,
-        /*debug_win_report_url=*/absl::nullopt,
-        /*set_priority=*/0, /*has_set_priority=*/false,
-        /*pa_requests=*/{}, errors);
+    // Otherwise call OnGenerateBidCompleteInternal() directly to complete the
+    // bid. This will also result in closing pipes. If
+    // `enable_bidding_signals_prioritization_` is true, the closed pipe will be
+    // noticed, and it will be removed before applying the priority filter.
+    OnGenerateBidCompleteInternal(bid_state,
+                                  auction_worklet::mojom::BidderWorkletBidPtr(),
+                                  /*bidding_signals_data_version=*/0,
+                                  /*has_bidding_signals_data_version=*/false,
+                                  /*debug_loss_report_url=*/absl::nullopt,
+                                  /*debug_win_report_url=*/absl::nullopt,
+                                  /*set_priority=*/0,
+                                  /*has_set_priority=*/false,
+                                  /*pa_requests=*/{},
+                                  /*errors=*/{});
   }
 
   // Invoked whenever the AuctionWorkletManager has provided a BidderWorket
@@ -510,6 +562,116 @@
     }
   }
 
+  // Invoked when OnBiddingSignalsReceived() has been called for `state`, or
+  // with a negative priority when the worklet process has an error and is
+  // waiting on the OnBiddingSignalsReceived() invocation.
+  void OnBiddingSignalsReceivedInternal(
+      BidState* state,
+      absl::optional<double> new_priority,
+      base::OnceClosure resume_generate_bid_callback) {
+    DCHECK(!state->bidding_signals_received);
+    DCHECK(state->generate_bid_client_receiver_id);
+    DCHECK_GT(num_outstanding_bids_, 0);
+    DCHECK_GT(num_outstanding_bidding_signals_received_calls_, 0);
+    // `resume_generate_bid_callback` must be non-null except when invoked with
+    // a negative `net_priority` on worklet error.
+    DCHECK(resume_generate_bid_callback || *new_priority < 0);
+
+    state->bidding_signals_received = true;
+    --num_outstanding_bidding_signals_received_calls_;
+
+    // If `new_priority` has a value and is negative, need to record the bidder
+    // as no longer participating in the auction and cancel bid generation.
+    if (new_priority.has_value() && *new_priority < 0) {
+      // Record if there are other bidders, as if there are not, the next call
+      // may delete `this`.
+      bool other_bidders = (num_outstanding_bids_ > 1);
+
+      // If the result of applying the filter is negative, complete the bid
+      // with OnGenerateBidCompleteInternal(), which will close the relevant
+      // pipes and abort bid generation.
+      OnGenerateBidCompleteInternal(
+          state, auction_worklet::mojom::BidderWorkletBidPtr(),
+          /*bidding_signals_data_version=*/0,
+          /*has_bidding_signals_data_version=*/false,
+          /*debug_loss_report_url=*/absl::nullopt,
+          /*debug_win_report_url=*/absl::nullopt,
+          /*set_priority=*/0,
+          /*has_set_priority=*/false,
+          /*pa_requests=*/{},
+          /*errors=*/{});
+      // If this was the last bidder, and it was filtered out, there's nothing
+      // else to do, and `this` may have already been deleted.
+      if (!other_bidders)
+        return;
+
+      // If bidding_signals_prioritization is not enabled, there's also
+      // nothing else to do - no other bidders were blocked on the bidder's
+      // OnBiddingSignalsReceived() call.
+      if (!enable_bidding_signals_prioritization_)
+        return;
+    } else {
+      if (new_priority.has_value())
+        state->calculated_priority = *new_priority;
+      // Otherwise, invoke the callback to proceed to generate a bid, if don't
+      // need to prioritize / filter based on number of interest groups.
+      if (!enable_bidding_signals_prioritization_) {
+        std::move(resume_generate_bid_callback).Run();
+        return;
+      }
+
+      state->resume_generate_bid_callback =
+          std::move(resume_generate_bid_callback);
+    }
+
+    // Check if there are any outstanding OnBiddingSignalsReceived() calls. If
+    // so, need to sort interest groups by priority resume pending generate bid
+    // calls.
+    DCHECK(enable_bidding_signals_prioritization_);
+    if (num_outstanding_bidding_signals_received_calls_ > 0)
+      return;
+
+    // Remove Bid states that were filtered out due to having negative new
+    // priorities, as ApplySizeLimitAndSort() assumes all bidders are still
+    // potentially capable of generating bids. Do these all at once to avoid
+    // repeatedly searching for bid stats that had negative priority vector
+    // multiplication results, each time a priority vector is received.
+    for (size_t i = 0; i < bid_states_.size();) {
+      // Removing a bid is guaranteed to destroy the worklet handle, though not
+      // necessarily the `resume_generate_bid_callback` (in particular,
+      // OnBidderWorkletGenerateBidFatalError() calls OnGenerateBidInternal() if
+      // a worklet with a `resume_generate_bid_callback` already set crashes,
+      // but does not clear `resume_generate_bid_callback`, since doing so
+      // directly without closing the pipe first will DCHECK).
+      if (!bid_states_[i]->worklet_handle) {
+        // The GenerateBidClient pipe should also have been closed.
+        DCHECK(!bid_states_[i]->generate_bid_client_receiver_id);
+        // std::swap() instead of std::move() because self-move isn't guaranteed
+        // to work.
+        std::swap(bid_states_[i], bid_states_.back());
+        bid_states_.pop_back();
+        continue;
+      }
+      DCHECK(bid_states_[i]->resume_generate_bid_callback);
+      ++i;
+    }
+
+    // The above loop should have deleted any bid states not accounted for in
+    // `num_outstanding_bids_`.
+    DCHECK_EQ(static_cast<size_t>(num_outstanding_bids_), bid_states_.size());
+
+    ApplySizeLimitAndSort();
+
+    // Update `num_outstanding_bids_` to reflect the remaining number of pending
+    // bids, after applying the size limit.
+    num_outstanding_bids_ = bid_states_.size();
+
+    // Let all generate bid calls proceed.
+    for (auto& pending_state : bid_states_) {
+      std::move(pending_state->resume_generate_bid_callback).Run();
+    }
+  }
+
   // Called once a bid has been generated, or has failed to be generated.
   // Releases the BidderWorklet handle and instructs the SellerWorklet to
   // start scoring the bid, if there is one.
@@ -586,8 +748,10 @@
     }
 
     --num_outstanding_bids_;
-    if (num_outstanding_bids_ == 0)
+    if (num_outstanding_bids_ == 0) {
+      DCHECK_EQ(num_outstanding_bidding_signals_received_calls_, 0);
       auction_->OnBidSourceDone();
+    }
   }
 
   // Calls SendPendingSignalsRequests() for the BidderWorklet of `bid_state`,
@@ -701,7 +865,8 @@
 
   const url::Origin owner_;
 
-  // State of loaded interest groups owned by `owner_`.
+  // State of loaded interest groups owned by `owner_`. Use unique_ptrs so that
+  // pointers aren't invalidated by sorting / deleting BidStates.
   std::vector<std::unique_ptr<BidState>> bid_states_;
 
   // Per-BidState receivers. These can never be null. Uses unique_ptrs so that
@@ -710,8 +875,21 @@
                               BidState*>
       generate_bid_client_receiver_set_;
 
+  int num_outstanding_bidding_signals_received_calls_ = 0;
   int num_outstanding_bids_ = 0;
 
+  // True if any interest group owned by `owner_` participating in this auction
+  // has `use_biddings_signals_prioritization` set to true. When this is true,
+  // all GenerateBid() calls will be deferred until OnBiddingSignalsReceived()
+  // has been invoked for all bidders (or they've failed to generate bids due to
+  // errors).
+  //
+  // TODO(mmenke): Could only set this to true if the number of bidders exceeds
+  // the per-buyer limit as well, and only the `priority_vector` as a filter for
+  // buyers with `use_biddings_signals_prioritization` set to true, as a small
+  // performance optimization.
+  bool enable_bidding_signals_prioritization_ = false;
+
   base::WeakPtrFactory<BuyerHelper> weak_ptr_factory_{this};
 };
 
@@ -1168,6 +1346,7 @@
       std::remove_if(interest_groups.begin(), interest_groups.end(),
                      [](const StorageInterestGroup& bidder) {
                        return !bidder.interest_group.bidding_url ||
+                              !bidder.interest_group.ads ||
                               bidder.interest_group.ads->empty();
                      }),
       interest_groups.end());
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h
index ea5988b..8536b69a 100644
--- a/content/browser/interest_group/interest_group_auction.h
+++ b/content/browser/interest_group/interest_group_auction.h
@@ -204,6 +204,18 @@
     // generateBid() is running.
     absl::optional<mojo::ReceiverId> generate_bid_client_receiver_id;
 
+    // True when OnBiddingSignalsReceived() has been invoked. Needed to
+    // correctly handle the case the bidder worklet pipe is closed before
+    // OnBiddingSignalsReceived() is invoked.
+    bool bidding_signals_received = false;
+
+    // Callback to resume generating a bid after OnBiddingSignalsReceived() has
+    // been invoked. Only used when `enabled_bidding_signals_prioritization` is
+    // true for any interest group with the same owner, while waiting for all
+    // interest groups to receive their final priorities. In other cases, the
+    // callback is invoked immediately.
+    base::OnceClosure resume_generate_bid_callback;
+
     // True if the worklet successfully made a bid.
     bool made_bid = false;
 
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc
index bdf08ab..fff13fc 100644
--- a/content/browser/interest_group/interest_group_browsertest.cc
+++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -4511,6 +4511,25 @@
           /*user_bidding_signals=*/R"({"some":"json","stuff":{"here":[1,2]}})",
           /*ads=*/{{{ad3_url, /*metadata=*/absl::nullopt}}},
           /*ad_components=*/absl::nullopt)));
+  EXPECT_EQ(
+      kSuccess,
+      JoinInterestGroupAndVerify(blink::InterestGroup(
+          /*expiry=*/base::Time(),
+          /*owner=*/test_origin,
+          /*name=*/"jetskis",
+          /*priority=*/0.0, /*enable_bidding_signals_prioritization=*/false,
+          /*priority_vector=*/absl::nullopt,
+          /*priority_signals_overrides=*/absl::nullopt, /*execution_mode=*/
+          blink::InterestGroup::ExecutionMode::kCompatibilityMode,
+          /*bidding_url=*/
+          https_server_->GetURL("a.test", "/interest_group/bidding_logic.js"),
+          /*bidding_wasm_helper_url=*/absl::nullopt,
+          /*daily_update_url=*/absl::nullopt,
+          /*trusted_bidding_signals_url=*/absl::nullopt,
+          /*trusted_bidding_signals_keys=*/absl::nullopt,
+          /*user_bidding_signals=*/R"({"some":"json","stuff":{"here":[1,2]}})",
+          /*ads=*/absl::nullopt,
+          /*ad_components=*/absl::nullopt)));
 
   std::string auction_config = JsReplace(
       R"({
diff --git a/content/browser/interest_group/interest_group_permissions_checker_unittest.cc b/content/browser/interest_group/interest_group_permissions_checker_unittest.cc
index 3923505..bfc450e4 100644
--- a/content/browser/interest_group/interest_group_permissions_checker_unittest.cc
+++ b/content/browser/interest_group/interest_group_permissions_checker_unittest.cc
@@ -440,7 +440,8 @@
               producer_handle->WriteData(response_body.data(), &bytes_written,
                                          MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
 
-    pending_request.client->OnReceiveResponse(std::move(head), std::move(body));
+    pending_request.client->OnReceiveResponse(std::move(head), std::move(body),
+                                              absl::nullopt);
 
     auto status = network::URLLoaderCompletionStatus();
     status.decoded_body_length = response_body.size();
diff --git a/content/browser/interest_group/interest_group_priority_util.cc b/content/browser/interest_group/interest_group_priority_util.cc
index 122dd09a..082777b 100644
--- a/content/browser/interest_group/interest_group_priority_util.cc
+++ b/content/browser/interest_group/interest_group_priority_util.cc
@@ -7,6 +7,8 @@
 #include <string>
 
 #include "base/containers/flat_map.h"
+#include "base/time/time.h"
+#include "content/browser/interest_group/storage_interest_group.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/interest_group/auction_config.h"
 #include "third_party/blink/public/common/interest_group/interest_group.h"
@@ -16,19 +18,35 @@
 
 double CalculateInterestGroupPriority(
     const blink::AuctionConfig& auction_config,
-    const blink::InterestGroup& interest_group,
+    const StorageInterestGroup& storage_interest_group,
+    const base::Time auction_start_time,
     const base::flat_map<std::string, double>& priority_vector,
     absl::optional<double> first_dot_product_priority) {
   // Empty priority vectors should be ignored, so updating an interest group can
   // set an empty priority vector to disable it.
   DCHECK(!priority_vector.empty());
 
+  const blink::InterestGroup& interest_group =
+      storage_interest_group.interest_group;
+
+  // Calculate the time since the interest group was joined. Force it to be
+  // between 0 and 30 days. Less than 0 could happen due to clock changes. The
+  // expiration time is 30 days, but could exceed it due to races or clock
+  // changes in the middle of an auction, though seems unlikely.
+  base::TimeDelta age = auction_start_time - storage_interest_group.join_time;
+  age = std::max(age, base::TimeDelta());
+  age = std::min(age, base::Days(30));
+
   // TODO(https://crbug.com/1343389): Add browserSignals.age.
   base::flat_map<std::string, double> browser_signals{
       {"browserSignals.one", 1},
       {"browserSignals.basePriority", interest_group.priority},
       {"browserSignals.firstDotProductPriority",
        first_dot_product_priority.value_or(0)},
+      {"browserSignals.ageInMinutes", age.InMinutes()},
+      {"browserSignals.ageInMinutesMax60", std::min(age.InMinutes(), 60)},
+      {"browserSignals.ageInHoursMax24", std::min(age.InHours(), 24)},
+      {"browserSignals.ageInDaysMax30", std::min(age.InDays(), 30)},
   };
 
   // Ordered list of priority signals map. Order is
diff --git a/content/browser/interest_group/interest_group_priority_util.h b/content/browser/interest_group/interest_group_priority_util.h
index 83359e6..6e43cc7 100644
--- a/content/browser/interest_group/interest_group_priority_util.h
+++ b/content/browser/interest_group/interest_group_priority_util.h
@@ -8,18 +8,24 @@
 #include <string>
 
 #include "base/containers/flat_map.h"
+#include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace blink {
 struct AuctionConfig;
-struct InterestGroup;
 }  // namespace blink
 
 namespace content {
 
-// Calculates the priority of `interest_group` given `auction_config` using the
-// provided priority vector.
+struct StorageInterestGroup;
+
+// Calculates the priority of `storage_interest_group` given `auction_config`
+// using the provided priority vector.
+//
+// `auction_start_time` is the time the auction started. The same value should
+// be used for all calls within a single auction, to ensure consistency between
+// information passed to different bidders.
 //
 // `priority_vector` is either the field of that name from `interest_group`, or
 // the priority vector received as part of the trusted bidding signals fetch. It
@@ -31,7 +37,8 @@
 // priority vector received from a trusted bidding server.
 CONTENT_EXPORT double CalculateInterestGroupPriority(
     const blink::AuctionConfig& auction_config,
-    const blink::InterestGroup& interest_group,
+    const StorageInterestGroup& storage_interest_group,
+    const base::Time auction_start_time,
     const base::flat_map<std::string, double>& priority_vector,
     absl::optional<double> first_dot_product_priority = absl::nullopt);
 
diff --git a/content/browser/interest_group/interest_group_priority_util_unittest.cc b/content/browser/interest_group/interest_group_priority_util_unittest.cc
index febce94..3013a51 100644
--- a/content/browser/interest_group/interest_group_priority_util_unittest.cc
+++ b/content/browser/interest_group/interest_group_priority_util_unittest.cc
@@ -7,6 +7,8 @@
 #include <string>
 
 #include "base/containers/flat_map.h"
+#include "base/time/time.h"
+#include "content/browser/interest_group/storage_interest_group.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/interest_group/auction_config.h"
@@ -19,14 +21,14 @@
 class InterestGroupPriorityUtilTest : public testing::Test {
  public:
   InterestGroupPriorityUtilTest() {
-    interest_group_.priority = 2.5;
-    interest_group_.owner = kOrigin;
+    storage_interest_group_.interest_group.priority = 2.5;
+    storage_interest_group_.interest_group.owner = kOrigin;
   }
 
   ~InterestGroupPriorityUtilTest() override = default;
 
   blink::AuctionConfig auction_config_;
-  blink::InterestGroup interest_group_;
+  StorageInterestGroup storage_interest_group_;
 
   const url::Origin kOrigin = url::Origin::Create(GURL("https://origin.test"));
   const url::Origin kOtherOrigin =
@@ -35,24 +37,24 @@
 
 // All priority signals maps are null.
 TEST_F(InterestGroupPriorityUtilTest, NullSignals) {
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"foo", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"foo", 2}}));
   EXPECT_EQ(2, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.one", 2}}));
   EXPECT_EQ(5, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.basePriority", 2}}));
   EXPECT_EQ(
       0,
       CalculateInterestGroupPriority(
-          auction_config_, interest_group_,
+          auction_config_, storage_interest_group_, base::Time(),
           /*priority_vector=*/{{"browserSignals.firstDotProductPriority", 2}}));
   EXPECT_EQ(
       6,
       CalculateInterestGroupPriority(
-          auction_config_, interest_group_,
+          auction_config_, storage_interest_group_, base::Time(),
           /*priority_vector=*/{{"browserSignals.firstDotProductPriority", 2}},
           /*first_dot_product_priority=*/3));
 }
@@ -63,16 +65,16 @@
   auction_config_.non_shared_params.per_buyer_priority_signals->emplace(
       kOrigin, base::flat_map<std::string, double>{});
   auction_config_.non_shared_params.all_buyers_priority_signals.emplace();
-  interest_group_.priority_signals_overrides.emplace();
+  storage_interest_group_.interest_group.priority_signals_overrides.emplace();
 
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"foo", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"foo", 2}}));
   EXPECT_EQ(2, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.one", 2}}));
   EXPECT_EQ(5, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.basePriority", 2}}));
 }
 
@@ -82,25 +84,25 @@
       kOrigin, base::flat_map<std::string, double>{{"foo", 2}, {"bar", -1.5}});
 
   // <missing>*2
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"one", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"one", 2}}));
   // 2*-1.5
-  EXPECT_EQ(
-      -3, CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                         /*priority_vector=*/{{"foo", -1.5}}));
+  EXPECT_EQ(-3, CalculateInterestGroupPriority(
+                    auction_config_, storage_interest_group_, base::Time(),
+                    /*priority_vector=*/{{"foo", -1.5}}));
   // 2*4 + -1.5*3
   EXPECT_EQ(3.5, CalculateInterestGroupPriority(
-                     auction_config_, interest_group_,
+                     auction_config_, storage_interest_group_, base::Time(),
                      /*priority_vector=*/{{"foo", 4}, {"bar", 3}}));
 
   // 1*3
   EXPECT_EQ(3, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.one", 3}}));
   // 2*4 + 1*3
   EXPECT_EQ(11, CalculateInterestGroupPriority(
-                    auction_config_, interest_group_,
+                    auction_config_, storage_interest_group_, base::Time(),
                     /*priority_vector=*/
                     {{"foo", 4}, {"browserSignals.one", 3}}));
 }
@@ -112,11 +114,11 @@
       kOtherOrigin,
       base::flat_map<std::string, double>{{"foo", 2}, {"bar", -1.5}});
 
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"foo", 2}}));
   EXPECT_EQ(0, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"foo", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"foo", 3}, {"bar", 4}}));
 
   // Add an entry for kOrigin with the same key as one of the entries for
@@ -124,7 +126,7 @@
   auction_config_.non_shared_params.per_buyer_priority_signals->emplace(
       kOrigin, base::flat_map<std::string, double>{{"foo", 5}});
   EXPECT_EQ(15, CalculateInterestGroupPriority(
-                    auction_config_, interest_group_,
+                    auction_config_, storage_interest_group_, base::Time(),
                     /*priority_vector=*/{{"foo", 3}, {"bar", -30}}));
 }
 
@@ -133,62 +135,62 @@
       {"foo", 2}, {"bar", -1.5}};
 
   // <missing>*2
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"one", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"one", 2}}));
   // 2*-1.5
-  EXPECT_EQ(
-      -3, CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                         /*priority_vector=*/{{"foo", -1.5}}));
+  EXPECT_EQ(-3, CalculateInterestGroupPriority(
+                    auction_config_, storage_interest_group_, base::Time(),
+                    /*priority_vector=*/{{"foo", -1.5}}));
   // 2*4 + -1.5*3
   EXPECT_EQ(3.5, CalculateInterestGroupPriority(
-                     auction_config_, interest_group_,
+                     auction_config_, storage_interest_group_, base::Time(),
                      /*priority_vector=*/{{"foo", 4}, {"bar", 3}}));
 
   // 1*3
   EXPECT_EQ(3, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.one", 3}}));
   // 2*4 + 1*3
   EXPECT_EQ(11, CalculateInterestGroupPriority(
-                    auction_config_, interest_group_,
+                    auction_config_, storage_interest_group_, base::Time(),
                     /*priority_vector=*/
                     {{"foo", 4}, {"browserSignals.one", 3}}));
 }
 
 TEST_F(InterestGroupPriorityUtilTest, PrioritySignalsOverrides) {
-  interest_group_.priority_signals_overrides = {
+  storage_interest_group_.interest_group.priority_signals_overrides = {
       {"foo", 2},
       {"bar", -1.5},
       // This should override the `browserSignals` values added by default.
       {"browserSignals.one", -4}};
 
   // <missing>*2
-  EXPECT_EQ(0,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"one", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"one", 2}}));
   // 2*-1.5
-  EXPECT_EQ(
-      -3, CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                         /*priority_vector=*/{{"foo", -1.5}}));
+  EXPECT_EQ(-3, CalculateInterestGroupPriority(
+                    auction_config_, storage_interest_group_, base::Time(),
+                    /*priority_vector=*/{{"foo", -1.5}}));
   // 2*4 + -1.5*3
   EXPECT_EQ(3.5, CalculateInterestGroupPriority(
-                     auction_config_, interest_group_,
+                     auction_config_, storage_interest_group_, base::Time(),
                      /*priority_vector=*/{{"foo", 4}, {"bar", 3}}));
 
   // -4 * 3
   EXPECT_EQ(-12, CalculateInterestGroupPriority(
-                     auction_config_, interest_group_,
+                     auction_config_, storage_interest_group_, base::Time(),
                      /*priority_vector=*/{{"browserSignals.one", 3}}));
   // 2*4 + -4*3
   EXPECT_EQ(-4, CalculateInterestGroupPriority(
-                    auction_config_, interest_group_,
+                    auction_config_, storage_interest_group_, base::Time(),
                     /*priority_vector=*/
                     {{"foo", 4}, {"browserSignals.one", 3}}));
   // browserSignals.priority should not be masked.
   // 2.5 * 5
   EXPECT_EQ(5, CalculateInterestGroupPriority(
-                   auction_config_, interest_group_,
+                   auction_config_, storage_interest_group_, base::Time(),
                    /*priority_vector=*/{{"browserSignals.basePriority", 2}}));
 }
 
@@ -196,7 +198,8 @@
 // prioritySignalsOverrides (browserSignals are tested in the overrides test
 // case).
 TEST_F(InterestGroupPriorityUtilTest, PrioritySignalsMasking) {
-  interest_group_.priority_signals_overrides = {{"foo", 1}};
+  storage_interest_group_.interest_group.priority_signals_overrides = {
+      {"foo", 1}};
   auction_config_.non_shared_params.per_buyer_priority_signals.emplace();
   auction_config_.non_shared_params.per_buyer_priority_signals->emplace(
       kOrigin, base::flat_map<std::string, double>{{"foo", 10}, {"bar", 2}});
@@ -205,29 +208,151 @@
 
   // "foo" should come from `priority_signals_overrides`, masking the values in
   // the other two maps.
-  EXPECT_EQ(1,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"foo", 1}}));
+  EXPECT_EQ(1, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"foo", 1}}));
 
   // "bar" should come from `per_buyer_priority_signals`, masking the value in
   // `all_buyers_priority_signals`.
-  EXPECT_EQ(2,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"bar", 1}}));
+  EXPECT_EQ(2, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"bar", 1}}));
 
   // "baz" should come from `all_buyers_priority_signals`, since no other maps
   // have an entry for it.
-  EXPECT_EQ(3,
-            CalculateInterestGroupPriority(auction_config_, interest_group_,
-                                           /*priority_vector=*/{{"baz", 1}}));
+  EXPECT_EQ(3, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base::Time(),
+                   /*priority_vector=*/{{"baz", 1}}));
 
   // Combine one value from each map.
   //
   // 1*1 + 2*2 + 3*3 + 4*<null>
   EXPECT_EQ(14, CalculateInterestGroupPriority(
-                    auction_config_, interest_group_,
+                    auction_config_, storage_interest_group_, base::Time(),
                     /*priority_vector=*/
                     {{"foo", 1}, {"bar", 2}, {"baz", 3}, {"qux", 4}}));
 }
 
+TEST_F(InterestGroupPriorityUtilTest, BrowserSignalsAge) {
+  base::Time base_time = base::Time::Now();
+  storage_interest_group_.join_time = base_time;
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base_time,
+                   /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, base_time,
+                /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, base_time,
+                /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_, base_time,
+                   /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+
+  // Add 59 seconds to make sure minutes are not rounded up. Don't need to do
+  // this for hours or years because the 59 minutes case test hours aren't
+  // rounded up, and the 23 hours test makes sure days aren't rounded up.
+  base::Time fifty_nine_minutes_from_base =
+      base_time + base::Minutes(59) + base::Seconds(59);
+  EXPECT_EQ(118, CalculateInterestGroupPriority(
+                     auction_config_, storage_interest_group_,
+                     fifty_nine_minutes_from_base,
+                     /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(118,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_,
+                fifty_nine_minutes_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_,
+                fifty_nine_minutes_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_,
+                   fifty_nine_minutes_from_base,
+                   /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+
+  base::Time twenty_three_hours_frome_base = base_time + base::Hours(23);
+  EXPECT_EQ(2 * 23 * 60,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_,
+                twenty_three_hours_frome_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(2 * 60,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_,
+                twenty_three_hours_frome_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(2 * 23,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_,
+                twenty_three_hours_frome_base,
+                /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(0, CalculateInterestGroupPriority(
+                   auction_config_, storage_interest_group_,
+                   twenty_three_hours_frome_base,
+                   /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+
+  base::Time twenty_nine_days_frome_base = base_time + base::Days(29);
+  EXPECT_EQ(
+      2 * 29 * 24 * 60,
+      CalculateInterestGroupPriority(
+          auction_config_, storage_interest_group_, twenty_nine_days_frome_base,
+          /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(
+      2 * 60,
+      CalculateInterestGroupPriority(
+          auction_config_, storage_interest_group_, twenty_nine_days_frome_base,
+          /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(
+      2 * 24,
+      CalculateInterestGroupPriority(
+          auction_config_, storage_interest_group_, twenty_nine_days_frome_base,
+          /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(
+      2 * 29,
+      CalculateInterestGroupPriority(
+          auction_config_, storage_interest_group_, twenty_nine_days_frome_base,
+          /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+
+  base::Time one_year_from_base = base_time + base::Days(365);
+  EXPECT_EQ(2 * 30 * 24 * 60,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(2 * 60,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(2 * 24,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(2 * 30,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_from_base,
+                /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+
+  base::Time one_year_before_base = base_time - base::Days(365);
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_before_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutes", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_before_base,
+                /*priority_vector=*/{{"browserSignals.ageInMinutesMax60", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_before_base,
+                /*priority_vector=*/{{"browserSignals.ageInHoursMax24", 2}}));
+  EXPECT_EQ(0,
+            CalculateInterestGroupPriority(
+                auction_config_, storage_interest_group_, one_year_before_base,
+                /*priority_vector=*/{{"browserSignals.ageInDaysMax30", 2}}));
+}
+
 }  // namespace content
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc
index d0cc3c4..8e8180c 100644
--- a/content/browser/loader/cross_site_document_blocking_browsertest.cc
+++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -390,8 +390,8 @@
       ASSERT_EQ(mojo::CreateDataPipe(response_body.size() + 1, producer_handle,
                                      consumer_handle),
                 MOJO_RESULT_OK);
-      original_client_->OnReceiveResponse(std::move(response_head),
-                                          std::move(consumer_handle));
+      original_client_->OnReceiveResponse(
+          std::move(response_head), std::move(consumer_handle), absl::nullopt);
 
       uint32_t num_bytes = response_body.size();
       EXPECT_EQ(MOJO_RESULT_OK,
diff --git a/content/browser/loader/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc
index e1894ae6..b104265 100644
--- a/content/browser/loader/file_url_loader_factory.cc
+++ b/content/browser/loader/file_url_loader_factory.cc
@@ -226,7 +226,8 @@
     head->mime_type = "text/html";
     head->charset = "utf-8";
     head->response_type = response_type;
-    client->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                              absl::nullopt);
     client_ = std::move(client);
 
     lister_ = std::make_unique<net::DirectoryLister>(path_, this);
@@ -691,7 +692,8 @@
     // implementation of document.lastModified can access it (crbug.com/875299).
     head->headers->AddHeader(net::HttpResponseHeaders::kLastModified,
                              base::TimeFormatHTTP(info.last_modified));
-    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                               absl::nullopt);
 
     if (total_bytes_to_send == 0) {
       // There's definitely no more data, so we're already done.
diff --git a/content/browser/loader/navigation_early_hints_manager.cc b/content/browser/loader/navigation_early_hints_manager.cc
index 2b32db55..4c0dbe0b 100644
--- a/content/browser/loader/navigation_early_hints_manager.cc
+++ b/content/browser/loader/navigation_early_hints_manager.cc
@@ -328,8 +328,10 @@
   // mojom::URLLoaderClient overrides:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
   }
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     if (!head->network_accessed && head->was_fetched_via_cache) {
       // Cancel the client since the response is already stored in the cache.
       result_.was_canceled = true;
@@ -354,7 +356,6 @@
                         OnUploadProgressCallback callback) override {
     NOTREACHED();
   }
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
   void OnComplete(const network::URLLoaderCompletionStatus& status) override {
     if (result_.was_canceled || result_.error_code.has_value()) {
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 033c273..906fe79 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -816,7 +816,9 @@
 
 void NavigationURLLoaderImpl::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle response_body) {
+    mojo::ScopedDataPipeConsumerHandle response_body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
+  DCHECK(!cached_metadata);
   LogQueueTimeHistogram("Navigation.QueueTime.OnReceiveResponse",
                         resource_request_->is_outermost_main_frame);
   head_ = std::move(head);
@@ -984,11 +986,6 @@
   NOTREACHED();
 }
 
-void NavigationURLLoaderImpl::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  NOTREACHED();
-}
-
 void NavigationURLLoaderImpl::OnComplete(
     const network::URLLoaderCompletionStatus& status) {
   // Successful load must have used OnResponseStarted first. In this case, the
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 0e32ca5b..dd70a0e 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -189,13 +189,13 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
   void OnReceiveResponse(
       network::mojom::URLResponseHeadPtr head,
-      mojo::ScopedDataPipeConsumerHandle response_body) override;
+      mojo::ScopedDataPipeConsumerHandle response_body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/loader/object_navigation_fallback_body_loader.cc b/content/browser/loader/object_navigation_fallback_body_loader.cc
index ae6b0958..8f4da963 100644
--- a/content/browser/loader/object_navigation_fallback_body_loader.cc
+++ b/content/browser/loader/object_navigation_fallback_body_loader.cc
@@ -297,7 +297,8 @@
 
 void ObjectNavigationFallbackBodyLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // Should have already happened.
   NOTREACHED();
 }
@@ -317,11 +318,6 @@
   NOTREACHED();
 }
 
-void ObjectNavigationFallbackBodyLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  // Not needed so implementation omitted.
-}
-
 void ObjectNavigationFallbackBodyLoader::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   // Not needed so implementation omitted.
diff --git a/content/browser/loader/object_navigation_fallback_body_loader.h b/content/browser/loader/object_navigation_fallback_body_loader.h
index 14f6680..4dc44fa 100644
--- a/content/browser/loader/object_navigation_fallback_body_loader.h
+++ b/content/browser/loader/object_navigation_fallback_body_loader.h
@@ -100,14 +100,15 @@
 
   // URLLoaderClient overrides:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo&,
                          network::mojom::URLResponseHeadPtr) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/loader/prefetch_url_loader.cc b/content/browser/loader/prefetch_url_loader.cc
index 10303c12..39b1088 100644
--- a/content/browser/loader/prefetch_url_loader.cc
+++ b/content/browser/loader/prefetch_url_loader.cc
@@ -143,7 +143,8 @@
 
 void PrefetchURLLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (is_signed_exchange_handling_enabled_ &&
       signed_exchange_utils::ShouldHandleAsSignedHTTPExchange(
           resource_request_.url, *response)) {
@@ -178,9 +179,14 @@
     response->recursive_prefetch_token = recursive_prefetch_token;
   }
 
+  // Just drop any cached metadata; we don't need to forward it to the renderer
+  // for prefetch.
+  cached_metadata.reset();
+
   if (!body) {
     forwarding_client_->OnReceiveResponse(std::move(response),
-                                          mojo::ScopedDataPipeConsumerHandle());
+                                          mojo::ScopedDataPipeConsumerHandle(),
+                                          absl::nullopt);
     return;
   }
 
@@ -224,11 +230,6 @@
                                        std::move(callback));
 }
 
-void PrefetchURLLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  // Just drop this; we don't need to forward this to the renderer
-  // for prefetch.
-}
-
 void PrefetchURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   forwarding_client_->OnTransferSizeUpdated(transfer_size_diff);
 }
@@ -259,7 +260,7 @@
   }
   DCHECK(response_);
   forwarding_client_->OnReceiveResponse(std::move(response_),
-                                        std::move(consumer));
+                                        std::move(consumer), absl::nullopt);
   return true;
 }
 
diff --git a/content/browser/loader/prefetch_url_loader.h b/content/browser/loader/prefetch_url_loader.h
index 1ba8755..6e60328 100644
--- a/content/browser/loader/prefetch_url_loader.h
+++ b/content/browser/loader/prefetch_url_loader.h
@@ -103,14 +103,15 @@
 
   // network::mojom::URLLoaderClient overrides:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         base::OnceCallback<void()> callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/media/cdm_registry_impl.cc b/content/browser/media/cdm_registry_impl.cc
index e75f396..247e90f 100644
--- a/content/browser/media/cdm_registry_impl.cc
+++ b/content/browser/media/cdm_registry_impl.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_split.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "content/browser/media/cdm_registry_impl.h"
@@ -23,6 +24,7 @@
 #include "media/base/key_system_names.h"
 #include "media/base/key_systems.h"
 #include "media/base/media_switches.h"
+#include "media/base/video_codecs.h"
 #include "media/media_buildflags.h"
 #include "media/mojo/buildflags.h"
 
@@ -53,19 +55,52 @@
                             available);
 }
 
-// Reports the status of the hardware secure CDM. Only reported once per browser
-// session per `key_system`.
-void ReportHardwareSecureCapabilityStatusUMA(const std::string& key_system,
-                                             CdmInfo::Status status) {
+constexpr media::VideoCodec kVideoCodecsToReportToUma[] = {
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+    media::VideoCodec::kH264,
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+    media::VideoCodec::kHEVC,
+#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
+    media::VideoCodec::kDolbyVision,
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+    media::VideoCodec::kVP9, media::VideoCodec::kAV1};
+
+// Reports the status and capabilities of the hardware secure CDM. Only reported
+// once per browser session per `key_system`.
+void ReportHardwareSecureCapabilityStatusUMA(
+    const std::string& key_system,
+    CdmInfo::Status status,
+    const media::CdmCapability* hw_secure_capability) {
+  // Use a set to track whether the UMA has been reported for `key_system` to
+  // make sure we only report once.
   static base::NoDestructor<std::set<std::string>> reported_key_systems;
   if (reported_key_systems->count(key_system))
     return;
 
   reported_key_systems->insert(key_system);
-  auto key_system_name_for_uma =
+
+  auto uma_prefix =
+      "Media.EME." +
       media::GetKeySystemNameForUMA(key_system, /*use_hw_secure_codecs=*/true);
-  base::UmaHistogramEnumeration(
-      "Media.EME." + key_system_name_for_uma + ".CdmInfoStatus", status);
+
+  // Report whether hardware secure decryption is disabled and if so why.
+  base::UmaHistogramEnumeration(uma_prefix + ".CdmInfoStatus", status);
+
+  // When hardware secure decryption is enabled, report whether it is supported.
+  if (status == CdmInfo::Status::kEnabled) {
+    base::UmaHistogramBoolean(uma_prefix + ".Support", hw_secure_capability);
+    // When supported, report whether a particular video codec is supported.
+    if (hw_secure_capability) {
+      const auto& video_codecs = hw_secure_capability->video_codecs;
+      for (const auto& video_codec : kVideoCodecsToReportToUma) {
+        base::UmaHistogramBoolean(
+            uma_prefix + ".Support." + media::GetCodecNameForUMA(video_codec),
+            video_codecs.count(video_codec));
+      }
+    }
+  }
 }
 
 bool IsEnabled(CdmInfo::Status status) {
@@ -539,7 +574,8 @@
     std::tie(hw_secure_capability, status) =
         GetHardwareSecureCapability(*this, key_system);
     DCHECK(status != CdmInfo::Status::kUninitialized);
-    ReportHardwareSecureCapabilityStatusUMA(key_system, status);
+    ReportHardwareSecureCapabilityStatusUMA(
+        key_system, status, base::OptionalToPtr(hw_secure_capability));
     capability.hw_secure_capability =
         IsEnabled(status) ? hw_secure_capability : absl::nullopt;
 
diff --git a/content/browser/media/cdm_registry_impl_unittest.cc b/content/browser/media/cdm_registry_impl_unittest.cc
index 30fd42a..6dc0a18 100644
--- a/content/browser/media/cdm_registry_impl_unittest.cc
+++ b/content/browser/media/cdm_registry_impl_unittest.cc
@@ -62,7 +62,7 @@
 std::vector<media::VideoCodec> VideoCodecMapToList(
     const media::CdmCapability::VideoCodecMap& map) {
   std::vector<media::VideoCodec> list;
-  for (const auto& [video_codec, _] : map) {
+  for (const auto& [video_codec, ignore] : map) {
     list.push_back(video_codec);
   }
   return list;
diff --git a/content/browser/media/fullscreen_video_detection_browsertest.cc b/content/browser/media/fullscreen_video_detection_browsertest.cc
index f09ca0c0..c8b0895 100644
--- a/content/browser/media/fullscreen_video_detection_browsertest.cc
+++ b/content/browser/media/fullscreen_video_detection_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include <memory>
 #include <vector>
+#include "build/build_config.h"
 
 #include "base/path_service.h"
 #include "content/browser/media/media_browsertest.h"
@@ -222,7 +223,13 @@
 
 // The test changes visibility of the <video> and observes
 // how it gets and loses effectively-fullscreen status.
-IN_PROC_BROWSER_TEST_F(FullscreenDetectionTest, HideVideoTag) {
+// TODO(crbug.com/1352246): Re-enable this test
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
+#define MAYBE_HideVideoTag DISABLED_HideVideoTag
+#else
+#define MAYBE_HideVideoTag HideVideoTag
+#endif
+IN_PROC_BROWSER_TEST_F(FullscreenDetectionTest, MAYBE_HideVideoTag) {
   auto* web_contents = shell()->web_contents();
   EXPECT_TRUE(NavigateToURL(
       shell(), embedded_test_server()->GetURL("/media/fullscreen.html")));
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc
index febfb51..9510b8a 100644
--- a/content/browser/network_service_browsertest.cc
+++ b/content/browser/network_service_browsertest.cc
@@ -468,7 +468,8 @@
                                      "https://www2.example.com");
         response->headers->SetHeader("access-control-allow-methods", "*");
         client->OnReceiveResponse(std::move(response),
-                                  mojo::ScopedDataPipeConsumerHandle());
+                                  mojo::ScopedDataPipeConsumerHandle(),
+                                  absl::nullopt);
       } else if (resource_request.method == "custom-method") {
         has_received_request_ = true;
         auto response = network::mojom::URLResponseHead::New();
@@ -477,7 +478,8 @@
         response->headers->SetHeader("access-control-allow-origin",
                                      "https://www2.example.com");
         client->OnReceiveResponse(std::move(response),
-                                  mojo::ScopedDataPipeConsumerHandle());
+                                  mojo::ScopedDataPipeConsumerHandle(),
+                                  absl::nullopt);
         client->OnComplete(network::URLLoaderCompletionStatus(net::OK));
       } else {
         client->OnComplete(
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc
index 7f41c14a..e81c6e69 100644
--- a/content/browser/plugin_service_impl.cc
+++ b/content/browser/plugin_service_impl.cc
@@ -38,8 +38,8 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_constants.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/pepper_plugin_info.h"
 #include "content/public/common/process_type.h"
 #include "content/public/common/webplugininfo.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
@@ -111,7 +111,7 @@
   PluginList::Singleton()->set_will_load_plugins_callback(base::BindRepeating(
       &WillLoadPluginsCallback, &plugin_list_sequence_checker_));
 
-  RegisterPepperPlugins();
+  RegisterPlugins();
 }
 
 #if BUILDFLAG(ENABLE_PPAPI)
@@ -142,7 +142,7 @@
   }
 
   // Validate that the plugin is actually registered.
-  const PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
+  const ContentPluginInfo* info = GetRegisteredPluginInfo(plugin_path);
   if (!info) {
     VLOG(1) << "Unable to find ppapi plugin registration for: "
             << plugin_path.MaybeAsASCII();
@@ -269,20 +269,20 @@
       std::move(callback));
 }
 
-void PluginServiceImpl::RegisterPepperPlugins() {
+void PluginServiceImpl::RegisterPlugins() {
 #if BUILDFLAG(ENABLE_PPAPI)
-  ComputePepperPluginList(&ppapi_plugins_);
+  ComputePepperPluginList(&plugins_);
 #else
-  GetContentClient()->AddPepperPlugins(&ppapi_plugins_);
+  GetContentClient()->AddPlugins(&plugins_);
 #endif  // BUILDFLAG(ENABLE_PPAPI)
-  for (const auto& plugin : ppapi_plugins_)
+  for (const auto& plugin : plugins_)
     RegisterInternalPlugin(plugin.ToWebPluginInfo(), /*add_at_beginning=*/true);
 }
 
 // There should generally be very few plugins so a brute-force search is fine.
-const PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo(
+const ContentPluginInfo* PluginServiceImpl::GetRegisteredPluginInfo(
     const base::FilePath& plugin_path) {
-  for (auto& plugin : ppapi_plugins_) {
+  for (auto& plugin : plugins_) {
     if (plugin.path == plugin_path)
       return &plugin;
   }
@@ -296,11 +296,11 @@
   WebPluginInfo webplugin_info;
   if (!GetPluginInfoByPath(plugin_path, &webplugin_info))
     return nullptr;
-  PepperPluginInfo new_pepper_info;
+  ContentPluginInfo new_pepper_info;
   if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
     return nullptr;
-  ppapi_plugins_.push_back(new_pepper_info);
-  return &ppapi_plugins_.back();
+  plugins_.push_back(new_pepper_info);
+  return &plugins_.back();
 #else
   return nullptr;
 #endif  // BUILDFLAG(ENABLE_PPAPI)
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h
index a41b6578..58dfe45 100644
--- a/content/browser/plugin_service_impl.h
+++ b/content/browser/plugin_service_impl.h
@@ -27,12 +27,11 @@
 
 #if BUILDFLAG(ENABLE_PPAPI)
 #include "content/browser/ppapi_plugin_process_host.h"
-#include "content/public/common/pepper_plugin_info.h"
 #endif
 
 namespace content {
 class PluginServiceFilter;
-struct PepperPluginInfo;
+struct ContentPluginInfo;
 
 // This class responds to requests from renderers for the list of plugins, and
 // also a proxy object for plugin instances.
@@ -63,7 +62,7 @@
   std::u16string GetPluginDisplayNameByPath(
       const base::FilePath& path) override;
   void GetPlugins(GetPluginsCallback callback) override;
-  const PepperPluginInfo* GetRegisteredPpapiPluginInfo(
+  const ContentPluginInfo* GetRegisteredPluginInfo(
       const base::FilePath& plugin_path) override;
   void SetFilter(PluginServiceFilter* filter) override;
   PluginServiceFilter* GetFilter() override;
@@ -126,9 +125,9 @@
       const absl::optional<url::Origin>& origin_lock);
 #endif  // BUILDFLAG(ENABLE_PPAPI)
 
-  void RegisterPepperPlugins();
+  void RegisterPlugins();
 
-  std::vector<PepperPluginInfo> ppapi_plugins_;
+  std::vector<ContentPluginInfo> plugins_;
 
   int max_ppapi_processes_per_profile_ = kDefaultMaxPpapiProcessesPerProfile;
 
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index db8d8f5e..9f5956f 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -29,8 +29,8 @@
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_constants.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/pepper_plugin_info.h"
 #include "content/public/common/process_type.h"
 #include "ppapi/proxy/ppapi_messages.h"
 #include "sandbox/policy/mojom/sandbox.mojom.h"
@@ -90,7 +90,7 @@
 
 // static
 PpapiPluginProcessHost* PpapiPluginProcessHost::CreatePluginHost(
-    const PepperPluginInfo& info,
+    const ContentPluginInfo& info,
     const base::FilePath& profile_data_directory,
     const absl::optional<url::Origin>& origin_lock) {
   PpapiPluginProcessHost* plugin_host =
@@ -170,7 +170,7 @@
 }
 
 PpapiPluginProcessHost::PpapiPluginProcessHost(
-    const PepperPluginInfo& info,
+    const ContentPluginInfo& info,
     const base::FilePath& profile_data_directory,
     const absl::optional<url::Origin>& origin_lock)
     : profile_data_directory_(profile_data_directory),
@@ -200,7 +200,7 @@
     network_observer_ = std::make_unique<PluginNetworkObserver>(this);
 }
 
-bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
+bool PpapiPluginProcessHost::Init(const ContentPluginInfo& info) {
   plugin_path_ = info.path;
   if (info.name.empty()) {
     process_->SetName(plugin_path_.BaseName().LossyDisplayName());
diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h
index bfb9f66..436216e 100644
--- a/content/browser/ppapi_plugin_process_host.h
+++ b/content/browser/ppapi_plugin_process_host.h
@@ -25,7 +25,7 @@
 
 namespace content {
 class BrowserChildProcessHostImpl;
-struct PepperPluginInfo;
+struct ContentPluginInfo;
 
 // Process host for PPAPI plugin processes.
 class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate,
@@ -67,7 +67,7 @@
   ~PpapiPluginProcessHost() override;
 
   static PpapiPluginProcessHost* CreatePluginHost(
-      const PepperPluginInfo& info,
+      const ContentPluginInfo& info,
       const base::FilePath& profile_data_directory,
       const absl::optional<url::Origin>& origin_lock);
 
@@ -114,13 +114,13 @@
 
   // Constructors for plugin process hosts.
   // You must call Init before doing anything else.
-  PpapiPluginProcessHost(const PepperPluginInfo& info,
+  PpapiPluginProcessHost(const ContentPluginInfo& info,
                          const base::FilePath& profile_data_directory,
                          const absl::optional<url::Origin>& origin_lock);
 
   // Actually launches the process with the given plugin info. Returns true
   // on success (the process was spawned).
-  bool Init(const PepperPluginInfo& info);
+  bool Init(const ContentPluginInfo& info);
 
   void RequestPluginChannel(Client* client);
 
diff --git a/content/browser/preloading/prefetch/prefetch_canary_checker.cc b/content/browser/preloading/prefetch/prefetch_canary_checker.cc
index 9a56e751..85fc17c 100644
--- a/content/browser/preloading/prefetch/prefetch_canary_checker.cc
+++ b/content/browser/preloading/prefetch/prefetch_canary_checker.cc
@@ -382,10 +382,13 @@
           base::BindOnce(&PrefetchCanaryChecker::OnDNSResolved, GetWeakPtr())),
       client_remote.InitWithNewPipeAndPassReceiver());
 
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
   browser_context_->GetDefaultStoragePartition()
       ->GetNetworkContext()
-      ->ResolveHost(net::HostPortPair::FromURL(url), nik,
-                    std::move(resolve_host_parameters),
+      ->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                        net::HostPortPair::FromURL(url)),
+                    nik, std::move(resolve_host_parameters),
                     std::move(client_remote));
 
   timeout_timer_ = std::make_unique<base::OneShotTimer>();
diff --git a/content/browser/preloading/prefetch/prefetch_canary_checker_unittest.cc b/content/browser/preloading/prefetch/prefetch_canary_checker_unittest.cc
index c07cc864..dea8b16 100644
--- a/content/browser/preloading/prefetch/prefetch_canary_checker_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_canary_checker_unittest.cc
@@ -35,16 +35,22 @@
       mojo::PendingReceiver<network::mojom::NetworkContext> receiver)
       : receiver_(this, std::move(receiver)) {}
 
-  void ResolveHost(const net::HostPortPair& host,
+  void ResolveHost(network::mojom::HostResolverHostPtr host,
                    const net::NetworkIsolationKey& network_isolation_key,
                    network::mojom::ResolveHostParametersPtr optional_parameters,
                    mojo::PendingRemote<network::mojom::ResolveHostClient>
                        response_client) override {
-    EXPECT_TRUE(pending_requests_.find(host) == pending_requests_.end());
+    net::HostPortPair host_port_pair =
+        host->is_host_port_pair()
+            ? host->get_host_port_pair()
+            : net::HostPortPair(host->get_scheme_host_port().host(),
+                                host->get_scheme_host_port().port());
+    EXPECT_TRUE(pending_requests_.find(host_port_pair) ==
+                pending_requests_.end());
     auto request = std::make_unique<ResolveHostRequest>(
-        this, host, std::move(response_client),
+        this, host_port_pair, std::move(response_client),
         std::move(optional_parameters->control_handle));
-    pending_requests_.emplace(host, std::move(request));
+    pending_requests_.emplace(host_port_pair, std::move(request));
     num_requests_made_++;
   }
 
diff --git a/content/browser/preloading/prefetch/prefetch_from_string_url_loader.cc b/content/browser/preloading/prefetch/prefetch_from_string_url_loader.cc
index 5eebd854..e779d1d 100644
--- a/content/browser/preloading/prefetch/prefetch_from_string_url_loader.cc
+++ b/content/browser/preloading/prefetch/prefetch_from_string_url_loader.cc
@@ -111,7 +111,8 @@
     return;
   }
 
-  client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle));
+  client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle),
+                             absl::nullopt);
 
   producer_handle_ = std::move(producer_handle);
 
diff --git a/content/browser/preloading/prefetch/prefetch_origin_prober.cc b/content/browser/preloading/prefetch/prefetch_origin_prober.cc
index 79d15d6..3c837899 100644
--- a/content/browser/preloading/prefetch/prefetch_origin_prober.cc
+++ b/content/browser/preloading/prefetch/prefetch_origin_prober.cc
@@ -239,10 +239,13 @@
           std::move(callback), also_do_tls_connect)),
       client_remote.InitWithNewPipeAndPassReceiver());
 
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
   browser_context_->GetDefaultStoragePartition()
       ->GetNetworkContext()
-      ->ResolveHost(net::HostPortPair::FromURL(url), nik,
-                    std::move(resolve_host_parameters),
+      ->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                        net::HostPortPair::FromURL(url)),
+                    nik, std::move(resolve_host_parameters),
                     std::move(client_remote));
 }
 
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index f9165824..2de7c48f 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -475,9 +475,10 @@
   std::unique_ptr<base::RunLoop> run_loop_;
 };
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_DefaultAuto DISABLED_DefaultAuto
 #else
 #define MAYBE_DefaultAuto DefaultAuto
@@ -522,9 +523,10 @@
   EXPECT_EQ(0, ExecuteScriptAndExtractInt("eventCounts.touchcancel"));
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanYMainThreadJanky DISABLED_PanYMainThreadJanky
 #else
 #define MAYBE_PanYMainThreadJanky PanYMainThreadJanky
@@ -538,9 +540,10 @@
                                     gfx::Vector2d(0, 45), kShortJankTime);
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXMainThreadJanky DISABLED_PanXMainThreadJanky
 #else
 #define MAYBE_PanXMainThreadJanky PanXMainThreadJanky
@@ -584,9 +587,10 @@
   DoTwoFingerTouchScroll(true, gfx::Vector2d(20, 0));
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXYMainThreadJanky DISABLED_PanXYMainThreadJanky
 #else
 #define MAYBE_PanXYMainThreadJanky PanXYMainThreadJanky
@@ -600,9 +604,10 @@
                                     gfx::Vector2d(45, 45), kShortJankTime);
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXYAtXAreaMainThreadJanky DISABLED_PanXYAtXAreaMainThreadJanky
 #else
 #define MAYBE_PanXYAtXAreaMainThreadJanky PanXYAtXAreaMainThreadJanky
@@ -616,9 +621,10 @@
                                     kShortJankTime);
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXYAtYAreaMainThreadJanky DISABLED_PanXYAtYAreaMainThreadJanky
 #else
 #define MAYBE_PanXYAtYAreaMainThreadJanky PanXYAtYAreaMainThreadJanky
@@ -632,9 +638,10 @@
                                     kShortJankTime);
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXYAtAutoYOverlapAreaMainThreadJanky \
   DISABLED_PanXYAtAutoYOverlapAreaMainThreadJanky
 #else
@@ -650,9 +657,10 @@
                                     kShortJankTime);
 }
 
+// TODO(crbug.com/1357167): Fix Mac failures.
 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) ||       \
     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(THREAD_SANITIZER)
+    defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC)
 #define MAYBE_PanXYAtAutoXOverlapAreaMainThreadJanky \
   DISABLED_PanXYAtAutoXOverlapAreaMainThreadJanky
 #else
diff --git a/content/browser/renderer_host/navigation_controller_impl.h b/content/browser/renderer_host/navigation_controller_impl.h
index 192a79c..697ea4cc 100644
--- a/content/browser/renderer_host/navigation_controller_impl.h
+++ b/content/browser/renderer_host/navigation_controller_impl.h
@@ -439,6 +439,18 @@
     return in_navigate_to_pending_entry_;
   }
 
+  // Whether to maintain a session history with just one entry.
+  //
+  // This returns true for a prerendering page and for fenced frames.
+  // `frame_tree_node` is checked to see if it belongs to a frame tree for
+  // prerendering or for a fenced frame.
+  // Explainer:
+  // https://github.com/jeremyroman/alternate-loading-modes/blob/main/browsing-context.md#session-history)
+  //
+  // TODO(crbug.com/914108): Consider portals here as well.
+  bool ShouldMaintainTrivialSessionHistory(
+      const FrameTreeNode* frame_tree_node) const;
+
  private:
   friend class RestoreHelper;
 
@@ -775,18 +787,6 @@
       FrameNavigationEntry* target_entry,
       const std::string& navigation_api_key);
 
-  // Whether to maintain a session history with just one entry.
-  //
-  // This returns true for a prerendering page and for fenced frames.
-  // `frame_tree_node` is checked to see if it belongs to a frame tree for
-  // prerendering or for a fenced frame.
-  // Explainer:
-  // https://github.com/jeremyroman/alternate-loading-modes/blob/main/browsing-context.md#session-history)
-  //
-  // Portals will be added to this in the future.
-  bool ShouldMaintainTrivialSessionHistory(
-      const FrameTreeNode* frame_tree_node) const;
-
   // ---------------------------------------------------------------------------
 
   // The FrameTree this instance belongs to. Each FrameTree gets its own
diff --git a/content/browser/renderer_host/navigator_unittest.cc b/content/browser/renderer_host/navigator_unittest.cc
index 20ed4fc1..17ac47d 100644
--- a/content/browser/renderer_host/navigator_unittest.cc
+++ b/content/browser/renderer_host/navigator_unittest.cc
@@ -574,7 +574,8 @@
       std::string(kNoContentHeaders, std::size(kNoContentHeaders)));
   GetLoaderForNavigationRequest(main_request)
       ->CallOnResponseStarted(std::move(response),
-                              mojo::ScopedDataPipeConsumerHandle());
+                              mojo::ScopedDataPipeConsumerHandle(),
+                              absl::nullopt);
 
   // There should be no pending nor speculative RenderFrameHost; the navigation
   // was aborted.
@@ -599,7 +600,8 @@
       std::string(kResetContentHeaders, std::size(kResetContentHeaders)));
   GetLoaderForNavigationRequest(main_request)
       ->CallOnResponseStarted(std::move(response),
-                              mojo::ScopedDataPipeConsumerHandle());
+                              mojo::ScopedDataPipeConsumerHandle(),
+                              absl::nullopt);
 
   // There should be no pending nor speculative RenderFrameHost; the navigation
   // was aborted.
diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
index 4a42fd84f..9de753e 100644
--- a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
@@ -16,7 +16,7 @@
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #include "net/base/mime_util.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
@@ -568,8 +568,8 @@
 
 std::string PepperFileSystemBrowserHost::GetPluginMimeType() const {
   base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath();
-  const PepperPluginInfo* info =
-      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path);
+  const ContentPluginInfo* info =
+      PluginService::GetInstance()->GetRegisteredPluginInfo(plugin_path);
   if (!info || info->mime_types.empty())
     return std::string();
   // Use the first element in |info->mime_types| even if several elements exist.
diff --git a/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc b/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
index ed499f3..6d2ec39 100644
--- a/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
@@ -152,8 +152,10 @@
       network::mojom::ResolveHostParameters::New();
   PrepareRequestInfo(hint, parameters.get());
 
+  // Intentionally using a HostPortPair because scheme isn't specified.
   storage_partition->GetNetworkContext()->ResolveHost(
-      net::HostPortPair(host_port.host, host_port.port),
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair(host_port.host, host_port.port)),
       render_frame_host->GetNetworkIsolationKey(), std::move(parameters),
       receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
index 384dd8b..eca91ef 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -389,10 +389,13 @@
   if (!render_frame_host)
     return PP_ERROR_FAILED;
 
+  // Intentionally using a HostPortPair because scheme isn't specified.
   // TODO(mmenke): Pass in correct NetworkIsolationKey.
-  network_context->ResolveHost(net::HostPortPair(host, port),
-                               render_frame_host->GetNetworkIsolationKey(),
-                               nullptr, receiver_.BindNewPipeAndPassRemote());
+  network_context->ResolveHost(
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair(host, port)),
+      render_frame_host->GetNetworkIsolationKey(), nullptr,
+      receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(
       base::BindOnce(&PepperTCPSocketMessageFilter::OnComplete,
                      base::Unretained(this), net::ERR_NAME_NOT_RESOLVED,
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index bdc49f5b..a8cd62e 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2907,7 +2907,10 @@
 RenderFrameHostImpl::AccessibilityGetAcceleratedWidget() {
   // Only the active RenderFrameHost is connected to the native widget tree for
   // accessibility, so return null if this is queried on any other frame.
-  if (!is_main_frame() || !IsActive())
+  // TODO(crbug.com/1316388): With MPArch there may be embedded main frames
+  // and so is_main_frame should not be used to identify all embedded frames.
+  // Follow up to confirm correctness.
+  if (!AccessibilityIsMainFrame() || !IsActive())
     return gfx::kNullAcceleratedWidget;
 
   RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
@@ -3069,7 +3072,10 @@
     // frames arguably are renderer-created.
     //
     // TODO(https://crbug.com/1194421): Address the prerendering case.
-    if (is_main_frame() && !renderer_initiated_creation_of_main_frame &&
+    // TODO(crbug.com/1316388): With MPArch there may be embedded main frames
+    // and so is_main_frame should not be used to identify all embedded frames.
+    // Follow up to confirm correctness.
+    if (IsOutermostMainFrame() && !renderer_initiated_creation_of_main_frame &&
         lifecycle_state_ != LifecycleStateImpl::kPrerendering) {
       policies.ip_address_space = network::mojom::IPAddressSpace::kLocal;
     }
@@ -3388,6 +3394,8 @@
     // (1) to allow the process to be potentially reused by future navigations
     // withjin a short time window, and
     // (2) to give the subframe unload handlers a chance to execute.
+    // TODO(crbug.com/1356280): consider delaying process shutdown for fenced
+    // frames.
     if (!is_main_frame() && IsActive()) {
       base::TimeDelta subframe_shutdown_timeout =
           frame_tree_->IsBeingDestroyed()
@@ -7025,7 +7033,10 @@
           DisallowActivationReasonId::kCapturePaintPreview))
     return;
   // This should only be called on a subframe.
-  if (is_main_frame()) {
+  // TODO(crbug.com/1316388): With MPArch there may be embedded main frames
+  // and so is_main_frame should not be used to identify all embedded frames.
+  // Follow up to confirm correctness.
+  if (IsOutermostMainFrame()) {
     bad_message::ReceivedBadMessage(
         GetProcess(), bad_message::RFH_SUBFRAME_CAPTURE_ON_MAIN_FRAME);
     return;
@@ -8334,10 +8345,12 @@
       type == BeforeUnloadType::INNER_DELEGATE_ATTACH;
   DCHECK(for_navigation || for_inner_delegate_attach || !is_reload);
 
-  // TAB_CLOSE and DISCARD should only dispatch beforeunload on main frames.
+  // TAB_CLOSE and DISCARD should only dispatch beforeunload on outermost main
+  // frames.
   DCHECK(type == BeforeUnloadType::BROWSER_INITIATED_NAVIGATION ||
          type == BeforeUnloadType::RENDERER_INITIATED_NAVIGATION ||
-         type == BeforeUnloadType::INNER_DELEGATE_ATTACH || is_main_frame());
+         type == BeforeUnloadType::INNER_DELEGATE_ATTACH ||
+         IsOutermostMainFrame());
 
   if (!for_navigation) {
     // Cancel any pending navigations, to avoid their navigation commit/fail
@@ -8823,6 +8836,10 @@
         "CommitNavigation", "commit_origin",
         common_params->url.DeprecatedGetOriginAsURL().spec());
     SCOPED_CRASH_KEY_BOOL("CommitNavigation", "is_main_frame", is_main_frame());
+    // The reason this isn't is_outermost_main_frame is so that the full name of
+    // the key does not exceed the 40 character limit.
+    SCOPED_CRASH_KEY_BOOL("CommitNavigation", "is_outermost_frame",
+                          IsOutermostMainFrame());
     NOTREACHED() << "Commiting in incompatible process for URL: "
                  << process_lock.lock_url() << " lock vs "
                  << common_params->url.DeprecatedGetOriginAsURL();
@@ -10232,7 +10249,10 @@
 
 ui::AXTreeID RenderFrameHostImpl::GetFocusedAXTreeID() {
   // If this is not the root frame tree node, we're done.
-  if (!is_main_frame())
+  // TODO(crbug.com/1316388): With MPArch there may be embedded main frames
+  // and so is_main_frame should not be used to identify all embedded frames.
+  // Follow up to confirm correctness.
+  if (!AccessibilityIsMainFrame())
     return ui::AXTreeIDUnknown();
 
   RenderFrameHostImpl* focused_frame = delegate_->GetFocusedFrame();
@@ -10601,12 +10621,16 @@
   auto is_shutting_down_cb = base::BindRepeating(
       []() { return GetContentClient()->browser()->IsShuttingDown(); });
 
+  // TODO(crbug.com/1316388): With MPArch there may be embedded main frames
+  // and so is_main_frame should not be used to identify all embedded frames.
+  // Follow up to confirm correctness.
   media::MediaMetricsProvider::Create(
       GetProcess()->GetBrowserContext()->IsOffTheRecord()
           ? media::MediaMetricsProvider::BrowsingMode::kIncognito
           : media::MediaMetricsProvider::BrowsingMode::kNormal,
-      is_main_frame() ? media::MediaMetricsProvider::FrameStatus::kTopFrame
-                      : media::MediaMetricsProvider::FrameStatus::kNotTopFrame,
+      IsOutermostMainFrame()
+          ? media::MediaMetricsProvider::FrameStatus::kTopFrame
+          : media::MediaMetricsProvider::FrameStatus::kNotTopFrame,
       GetPage().last_main_document_source_id(),
       media::learning::FeatureValue(GetLastCommittedOrigin().host()),
       std::move(save_stats_cb),
@@ -12304,7 +12328,7 @@
       BuildCommitNavigationCallback(navigation_request));
   base::UmaHistogramTimes(
       base::StrCat({"Navigation.SendCommitNavigationTime.",
-                    is_main_frame() ? "MainFrame" : "Subframe"}),
+                    IsOutermostMainFrame() ? "MainFrame" : "Subframe"}),
       timer.Elapsed());
 }
 
@@ -12672,6 +12696,12 @@
   base::debug::SetCrashKeyString(is_main_frame_key,
                                  bool_to_crash_key(is_main_frame()));
 
+  static auto* const is_outermost_frame_key =
+      base::debug::AllocateCrashKeyString("is_outermost_frame",
+                                          base::debug::CrashKeySize::Size32);
+  base::debug::SetCrashKeyString(is_outermost_frame_key,
+                                 bool_to_crash_key(IsOutermostMainFrame()));
+
   static auto* const is_cross_process_subframe_key =
       base::debug::AllocateCrashKeyString("is_cross_process_subframe",
                                           base::debug::CrashKeySize::Size32);
@@ -13904,21 +13934,22 @@
   // have |is_cross_origin_frame| set to false, even though this frame is cross-
   // origin from its parent frame B. This value is only used in manual analysis.
   bool is_cross_origin_frame =
-      !is_main_frame() &&
-      !GetMainFrame()->GetLastCommittedOrigin().IsSameOriginWith(origin);
+      !IsOutermostMainFrame() &&
+      !GetOutermostMainFrame()->GetLastCommittedOrigin().IsSameOriginWith(
+          origin);
 
   // Compares the subframe site with the main frame site. In the case of
   // nested subframes such as A(B(A)), the bottom-most frame A is expected to
   // have |is_cross_site_frame| set to false, even though this frame is cross-
   // site from its parent frame B. This value is only used in manual analysis.
   bool is_cross_site_frame =
-      !is_main_frame() &&
+      !IsOutermostMainFrame() &&
       (net::SchemefulSite(origin) !=
-       net::SchemefulSite(GetMainFrame()->GetLastCommittedOrigin()));
+       net::SchemefulSite(GetOutermostMainFrame()->GetLastCommittedOrigin()));
 
   ukm::builders::DocumentCreated(document_ukm_source_id)
       .SetNavigationSourceId(GetPageUkmSourceId())
-      .SetIsMainFrame(is_main_frame())
+      .SetIsMainFrame(IsOutermostMainFrame())
       .SetIsCrossOriginFrame(is_cross_origin_frame)
       .SetIsCrossSiteFrame(is_cross_site_frame)
       .Record(ukm_recorder);
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc
index 7ad4146..3bdc794 100644
--- a/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "content/browser/child_process_security_policy_impl.h"
@@ -22,6 +23,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/navigation_simulator.h"
+#include "content/public/test/scoped_web_ui_controller_factory_registration.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_utils.h"
 #include "content/test/storage_partition_test_helpers.h"
@@ -32,6 +34,7 @@
 #include "third_party/blink/public/common/frame/frame_policy.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
 #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
+#include "ui/webui/untrusted_web_ui_browsertest_util.h"
 
 namespace content {
 
@@ -431,6 +434,140 @@
             sw_site_instance2->GetLastProcessAssignmentOutcome());
 }
 
+class RenderProcessHostUntrustedWebUIUnitTest
+    : public RenderProcessHostUnitTest {
+ public:
+  void SetUp() override {
+    RenderProcessHostUnitTest::SetUp();
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kEnableServiceWorkersForChromeUntrusted);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(RenderProcessHostUntrustedWebUIUnitTest,
+       DontReuseServiceWorkerProcessForDifferentWebUI) {
+  ScopedWebUIConfigRegistration config_registration1(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("test-host"));
+  ScopedWebUIConfigRegistration config_registration2(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("second-host"));
+
+  const GURL kWebUI1("chrome-untrusted://test-host/");
+  const GURL kWebUI2("chrome-untrusted://second-host/");
+
+  // Gets a RenderProcessHost for an unmatched service worker.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
+      CreateForServiceWorker(kWebUI1);
+  RenderProcessHost* sw_host = sw_site_instance1->GetProcess();
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance1->GetLastProcessAssignmentOutcome());
+
+  // Discard the spare, so it cannot be considered by the GetProcess call below.
+  RenderProcessHostImpl::DiscardSpareRenderProcessHostForTesting();
+
+  // Getting RenderProcessHost for a service worker for a different WebUI
+  // should return a new process because there is no reusable process.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance2 = CreateForUrl(kWebUI2);
+  EXPECT_NE(sw_host, sw_site_instance2->GetProcess());
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance2->GetLastProcessAssignmentOutcome());
+}
+
+TEST_F(RenderProcessHostUntrustedWebUIUnitTest,
+       DontReuseServiceWorkerProcessForWebUrl) {
+  ScopedWebUIConfigRegistration config_registration1(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("test-host"));
+
+  const GURL kWebUI1("chrome-untrusted://test-host/");
+
+  // Gets a RenderProcessHost for an unmatched service worker.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
+      CreateForServiceWorker(kWebUI1);
+  RenderProcessHost* sw_host = sw_site_instance1->GetProcess();
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance1->GetLastProcessAssignmentOutcome());
+
+  const GURL kWebUrl("https://test.example/");
+
+  // Getting RenderProcessHost for a service worker for a regular site should
+  // return a new process because there is no reusable process.
+  scoped_refptr<SiteInstanceImpl> web_sw_site_instance =
+      CreateForServiceWorker(kWebUrl);
+  EXPECT_NE(sw_host, web_sw_site_instance->GetProcess());
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            web_sw_site_instance->GetLastProcessAssignmentOutcome());
+
+  // Getting RenderProcessHost for a navigation to a regular site should
+  // re-use the Web Service Worker process and not the WebUI one.
+  scoped_refptr<SiteInstanceImpl> web_site_instance = CreateForUrl(kWebUrl);
+  EXPECT_NE(sw_host, web_site_instance->GetProcess());
+  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
+            web_site_instance->GetLastProcessAssignmentOutcome());
+}
+
+// Tests that Service Worker processes for WebUIs are not re-used even
+// for the same WebUI. Ideally we would re-use the process if it's for
+// the same WebUI but we currently don't because of crbug.com/1158277.
+TEST_F(RenderProcessHostUntrustedWebUIUnitTest,
+       DontReuseServiceWorkerProcessForSameWebUI) {
+  ScopedWebUIConfigRegistration config_registration(
+      std::make_unique<ui::TestUntrustedWebUIConfig>("test-host"));
+  const GURL kUrl("chrome-untrusted://test-host");
+
+  // Gets a RenderProcessHost for a service worker.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
+      CreateForServiceWorker(kUrl,
+                             /*can_reuse_process=*/true);
+  RenderProcessHost* sw_host1 = sw_site_instance1->GetProcess();
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance1->GetLastProcessAssignmentOutcome());
+
+  // Getting a RenderProcessHost for a service worker with DEFAULT reuse policy
+  // should not reuse the existing service worker's process. This is because
+  // we use DEFAULT reuse policy for a service worker when we have failed to
+  // start the service worker and want to use a new process. We create this
+  // second service worker to test the "find the newest process" logic later.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance2 =
+      CreateForServiceWorker(kUrl);
+  RenderProcessHost* sw_host2 = sw_site_instance2->GetProcess();
+  EXPECT_NE(sw_host1, sw_host2);
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance2->GetLastProcessAssignmentOutcome());
+
+  // Getting a RenderProcessHost for a service worker of the same WebUI with
+  // REUSE_PENDING_OR_COMMITTED_SITE reuse policy doesn't reuse any service
+  // worker processes.
+  scoped_refptr<SiteInstanceImpl> sw_site_instance3 =
+      CreateForServiceWorker(kUrl,
+                             /*can_reuse_process=*/true);
+  RenderProcessHost* sw_host3 = sw_site_instance3->GetProcess();
+  EXPECT_NE(sw_host1, sw_host3);
+  EXPECT_NE(sw_host2, sw_host3);
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            sw_site_instance3->GetLastProcessAssignmentOutcome());
+
+  // Getting a RenderProcessHost for a navigation to the same WebUI doesn't
+  // reuse any service worker's processes.
+  scoped_refptr<SiteInstanceImpl> site_instance1 = CreateForUrl(kUrl);
+  EXPECT_NE(sw_host1, site_instance1->GetProcess());
+  EXPECT_NE(sw_host2, site_instance1->GetProcess());
+  EXPECT_NE(sw_host3, site_instance1->GetProcess());
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            site_instance1->GetLastProcessAssignmentOutcome());
+
+  // Getting a RenderProcessHost for a navigation to a web URL doesn't reuse any
+  // service worker's processes.
+  const GURL kWebUrl("https://test.example");
+  scoped_refptr<SiteInstanceImpl> web_site_instance = CreateForUrl(kWebUrl);
+  EXPECT_NE(sw_host1, web_site_instance->GetProcess());
+  EXPECT_NE(sw_host2, web_site_instance->GetProcess());
+  EXPECT_NE(sw_host3, web_site_instance->GetProcess());
+  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
+            web_site_instance->GetLastProcessAssignmentOutcome());
+}
+
 // Tests that RenderProcessHost will not consider reusing a process that has
 // committed an error page.
 TEST_F(RenderProcessHostUnitTest, DoNotReuseError) {
diff --git a/content/browser/sandbox_parameters_mac.mm b/content/browser/sandbox_parameters_mac.mm
index 8149c11..921fb95 100644
--- a/content/browser/sandbox_parameters_mac.mm
+++ b/content/browser/sandbox_parameters_mac.mm
@@ -34,7 +34,7 @@
 
 #if BUILDFLAG(ENABLE_PPAPI)
 #include "content/public/browser/plugin_service.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/webplugininfo.h"
 #endif
 
 namespace content {
diff --git a/content/browser/service_worker/fake_embedded_worker_instance_client.cc b/content/browser/service_worker/fake_embedded_worker_instance_client.cc
index 3f00485..0eaa783 100644
--- a/content/browser/service_worker/fake_embedded_worker_instance_client.cc
+++ b/content/browser/service_worker/fake_embedded_worker_instance_client.cc
@@ -62,12 +62,13 @@
 
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
   }
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {}
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {}
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override {}
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc
index 3b4faa9..888e27e 100644
--- a/content/browser/service_worker/service_worker_container_host.cc
+++ b/content/browser/service_worker/service_worker_container_host.cc
@@ -720,7 +720,7 @@
     return existing_object_host->second->CreateCompleteObjectInfoToSend();
   }
   service_worker_object_hosts_[version_id] =
-      std::make_unique<ServiceWorkerObjectHost>(context_, this,
+      std::make_unique<ServiceWorkerObjectHost>(context_, GetWeakPtr(),
                                                 std::move(version));
   return service_worker_object_hosts_[version_id]
       ->CreateCompleteObjectInfoToSend();
@@ -739,7 +739,7 @@
     return existing_object_host->second->AsWeakPtr();
 
   service_worker_object_hosts_[version_id] =
-      std::make_unique<ServiceWorkerObjectHost>(context_, this,
+      std::make_unique<ServiceWorkerObjectHost>(context_, GetWeakPtr(),
                                                 std::move(version));
   return service_worker_object_hosts_[version_id]->AsWeakPtr();
 }
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index ffbacf6..47692adc 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -130,17 +130,16 @@
     client_->OnUploadProgress(current_position, total_size,
                               std::move(ack_callback));
   }
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    client_->OnReceiveCachedMetadata(std::move(data));
-  }
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     client_->OnTransferSizeUpdated(transfer_size_diff);
   }
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
     client_->OnReceiveEarlyHints(std::move(early_hints));
   }
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     if (devtools_enabled_) {
       // Make a deep copy of URLResponseHead before posting it to a task.
       auto deep_copied_response = head.Clone();
@@ -153,7 +152,8 @@
           base::BindOnce(&NotifyNavigationPreloadResponseReceived, url_,
                          std::move(deep_copied_response)));
     }
-    client_->OnReceiveResponse(std::move(head), std::move(body));
+    client_->OnReceiveResponse(std::move(head), std::move(body),
+                               std::move(cached_metadata));
   }
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override {
diff --git a/content/browser/service_worker/service_worker_installed_script_loader.cc b/content/browser/service_worker/service_worker_installed_script_loader.cc
index 3f8d6443..c041004 100644
--- a/content/browser/service_worker/service_worker_installed_script_loader.cc
+++ b/content/browser/service_worker/service_worker_installed_script_loader.cc
@@ -72,10 +72,8 @@
             *response_head));
   }
 
-  client_->OnReceiveResponse(std::move(response_head), std::move(body_handle));
-  if (metadata) {
-    client_->OnReceiveCachedMetadata(std::move(*metadata));
-  }
+  client_->OnReceiveResponse(std::move(response_head), std::move(body_handle),
+                             std::move(metadata));
   // We continue in OnFinished().
 }
 
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.cc b/content/browser/service_worker/service_worker_main_resource_loader.cc
index 98bdd538..84fbe30 100644
--- a/content/browser/service_worker/service_worker_main_resource_loader.cc
+++ b/content/browser/service_worker/service_worker_main_resource_loader.cc
@@ -197,10 +197,12 @@
 }
 
 void ServiceWorkerMainResourceLoader::CommitResponseBody(
-    mojo::ScopedDataPipeConsumerHandle response_body) {
+    mojo::ScopedDataPipeConsumerHandle response_body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TransitionToStatus(Status::kSentBody);
   url_loader_client_->OnReceiveResponse(response_head_.Clone(),
-                                        std::move(response_body));
+                                        std::move(response_body),
+                                        std::move(cached_metadata));
 }
 
 void ServiceWorkerMainResourceLoader::CommitEmptyResponseAndComplete() {
@@ -214,7 +216,7 @@
   }
 
   producer_handle.reset();  // The data pipe is empty.
-  CommitResponseBody(std::move(consumer_handle));
+  CommitResponseBody(std::move(consumer_handle), absl::nullopt);
   CommitCompleted(net::OK, "No body exists.");
 }
 
@@ -396,7 +398,7 @@
         "stream response");
     stream_waiter_ = std::make_unique<StreamWaiter>(
         this, std::move(body_as_stream->callback_receiver));
-    CommitResponseBody(std::move(body_as_stream->stream));
+    CommitResponseBody(std::move(body_as_stream->stream), absl::nullopt);
     // StreamWaiter will call CommitCompleted() when done.
     return;
   }
@@ -420,7 +422,7 @@
         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result",
         "blob response");
 
-    CommitResponseBody(std::move(data_pipe));
+    CommitResponseBody(std::move(data_pipe), absl::nullopt);
     // We continue in OnBlobReadingComplete().
     return;
   }
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.h b/content/browser/service_worker/service_worker_main_resource_loader.h
index 3008ddf..7c32e2a 100644
--- a/content/browser/service_worker/service_worker_main_resource_loader.h
+++ b/content/browser/service_worker/service_worker_main_resource_loader.h
@@ -128,8 +128,9 @@
   void CommitResponseHeaders();
 
   // Calls url_loader_client_->OnReceiveResponse() with
-  // |response_body|.
-  void CommitResponseBody(mojo::ScopedDataPipeConsumerHandle response_body);
+  // |response_body| and |cached_metadata|.
+  void CommitResponseBody(mojo::ScopedDataPipeConsumerHandle response_body,
+                          absl::optional<mojo_base::BigBuffer> cached_metadata);
 
   // Creates and sends an empty response's body with the net::OK status.
   // Sends net::ERR_INSUFFICIENT_RESOURCES when it can't be created.
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
index f2672a11..8155031 100644
--- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
+++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "build/chromeos_buildflags.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
 #include "content/browser/renderer_host/navigation_request_info.h"
@@ -225,7 +226,7 @@
   // cause for https://crbug.com/1346450.
   absl::optional<blink::StorageKey> storage_key =
       GetStorageKeyFromRenderFrameHost(
-          new_origin, base::OptionalOrNullptr(isolation_info_.nonce()));
+          new_origin, base::OptionalToPtr(isolation_info_.nonce()));
   if (!storage_key.has_value()) {
     storage_key = GetStorageKeyFromWorkerHost(new_origin);
   }
diff --git a/content/browser/service_worker/service_worker_new_script_fetcher.cc b/content/browser/service_worker/service_worker_new_script_fetcher.cc
index 6a7ab4b..7af940b 100644
--- a/content/browser/service_worker/service_worker_new_script_fetcher.cc
+++ b/content/browser/service_worker/service_worker_new_script_fetcher.cc
@@ -126,7 +126,8 @@
 
 void ServiceWorkerNewScriptFetcher::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle response_body) {
+    mojo::ScopedDataPipeConsumerHandle response_body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (!response_body)
     return;
 
@@ -155,10 +156,6 @@
                                                      OnUploadProgressCallback) {
   mojo::ReportBadMessage("SWNSF_BAD_MSG");
 }
-void ServiceWorkerNewScriptFetcher::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  mojo::ReportBadMessage("SWNSF_BAD_MSG");
-}
 void ServiceWorkerNewScriptFetcher::OnTransferSizeUpdated(int32_t) {
   mojo::ReportBadMessage("SWNSF_BAD_MSG");
 }
diff --git a/content/browser/service_worker/service_worker_new_script_fetcher.h b/content/browser/service_worker/service_worker_new_script_fetcher.h
index 17265a6..2f2a5e21 100644
--- a/content/browser/service_worker/service_worker_new_script_fetcher.h
+++ b/content/browser/service_worker/service_worker_new_script_fetcher.h
@@ -60,14 +60,14 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
   void OnReceiveResponse(
       network::mojom::URLResponseHeadPtr response_head,
-      mojo::ScopedDataPipeConsumerHandle response_body) override;
+      mojo::ScopedDataPipeConsumerHandle response_body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc
index 1b58760..80507d3 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -216,7 +216,8 @@
 
 void ServiceWorkerNewScriptLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK_EQ(LoaderState::kLoadingHeader, network_loader_state_);
   if (!version_->context() || version_->is_redundant()) {
     CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED),
@@ -293,7 +294,8 @@
 
   if (!body) {
     client_->OnReceiveResponse(std::move(response_head),
-                               mojo::ScopedDataPipeConsumerHandle());
+                               mojo::ScopedDataPipeConsumerHandle(),
+                               std::move(cached_metadata));
     return;
   }
 
@@ -309,7 +311,8 @@
 
   // Pass the consumer handle for responding with the response to the client.
   client_->OnReceiveResponse(std::move(response_head),
-                             std::move(client_consumer));
+                             std::move(client_consumer),
+                             std::move(cached_metadata));
 
   network_consumer_ = std::move(body);
   network_loader_state_ = LoaderState::kLoadingBody;
@@ -338,11 +341,6 @@
                             std::move(ack_callback));
 }
 
-void ServiceWorkerNewScriptLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void ServiceWorkerNewScriptLoader::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   client_->OnTransferSizeUpdated(transfer_size_diff);
diff --git a/content/browser/service_worker/service_worker_new_script_loader.h b/content/browser/service_worker/service_worker_new_script_loader.h
index 62bbf1a..ab25ba3 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.h
+++ b/content/browser/service_worker/service_worker_new_script_loader.h
@@ -116,15 +116,16 @@
 
   // network::mojom::URLLoaderClient for the network load:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
index 8fe7e65..d8228a4 100644
--- a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
@@ -123,7 +123,8 @@
     MojoResult result = producer->WriteData(
         response.body.data(), &bytes_written, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
     CHECK_EQ(MOJO_RESULT_OK, result);
-    client->OnReceiveResponse(std::move(response_head), std::move(consumer));
+    client->OnReceiveResponse(std::move(response_head), std::move(consumer),
+                              absl::nullopt);
 
     network::URLLoaderCompletionStatus status;
     status.error_code = net::OK;
diff --git a/content/browser/service_worker/service_worker_object_host.cc b/content/browser/service_worker/service_worker_object_host.cc
index a60d8c8..406a947 100644
--- a/content/browser/service_worker/service_worker_object_host.cc
+++ b/content/browser/service_worker/service_worker_object_host.cc
@@ -194,7 +194,7 @@
 
 ServiceWorkerObjectHost::ServiceWorkerObjectHost(
     base::WeakPtr<ServiceWorkerContextCore> context,
-    ServiceWorkerContainerHost* container_host,
+    base::WeakPtr<ServiceWorkerContainerHost> container_host,
     scoped_refptr<ServiceWorkerVersion> version)
     : context_(context),
       container_host_(container_host),
@@ -279,6 +279,7 @@
 void ServiceWorkerObjectHost::DispatchExtendableMessageEvent(
     ::blink::TransferableMessage message,
     StatusCallback callback) {
+  DCHECK(container_host_);
   if (!context_) {
     std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
     return;
@@ -299,7 +300,7 @@
                        container_host_->GetWeakPtr()));
   } else if (container_host_->IsContainerForWindowClient()) {
     service_worker_client_utils::GetClient(
-        container_host_,
+        container_host_.get(),
         base::BindOnce(&DispatchExtendableMessageEventFromClient, context_,
                        version_, std::move(message), container_origin_,
                        std::move(callback)));
@@ -316,6 +317,7 @@
   // If there are still receivers, |this| is still being used.
   if (!receivers_.empty())
     return;
+  DCHECK(container_host_);
   // Will destroy |this|.
   container_host_->RemoveServiceWorkerObjectHost(version_->version_id());
 }
diff --git a/content/browser/service_worker/service_worker_object_host.h b/content/browser/service_worker/service_worker_object_host.h
index e3c117c5..78d8dec 100644
--- a/content/browser/service_worker/service_worker_object_host.h
+++ b/content/browser/service_worker/service_worker_object_host.h
@@ -41,9 +41,10 @@
     : public blink::mojom::ServiceWorkerObjectHost,
       public ServiceWorkerVersion::Observer {
  public:
-  ServiceWorkerObjectHost(base::WeakPtr<ServiceWorkerContextCore> context,
-                          ServiceWorkerContainerHost* container_host,
-                          scoped_refptr<ServiceWorkerVersion> version);
+  ServiceWorkerObjectHost(
+      base::WeakPtr<ServiceWorkerContextCore> context,
+      base::WeakPtr<ServiceWorkerContainerHost> container_host,
+      scoped_refptr<ServiceWorkerVersion> version);
 
   ServiceWorkerObjectHost(const ServiceWorkerObjectHost&) = delete;
   ServiceWorkerObjectHost& operator=(const ServiceWorkerObjectHost&) = delete;
@@ -104,7 +105,22 @@
   base::WeakPtr<ServiceWorkerContextCore> context_;
   // |container_host_| is valid throughout lifetime of |this| because it owns
   // |this|.
-  const raw_ptr<ServiceWorkerContainerHost, DanglingUntriaged> container_host_;
+  //
+  // However, there exists an exception, because of an ownership cycle
+  // between 1,2,3,4:
+  // 1. ServiceWorkerContainerHost owns via unique_ptr (2)
+  // 2. ServiceWorkerObjectHost owns via scoped_ptr(3)
+  // 3. ServiceWorkerVersion owns via unique_ptr (4)
+  // 4. ServiceWorkerHost owns via unique_ptr (1)
+  //
+  // The cycle is broken in
+  // `ServiceWorkerContainerHost::RemoveServiceWorkerObjectHost`, by
+  // transferring ownership of |this| to the stack, while deleting
+  // |container_host_|.
+  //
+  // As a result, |container_host_| is always valid, except during the
+  // destructor.
+  const base::WeakPtr<ServiceWorkerContainerHost> container_host_;
   // The origin of the |container_host_|. Note that this is const because once a
   // JavaScript ServiceWorker object is created for an execution context, we
   // don't expect that context to change origins and still hold on to the
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc
index d730049..1e9cedb 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker.cc
+++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -199,7 +199,8 @@
 
 void ServiceWorkerSingleScriptUpdateChecker::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle consumer) {
+    mojo::ScopedDataPipeConsumerHandle consumer,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TRACE_EVENT_WITH_FLOW0(
       "ServiceWorker",
       "ServiceWorkerSingleScriptUpdateChecker::OnReceiveResponse", this,
@@ -291,9 +292,6 @@
   NOTREACHED();
 }
 
-void ServiceWorkerSingleScriptUpdateChecker::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {}
-
 void ServiceWorkerSingleScriptUpdateChecker::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {}
 
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.h b/content/browser/service_worker/service_worker_single_script_update_checker.h
index 7a4d937..f1d5dac 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker.h
+++ b/content/browser/service_worker/service_worker_single_script_update_checker.h
@@ -151,15 +151,16 @@
 
   // network::mojom::URLLoaderClient override:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle consumer) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle consumer,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc b/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
index 5aab84d..12e9f03 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
+++ b/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
@@ -492,7 +492,8 @@
   mojo::ScopedDataPipeProducerHandle body_producer;
   ASSERT_EQ(MOJO_RESULT_OK,
             mojo::CreateDataPipe(&options, body_producer, body_consumer));
-  client->OnReceiveResponse(std::move(head), std::move(body_consumer));
+  client->OnReceiveResponse(std::move(head), std::move(body_consumer),
+                            absl::nullopt);
   mojo::BlockingCopyFromString(body_from_net, body_producer);
   body_producer.reset();
 
@@ -794,7 +795,8 @@
     EXPECT_EQ(MOJO_RESULT_OK,
               producer->WriteData(body_from_net.data(), &bytes_written,
                                   MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
-    request->client->OnReceiveResponse(std::move(head), std::move(consumer));
+    request->client->OnReceiveResponse(std::move(head), std::move(consumer),
+                                       absl::nullopt);
   }
 
   // Blocked on reading the header from the storage due to the asynchronous
diff --git a/content/browser/service_worker/service_worker_updated_script_loader.cc b/content/browser/service_worker/service_worker_updated_script_loader.cc
index f135418..b19426d 100644
--- a/content/browser/service_worker/service_worker_updated_script_loader.cc
+++ b/content/browser/service_worker/service_worker_updated_script_loader.cc
@@ -163,7 +163,8 @@
 
 void ServiceWorkerUpdatedScriptLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   NOTREACHED();
 }
 
@@ -180,11 +181,6 @@
   NOTREACHED();
 }
 
-void ServiceWorkerUpdatedScriptLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void ServiceWorkerUpdatedScriptLoader::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   client_->OnTransferSizeUpdated(transfer_size_diff);
@@ -248,7 +244,7 @@
 
   // Pass the consumer handle to the client.
   client_->OnReceiveResponse(std::move(client_response),
-                             std::move(client_consumer));
+                             std::move(client_consumer), absl::nullopt);
 
   client_producer_watcher_.Watch(
       client_producer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
diff --git a/content/browser/service_worker/service_worker_updated_script_loader.h b/content/browser/service_worker/service_worker_updated_script_loader.h
index 81e7e24..225e179 100644
--- a/content/browser/service_worker/service_worker_updated_script_loader.h
+++ b/content/browser/service_worker/service_worker_updated_script_loader.h
@@ -99,15 +99,16 @@
 
   // network::mojom::URLLoaderClient for the network load:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/service_worker/url_loader_client_checker.h b/content/browser/service_worker/url_loader_client_checker.h
index e9e1fcc..a7f6e2d4 100644
--- a/content/browser/service_worker/url_loader_client_checker.h
+++ b/content/browser/service_worker/url_loader_client_checker.h
@@ -35,10 +35,13 @@
     void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) {
       client_->OnReceiveEarlyHints(std::move(early_hints));
     }
-    void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                           mojo::ScopedDataPipeConsumerHandle body) {
+    void OnReceiveResponse(
+        network::mojom::URLResponseHeadPtr head,
+        mojo::ScopedDataPipeConsumerHandle body,
+        absl::optional<mojo_base::BigBuffer> cached_metadata) {
       on_receive_response_called_ = true;
-      client_->OnReceiveResponse(std::move(head), std::move(body));
+      client_->OnReceiveResponse(std::move(head), std::move(body),
+                                 std::move(cached_metadata));
     }
     void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                            network::mojom::URLResponseHeadPtr head) {
@@ -51,9 +54,6 @@
       client_->OnUploadProgress(current_position, total_size,
                                 std::move(callback));
     }
-    void OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-      client_->OnReceiveCachedMetadata(std::move(data));
-    }
     void OnTransferSizeUpdated(int32_t transfer_size_diff) {
       client_->OnTransferSizeUpdated(transfer_size_diff);
     }
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc
index f21a963..1e01459 100644
--- a/content/browser/shared_storage/shared_storage_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -68,6 +68,9 @@
 
 const char kErrorTypeHistogram[] = "Storage.SharedStorage.Worklet.Error.Type";
 
+const char kTimingUsefulResourceHistogram[] =
+    "Storage.SharedStorage.Worklet.Timing.UsefulResourceDuration";
+
 const double kBudgetAllowed = 5.0;
 
 const char kSelectFrom8URLsScript[] = R"(
@@ -503,11 +506,13 @@
 
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  WaitForHistograms({kDestroyedStatusHistogram});
+  WaitForHistograms(
+      {kDestroyedStatusHistogram, kTimingUsefulResourceHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, AddModule_ScriptNotFound) {
@@ -623,11 +628,13 @@
 
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  WaitForHistograms({kDestroyedStatusHistogram});
+  WaitForHistograms(
+      {kDestroyedStatusHistogram, kTimingUsefulResourceHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, RunOperation_Success) {
@@ -711,15 +718,16 @@
 
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  WaitForHistograms({kDestroyedStatusHistogram, kErrorTypeHistogram});
+  WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
+                     kErrorTypeHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 1);
-
   histogram_tester_.ExpectUniqueSample(
       kErrorTypeHistogram,
       blink::SharedStorageWorkletErrorType::kRunNonWebVisible, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -814,11 +822,13 @@
   EXPECT_EQ(0u, test_worklet_host_manager().GetAttachedWorkletHostsCount());
   EXPECT_EQ(0u, test_worklet_host_manager().GetKeepAliveWorkletHostsCount());
 
-  WaitForHistograms({kDestroyedStatusHistogram});
+  WaitForHistograms(
+      {kDestroyedStatusHistogram, kTimingUsefulResourceHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, TwoWorklets) {
@@ -870,11 +880,13 @@
 
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  WaitForHistograms({kDestroyedStatusHistogram});
+  WaitForHistograms(
+      {kDestroyedStatusHistogram, kTimingUsefulResourceHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 2);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 2);
 }
 
 IN_PROC_BROWSER_TEST_F(
@@ -927,8 +939,8 @@
   // dropped.
   EXPECT_EQ(0u, console_observer.messages().size());
 
-  WaitForHistograms(
-      {kDestroyedStatusHistogram, kTimingKeepAliveDurationHistogram});
+  WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
+                     kTimingKeepAliveDurationHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
@@ -936,6 +948,7 @@
           kKeepAliveEndedDueToOperationsFinished,
       1);
   histogram_tester_.ExpectTotalCount(kTimingKeepAliveDurationHistogram, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -983,13 +996,15 @@
   EXPECT_EQ(0u, test_worklet_host_manager().GetAttachedWorkletHostsCount());
   EXPECT_EQ(0u, test_worklet_host_manager().GetKeepAliveWorkletHostsCount());
 
-  WaitForHistograms({kDestroyedStatusHistogram});
+  WaitForHistograms(
+      {kDestroyedStatusHistogram, kTimingUsefulResourceHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kKeepAliveEndedDueToTimeout,
       1);
   histogram_tester_.ExpectTotalCount(kTimingKeepAliveDurationHistogram, 0);
+  histogram_tester_.ExpectUniqueSample(kTimingUsefulResourceHistogram, 100, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(
@@ -1051,8 +1066,8 @@
   // dropped.
   EXPECT_EQ(2u, console_observer.messages().size());
 
-  WaitForHistograms(
-      {kDestroyedStatusHistogram, kTimingKeepAliveDurationHistogram});
+  WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
+                     kTimingKeepAliveDurationHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
@@ -1060,6 +1075,7 @@
           kKeepAliveEndedDueToOperationsFinished,
       1);
   histogram_tester_.ExpectTotalCount(kTimingKeepAliveDurationHistogram, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, KeepAlive_SubframeWorklet) {
@@ -1136,8 +1152,8 @@
 
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  WaitForHistograms(
-      {kDestroyedStatusHistogram, kTimingKeepAliveDurationHistogram});
+  WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
+                     kTimingKeepAliveDurationHistogram});
 
   histogram_tester_.ExpectBucketCount(
       kDestroyedStatusHistogram,
@@ -1148,6 +1164,7 @@
       kDestroyedStatusHistogram,
       blink::SharedStorageWorkletDestroyedStatus::kDidNotEnterKeepAlive, 1);
   histogram_tester_.ExpectTotalCount(kTimingKeepAliveDurationHistogram, 1);
+  histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 2);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.cc b/content/browser/shared_storage/shared_storage_worklet_host.cc
index 6ed08ad6..eb6256c 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.cc
+++ b/content/browser/shared_storage/shared_storage_worklet_host.cc
@@ -89,12 +89,27 @@
           document_service.render_frame_host().GetBrowserContext()),
       shared_storage_origin_(
           document_service.render_frame_host().GetLastCommittedOrigin()),
-      main_frame_origin_(document_service.main_frame_origin()) {}
+      main_frame_origin_(document_service.main_frame_origin()),
+      creation_time_(base::TimeTicks::Now()) {}
 
 SharedStorageWorkletHost::~SharedStorageWorkletHost() {
   base::UmaHistogramEnumeration("Storage.SharedStorage.Worklet.DestroyedStatus",
                                 destroyed_status_);
 
+  base::TimeDelta elapsed_time_since_creation =
+      base::TimeTicks::Now() - creation_time_;
+  if (pending_operations_count_ > 0 ||
+      last_operation_finished_time_.is_null() ||
+      elapsed_time_since_creation.is_zero()) {
+    base::UmaHistogramCounts100(
+        "Storage.SharedStorage.Worklet.Timing.UsefulResourceDuration", 100);
+  } else {
+    base::UmaHistogramCounts100(
+        "Storage.SharedStorage.Worklet.Timing.UsefulResourceDuration",
+        100 * (last_operation_finished_time_ - creation_time_) /
+            elapsed_time_since_creation);
+  }
+
   if (!page_)
     return;
 
@@ -658,7 +673,14 @@
   base::CheckedNumeric<uint32_t> count = pending_operations_count_;
   pending_operations_count_ = (--count).ValueOrDie();
 
-  if (!IsInKeepAlivePhase() || pending_operations_count_)
+  if (pending_operations_count_)
+    return;
+
+  // This time will be overridden if another operation is subsequently queued
+  // and completed.
+  last_operation_finished_time_ = base::TimeTicks::Now();
+
+  if (!IsInKeepAlivePhase())
     return;
 
   FinishKeepAlive(/*timeout_reached=*/false);
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.h b/content/browser/shared_storage/shared_storage_worklet_host.h
index c9c35b3..1590b9d 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.h
+++ b/content/browser/shared_storage/shared_storage_worklet_host.h
@@ -225,6 +225,13 @@
   // Timer for starting and ending the keep-alive phase.
   base::OneShotTimer keep_alive_timer_;
 
+  // Time when worklet host is constructed.
+  base::TimeTicks creation_time_;
+
+  // Last time when `pending_operations_count_` reaches 0u after being positive.
+  base::TimeTicks last_operation_finished_time_;
+
+  // Time when worklet host entered keep-alive, if applicable.
   base::TimeTicks enter_keep_alive_time_;
 
   // Tracks whether the worklet has ever been kept-alive (in order to be
diff --git a/content/browser/speech/speech_recognition_engine_unittest.cc b/content/browser/speech/speech_recognition_engine_unittest.cc
index 9d84d1e2..01aa010 100644
--- a/content/browser/speech/speech_recognition_engine_unittest.cc
+++ b/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -571,8 +571,8 @@
   ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
             MOJO_RESULT_OK);
 
-  downstream_request->client->OnReceiveResponse(std::move(head),
-                                                std::move(consumer_handle));
+  downstream_request->client->OnReceiveResponse(
+      std::move(head), std::move(consumer_handle), absl::nullopt);
   downstream_data_pipe_ = std::move(producer_handle);
 }
 
@@ -637,7 +637,7 @@
     head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
         net::HttpUtil::AssembleRawHeaders(headers));
     downstream_request->client->OnReceiveResponse(
-        std::move(head), mojo::ScopedDataPipeConsumerHandle());
+        std::move(head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
     // Wait for the response to be handled.
     base::RunLoop().RunUntilIdle();
     return;
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc
index 19beb5377..83528168 100644
--- a/content/browser/web_package/prefetched_signed_exchange_cache.cc
+++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -289,7 +289,7 @@
       return;
     }
     client_->OnReceiveResponse(std::move(response_),
-                               std::move(pipe_consumer_handle));
+                               std::move(pipe_consumer_handle), absl::nullopt);
 
     // Send a dummy OnComplete message.
     network::URLLoaderCompletionStatus status =
@@ -346,7 +346,7 @@
             std::make_unique<storage::BlobDataHandle>(*blob_data_handle_)));
 
     client_->OnReceiveResponse(std::move(response_),
-                               std::move(pipe_consumer_handle));
+                               std::move(pipe_consumer_handle), absl::nullopt);
   }
 
   void BlobReaderComplete(net::Error result) {
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.cc b/content/browser/web_package/signed_exchange_cert_fetcher.cc
index 3b466553..8439cf3 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher.cc
+++ b/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -237,7 +237,8 @@
 
 void SignedExchangeCertFetcher::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
                "SignedExchangeCertFetcher::OnReceiveResponse");
   if (devtools_proxy_) {
@@ -317,12 +318,6 @@
   NOTREACHED();
 }
 
-void SignedExchangeCertFetcher::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  // Cert fetching doesn't use cached metadata.
-  NOTREACHED();
-}
-
 void SignedExchangeCertFetcher::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   // Do nothing.
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.h b/content/browser/web_package/signed_exchange_cert_fetcher.h
index 33d33fd..b9096071 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher.h
+++ b/content/browser/web_package/signed_exchange_cert_fetcher.h
@@ -102,14 +102,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
index 84f1930..7c9c163 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
+++ b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -257,7 +257,7 @@
                                       "application/cert-chain+cbor");
     response_head->mime_type = "application/cert-chain+cbor";
     mock_loader_factory_.client_remote()->OnReceiveResponse(
-        std::move(response_head), std::move(consumer_handle));
+        std::move(response_head), std::move(consumer_handle), absl::nullopt);
   }
 
   DeferringURLLoaderThrottle* InitializeDeferringURLLoaderThrottle() {
@@ -463,7 +463,7 @@
   CHECK(mojo::BlockingCopyFromString(message, producer_handle));
   producer_handle.reset();
   mock_loader_factory_.client_remote()->OnReceiveResponse(
-      std::move(response_head), std::move(consumer_handle));
+      std::move(response_head), std::move(consumer_handle), absl::nullopt);
   mock_loader_factory_.client_remote()->OnComplete(
       network::URLLoaderCompletionStatus(net::OK));
   RunUntilIdle();
@@ -493,7 +493,8 @@
   response_head->headers =
       base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 404 Not Found");
   mock_loader_factory_.client_remote()->OnReceiveResponse(
-      std::move(response_head), mojo::ScopedDataPipeConsumerHandle());
+      std::move(response_head), mojo::ScopedDataPipeConsumerHandle(),
+      absl::nullopt);
   RunUntilIdle();
 
   EXPECT_TRUE(callback_called_);
@@ -510,7 +511,8 @@
   response_head->headers->SetHeader("Content-Type", "application/octet-stream");
   response_head->mime_type = "application/octet-stream";
   mock_loader_factory_.client_remote()->OnReceiveResponse(
-      std::move(response_head), mojo::ScopedDataPipeConsumerHandle());
+      std::move(response_head), mojo::ScopedDataPipeConsumerHandle(),
+      absl::nullopt);
   RunUntilIdle();
 
   EXPECT_TRUE(callback_called_);
diff --git a/content/browser/web_package/signed_exchange_loader.cc b/content/browser/web_package/signed_exchange_loader.cc
index 0468c7b1..2d03d6db 100644
--- a/content/browser/web_package/signed_exchange_loader.cc
+++ b/content/browser/web_package/signed_exchange_loader.cc
@@ -119,7 +119,8 @@
 
 void SignedExchangeLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // Must not be called because this SignedExchangeLoader and the client
   // endpoints were bound after OnReceiveResponse() is called.
   NOTREACHED();
@@ -142,11 +143,6 @@
   NOTREACHED();
 }
 
-void SignedExchangeLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  // CachedMetadata for Signed Exchange is not supported.
-  NOTREACHED();
-}
-
 void SignedExchangeLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   // TODO(https://crbug.com/803774): Implement this to progressively update the
   // encoded data length in DevTools.
@@ -335,7 +331,7 @@
   }
 
   client_->OnReceiveResponse(std::move(inner_response_head_shown_to_client),
-                             std::move(consumer_handle));
+                             std::move(consumer_handle), absl::nullopt);
 
   body_data_pipe_adapter_ = std::make_unique<network::SourceStreamToDataPipe>(
       std::move(payload_stream), std::move(producer_handle));
diff --git a/content/browser/web_package/signed_exchange_loader.h b/content/browser/web_package/signed_exchange_loader.h
index 5b94952..f42032e 100644
--- a/content/browser/web_package/signed_exchange_loader.h
+++ b/content/browser/web_package/signed_exchange_loader.h
@@ -90,15 +90,16 @@
   // network::mojom::URLLoaderClient implementation
   // Only OnComplete() is called.
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/web_package/signed_exchange_loader_unittest.cc b/content/browser/web_package/signed_exchange_loader_unittest.cc
index 7473f34..5b73f4f 100644
--- a/content/browser/web_package/signed_exchange_loader_unittest.cc
+++ b/content/browser/web_package/signed_exchange_loader_unittest.cc
@@ -70,15 +70,15 @@
     // network::mojom::URLLoaderClient overrides:
     MOCK_METHOD1(OnReceiveEarlyHints,
                  void(const network::mojom::EarlyHintsPtr));
-    MOCK_METHOD2(OnReceiveResponse,
+    MOCK_METHOD3(OnReceiveResponse,
                  void(const network::mojom::URLResponseHeadPtr,
-                      mojo::ScopedDataPipeConsumerHandle));
+                      mojo::ScopedDataPipeConsumerHandle,
+                      absl::optional<mojo_base::BigBuffer>));
     MOCK_METHOD2(OnReceiveRedirect,
                  void(const net::RedirectInfo&,
                       network::mojom::URLResponseHeadPtr));
     MOCK_METHOD3(OnUploadProgress,
                  void(int64_t, int64_t, base::OnceCallback<void()> callback));
-    MOCK_METHOD1(OnReceiveCachedMetadata, void(mojo_base::BigBuffer));
     MOCK_METHOD1(OnTransferSizeUpdated, void(int32_t));
     MOCK_METHOD1(OnComplete, void(const network::URLLoaderCompletionStatus&));
 
@@ -239,7 +239,7 @@
   mojo::PendingRemote<network::mojom::URLLoaderClient> client_after_redirect;
   MockURLLoaderClient mock_client_after_redirect(
       client_after_redirect.InitWithNewPipeAndPassReceiver());
-  EXPECT_CALL(mock_client_after_redirect, OnReceiveResponse(_, _));
+  EXPECT_CALL(mock_client_after_redirect, OnReceiveResponse(_, _, _));
 
   if (!base::FeatureList::IsEnabled(
           features::kSignedHTTPExchangePingValidity)) {
@@ -258,7 +258,7 @@
     EXPECT_CALL(mock_client_after_redirect, OnComplete(_));
     ping_loader_client()->OnReceiveResponse(
         network::mojom::URLResponseHead::New(),
-        mojo::ScopedDataPipeConsumerHandle());
+        mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
     ping_loader_client()->OnComplete(
         network::URLLoaderCompletionStatus(net::OK));
     run_loop.Run();
diff --git a/content/browser/web_package/signed_exchange_prefetch_handler.cc b/content/browser/web_package/signed_exchange_prefetch_handler.cc
index 57adc82..8db377a 100644
--- a/content/browser/web_package/signed_exchange_prefetch_handler.cc
+++ b/content/browser/web_package/signed_exchange_prefetch_handler.cc
@@ -87,7 +87,8 @@
 
 void SignedExchangePrefetchHandler::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   NOTREACHED();
 }
 
@@ -104,11 +105,6 @@
   NOTREACHED();
 }
 
-void SignedExchangePrefetchHandler::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  NOTREACHED();
-}
-
 void SignedExchangePrefetchHandler::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   NOTREACHED();
diff --git a/content/browser/web_package/signed_exchange_prefetch_handler.h b/content/browser/web_package/signed_exchange_prefetch_handler.h
index 2eca3f82..81a86d5 100644
--- a/content/browser/web_package/signed_exchange_prefetch_handler.h
+++ b/content/browser/web_package/signed_exchange_prefetch_handler.h
@@ -82,14 +82,15 @@
  private:
   // network::mojom::URLLoaderClient overrides:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         base::OnceCallback<void()> callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/web_package/signed_exchange_validity_pinger.cc b/content/browser/web_package/signed_exchange_validity_pinger.cc
index a09aa5f..29ca0be 100644
--- a/content/browser/web_package/signed_exchange_validity_pinger.cc
+++ b/content/browser/web_package/signed_exchange_validity_pinger.cc
@@ -116,7 +116,8 @@
 
 void SignedExchangeValidityPinger::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (!body)
     return;
 
@@ -144,11 +145,6 @@
   NOTREACHED();
 }
 
-void SignedExchangeValidityPinger::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {
-  NOTREACHED();
-}
-
 void SignedExchangeValidityPinger::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {
   NOTREACHED();
diff --git a/content/browser/web_package/signed_exchange_validity_pinger.h b/content/browser/web_package/signed_exchange_validity_pinger.h
index aebaea4..96fb7df 100644
--- a/content/browser/web_package/signed_exchange_validity_pinger.h
+++ b/content/browser/web_package/signed_exchange_validity_pinger.h
@@ -54,14 +54,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/web_package/web_bundle_url_loader_factory.cc b/content/browser/web_package/web_bundle_url_loader_factory.cc
index 2540d8f..b629f360 100644
--- a/content/browser/web_package/web_bundle_url_loader_factory.cc
+++ b/content/browser/web_package/web_bundle_url_loader_factory.cc
@@ -131,8 +131,8 @@
 
     auto result =
         mojo::CreateDataPipe(&options, producer_handle, consumer_handle);
-    loader_client_->OnReceiveResponse(std::move(response_head),
-                                      std::move(consumer_handle));
+    loader_client_->OnReceiveResponse(
+        std::move(response_head), std::move(consumer_handle), absl::nullopt);
     if (result != MOJO_RESULT_OK) {
       loader_client_->OnComplete(
           network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES));
diff --git a/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc b/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
index 276758c6..68c80bb 100644
--- a/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
+++ b/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
@@ -118,10 +118,10 @@
     EXPECT_TRUE(test_client_.has_received_response());
     EXPECT_FALSE(test_client_.has_received_redirect());
     EXPECT_FALSE(test_client_.has_received_upload_progress());
-    EXPECT_FALSE(test_client_.has_received_cached_metadata());
 
     ASSERT_TRUE(test_client_.response_head()->headers);
     ASSERT_TRUE(test_client_.response_body());
+    ASSERT_FALSE(test_client_.cached_metadata().has_value());
 
     EXPECT_EQ(expected_response_code,
               test_client_.response_head()->headers->response_code());
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 570beb19..439ef2d4 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -86,6 +86,13 @@
   kCredBlob,
   kGetCredBlob,
   kMinPINLength,
+  kDevicePublicKey,
+};
+
+enum class AttestationErasureOption {
+  kIncludeAttestation,
+  kEraseAttestationButIncludeAaguid,
+  kEraseAttestationAndAaguid,
 };
 
 namespace {
@@ -225,12 +232,6 @@
   return ret;
 }
 
-enum class AttestationErasureOption {
-  kIncludeAttestation,
-  kEraseAttestationButIncludeAaguid,
-  kEraseAttestationAndAaguid,
-};
-
 base::TimeDelta AdjustTimeout(absl::optional<base::TimeDelta> timeout,
                               RenderFrameHost* render_frame_host) {
   // Time to wait for an authenticator to successfully complete an operation.
@@ -818,6 +819,49 @@
   ctap_make_credential_request_->app_id_exclude = std::move(appid_exclude);
   make_credential_options_->is_off_the_record_context =
       GetBrowserContext()->IsOffTheRecord();
+  if (options->device_public_key) {
+    requested_extensions_.insert(RequestExtension::kDevicePublicKey);
+    ctap_make_credential_request_->device_public_key.emplace();
+    device::DevicePublicKeyRequest& device_public_key =
+        ctap_make_credential_request_->device_public_key.value();
+    device_public_key.attestation = options->device_public_key->attestation;
+    device_public_key.attestation_formats =
+        options->device_public_key->attestation_formats;
+
+    device_public_key_attestation_requested_ =
+        device_public_key.attestation !=
+        device::AttestationConveyancePreference::kNone;
+
+    switch (device_public_key.attestation) {
+      // DPK attestation is currently an enterprise-only feature. Non-enterprise
+      // values are mapped to "none".
+      case device::AttestationConveyancePreference::kIndirect:
+      case device::AttestationConveyancePreference::kDirect:
+      case device::AttestationConveyancePreference::kNone:
+        device_public_key.attestation =
+            device::AttestationConveyancePreference::kNone;
+        device_public_key.attestation_formats.clear();
+        break;
+
+      case device::AttestationConveyancePreference::
+          kEnterpriseIfRPListedOnAuthenticator:
+        if (GetWebAuthenticationDelegate()->ShouldPermitIndividualAttestation(
+                GetBrowserContext(), caller_origin,
+                u2f_credential_app_id_override.value_or(relying_party_id_))) {
+          device_public_key.attestation = device::
+              AttestationConveyancePreference::kEnterpriseApprovedByBrowser;
+        }
+        break;
+
+      case device::AttestationConveyancePreference::
+          kEnterpriseApprovedByBrowser:
+        // This should never come from the renderer.
+        mojo::ReportBadMessage("invalid devicePubKey attestation value");
+        CompleteGetAssertionRequest(
+            blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
+        break;
+    }
+  }
 
   // Compute the effective attestation conveyance preference.
   device::AttestationConveyancePreference attestation = options->attestation;
@@ -1087,6 +1131,55 @@
 
   ctap_get_assertion_request_->is_u2f_only = origin_is_crypto_token_extension;
 
+  if (options->device_public_key) {
+    requested_extensions_.insert(RequestExtension::kDevicePublicKey);
+    ctap_get_assertion_request_->device_public_key.emplace();
+    device::DevicePublicKeyRequest& device_public_key =
+        ctap_get_assertion_request_->device_public_key.value();
+    device_public_key.attestation = options->device_public_key->attestation;
+    device_public_key.attestation_formats =
+        options->device_public_key->attestation_formats;
+
+    switch (device_public_key.attestation) {
+      // DPK attestation is currently an enterprise-only feature. Non-enterprise
+      // values are mapped to "none". There's no prompting for getAssertion
+      // either so only policy-configured enterprise attestation works for this
+      // call.
+      case device::AttestationConveyancePreference::
+          kEnterpriseIfRPListedOnAuthenticator:
+        device_public_key.attestation = device::
+            AttestationConveyancePreference::kEnterpriseApprovedByBrowser;
+        [[fallthrough]];
+
+      case device::AttestationConveyancePreference::kIndirect:
+      case device::AttestationConveyancePreference::kDirect:
+        if (GetWebAuthenticationDelegate()->ShouldPermitIndividualAttestation(
+                GetBrowserContext(), caller_origin, relying_party_id_)) {
+          break;
+        }
+        [[fallthrough]];
+
+      case device::AttestationConveyancePreference::kNone:
+        device_public_key.attestation =
+            device::AttestationConveyancePreference::kNone;
+        device_public_key.attestation_formats.clear();
+        break;
+
+      case device::AttestationConveyancePreference::
+          kEnterpriseApprovedByBrowser:
+        // This should never come from the renderer.
+        mojo::ReportBadMessage("invalid devicePubKey attestation value");
+        CompleteGetAssertionRequest(
+            blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
+        break;
+    }
+  }
+
+  if (options->get_cred_blob) {
+    requested_extensions_.insert(RequestExtension::kGetCredBlob);
+    ctap_get_assertion_request_->get_cred_blob = true;
+  }
+
   if (options->large_blob_write) {
     data_decoder_.Deflate(
         *options->large_blob_write,
@@ -1096,10 +1189,8 @@
     return;
   }
 
-  if (options->get_cred_blob) {
-    requested_extensions_.insert(RequestExtension::kGetCredBlob);
-    ctap_get_assertion_request_->get_cred_blob = true;
-  }
+  // Don't put any other extensions here: largeBlob might be decompressing
+  // something.
 
   StartGetAssertionRequest(/*allow_skipping_pin_touch=*/true);
 }
@@ -1314,6 +1405,16 @@
             *transport == device::FidoTransportProtocol::kHybrid;
       }
 
+      absl::optional<device::DevicePublicKeyOutput> device_public_key_output =
+          response_data->GetDevicePublicKeyResponse();
+      const bool have_enterprise_attestation =
+          response_data->enterprise_attestation_returned ||
+          (device_public_key_output &&
+           device_public_key_output->enterprise_attestation_returned);
+      const bool device_public_key_included_attestation =
+          device_public_key_output &&
+          device_public_key_output->attestation_format !=
+              device::kNoneAttestationValue;
       const auto attestation =
           ctap_make_credential_request_->attestation_preference;
       absl::optional<AttestationErasureOption> attestation_erasure;
@@ -1366,28 +1467,58 @@
             attestation != device::AttestationConveyancePreference::kNone
                 ? AttestationErasureOption::kIncludeAttestation
                 : AttestationErasureOption::kEraseAttestationButIncludeAaguid;
-      } else if (attestation !=
-                 device::AttestationConveyancePreference::kNone) {
-        awaiting_attestation_response_ = true;
-        request_delegate_->ShouldReturnAttestation(
-            relying_party_id_, authenticator,
-            response_data->enterprise_attestation_returned,
-            base::BindOnce(
-                &AuthenticatorCommon::OnRegisterResponseAttestationDecided,
-                weak_factory_.GetWeakPtr(), std::move(*response_data)));
-      } else if (response_data->IsSelfAttestation()) {
+      } else if (attestation ==
+                     device::AttestationConveyancePreference::kNone &&
+                 response_data->IsSelfAttestation()) {
         attestation_erasure = AttestationErasureOption::kIncludeAttestation;
-      } else {
+      } else if (attestation ==
+                 device::AttestationConveyancePreference::kNone) {
         attestation_erasure =
             AttestationErasureOption::kEraseAttestationAndAaguid;
       }
 
-      if (attestation_erasure.has_value()) {
+      // TODO(crbug.com/1356340): once
+      // https://github.com/fido-alliance/fido-2-specs/pull/1347 is a little
+      // more mature we can plumb the attestation preference down to the
+      // authenticator and enforce this in the request handler.
+      if (attestation_erasure ==
+              AttestationErasureOption::kEraseAttestationAndAaguid &&
+          device_public_key_output.has_value() &&
+          !response_data->attestation_object()
+               .authenticator_data()
+               .attested_data()
+               ->IsAaguidZero()) {
+        // Zeroing the AAGUID would invalidate the DPK signature. The
+        // authenticator should not have returned an attestation in this case.
+        CompleteMakeCredentialRequest(
+            blink::mojom::AuthenticatorStatus::
+                DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED,
+            nullptr, nullptr, Focus::kDoCheck);
+        return;
+      }
+
+      if (attestation_erasure.has_value() &&
+          // If a DPK attestation was requested then we show a prompt. (If
+          // the RP ID is allowlisted by policy then the prompt will be
+          // resolved immediately and never actually shown.)
+          !device_public_key_attestation_requested_) {
         CompleteMakeCredentialRequest(
             blink::mojom::AuthenticatorStatus::SUCCESS,
             CreateMakeCredentialResponse(std::move(*response_data),
                                          *attestation_erasure),
             nullptr, Focus::kDoCheck);
+      } else {
+        awaiting_attestation_response_ = true;
+        request_delegate_->ShouldReturnAttestation(
+            relying_party_id_, authenticator, have_enterprise_attestation,
+            base::BindOnce(
+                &AuthenticatorCommon::OnRegisterResponseAttestationDecided,
+                weak_factory_.GetWeakPtr(),
+                attestation_erasure.value_or(
+                    AttestationErasureOption::kIncludeAttestation),
+                device_public_key_output.has_value(),
+                device_public_key_included_attestation,
+                std::move(*response_data)));
       }
 
       return;
@@ -1396,6 +1527,9 @@
 }
 
 void AuthenticatorCommon::OnRegisterResponseAttestationDecided(
+    AttestationErasureOption attestation_erasure,
+    const bool has_device_public_key_output,
+    const bool device_public_key_included_attestation,
     device::AuthenticatorMakeCredentialResponse response_data,
     bool attestation_permitted) {
   awaiting_attestation_response_ = false;
@@ -1405,11 +1539,19 @@
     return;
   }
 
-  AttestationErasureOption attestation_erasure;
   if (!attestation_permitted) {
     attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
-  } else {
-    attestation_erasure = AttestationErasureOption::kIncludeAttestation;
+
+    if (device_public_key_included_attestation) {
+      // If the authenticator returned a DPK attestation due to
+      // kEnterpriseIfRPListedOnAuthenticator then, currently, we showed the
+      // attestation prompt too late and can only reject the response if
+      // there's an unwanted DPK attestation.
+      CompleteMakeCredentialRequest(blink::mojom::AuthenticatorStatus::
+                                        DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED,
+                                    nullptr, nullptr, Focus::kDoCheck);
+      return;
+    }
   }
 
   // The check for IsAttestationCertificateInappropriatelyIdentifying is
@@ -1430,6 +1572,14 @@
     // in the enterprise policy, because that enables the individual attestation
     // bit in the register request and permits individual attestation generally.
     attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
+
+    if (has_device_public_key_output) {
+      // Zeroing the AAGUID would invalidate the DPK signature. DPK cannot be
+      // supported in this case.
+      CompleteMakeCredentialRequest(blink::mojom::AuthenticatorStatus::
+                                        DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED,
+                                    nullptr, nullptr, Focus::kDoCheck);
+    }
   }
 
   CompleteMakeCredentialRequest(
@@ -1697,6 +1847,7 @@
 
   bool did_create_hmac_secret = false;
   bool did_store_cred_blob = false;
+  absl::optional<std::vector<uint8_t>> device_public_key_authenticator_output;
   const absl::optional<cbor::Value>& maybe_extensions =
       response_data.attestation_object().authenticator_data().extensions();
   if (maybe_extensions) {
@@ -1716,6 +1867,14 @@
         cred_blob_it->second.GetBool()) {
       did_store_cred_blob = true;
     }
+
+    const auto device_public_key_it =
+        extensions.find(cbor::Value(device::kExtensionDevicePublicKey));
+    if (device_public_key_it != extensions.end() &&
+        device_public_key_it->second.is_bytestring()) {
+      device_public_key_authenticator_output =
+          device_public_key_it->second.GetBytestring();
+    }
   }
 
   for (const RequestExtension ext : requested_extensions_) {
@@ -1752,6 +1911,17 @@
         // [1]
         // https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-minpinlength-extension
         break;
+      case RequestExtension::kDevicePublicKey:
+        if (device_public_key_authenticator_output &&
+            response_data.device_public_key_signature) {
+          response->device_public_key =
+              blink::mojom::DevicePublicKeyResponse::New();
+          response->device_public_key->authenticator_output =
+              std::move(*device_public_key_authenticator_output);
+          response->device_public_key->signature =
+              *response_data.device_public_key_signature;
+        }
+        break;
       case RequestExtension::kAppID:
       case RequestExtension::kLargeBlobRead:
       case RequestExtension::kLargeBlobWrite:
@@ -1891,6 +2061,26 @@
 
         break;
       }
+      case RequestExtension::kDevicePublicKey: {
+        const absl::optional<cbor::Value>& maybe_extensions =
+            response_data.authenticator_data.extensions();
+        if (maybe_extensions) {
+          DCHECK(maybe_extensions->is_map());
+          const cbor::Value::MapValue& extensions = maybe_extensions->GetMap();
+
+          const auto it =
+              extensions.find(cbor::Value(device::kExtensionDevicePublicKey));
+          if (it != extensions.end() && it->second.is_bytestring()) {
+            response->device_public_key =
+                blink::mojom::DevicePublicKeyResponse::New();
+            response->device_public_key->authenticator_output =
+                it->second.GetBytestring();
+            response->device_public_key->signature =
+                *response_data.device_public_key_signature;
+          }
+        }
+        break;
+      }
       case RequestExtension::kHMACSecret:
       case RequestExtension::kCredProps:
       case RequestExtension::kLargeBlobEnable:
@@ -1915,10 +2105,6 @@
 }
 
 void AuthenticatorCommon::Cleanup() {
-  if (awaiting_attestation_response_) {
-    awaiting_attestation_response_ = false;
-  }
-
   timer_->Stop();
   has_pending_request_ = false;
   request_handler_.reset();
@@ -1928,6 +2114,8 @@
   make_credential_options_.reset();
   ctap_get_assertion_request_.reset();
   ctap_get_assertion_options_.reset();
+  device_public_key_attestation_requested_ = false;
+  awaiting_attestation_response_ = false;
   request_delegate_.reset();
   make_credential_response_callback_.Reset();
   get_assertion_response_callback_.Reset();
diff --git a/content/browser/webauth/authenticator_common.h b/content/browser/webauth/authenticator_common.h
index 73d76ea..0697776 100644
--- a/content/browser/webauth/authenticator_common.h
+++ b/content/browser/webauth/authenticator_common.h
@@ -56,6 +56,7 @@
 class WebAuthRequestSecurityChecker;
 
 enum class RequestExtension;
+enum class AttestationErasureOption;
 
 // Common code for any WebAuthn Authenticator interfaces.
 class CONTENT_EXPORT AuthenticatorCommon {
@@ -130,12 +131,6 @@
     kDontCheck,
   };
 
-  enum class AttestationErasureOption {
-    kIncludeAttestation,
-    kEraseAttestationButIncludeAaguid,
-    kEraseAttestationAndAaguid,
-  };
-
   // Replaces the current |request_handler_| with a
   // |MakeCredentialRequestHandler|, effectively restarting the request.
   void StartMakeCredentialRequest(bool allow_skipping_pin_touch);
@@ -171,6 +166,9 @@
   // Callback to complete the registration process once a decision about
   // whether or not to return attestation data has been made.
   void OnRegisterResponseAttestationDecided(
+      AttestationErasureOption attestation_erasure,
+      const bool has_device_public_key_output,
+      const bool device_public_key_included_attestation,
       device::AuthenticatorMakeCredentialResponse response_data,
       bool attestation_permitted);
 
@@ -276,6 +274,10 @@
   absl::optional<device::MakeCredentialOptions> make_credential_options_;
   absl::optional<device::CtapGetAssertionRequest> ctap_get_assertion_request_;
   absl::optional<device::CtapGetAssertionOptions> ctap_get_assertion_options_;
+  // device_public_key_attestation_requested_ is true if any form of DPK
+  // attestation was requested, even if it was mapped to "none" in
+  // |ctap_*_request_|.
+  bool device_public_key_attestation_requested_ = false;
   // awaiting_attestation_response_ is true if the embedder has been queried
   // about an attestsation decision and the response is still pending.
   bool awaiting_attestation_response_ = false;
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index cec007f..d5cc175 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -1980,6 +1980,55 @@
   PACKED,
 };
 
+const char* AttestationConveyancePreferenceToString(
+    AttestationConveyancePreference v) {
+  switch (v) {
+    case AttestationConveyancePreference::NONE:
+      return "none";
+    case AttestationConveyancePreference::INDIRECT:
+      return "indirect";
+    case AttestationConveyancePreference::DIRECT:
+      return "direct";
+    case AttestationConveyancePreference::ENTERPRISE:
+      return "enterprise";
+    default:
+      NOTREACHED();
+      return "";
+  }
+}
+
+const char* AttestationConveyancePreferenceToString(
+    device::AttestationConveyancePreference v) {
+  switch (v) {
+    case device::AttestationConveyancePreference::kNone:
+      return "none";
+    case device::AttestationConveyancePreference::kIndirect:
+      return "indirect";
+    case device::AttestationConveyancePreference::kDirect:
+      return "direct";
+    case device::AttestationConveyancePreference::
+        kEnterpriseIfRPListedOnAuthenticator:
+      return "enterprise(ep=1)";
+    case device::AttestationConveyancePreference::kEnterpriseApprovedByBrowser:
+      return "enterprise(ep=2)";
+  }
+}
+
+const char* AttestationConsentToString(AttestationConsent ac) {
+  switch (ac) {
+    case AttestationConsent::GRANTED:
+      return "GRANTED";
+    case AttestationConsent::DENIED:
+      return "DENIED";
+    case AttestationConsent::GRANTED_FOR_ENTERPRISE_ATTESTATION:
+      return "GRANTED_FOR_ENTERPRISE_ATTESTATION";
+    case AttestationConsent::DENIED_FOR_ENTERPRISE_ATTESTATION:
+      return "DENIED_FOR_ENTERPRISE_ATTESTATION";
+    case AttestationConsent::NOT_USED:
+      return "NOT_USED";
+  }
+}
+
 // TestAuthenticatorRequestDelegate is a test fake implementation of the
 // AuthenticatorRequestClientDelegate embedder interface.
 class TestAuthenticatorRequestDelegate
@@ -2284,23 +2333,6 @@
  protected:
   TestAuthenticatorContentBrowserClient test_client_;
 
-  static const char* AttestationConveyancePreferenceToString(
-      AttestationConveyancePreference v) {
-    switch (v) {
-      case AttestationConveyancePreference::NONE:
-        return "none";
-      case AttestationConveyancePreference::INDIRECT:
-        return "indirect";
-      case AttestationConveyancePreference::DIRECT:
-        return "direct";
-      case AttestationConveyancePreference::ENTERPRISE:
-        return "enterprise";
-      default:
-        NOTREACHED();
-        return "";
-    }
-  }
-
   // Expects that |map| contains the given key with a string-value equal to
   // |expected|.
   static void ExpectMapHasKeyWithStringValue(const Value::MapValue& map,
@@ -4953,6 +4985,401 @@
   }
 }
 
+class AuthenticatorDevicePublicKeyTest : public AuthenticatorImplTest {
+  void SetUp() override {
+    AuthenticatorImplTest::SetUp();
+    old_client_ = SetBrowserClientForTesting(&test_client_);
+  }
+
+  void TearDown() override {
+    SetBrowserClientForTesting(old_client_);
+    AuthenticatorImplTest::TearDown();
+  }
+
+ protected:
+  TestAuthenticatorContentBrowserClient test_client_;
+  raw_ptr<ContentBrowserClient> old_client_ = nullptr;
+};
+
+TEST_F(AuthenticatorDevicePublicKeyTest, DevicePublicKeyMakeCredential) {
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  for (const bool dpk_support : {false, true}) {
+    device::VirtualCtap2Device::Config config;
+    config.device_public_key_support = dpk_support;
+    virtual_device_factory_->SetCtap2Config(config);
+
+    // self-attestation is needed because, otherwise, zeroing the AAGUID
+    // invalidates the DPK signature.
+    virtual_device_factory_->mutable_state()->self_attestation = true;
+
+    PublicKeyCredentialCreationOptionsPtr options =
+        GetTestPublicKeyCredentialCreationOptions();
+    options->device_public_key = blink::mojom::DevicePublicKeyRequest::New();
+    MakeCredentialResult result =
+        AuthenticatorMakeCredential(std::move(options));
+
+    ASSERT_EQ(result.status, AuthenticatorStatus::SUCCESS);
+    ASSERT_EQ(static_cast<bool>(result.response->device_public_key),
+              dpk_support);
+    if (dpk_support) {
+      ASSERT_FALSE(
+          result.response->device_public_key->authenticator_output.empty());
+      ASSERT_FALSE(result.response->device_public_key->signature.empty());
+    }
+  }
+}
+
+TEST_F(AuthenticatorDevicePublicKeyTest,
+       DevicePublicKeyWithPrimaryAttestation) {
+  // If the authenticator returns regular attestation and a devicePubKey
+  // response, and the browser needs to strip that attesation, then the request
+  // should fail because zeroing the AAGUID breaks the DPK signature.
+  // DPK-capable authenticators will need to support the forthcoming
+  // attestationFormats parameter if they wish to do non-null attestation with
+  // DPK.
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  device::VirtualCtap2Device::Config config;
+  config.device_public_key_support = true;
+  virtual_device_factory_->SetCtap2Config(config);
+
+  PublicKeyCredentialCreationOptionsPtr options =
+      GetTestPublicKeyCredentialCreationOptions();
+  options->device_public_key = blink::mojom::DevicePublicKeyRequest::New();
+  MakeCredentialResult result = AuthenticatorMakeCredential(std::move(options));
+
+  ASSERT_EQ(result.status,
+            AuthenticatorStatus::DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED);
+}
+
+TEST_F(AuthenticatorDevicePublicKeyTest, DevicePublicKeyGetAssertion) {
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  bool credential_injected = false;
+  for (const bool dpk_support : {false, true}) {
+    device::VirtualCtap2Device::Config config;
+    config.device_public_key_support = dpk_support;
+    virtual_device_factory_->SetCtap2Config(config);
+
+    PublicKeyCredentialRequestOptionsPtr options =
+        GetTestPublicKeyCredentialRequestOptions();
+    if (!credential_injected) {
+      ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
+          options->allow_credentials[0].id, kTestRelyingPartyId));
+      credential_injected = true;
+    }
+    options->device_public_key = blink::mojom::DevicePublicKeyRequest::New();
+    GetAssertionResult result = AuthenticatorGetAssertion(std::move(options));
+
+    ASSERT_EQ(result.status, AuthenticatorStatus::SUCCESS);
+    ASSERT_EQ(static_cast<bool>(result.response->device_public_key),
+              dpk_support);
+    if (dpk_support) {
+      ASSERT_FALSE(
+          result.response->device_public_key->authenticator_output.empty());
+      ASSERT_FALSE(result.response->device_public_key->signature.empty());
+    }
+  }
+}
+
+TEST_F(AuthenticatorDevicePublicKeyTest, DevicePublicKeyBadResponse) {
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  bool credential_injected = false;
+  for (int breakage = 0; breakage < 3; breakage++) {
+    SCOPED_TRACE(::testing::Message() << "breakage=" << breakage);
+
+    device::VirtualCtap2Device::Config config;
+    config.device_public_key_support = true;
+    switch (breakage) {
+      case 0:
+        break;
+
+      case 1:
+        config.device_public_key_drop_extension_response = true;
+        break;
+
+      case 2:
+        config.device_public_key_drop_signature = true;
+        break;
+
+      default:
+        CHECK(false);
+    }
+    virtual_device_factory_->SetCtap2Config(config);
+
+    // self-attestation is needed because, otherwise, zeroing the AAGUID
+    // invalidates the DPK signature.
+    virtual_device_factory_->mutable_state()->self_attestation = true;
+
+    AuthenticatorStatus status;
+    for (const bool is_make_credential : {false, true}) {
+      SCOPED_TRACE(::testing::Message()
+                   << "is_make_credential=" << is_make_credential);
+
+      if (is_make_credential) {
+        PublicKeyCredentialCreationOptionsPtr options =
+            GetTestPublicKeyCredentialCreationOptions();
+        options->device_public_key =
+            blink::mojom::DevicePublicKeyRequest::New();
+        MakeCredentialResult result =
+            AuthenticatorMakeCredential(std::move(options));
+        status = result.status;
+      } else {
+        PublicKeyCredentialRequestOptionsPtr options =
+            GetTestPublicKeyCredentialRequestOptions();
+        if (!credential_injected) {
+          ASSERT_TRUE(
+              virtual_device_factory_->mutable_state()->InjectRegistration(
+                  options->allow_credentials[0].id, kTestRelyingPartyId));
+          credential_injected = true;
+        }
+        options->device_public_key =
+            blink::mojom::DevicePublicKeyRequest::New();
+        GetAssertionResult result =
+            AuthenticatorGetAssertion(std::move(options));
+        status = result.status;
+      }
+
+      if (breakage) {
+        EXPECT_NE(status, AuthenticatorStatus::SUCCESS);
+      } else {
+        EXPECT_EQ(status, AuthenticatorStatus::SUCCESS);
+      }
+    }
+  }
+}
+
+TEST_F(AuthenticatorDevicePublicKeyTest,
+       DevicePublicKeyMakeCredentialAttestation) {
+  constexpr device::AttestationConveyancePreference req_none =
+      device::AttestationConveyancePreference::kNone;
+  constexpr device::AttestationConveyancePreference req_indirect =
+      device::AttestationConveyancePreference::kIndirect;
+  constexpr device::AttestationConveyancePreference req_direct =
+      device::AttestationConveyancePreference::kDirect;
+  constexpr device::AttestationConveyancePreference req_enterprise = device::
+      AttestationConveyancePreference::kEnterpriseIfRPListedOnAuthenticator;
+  constexpr bool no_allowlist = false;
+  constexpr bool allowlisted = true;
+  constexpr bool none = false;
+  constexpr bool direct = true;
+  constexpr bool ep = true;
+  constexpr bool no_ep = false;
+  constexpr AttestationConsent no_prompt = AttestationConsent::NOT_USED;
+  constexpr AttestationConsent prompt_no = AttestationConsent::DENIED;
+  constexpr AttestationConsent prompt_yes = AttestationConsent::GRANTED;
+  constexpr AttestationConsent prompt_ep_no =
+      AttestationConsent::DENIED_FOR_ENTERPRISE_ATTESTATION;
+  constexpr AttestationConsent prompt_ep_yes =
+      AttestationConsent::GRANTED_FOR_ENTERPRISE_ATTESTATION;
+
+  constexpr struct {
+    device::AttestationConveyancePreference requested_attestation;
+    bool is_permitted_by_policy;
+    bool has_attestation;
+    bool enterprise_attestation_returned;
+    AttestationConsent prompt;
+    bool ok;
+  } kTests[] = {
+      // clang-format off
+      // |Requested |   In policy? | Att   | Ent?  | Prompt?    |   OK? |
+      // ----------------------------------------------------------------
+
+      // No attestation requested and none provided is the simple case.
+      {req_none,       no_allowlist, none,   no_ep, no_prompt,     true},
+
+      // Any non-enterprise DPK attestation request is mapped to "none", so the
+      // authenticator cannot return a DPK attestation in these cases.
+      {req_none,       no_allowlist, direct, no_ep, no_prompt,     false},
+      {req_indirect,   no_allowlist, direct, no_ep, no_prompt,     false},
+      {req_direct,     no_allowlist, direct, no_ep, no_prompt,     false},
+      // ... and certainly can't return an enterprise attestation.
+      {req_none,       no_allowlist, direct, ep,    no_prompt,     false},
+      {req_indirect,   no_allowlist, direct, ep,    no_prompt,     false},
+      {req_direct,     no_allowlist, direct, ep,    no_prompt,     false},
+
+      // Requesting a DPK attestation results in a prompt, same as requesting
+      // a normal attestation, even if no attestation results.
+      {req_indirect,   no_allowlist, none,   no_ep, prompt_yes,    true},
+      {req_direct,     no_allowlist, none,   no_ep, prompt_yes,    true},
+
+      // A failed ep=1 attestation results in a standard prompt.
+      {req_enterprise, no_allowlist, none,   no_ep, prompt_yes,    true},
+      // ... rejecting that prompt is ok if there's no attestation.
+      {req_enterprise, no_allowlist, none,   no_ep, prompt_no,     true},
+      // A successful ep=1 attestation results in a special prompt.
+      {req_enterprise, no_allowlist, direct, ep,    prompt_ep_yes, true},
+      // ... rejecting that prompt is fatal to the request.
+      {req_enterprise, no_allowlist, direct, ep,    prompt_ep_no,  false},
+
+      // An ep=1 request should either return an enterprise attestation or
+      // nothing. So a "direct" response is invalid and should fail.
+      {req_enterprise, no_allowlist, direct, no_ep, no_prompt,     false},
+
+      // RP IDs listed in policy will cause prompts, but they'll be immediately
+      // resolved because of the policy allowlisting.
+      {req_indirect,   allowlisted,  none,   no_ep, prompt_yes,    true},
+      {req_direct,     allowlisted,  none,   no_ep, prompt_yes,    true},
+      {req_enterprise, allowlisted,  none,   no_ep, prompt_yes,    true},
+      {req_enterprise, allowlisted,  direct, no_ep, prompt_yes,    true},
+      {req_enterprise, allowlisted,  direct, ep,    prompt_ep_yes, true},
+      // clang-format on
+  };
+
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  unsigned test_num = 0;
+  for (const auto& test : kTests) {
+    SCOPED_TRACE(::testing::Message() << "ok=" << test.ok);
+    SCOPED_TRACE(::testing::Message()
+                 << "prompt=" << AttestationConsentToString(test.prompt));
+    SCOPED_TRACE(::testing::Message() << "enterprise_attestation_returned="
+                                      << test.enterprise_attestation_returned);
+    SCOPED_TRACE(::testing::Message()
+                 << "has_attestation=" << test.has_attestation);
+    SCOPED_TRACE(::testing::Message()
+                 << "is_permitted_by_policy=" << test.is_permitted_by_policy);
+    SCOPED_TRACE(
+        ::testing::Message()
+        << "requested_attestation="
+        << AttestationConveyancePreferenceToString(test.requested_attestation));
+    SCOPED_TRACE(::testing::Message() << "kTests[" << test_num++ << "]");
+
+    CHECK(!test.enterprise_attestation_returned || test.has_attestation);
+
+    device::VirtualCtap2Device::Config config;
+    config.device_public_key_support = true;
+    config.device_public_key_always_return_attestation = test.has_attestation;
+    config.device_public_key_always_return_enterprise_attestation =
+        test.enterprise_attestation_returned;
+    virtual_device_factory_->SetCtap2Config(config);
+
+    // self-attestation is needed because, otherwise, zeroing the AAGUID
+    // invalidates the DPK signature.
+    virtual_device_factory_->mutable_state()->self_attestation = true;
+
+    test_client_.GetTestWebAuthenticationDelegate()
+        ->permit_individual_attestation = test.is_permitted_by_policy;
+    test_client_.attestation_consent = test.prompt;
+
+    PublicKeyCredentialCreationOptionsPtr options =
+        GetTestPublicKeyCredentialCreationOptions();
+    options->device_public_key = blink::mojom::DevicePublicKeyRequest::New();
+    options->device_public_key->attestation = test.requested_attestation;
+    MakeCredentialResult result =
+        AuthenticatorMakeCredential(std::move(options));
+
+    EXPECT_EQ(result.status == AuthenticatorStatus::SUCCESS, test.ok);
+  }
+}
+
+TEST_F(AuthenticatorDevicePublicKeyTest,
+       DevicePublicKeyGetAssertionAttestation) {
+  constexpr device::AttestationConveyancePreference req_none =
+      device::AttestationConveyancePreference::kNone;
+  constexpr device::AttestationConveyancePreference req_indirect =
+      device::AttestationConveyancePreference::kIndirect;
+  constexpr device::AttestationConveyancePreference req_direct =
+      device::AttestationConveyancePreference::kDirect;
+  constexpr device::AttestationConveyancePreference req_enterprise = device::
+      AttestationConveyancePreference::kEnterpriseIfRPListedOnAuthenticator;
+  constexpr bool no_allowlist = false;
+  constexpr bool allowlisted = true;
+  constexpr bool none = false;
+  constexpr bool direct = true;
+  constexpr bool ep = true;
+  constexpr bool no_ep = false;
+
+  constexpr struct {
+    device::AttestationConveyancePreference requested_attestation;
+    bool is_permitted_by_policy;
+    bool has_attestation;
+    bool enterprise_attestation_returned;
+    bool ok;
+  } kTests[] = {
+      // clang-format off
+      // |Requested |   In policy? | Att   | Ent?  | OK? |
+      // ----------------------------------------------------------------
+
+      // No attestation requested and none provided is the simple case.
+      {req_none,       no_allowlist, none,   no_ep, true},
+
+      // If the authenticator doesn't provide any attestation then anything
+      // works.
+      {req_indirect,   no_allowlist, none,   no_ep, true},
+      {req_direct,     no_allowlist, none,   no_ep, true},
+      {req_enterprise, no_allowlist, none,   no_ep, true},
+      {req_enterprise, allowlisted,  none,   no_ep, true},
+
+      // If the authenticator provides attestation in unsupported cases then
+      // the request should fail.
+      {req_none,       no_allowlist, direct, no_ep, false},
+      {req_indirect,   no_allowlist, direct, no_ep, false},
+      {req_direct,     no_allowlist, direct, no_ep, false},
+      {req_enterprise, no_allowlist, direct, no_ep, false},
+      {req_enterprise, no_allowlist, direct, ep,    false},
+
+      // The only supported case for DPK attestation during getAssertion is
+      // via policy, when all requests should work.
+      {req_indirect,   allowlisted,  direct, no_ep, true},
+      {req_direct,     allowlisted,  direct, no_ep, true},
+      {req_enterprise, allowlisted,  direct, no_ep, true},
+      {req_enterprise, allowlisted,  direct, ep,    true},
+
+      // But no ep responses to non-ep requests are allowed.
+      {req_indirect,   allowlisted,  direct, ep,    false},
+      {req_direct,     allowlisted,  direct, ep,    false},
+
+      // clang-format on
+  };
+
+  NavigateAndCommit(GURL(kTestOrigin1));
+
+  bool credential_injected = false;
+  unsigned test_num = 0;
+  for (const auto& test : kTests) {
+    SCOPED_TRACE(::testing::Message() << "ok=" << test.ok);
+    SCOPED_TRACE(::testing::Message() << "enterprise_attestation_returned="
+                                      << test.enterprise_attestation_returned);
+    SCOPED_TRACE(::testing::Message()
+                 << "has_attestation=" << test.has_attestation);
+    SCOPED_TRACE(::testing::Message()
+                 << "is_permitted_by_policy=" << test.is_permitted_by_policy);
+    SCOPED_TRACE(
+        ::testing::Message()
+        << "requested_attestation="
+        << AttestationConveyancePreferenceToString(test.requested_attestation));
+    SCOPED_TRACE(::testing::Message() << "kTests[" << test_num++ << "]");
+
+    CHECK(!test.enterprise_attestation_returned || test.has_attestation);
+
+    device::VirtualCtap2Device::Config config;
+    config.device_public_key_support = true;
+    config.device_public_key_always_return_attestation = test.has_attestation;
+    config.device_public_key_always_return_enterprise_attestation =
+        test.enterprise_attestation_returned;
+    virtual_device_factory_->SetCtap2Config(config);
+
+    test_client_.GetTestWebAuthenticationDelegate()
+        ->permit_individual_attestation = test.is_permitted_by_policy;
+
+    PublicKeyCredentialRequestOptionsPtr options =
+        GetTestPublicKeyCredentialRequestOptions();
+    if (!credential_injected) {
+      ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectRegistration(
+          options->allow_credentials[0].id, kTestRelyingPartyId));
+      credential_injected = true;
+    }
+    options->device_public_key = blink::mojom::DevicePublicKeyRequest::New();
+    options->device_public_key->attestation = test.requested_attestation;
+    GetAssertionResult result = AuthenticatorGetAssertion(std::move(options));
+
+    EXPECT_EQ(result.status == AuthenticatorStatus::SUCCESS, test.ok);
+  }
+}
+
 static constexpr char kTestPIN[] = "1234";
 static constexpr char16_t kTestPIN16[] = u"1234";
 
diff --git a/content/browser/webauth/webauth_browsertest.cc b/content/browser/webauth/webauth_browsertest.cc
index 06bcc3b4..a41f132 100644
--- a/content/browser/webauth/webauth_browsertest.cc
+++ b/content/browser/webauth/webauth_browsertest.cc
@@ -7,17 +7,21 @@
 #include <memory>
 #include <vector>
 
+#include "base/base64.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/json/json_reader.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "components/cbor/reader.h"
 #include "content/browser/renderer_host/back_forward_cache_disable.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/webauth/authenticator_environment_impl.h"
@@ -39,7 +43,10 @@
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/did_commit_navigation_interceptor.h"
+#include "crypto/sha2.h"
+#include "crypto/signature_verifier.h"
 #include "device/base/features.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/fake_fido_discovery.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_discovery_factory.h"
@@ -47,6 +54,8 @@
 #include "device/fido/fido_types.h"
 #include "device/fido/hid/fake_hid_impl_for_testing.h"
 #include "device/fido/mock_fido_device.h"
+#include "device/fido/p256_public_key.h"
+#include "device/fido/public_key.h"
 #include "device/fido/test_callback_receiver.h"
 #include "device/fido/virtual_fido_device_factory.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -118,9 +127,7 @@
     "webauth: SecurityError: 'rp.icon' should be a secure URL";
 
 constexpr char kAbortErrorMessage[] =
-    "webauth: AbortError: signal is aborted without reason";
-
-constexpr char kAbortReasonMessage[] = "webauth: Error";
+    "webauth: AbortError: Request has been aborted.";
 
 constexpr char kGetPermissionsPolicyMissingMessage[] =
     "webauth: NotAllowedError: The 'publickey-credentials-get' feature is "
@@ -982,6 +989,7 @@
     ASSERT_EQ(kNotAllowedErrorMessage, result);
   }
 }
+
 // Tests that when navigator.credentials.create() is called with abort
 // signal's aborted flag not set, we get a SUCCESS.
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
@@ -1023,26 +1031,6 @@
 }
 
 // Tests that when navigator.credentials.create() is called with abort
-// signal's aborted flag set with reason before sending request,
-// we get an error from the reason.
-IN_PROC_BROWSER_TEST_F(
-    WebAuthJavascriptClientBrowserTest,
-    CreatePublicKeyCredentialWithAbortSetWithReasonBeforeCreate) {
-  CreateParameters parameters;
-  parameters.signal = "authAbortSignal";
-  std::string script =
-      "authAbortController = new AbortController();"
-      "authAbortSignal = authAbortController.signal;"
-      "authAbortController.abort('Error');" +
-      BuildCreateCallWithParameters(parameters);
-
-  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
-                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
-                           .ExtractString();
-  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
-}
-
-// Tests that when navigator.credentials.create() is called with abort
 // signal's aborted flag set after sending request, we get an AbortError.
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
                        CreatePublicKeyCredentialWithAbortSetAfterCreate) {
@@ -1071,37 +1059,6 @@
   ASSERT_EQ(kAbortErrorMessage, result.substr(0, strlen(kAbortErrorMessage)));
 }
 
-// Tests that when navigator.credentials.create() is called with abort
-// signal's aborted flag set with reason after sending request, we get an error
-// from the reason.
-IN_PROC_BROWSER_TEST_F(
-    WebAuthJavascriptClientBrowserTest,
-    CreatePublicKeyCredentialWithAbortSetWithReasonAfterCreate) {
-  // This test sends the abort signal after making the WebAuthn call. However,
-  // the WebAuthn call could complete before the abort signal is sent, leading
-  // to a flakey test. Thus the |simulate_press_callback| is installed and
-  // always returns false, to ensure that the VirtualFidoDevice stalls the
-  // WebAuthn call and the abort signal will happen in time.
-  device::test::VirtualFidoDeviceFactory* virtual_device_factory =
-      InjectVirtualFidoDeviceFactory();
-  virtual_device_factory->mutable_state()->simulate_press_callback =
-      base::BindRepeating(
-          [](device::VirtualFidoDevice*) -> bool { return false; });
-
-  CreateParameters parameters;
-  parameters.signal = "authAbortSignal";
-  std::string script =
-      "authAbortController = new AbortController();"
-      "authAbortSignal = authAbortController.signal;" +
-      BuildCreateCallWithParameters(parameters) +
-      "authAbortController.abort('Error');";
-
-  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
-                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
-                           .ExtractString();
-  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
-}
-
 // Tests that when navigator.credentials.get() is called with user verification
 // required, we get an NotAllowedError because the virtual device isn't
 // configured with UV and GetAssertionRequestHandler will return
@@ -1238,25 +1195,6 @@
 }
 
 // Tests that when navigator.credentials.get() is called with abort
-// signal's aborted flag set with reason before sending request,
-// we get an error from the reason.
-IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
-                       GetPublicKeyCredentialWithAbortSetWithReasonBeforeGet) {
-  GetParameters parameters;
-  parameters.signal = "authAbortSignal";
-  std::string script =
-      "authAbortController = new AbortController();"
-      "authAbortSignal = authAbortController.signal;"
-      "authAbortController.abort('Error');" +
-      BuildGetCallWithParameters(parameters);
-
-  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
-                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
-                           .ExtractString();
-  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
-}
-
-// Tests that when navigator.credentials.get() is called with abort
 // signal's aborted flag set after sending request, we get an AbortError.
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
                        GetPublicKeyCredentialWithAbortSetAfterGet) {
@@ -1284,36 +1222,6 @@
   ASSERT_EQ(kAbortErrorMessage, result.substr(0, strlen(kAbortErrorMessage)));
 }
 
-// Tests that when navigator.credentials.get() is called with abort
-// signal's aborted flag set with reason after sending request,
-// we get an error from the reason.
-IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
-                       GetPublicKeyCredentialWithAbortSetWithReasonAfterGet) {
-  // This test sends the abort signal after making the WebAuthn call. However,
-  // the WebAuthn call could complete before the abort signal is sent, leading
-  // to a flakey test. Thus the |simulate_press_callback| is installed and
-  // always returns false, to ensure that the VirtualFidoDevice stalls the
-  // WebAuthn call and the abort signal will happen in time.
-  device::test::VirtualFidoDeviceFactory* virtual_device_factory =
-      InjectVirtualFidoDeviceFactory();
-  virtual_device_factory->mutable_state()->simulate_press_callback =
-      base::BindRepeating(
-          [](device::VirtualFidoDevice*) -> bool { return false; });
-
-  GetParameters parameters;
-  parameters.signal = "authAbortSignal";
-  std::string script =
-      "authAbortController = new AbortController();"
-      "authAbortSignal = authAbortController.signal;" +
-      BuildGetCallWithParameters(parameters) +
-      "authAbortController.abort('Error');";
-
-  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
-                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
-                           .ExtractString();
-  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
-}
-
 // Executes Javascript in the given WebContents and waits until a string with
 // the given prefix is received. It will ignore values other than strings, and
 // strings without the given prefix. Since messages are broadcast to
@@ -1558,6 +1466,118 @@
                    EXECUTE_SCRIPT_USE_MANUAL_REPLY));
 }
 
+// VerifyDevicePublicKeyOutput checks the result of a DPK-enabled operation.
+// The given Javascript result string contains the comma-separated, base64-
+// encoded values of:
+//    1. The authenticator data.
+//    2. The clientDataJSON
+//    3. The DPK authenticator output.
+//    4. The DPK signature.
+void VerifyDevicePublicKeyOutput(const std::string& output) {
+  const std::vector<std::string> base64_parts = base::SplitString(
+      output, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+  ASSERT_EQ(base64_parts.size(), 4u);
+  std::vector<uint8_t> authenticator_data =
+      *base::Base64Decode(base64_parts[0]);
+  std::vector<uint8_t> client_data_json = *base::Base64Decode(base64_parts[1]);
+  std::vector<uint8_t> dpk_output_bytes = *base::Base64Decode(base64_parts[2]);
+  std::vector<uint8_t> dpk_sig = *base::Base64Decode(base64_parts[3]);
+
+  const device::DevicePublicKeyOutput dpk_output =
+      *device::DevicePublicKeyOutput::FromExtension(
+          cbor::Value(dpk_output_bytes));
+  const std::unique_ptr<device::PublicKey> dpk_key =
+      device::P256PublicKey::ExtractFromCOSEKey(
+          static_cast<int32_t>(device::CoseAlgorithmIdentifier::kEs256),
+          base::span<const uint8_t>(), dpk_output.dpk.GetMap());
+
+  crypto::SignatureVerifier verifier;
+  verifier.VerifyInit(
+      crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256, dpk_sig,
+      dpk_key->der_bytes.value());
+  verifier.VerifyUpdate(authenticator_data);
+  verifier.VerifyUpdate(crypto::SHA256Hash(client_data_json));
+  EXPECT_TRUE(verifier.VerifyFinal());
+}
+
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+                       DevicePublicKeyMakeCredential) {
+  device::VirtualCtap2Device::Config config;
+  config.device_public_key_support = true;
+  auto* virtual_device_factory = InjectVirtualFidoDeviceFactory();
+  virtual_device_factory->SetCtap2Config(config);
+
+  // self-attestation is needed because, otherwise, zeroing the AAGUID
+  // invalidates the DPK signature.
+  virtual_device_factory->mutable_state()->self_attestation = true;
+
+  EXPECT_TRUE(
+      NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html")));
+
+  constexpr char kJavascript[] =
+      "navigator.credentials.create({ publicKey: {"
+      "  challenge: new TextEncoder().encode('abcd'),"
+      "  rp: { id: 'www.acme.com', name: 'name' },"
+      "  user: { id: new Uint8Array([0]), name: 'name', displayName: 'dn' },"
+      "  pubKeyCredParams: [{ type: 'public-key', alg: '-7' }],"
+      "  extensions: { devicePubKey: {} },"
+      "}}).then(c => {"
+      "  const e = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)));"
+      "  window.domAutomationController.send("
+      "      'webauth: ' + e(c.response.getAuthenticatorData())"
+      "                  + ',' + e(c.response.clientDataJSON)"
+      "                  + ',' + e(c.getClientExtensionResults()"
+      "                               .devicePubKey"
+      "                               .authenticatorOutput)"
+      "                  + ',' + e(c.getClientExtensionResults()"
+      "                               .devicePubKey"
+      "                               .signature));"
+      "}, e => window.domAutomationController.send("
+      "      'webauth: ' + e.toString()));";
+  absl::optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
+      shell()->web_contents(), kJavascript, "webauth: ");
+  ASSERT_TRUE(result);
+  VerifyDevicePublicKeyOutput(result->substr(9));
+}
+
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+                       DevicePublicKeyGetAssertion) {
+  device::VirtualCtap2Device::Config config;
+  config.device_public_key_support = true;
+  auto* virtual_device_factory = InjectVirtualFidoDeviceFactory();
+  virtual_device_factory->SetCtap2Config(config);
+  constexpr uint8_t kCredentialId[] = {1};
+  ASSERT_TRUE(virtual_device_factory->mutable_state()->InjectRegistration(
+      kCredentialId, "www.acme.com"));
+
+  EXPECT_TRUE(
+      NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html")));
+
+  constexpr char kJavascript[] =
+      "navigator.credentials.get({ publicKey: {"
+      "  challenge: new TextEncoder().encode('abcd'),"
+      "  userVerification: 'discouraged',"
+      "  allowCredentials: [{type: 'public-key', id: new Uint8Array([1])}],"
+      "  extensions: { devicePubKey: {} },"
+      "}}).then(c => {"
+      "  const e = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)));"
+      "  window.domAutomationController.send("
+      "      'webauth: ' + e(c.response.authenticatorData)"
+      "                  + ',' + e(c.response.clientDataJSON)"
+      "                  + ',' + e(c.getClientExtensionResults()"
+      "                               .devicePubKey"
+      "                               .authenticatorOutput)"
+      "                  + ',' + e(c.getClientExtensionResults()"
+      "                               .devicePubKey"
+      "                               .signature));"
+      "}, e => window.domAutomationController.send("
+      "      'webauth: ' + e.toString()));";
+  absl::optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
+      shell()->web_contents(), kJavascript, "webauth: ");
+  ASSERT_TRUE(result);
+  VerifyDevicePublicKeyOutput(result->substr(9));
+}
+
 #if BUILDFLAG(IS_WIN)
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest, WinMakeCredential) {
   EXPECT_TRUE(
diff --git a/content/browser/webkit_browsertest.cc b/content/browser/webkit_browsertest.cc
index 5270982..3bdd2508 100644
--- a/content/browser/webkit_browsertest.cc
+++ b/content/browser/webkit_browsertest.cc
@@ -45,7 +45,7 @@
            producer_handle->WriteData(body.data(), &bytes_written,
                                       MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
   params->client->OnReceiveResponse(std::move(response),
-                                    std::move(consumer_handle));
+                                    std::move(consumer_handle), absl::nullopt);
 
   params->client->OnComplete(
       network::URLLoaderCompletionStatus(net::ERR_CONNECTION_ABORTED));
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc
index 9fbaf27..0ad04f16 100644
--- a/content/browser/webui/web_ui_url_loader_factory.cc
+++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -145,8 +145,8 @@
   mojo::Remote<network::mojom::URLLoaderClient> client(
       std::move(client_remote));
 
-  client->OnReceiveResponse(std::move(headers),
-                            std::move(pipe_consumer_handle));
+  client->OnReceiveResponse(std::move(headers), std::move(pipe_consumer_handle),
+                            absl::nullopt);
 
   network::URLLoaderCompletionStatus status(net::OK);
   status.encoded_data_length = output_size;
diff --git a/content/browser/worker_host/worker_script_fetcher.cc b/content/browser/worker_host/worker_script_fetcher.cc
index 8c7743d..3677fb7d 100644
--- a/content/browser/worker_host/worker_script_fetcher.cc
+++ b/content/browser/worker_host/worker_script_fetcher.cc
@@ -626,8 +626,10 @@
 
 void WorkerScriptFetcher::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(!cached_metadata);
   response_head_ = std::move(response_head);
   if (!body)
     return;
@@ -713,10 +715,6 @@
   NOTREACHED();
 }
 
-void WorkerScriptFetcher::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  NOTREACHED();
-}
-
 void WorkerScriptFetcher::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   NOTREACHED();
 }
diff --git a/content/browser/worker_host/worker_script_fetcher.h b/content/browser/worker_host/worker_script_fetcher.h
index 880daa6..3877530 100644
--- a/content/browser/worker_host/worker_script_fetcher.h
+++ b/content/browser/worker_host/worker_script_fetcher.h
@@ -206,14 +206,15 @@
 
   // network::mojom::URLLoaderClient
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/browser/worker_host/worker_script_loader.cc b/content/browser/worker_host/worker_script_loader.cc
index 386bc7b..fe249eb8 100644
--- a/content/browser/worker_host/worker_script_loader.cc
+++ b/content/browser/worker_host/worker_script_loader.cc
@@ -232,9 +232,11 @@
 
 void WorkerScriptLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  client_->OnReceiveResponse(std::move(response_head), std::move(body));
+  client_->OnReceiveResponse(std::move(response_head), std::move(body),
+                             std::move(cached_metadata));
 }
 
 void WorkerScriptLoader::OnReceiveRedirect(
@@ -260,11 +262,6 @@
                             std::move(ack_callback));
 }
 
-void WorkerScriptLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void WorkerScriptLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   client_->OnTransferSizeUpdated(transfer_size_diff);
diff --git a/content/browser/worker_host/worker_script_loader.h b/content/browser/worker_host/worker_script_loader.h
index 43c00645..edd0b5f7 100644
--- a/content/browser/worker_host/worker_script_loader.h
+++ b/content/browser/worker_host/worker_script_loader.h
@@ -97,15 +97,16 @@
 
   // network::mojom::URLLoaderClient:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/content/common/pepper_plugin_list.cc b/content/common/pepper_plugin_list.cc
index 1ff53a0..5148d42 100644
--- a/content/common/pepper_plugin_list.cc
+++ b/content/common/pepper_plugin_list.cc
@@ -15,8 +15,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/pepper_plugin_info.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
 
 namespace content {
@@ -26,7 +26,7 @@
 const size_t kMaxPluginsToRegisterFromCommandLine = 64;
 
 // Appends any plugins from the command line to the given vector.
-void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
+void ComputePluginsFromCommandLine(std::vector<ContentPluginInfo>* plugins) {
   // On Linux, once we're sandboxed, we can't know if a plugin is available or
   // not. But (on Linux) this function is always called once before we're
   // sandboxed. So when this function is called for the first time we set a
@@ -79,7 +79,7 @@
     std::vector<std::string> name_parts = base::SplitString(
         parts[0], "#", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
 
-    PepperPluginInfo plugin;
+    ContentPluginInfo plugin;
     plugin.is_out_of_process = out_of_process;
     plugin.path = base::FilePath::FromUTF8Unsafe(name_parts[0]);
 
@@ -128,7 +128,7 @@
 }  // namespace
 
 bool MakePepperPluginInfo(const WebPluginInfo& webplugin_info,
-                          PepperPluginInfo* pepper_info) {
+                          ContentPluginInfo* pepper_info) {
   if (!webplugin_info.is_pepper_plugin())
     return false;
 
@@ -145,8 +145,8 @@
   return true;
 }
 
-void ComputePepperPluginList(std::vector<PepperPluginInfo>* plugins) {
-  GetContentClient()->AddPepperPlugins(plugins);
+void ComputePepperPluginList(std::vector<ContentPluginInfo>* plugins) {
+  GetContentClient()->AddPlugins(plugins);
   ComputePluginsFromCommandLine(plugins);
 }
 
diff --git a/content/common/pepper_plugin_list.h b/content/common/pepper_plugin_list.h
index 44f33416..1a6991b 100644
--- a/content/common/pepper_plugin_list.h
+++ b/content/common/pepper_plugin_list.h
@@ -15,17 +15,17 @@
 
 namespace content {
 
-struct PepperPluginInfo;
+struct ContentPluginInfo;
 struct WebPluginInfo;
 
-// Constructs a PepperPluginInfo from a WebPluginInfo. Returns false if
-// the operation is not possible, in particular the WebPluginInfo::type
-// must be one of the pepper types.
+// Constructs a Pepper-specific `ContentPluginInfo` from a `WebPluginInfo`.
+// Returns false if the operation is not possible, in particular the
+// `WebPluginInfo::type` must be one of the Pepper types.
 bool MakePepperPluginInfo(const WebPluginInfo& webplugin_info,
-                          PepperPluginInfo* pepper_info);
+                          ContentPluginInfo* pepper_info);
 
 // Computes the list of known pepper plugins.
-void ComputePepperPluginList(std::vector<PepperPluginInfo>* plugins);
+void ComputePepperPluginList(std::vector<ContentPluginInfo>* plugins);
 
 }  // namespace content
 
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
index d13e878..6a2e7905 100644
--- a/content/ppapi_plugin/ppapi_thread.cc
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -28,8 +28,8 @@
 #include "content/ppapi_plugin/plugin_process_dispatcher.h"
 #include "content/ppapi_plugin/ppapi_blink_platform_impl.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/pepper_plugin_info.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_platform_file.h"
 #include "ipc/ipc_sync_channel.h"
@@ -244,8 +244,8 @@
   // Trusted Pepper plugins may be "internal", i.e. built-in to the browser
   // binary.  If we're being asked to load such a plugin (e.g. the Chromoting
   // client) then fetch the entry points from the embedder, rather than a DLL.
-  std::vector<PepperPluginInfo> plugins;
-  GetContentClient()->AddPepperPlugins(&plugins);
+  std::vector<ContentPluginInfo> plugins;
+  GetContentClient()->AddPlugins(&plugins);
   for (const auto& plugin : plugins) {
     if (plugin.is_internal && plugin.path == path) {
       // An internal plugin is being loaded, so fetch the entry points.
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h
index 6f9bb7d7..10a8bb8 100644
--- a/content/ppapi_plugin/ppapi_thread.h
+++ b/content/ppapi_plugin/ppapi_thread.h
@@ -15,7 +15,7 @@
 #include "base/scoped_native_library.h"
 #include "build/build_config.h"
 #include "content/child/child_thread_impl.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #include "ppapi/c/pp_module.h"
 #include "ppapi/proxy/connection.h"
 #include "ppapi/proxy/plugin_dispatcher.h"
@@ -122,7 +122,7 @@
   ppapi::proxy::PluginGlobals plugin_globals_;
 
   // Storage for plugin entry points.
-  PepperPluginInfo::EntryPoints plugin_entry_points_;
+  ContentPluginInfo::EntryPoints plugin_entry_points_;
 
   // Local concept of the module ID. Some functions take this. It's necessary
   // for the in-process PPAPI to handle this properly, but for proxied it's
diff --git a/content/public/browser/identity_request_dialog_controller.cc b/content/public/browser/identity_request_dialog_controller.cc
index e48ef322..337dd3e 100644
--- a/content/public/browser/identity_request_dialog_controller.cc
+++ b/content/public/browser/identity_request_dialog_controller.cc
@@ -52,7 +52,7 @@
 
 IdentityProviderData::IdentityProviderData(
     const GURL& idp_config_url,
-    base::span<const IdentityRequestAccount> accounts,
+    const std::vector<IdentityRequestAccount>& accounts,
     const IdentityProviderMetadata& idp_metadata,
     const ClientIdData& client_id_data)
     : idp_config_url{idp_config_url},
diff --git a/content/public/browser/identity_request_dialog_controller.h b/content/public/browser/identity_request_dialog_controller.h
index e022ffd..c244fb1 100644
--- a/content/public/browser/identity_request_dialog_controller.h
+++ b/content/public/browser/identity_request_dialog_controller.h
@@ -86,14 +86,14 @@
 
 struct CONTENT_EXPORT IdentityProviderData {
   IdentityProviderData(const GURL& idp_config_url,
-                       base::span<const IdentityRequestAccount> accounts,
+                       const std::vector<IdentityRequestAccount>& accounts,
                        const IdentityProviderMetadata& idp_metadata,
                        const ClientIdData& client_id_data);
   IdentityProviderData(const IdentityProviderData& other);
   ~IdentityProviderData();
 
   GURL idp_config_url;
-  base::span<const IdentityRequestAccount> accounts;
+  std::vector<IdentityRequestAccount> accounts;
   IdentityProviderMetadata idp_metadata;
   ClientIdData client_id_data;
 };
diff --git a/content/public/browser/plugin_service.h b/content/public/browser/plugin_service.h
index ad33618..5432fcd 100644
--- a/content/public/browser/plugin_service.h
+++ b/content/public/browser/plugin_service.h
@@ -27,7 +27,7 @@
 
 class BrowserContext;
 class PluginServiceFilter;
-struct PepperPluginInfo;
+struct ContentPluginInfo;
 struct WebPluginInfo;
 
 // This must be created on the main thread but it's only called on the IO/file
@@ -98,10 +98,10 @@
   // This can be called from any thread.
   virtual void GetPlugins(GetPluginsCallback callback) = 0;
 
-  // Returns information about a pepper plugin if it exists, otherwise nullptr.
-  // The caller does not own the pointer, and it's not guaranteed to live past
-  // the call stack.
-  virtual const PepperPluginInfo* GetRegisteredPpapiPluginInfo(
+  // Returns information about a plugin if it exists, otherwise `nullptr`. The
+  // caller does not own the pointer, and it's not guaranteed to live past the
+  // call stack.
+  virtual const ContentPluginInfo* GetRegisteredPluginInfo(
       const base::FilePath& plugin_path) = 0;
 
   virtual void SetFilter(PluginServiceFilter* filter) = 0;
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index 0ad7673b..7624a0b 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -340,8 +340,8 @@
 
   if (enable_plugins) {
     sources += [
-      "pepper_plugin_info.cc",
-      "pepper_plugin_info.h",
+      "content_plugin_info.cc",
+      "content_plugin_info.h",
     ]
 
     if (enable_ppapi) {
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index aded7807..d629b70b 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -55,7 +55,7 @@
 class ContentRendererClient;
 class ContentUtilityClient;
 struct CdmInfo;
-struct PepperPluginInfo;
+struct ContentPluginInfo;
 
 // Setter and getter for the client. The client should be set early, before any
 // content code is called.
@@ -101,9 +101,8 @@
   // Sets the data on the current gpu.
   virtual void SetGpuInfo(const gpu::GPUInfo& gpu_info) {}
 
-  // Gives the embedder a chance to register its own pepper plugins.
-  virtual void AddPepperPlugins(
-      std::vector<content::PepperPluginInfo>* plugins) {}
+  // Gives the embedder a chance to register its own plugins.
+  virtual void AddPlugins(std::vector<content::ContentPluginInfo>* plugins) {}
 
   // Gives the embedder a chance to register the Content Decryption Modules
   // (CDM) it supports, as well as the CDM host file paths to verify CDM host.
diff --git a/content/public/common/content_plugin_info.cc b/content/public/common/content_plugin_info.cc
new file mode 100644
index 0000000..4c134bd
--- /dev/null
+++ b/content/public/common/content_plugin_info.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2011 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 "content/public/common/content_plugin_info.h"
+
+#include "base/files/file_path.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/webplugininfo.h"
+#include "ppapi/buildflags/buildflags.h"
+
+namespace content {
+
+#if BUILDFLAG(ENABLE_PPAPI)
+ContentPluginInfo::EntryPoints::EntryPoints() = default;
+#endif  // BUILDFLAG(ENABLE_PPAPI)
+
+ContentPluginInfo::ContentPluginInfo() = default;
+ContentPluginInfo::ContentPluginInfo(const ContentPluginInfo& other) = default;
+ContentPluginInfo::ContentPluginInfo(ContentPluginInfo&& other) noexcept =
+    default;
+ContentPluginInfo::~ContentPluginInfo() = default;
+
+WebPluginInfo ContentPluginInfo::ToWebPluginInfo() const {
+  WebPluginInfo info;
+
+  info.type = is_out_of_process
+                  ? WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS
+                  : WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
+
+  info.name = name.empty() ? path.BaseName().LossyDisplayName()
+                           : base::UTF8ToUTF16(name);
+  info.path = path;
+  info.version = base::ASCIIToUTF16(version);
+  info.desc = base::ASCIIToUTF16(description);
+  info.mime_types = mime_types;
+  info.pepper_permissions = permissions;
+
+  return info;
+}
+
+}  // namespace content
diff --git a/content/public/common/pepper_plugin_info.h b/content/public/common/content_plugin_info.h
similarity index 82%
rename from content/public/common/pepper_plugin_info.h
rename to content/public/common/content_plugin_info.h
index 73b5f60..7ed1681 100644
--- a/content/public/common/pepper_plugin_info.h
+++ b/content/public/common/content_plugin_info.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 CONTENT_PUBLIC_COMMON_PEPPER_PLUGIN_INFO_H_
-#define CONTENT_PUBLIC_COMMON_PEPPER_PLUGIN_INFO_H_
+#ifndef CONTENT_PUBLIC_COMMON_CONTENT_PLUGIN_INFO_H_
+#define CONTENT_PUBLIC_COMMON_CONTENT_PLUGIN_INFO_H_
 
 #include <stdint.h>
 
@@ -26,8 +26,7 @@
 
 namespace content {
 
-// TODO(crbug.com/1344644): Rename `PepperPluginInfo`, which has non-PPAPI uses.
-struct CONTENT_EXPORT PepperPluginInfo {
+struct CONTENT_EXPORT ContentPluginInfo {
 #if BUILDFLAG(ENABLE_PPAPI)
   typedef const void* (*GetInterfaceFunc)(const char*);
   typedef int (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface);
@@ -43,10 +42,10 @@
   };
 #endif  // BUILDFLAG(ENABLE_PPAPI)
 
-  PepperPluginInfo();
-  PepperPluginInfo(const PepperPluginInfo& other);
-  PepperPluginInfo(PepperPluginInfo&& other) noexcept;
-  ~PepperPluginInfo();
+  ContentPluginInfo();
+  ContentPluginInfo(const ContentPluginInfo& other);
+  ContentPluginInfo(ContentPluginInfo&& other) noexcept;
+  ~ContentPluginInfo();
 
   WebPluginInfo ToWebPluginInfo() const;
 
@@ -77,4 +76,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_PUBLIC_COMMON_PEPPER_PLUGIN_INFO_H_
+#endif  // CONTENT_PUBLIC_COMMON_CONTENT_PLUGIN_INFO_H_
diff --git a/content/public/common/pepper_plugin_info.cc b/content/public/common/pepper_plugin_info.cc
deleted file mode 100644
index 71459cc..0000000
--- a/content/public/common/pepper_plugin_info.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2011 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 "content/public/common/pepper_plugin_info.h"
-
-#include "base/files/file_path.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/public/common/webplugininfo.h"
-#include "ppapi/buildflags/buildflags.h"
-
-namespace content {
-
-#if BUILDFLAG(ENABLE_PPAPI)
-PepperPluginInfo::EntryPoints::EntryPoints() = default;
-#endif  // BUILDFLAG(ENABLE_PPAPI)
-
-PepperPluginInfo::PepperPluginInfo() = default;
-PepperPluginInfo::PepperPluginInfo(const PepperPluginInfo& other) = default;
-PepperPluginInfo::PepperPluginInfo(PepperPluginInfo&& other) noexcept = default;
-PepperPluginInfo::~PepperPluginInfo() = default;
-
-WebPluginInfo PepperPluginInfo::ToWebPluginInfo() const {
-  WebPluginInfo info;
-
-  info.type = is_out_of_process ?
-      WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS :
-      WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
-
-  info.name = name.empty() ?
-      path.BaseName().LossyDisplayName() : base::UTF8ToUTF16(name);
-  info.path = path;
-  info.version = base::ASCIIToUTF16(version);
-  info.desc = base::ASCIIToUTF16(description);
-  info.mime_types = mime_types;
-  info.pepper_permissions = permissions;
-
-  return info;
-}
-
-}  // namespace content
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 224e244..1931aaf 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1087,12 +1087,12 @@
 
 #endif  // !BUILDFLAG(IS_MAC)
 
-void SimulateGesturePinchSequence(WebContents* web_contents,
+void SimulateGesturePinchSequence(RenderWidgetHost* render_widget_host,
                                   const gfx::Point& point,
                                   float scale,
                                   blink::WebGestureDevice source_device) {
-  RenderWidgetHostImpl* widget_host = RenderWidgetHostImpl::From(
-      web_contents->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget());
+  RenderWidgetHostImpl* widget_host =
+      RenderWidgetHostImpl::From(render_widget_host);
 
   blink::WebGestureEvent pinch_begin(
       blink::WebInputEvent::Type::kGesturePinchBegin,
@@ -1117,6 +1117,15 @@
   widget_host->ForwardGestureEvent(pinch_end);
 }
 
+void SimulateGesturePinchSequence(WebContents* web_contents,
+                                  const gfx::Point& point,
+                                  float scale,
+                                  blink::WebGestureDevice source_device) {
+  RenderWidgetHost* widget_host =
+      web_contents->GetPrimaryMainFrame()->GetRenderWidgetHost();
+  SimulateGesturePinchSequence(widget_host, point, scale, source_device);
+}
+
 void SimulateGestureScrollSequence(WebContents* web_contents,
                                    const gfx::Point& point,
                                    const gfx::Vector2dF& delta) {
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 5c7793a1..141a142 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -321,6 +321,11 @@
 #endif  // !BUILDFLAG(IS_MAC)
 
 // Sends a GesturePinch Begin/Update/End sequence.
+void SimulateGesturePinchSequence(RenderWidgetHost* render_widget_host,
+                                  const gfx::Point& point,
+                                  float scale,
+                                  blink::WebGestureDevice source_device);
+
 void SimulateGesturePinchSequence(WebContents* web_contents,
                                   const gfx::Point& point,
                                   float scale,
diff --git a/content/public/test/scoped_web_ui_controller_factory_registration.cc b/content/public/test/scoped_web_ui_controller_factory_registration.cc
index c8ce1ad..349a4a10 100644
--- a/content/public/test/scoped_web_ui_controller_factory_registration.cc
+++ b/content/public/test/scoped_web_ui_controller_factory_registration.cc
@@ -16,6 +16,12 @@
 
 namespace {
 
+url::Origin GetOriginFromConfig(WebUIConfig& webui_config) {
+  return url::Origin::Create(
+      GURL(base::StrCat({webui_config.scheme(), url::kStandardSchemeSeparator,
+                         webui_config.host()})));
+}
+
 void AddWebUIConfig(std::unique_ptr<WebUIConfig> webui_config) {
   auto& config_map = WebUIConfigMap::GetInstance();
 
@@ -57,26 +63,19 @@
 
 ScopedWebUIConfigRegistration::ScopedWebUIConfigRegistration(
     std::unique_ptr<WebUIConfig> webui_config)
-    : ScopedWebUIConfigRegistration(
-          GURL(base::StrCat({webui_config->scheme(),
-                             url::kStandardSchemeSeparator,
-                             webui_config->host()})),
-          std::move(webui_config)) {}
-
-ScopedWebUIConfigRegistration::ScopedWebUIConfigRegistration(
-    const GURL& webui_origin)
-    : ScopedWebUIConfigRegistration(webui_origin,
-                                    /*webui_config=*/nullptr) {}
-
-ScopedWebUIConfigRegistration::ScopedWebUIConfigRegistration(
-    const GURL& webui_origin,
-    std::unique_ptr<WebUIConfig> webui_config)
-    : webui_config_origin_(url::Origin::Create(webui_origin)) {
+    : webui_config_origin_(GetOriginFromConfig(*webui_config)) {
   auto& config_map = WebUIConfigMap::GetInstance();
   replaced_webui_config_ = config_map.RemoveConfig(webui_config_origin_);
 
-  if (webui_config != nullptr)
-    AddWebUIConfig(std::move(webui_config));
+  DCHECK(webui_config.get() != nullptr);
+  AddWebUIConfig(std::move(webui_config));
+}
+
+ScopedWebUIConfigRegistration::ScopedWebUIConfigRegistration(
+    const GURL& webui_origin)
+    : webui_config_origin_(url::Origin::Create(webui_origin)) {
+  auto& config_map = WebUIConfigMap::GetInstance();
+  replaced_webui_config_ = config_map.RemoveConfig(webui_config_origin_);
 }
 
 ScopedWebUIConfigRegistration::~ScopedWebUIConfigRegistration() {
diff --git a/content/public/test/scoped_web_ui_controller_factory_registration.h b/content/public/test/scoped_web_ui_controller_factory_registration.h
index 57c0021..133b652 100644
--- a/content/public/test/scoped_web_ui_controller_factory_registration.h
+++ b/content/public/test/scoped_web_ui_controller_factory_registration.h
@@ -52,9 +52,6 @@
   ~ScopedWebUIConfigRegistration();
 
  private:
-  ScopedWebUIConfigRegistration(const GURL& webui_origin,
-                                std::unique_ptr<WebUIConfig> webui_config);
-
   const url::Origin webui_config_origin_;
   std::unique_ptr<WebUIConfig> replaced_webui_config_;
 };
diff --git a/content/public/test/text_input_test_utils.cc b/content/public/test/text_input_test_utils.cc
index 79fa000d..ee0f5dd 100644
--- a/content/public/test/text_input_test_utils.cc
+++ b/content/public/test/text_input_test_utils.cc
@@ -310,8 +310,10 @@
   while (!rfh->is_local_root())
     rfh = rfh->GetParent();
 
+  DCHECK(rfh->GetPage().IsPrimary())
+      << "Only implemented for frames in a primary page";
   FrameTreeNode* ftn = rfh->frame_tree_node();
-  if (rfh->is_main_frame()) {
+  if (rfh->IsOutermostMainFrame()) {
     WebContents::FromRenderFrameHost(rfh)->Close();
   } else {
     ftn->frame_tree()->RemoveFrame(ftn);
diff --git a/content/public/test/url_loader_interceptor.cc b/content/public/test/url_loader_interceptor.cc
index 7c5c300..5c5e8e87 100644
--- a/content/public/test/url_loader_interceptor.cc
+++ b/content/public/test/url_loader_interceptor.cc
@@ -185,9 +185,12 @@
     original_client_->OnReceiveEarlyHints(std::move(early_hints));
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
-    original_client_->OnReceiveResponse(std::move(head), std::move(body));
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
+    original_client_->OnReceiveResponse(std::move(head), std::move(body),
+                                        std::move(cached_metadata));
   }
 
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -202,10 +205,6 @@
                                        std::move(callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    original_client_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     original_client_->OnTransferSizeUpdated(transfer_size_diff);
   }
@@ -614,7 +613,8 @@
                                       MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
   CHECK_EQ(result, MOJO_RESULT_OK);
 
-  client->OnReceiveResponse(std::move(response), std::move(consumer_handle));
+  client->OnReceiveResponse(std::move(response), std::move(consumer_handle),
+                            absl::nullopt);
 
   network::URLLoaderCompletionStatus status;
   status.decoded_body_length = body.size();
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 7b448f3..624f8392 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -980,7 +980,6 @@
       continue;
 
     if (ui::IsImage(node.role)) {
-      WebAXObject src = WebAXObject::FromWebDocumentByID(document, node.id);
       AddImageAnnotationsForNode(src, &node);
     } else if ((ui::IsLink(node.role) || ui::IsPlatformDocument(node.role)) &&
                node.GetNameFrom() != ax::mojom::NameFrom::kAttribute) {
diff --git a/content/renderer/pepper/pepper_plugin_registry.cc b/content/renderer/pepper/pepper_plugin_registry.cc
index c7c9bed..c422929 100644
--- a/content/renderer/pepper/pepper_plugin_registry.cc
+++ b/content/renderer/pepper/pepper_plugin_registry.cc
@@ -26,7 +26,7 @@
   return registry;
 }
 
-const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
+const ContentPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
     const WebPluginInfo& info) {
   for (const auto& plugin : plugin_list_) {
     if (info.path == plugin.path)
@@ -37,7 +37,7 @@
   // is actually in |info| and we can use it to construct it and add it to
   // the list. This same deal needs to be done in the browser side in
   // PluginService.
-  PepperPluginInfo plugin;
+  ContentPluginInfo plugin;
   if (!MakePepperPluginInfo(info, &plugin))
     return nullptr;
 
diff --git a/content/renderer/pepper/pepper_plugin_registry.h b/content/renderer/pepper/pepper_plugin_registry.h
index 5fe2e9a..7e2b6f6b 100644
--- a/content/renderer/pepper/pepper_plugin_registry.h
+++ b/content/renderer/pepper/pepper_plugin_registry.h
@@ -8,7 +8,7 @@
 #include <map>
 
 #include "base/memory/ref_counted.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
@@ -33,7 +33,7 @@
   // return value will be NULL if there is no such plugin.
   //
   // The returned pointer is owned by the PluginRegistry.
-  const PepperPluginInfo* GetInfoForPlugin(const WebPluginInfo& info);
+  const ContentPluginInfo* GetInfoForPlugin(const WebPluginInfo& info);
 
   // Returns an existing loaded module for the given path. It will search for
   // both preloaded in-process or currently active (non crashed) out-of-process
@@ -59,7 +59,7 @@
   void Initialize();
 
   // All known pepper plugins.
-  std::vector<PepperPluginInfo> plugin_list_;
+  std::vector<ContentPluginInfo> plugin_list_;
 
   // Plugins that have been preloaded so they can be executed in-process in
   // the renderer (the sandbox prevents on-demand loading).
diff --git a/content/renderer/pepper/pepper_webplugin_impl_browsertest.cc b/content/renderer/pepper/pepper_webplugin_impl_browsertest.cc
index b98b9cb..22401902 100644
--- a/content/renderer/pepper/pepper_webplugin_impl_browsertest.cc
+++ b/content/renderer/pepper/pepper_webplugin_impl_browsertest.cc
@@ -10,8 +10,8 @@
 #include "base/memory/ptr_util.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_constants.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/pepper_plugin_info.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/public/test/render_view_test.h"
 #include "content/renderer/pepper/plugin_module.h"
@@ -124,8 +124,8 @@
     return PP_FALSE;
   }
 
-  static PepperPluginInfo GetPluginInfo() {
-    PepperPluginInfo info;
+  static ContentPluginInfo GetPluginInfo() {
+    ContentPluginInfo info;
     info.is_internal = true;
     info.path = base::FilePath(FILE_PATH_LITERAL("internal-always-throttle"));
     info.name = "Always Throttle";
@@ -142,7 +142,7 @@
 
   class MockContentClient : public TestContentClient {
    public:
-    void AddPepperPlugins(std::vector<PepperPluginInfo>* plugins) override {
+    void AddPlugins(std::vector<ContentPluginInfo>* plugins) override {
       plugins->push_back(GetPluginInfo());
     }
   };
diff --git a/content/renderer/pepper/plugin_module.cc b/content/renderer/pepper/plugin_module.cc
index b292431a..5c712e5 100644
--- a/content/renderer/pepper/plugin_module.cc
+++ b/content/renderer/pepper/plugin_module.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/nacl/common/buildflags.h"
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/pepper/host_dispatcher_wrapper.h"
 #include "content/renderer/pepper/host_globals.h"
@@ -328,9 +329,9 @@
 // Gets the PPAPI entry points from the given library and places them into the
 // given structure. Returns true on success.
 bool LoadEntryPointsFromLibrary(const base::NativeLibrary& library,
-                                PepperPluginInfo::EntryPoints* entry_points) {
+                                ContentPluginInfo::EntryPoints* entry_points) {
   entry_points->get_interface =
-      reinterpret_cast<PepperPluginInfo::GetInterfaceFunc>(
+      reinterpret_cast<ContentPluginInfo::GetInterfaceFunc>(
           base::GetFunctionPointerFromNativeLibrary(library,
                                                     "PPP_GetInterface"));
   if (!entry_points->get_interface) {
@@ -339,7 +340,7 @@
   }
 
   entry_points->initialize_module =
-      reinterpret_cast<PepperPluginInfo::PPP_InitializeModuleFunc>(
+      reinterpret_cast<ContentPluginInfo::PPP_InitializeModuleFunc>(
           base::GetFunctionPointerFromNativeLibrary(library,
                                                     "PPP_InitializeModule"));
   if (!entry_points->initialize_module) {
@@ -350,7 +351,7 @@
   // It's okay for PPP_ShutdownModule to not be defined and shutdown_module to
   // be NULL.
   entry_points->shutdown_module =
-      reinterpret_cast<PepperPluginInfo::PPP_ShutdownModuleFunc>(
+      reinterpret_cast<ContentPluginInfo::PPP_ShutdownModuleFunc>(
           base::GetFunctionPointerFromNativeLibrary(library,
                                                     "PPP_ShutdownModule"));
 
@@ -361,7 +362,7 @@
                                   PluginModule* module,
                                   const WebPluginInfo& webplugin_info) {
   // First time an in-process plugin was used, make a host for it.
-  const PepperPluginInfo* info =
+  const ContentPluginInfo* info =
       PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info);
   DCHECK(!info->is_out_of_process);
 
@@ -443,7 +444,7 @@
 }
 
 bool PluginModule::InitAsInternalPlugin(
-    const PepperPluginInfo::EntryPoints& entry_points) {
+    const ContentPluginInfo::EntryPoints& entry_points) {
   if (InitializeModule(entry_points)) {
     entry_points_ = entry_points;
     return true;
@@ -456,7 +457,7 @@
   if (!library)
     return false;
 
-  PepperPluginInfo::EntryPoints entry_points;
+  ContentPluginInfo::EntryPoints entry_points;
 
   if (!LoadEntryPointsFromLibrary(library, &entry_points) ||
       !InitializeModule(entry_points)) {
@@ -642,7 +643,7 @@
 }
 
 bool PluginModule::InitializeModule(
-    const PepperPluginInfo::EntryPoints& entry_points) {
+    const ContentPluginInfo::EntryPoints& entry_points) {
   DCHECK(!host_dispatcher_wrapper_.get()) << "Don't call for proxied modules.";
   DCHECK(entry_points.initialize_module != nullptr);
   int retval = entry_points.initialize_module(pp_module(), &GetInterface);
@@ -680,7 +681,7 @@
   // In-process plugins will have always been created up-front to avoid the
   // sandbox restrictions. So getting here implies it doesn't exist or should
   // be out of process.
-  const PepperPluginInfo* info =
+  const ContentPluginInfo* info =
       PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info);
   if (!info) {
     *pepper_plugin_was_registered = false;
diff --git a/content/renderer/pepper/plugin_module.h b/content/renderer/pepper/plugin_module.h
index a80aa01..cc24505 100644
--- a/content/renderer/pepper/plugin_module.h
+++ b/content/renderer/pepper/plugin_module.h
@@ -17,7 +17,7 @@
 #include "base/process/process.h"
 #include "base/task/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
 #include "ppapi/c/pp_bool.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/c/ppb_core.h"
@@ -85,7 +85,7 @@
   // Initializes this module as an internal plugin with the given entrypoints.
   // This is used for "plugins" compiled into Chrome. Returns true on success.
   // False means that the plugin can not be used.
-  bool InitAsInternalPlugin(const PepperPluginInfo::EntryPoints& entry_points);
+  bool InitAsInternalPlugin(const ContentPluginInfo::EntryPoints& entry_points);
 
   // Initializes this module using the given library path as the plugin.
   // Returns true on success. False means that the plugin can not be used.
@@ -224,7 +224,7 @@
   // Calls the InitializeModule entrypoint. The entrypoint must have been
   // set and the plugin must not be out of process (we don't maintain
   // entrypoints in that case).
-  bool InitializeModule(const PepperPluginInfo::EntryPoints& entry_points);
+  bool InitializeModule(const ContentPluginInfo::EntryPoints& entry_points);
 
   std::unique_ptr<RendererPpapiHostImpl> renderer_ppapi_host_;
 
@@ -255,7 +255,7 @@
   // Contains pointers to the entry points of the actual plugin implementation.
   // These will be NULL for out-of-process plugins, which is indicated by the
   // presence of the host_dispatcher_wrapper_ value.
-  PepperPluginInfo::EntryPoints entry_points_;
+  ContentPluginInfo::EntryPoints entry_points_;
 
   // The name, version, and file location of the module.
   const std::string name_;
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc
index 3751674..19dd8d2 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -80,12 +80,14 @@
     url_loader_client_->OnReceiveEarlyHints(std::move(early_hints));
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     DCHECK(url_loader_client_.is_bound());
     url_loader_client_->OnReceiveResponse(
-        rewrite_header_callback_.Run(std::move(response_head)),
-        std::move(body));
+        rewrite_header_callback_.Run(std::move(response_head)), std::move(body),
+        std::move(cached_metadata));
   }
 
   void OnReceiveRedirect(
@@ -104,11 +106,6 @@
                                          std::move(ack_callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    DCHECK(url_loader_client_.is_bound());
-    url_loader_client_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     DCHECK(url_loader_client_.is_bound());
     url_loader_client_->OnTransferSizeUpdated(transfer_size_diff);
@@ -135,6 +132,23 @@
 
   elements[0] = network::DataElement(std::move(original_body));
 }
+
+// As a workaround for the future timestamp set by the sender, we adjust the
+// time if it happens for a machine without a timer consistent across
+// processes.  (See crbug.com/1342408)
+blink::mojom::ServiceWorkerFetchEventTimingPtr AdjustTimingIfNeededCrBug1342408(
+    blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
+  base::TimeTicks now = base::TimeTicks::Now();
+  if (base::TimeTicks::IsConsistentAcrossProcesses() ||
+      timing->respond_with_settled_time <= now) {
+    return timing;
+  }
+  auto diff = timing->respond_with_settled_time - now;
+  timing->dispatch_event_time -= diff;
+  timing->respond_with_settled_time -= diff;
+  return timing;
+}
+
 }  // namespace
 
 // A ServiceWorkerStreamCallback implementation which waits for completion of
@@ -404,6 +418,9 @@
     blink::mojom::FetchAPIResponsePtr response,
     blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
     blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
+  // TODO(crbug.com/1342408): remove the following workaround when we can always
+  // expect CPUs have invariant TSC.
+  timing = AdjustTimingIfNeededCrBug1342408(std::move(timing));
   TRACE_EVENT_WITH_FLOW0(
       "ServiceWorker", "ServiceWorkerSubresourceLoader::OnResponseStream",
       TRACE_ID_WITH_SCOPE(kServiceWorkerSubresourceLoaderScope,
@@ -571,11 +588,13 @@
 }
 
 void ServiceWorkerSubresourceLoader::CommitResponseBody(
-    mojo::ScopedDataPipeConsumerHandle response_body) {
+    mojo::ScopedDataPipeConsumerHandle response_body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TransitionToStatus(Status::kSentBody);
   // TODO(kinuko): Fill the ssl_info.
   url_loader_client_->OnReceiveResponse(response_head_.Clone(),
-                                        std::move(response_body));
+                                        std::move(response_body),
+                                        std::move(cached_metadata));
 }
 
 void ServiceWorkerSubresourceLoader::CommitEmptyResponseAndComplete() {
@@ -588,7 +607,7 @@
   }
 
   producer_handle.reset();  // The data pipe is empty.
-  CommitResponseBody(std::move(consumer_handle));
+  CommitResponseBody(std::move(consumer_handle), absl::nullopt);
   CommitCompleted(net::OK);
 }
 
@@ -779,13 +798,7 @@
   side_data_reading_complete_ = true;
 
   DCHECK(data_pipe.is_valid());
-  CommitResponseBody(std::move(data_pipe));
-
-  // See https://crbug.com/1294238. The cached meta data needs to be sent after
-  // the response head.
-  if (metadata.has_value()) {
-    url_loader_client_->OnReceiveCachedMetadata(std::move(metadata.value()));
-  }
+  CommitResponseBody(std::move(data_pipe), std::move(metadata));
 
   // If the blob reading completed before the side data reading, then we
   // must manually finalize the blob reading now.
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.h b/content/renderer/service_worker/service_worker_subresource_loader.h
index 8df01b0..444b970f 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.h
+++ b/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -137,9 +137,10 @@
 
   void CommitResponseHeaders();
 
-  // Calls url_loader_client_->OnReceiveResponse() with |response_head_| and
-  // |response_body|.
-  void CommitResponseBody(mojo::ScopedDataPipeConsumerHandle response_body);
+  // Calls url_loader_client_->OnReceiveResponse() with |response_head_|,
+  // |response_body|, and |cached_metadata|.
+  void CommitResponseBody(mojo::ScopedDataPipeConsumerHandle response_body,
+                          absl::optional<mojo_base::BigBuffer> cached_metadata);
 
   // Creates and sends an empty response's body with the net::OK status.
   // Sends net::ERR_INSUFFICIENT_RESOURCES when it can't be created.
diff --git a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
index 560a1aa..4e34ec0e 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
+++ b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -1122,10 +1122,6 @@
   StartRequest(factory, request, &loader, &client);
   client->RunUntilResponseReceived();
 
-  // This needs to come after the response, not the before, as some consumers
-  // such as ScriptResource depend on that.
-  ASSERT_FALSE(client->has_received_cached_metadata());
-
   auto expected_info = CreateResponseInfoFromServiceWorker();
   auto& info = client->response_head();
   expected_info->response_time = response_time;
@@ -1136,8 +1132,7 @@
   EXPECT_EQ(39, info->content_length);
 
   // Test the cached metadata.
-  client->RunUntilCachedMetadataReceived();
-  EXPECT_EQ(client->cached_metadata(),
+  EXPECT_EQ(*client->cached_metadata(),
             std::string(kMetadata.begin(), kMetadata.end()));
 
   client->RunUntilComplete();
@@ -1199,7 +1194,7 @@
   EXPECT_TRUE(
       mojo::BlockingCopyToString(client->response_body_release(), &response));
   EXPECT_EQ(kResponseBody, response);
-  EXPECT_FALSE(client->has_received_cached_metadata());
+  EXPECT_FALSE(client->cached_metadata().has_value());
 
   histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
                                       blink::ServiceWorkerStatusCode::kOk, 1);
@@ -1249,7 +1244,7 @@
 
   // Even though the blob has metadata, verify that the client didn't receive
   // it because this is not a script resource.
-  EXPECT_TRUE(client->cached_metadata().empty());
+  EXPECT_FALSE(client->cached_metadata().has_value());
 
   // Test the body.
   std::string response;
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc
index f680ac5..4e402a4 100644
--- a/content/services/auction_worklet/bidder_worklet.cc
+++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -215,6 +215,12 @@
   generate_bid_task->auction_start_time = auction_start_time;
   generate_bid_task->trace_id = trace_id;
   generate_bid_task->generate_bid_client.Bind(std::move(generate_bid_client));
+  // Deleting `generate_bid_task` will destroy `generate_bid_client` and thus
+  // abort this callback, so it's safe to use Unretained(this) and
+  // `generate_bid_task` here.
+  generate_bid_task->generate_bid_client.set_disconnect_handler(
+      base::BindOnce(&BidderWorklet::OnGenerateBidClientDestroyed,
+                     base::Unretained(this), generate_bid_task));
 
   const auto& trusted_bidding_signals_keys =
       generate_bid_task->bidder_worklet_non_shared_params
@@ -233,7 +239,13 @@
 
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "waiting_for_bidder_script",
                                     trace_id);
-  GenerateBidIfReady(generate_bid_task);
+  // Deleting `generate_bid_task` will destroy `generate_bid_client` and thus
+  // abort this callback, so it's safe to use Unretained(this) and
+  // `generate_bid_task` here.
+  generate_bid_task->generate_bid_client->OnBiddingSignalsReceived(
+      /*priority_vector=*/{},
+      base::BindOnce(&BidderWorklet::SignalsReceivedCallback,
+                     base::Unretained(this), generate_bid_task));
 }
 
 void BidderWorklet::SendPendingSignalsRequests() {
@@ -903,24 +915,77 @@
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "waiting_for_bidder_script",
                                     task->trace_id);
 
+  const TrustedSignals::Result::PriorityVector* priority_vector = nullptr;
+  if (result) {
+    priority_vector =
+        result->GetPriorityVector(task->bidder_worklet_non_shared_params->name);
+  }
+
   task->trusted_bidding_signals_error_msg = std::move(error_msg);
-  task->trusted_bidding_signals_result = std::move(result);
+  // Only hold onto `result` if it has information that needs to be passed to
+  // generateBid().
+  if (task->bidder_worklet_non_shared_params->trusted_bidding_signals_keys &&
+      !task->bidder_worklet_non_shared_params->trusted_bidding_signals_keys
+           ->empty()) {
+    task->trusted_bidding_signals_result = std::move(result);
+  }
   task->trusted_bidding_signals_request.reset();
 
+  // Deleting `generate_bid_task` will destroy `generate_bid_client` and thus
+  // abort this callback, so it's safe to use Unretained(this) and
+  // `generate_bid_task` here.
+  task->generate_bid_client->OnBiddingSignalsReceived(
+      priority_vector ? *priority_vector
+                      : TrustedSignals::Result::PriorityVector(),
+      base::BindOnce(&BidderWorklet::SignalsReceivedCallback,
+                     base::Unretained(this), task));
+}
+
+void BidderWorklet::OnGenerateBidClientDestroyed(
+    GenerateBidTaskList::iterator task) {
+  // If the task hasn't received the signals called callback, it hasn't posted a
+  // task to run off-thread, so can be safely deleted, as everything else,
+  // including fetching trusted bidding signals, can be safely cancelled.
+  //
+  // Otherwise, there may be a pending V8 call. In that case, just let it run
+  // and invoke the GenerateBidClient's OnGenerateBidComplete() method, which
+  // will safely do nothing since the pipe is now closed.
+  //
+  // TODO(mmenke): Consider supporting cancellation after the task to run V8 has
+  // been posted.
+  if (!task->signals_received_callback_invoked)
+    generate_bid_tasks_.erase(task);
+}
+
+void BidderWorklet::SignalsReceivedCallback(
+    GenerateBidTaskList::iterator task) {
+  DCHECK(!task->signals_received_callback_invoked);
+  task->signals_received_callback_invoked = true;
   GenerateBidIfReady(task);
 }
 
 void BidderWorklet::GenerateBidIfReady(GenerateBidTaskList::iterator task) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
-  if (task->trusted_bidding_signals_request || !IsCodeReady())
+  if (!task->signals_received_callback_invoked || !IsCodeReady())
     return;
 
+  // If there was a trusted signals request, it should have already completed
+  // and been cleaned up before `signals_received_callback_invoked` was set to
+  // true.
+  DCHECK(!task->trusted_bidding_signals_request);
+
   TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "waiting_for_bidder_script",
                                   task->trace_id);
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "post_v8_task", task->trace_id);
 
-  // Other than the callback field, no fields of `task` are needed after this
+  // Other than the client field, no fields of `task` are needed after this
   // point, so can consume them instead of copying them.
+  //
+  // Since `signals_received_callback_invoked` is true, the GenerateBidTask
+  // won't be deleted on the main thread during this call, even if the
+  // GenerateBidClient pipe is deleted by the caller (unless the BidderWorklet
+  // itself is deleted). Therefore, it's safe to post a callback with the `task`
+  // iterator the v8 thread.
   v8_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h
index c60caf7..983a037 100644
--- a/content/services/auction_worklet/bidder_worklet.h
+++ b/content/services/auction_worklet/bidder_worklet.h
@@ -162,6 +162,11 @@
     // reported on bid completion.
     absl::optional<std::string> trusted_bidding_signals_error_msg;
 
+    // Set to true once the callback sent to the OnBiddingSignalsReceived()
+    // method of `generate_bid_client` has been invoked. the Javascript
+    // generateBid() method will not be run until that happens.
+    bool signals_received_callback_invoked = false;
+
     mojo::AssociatedRemote<mojom::GenerateBidClient> generate_bid_client;
   };
 
@@ -316,6 +321,15 @@
       scoped_refptr<TrustedSignals::Result> result,
       absl::optional<std::string> error_msg);
 
+  // Invoked when the GenerateBidClient associated with `task` is destroyed.
+  // Cancels bid generation.
+  void OnGenerateBidClientDestroyed(GenerateBidTaskList::iterator task);
+
+  // Callback passed to mojom::GenerateBidClient::OnSignalsReceived. Sets
+  // `task->signals_received_callback_invoked` to true, and invokes
+  // GenerateBidIfReady().
+  void SignalsReceivedCallback(GenerateBidTaskList::iterator task);
+
   // Checks if the script has been loaded successfully, and the
   // TrustedSignals load has finished (successfully or not). If so, calls
   // generateBid(), and invokes `load_script_and_generate_bid_callback_` with
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc
index 9cfc5ca..a982da5 100644
--- a/content/services/auction_worklet/bidder_worklet_unittest.cc
+++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -115,9 +115,16 @@
          base::StringPrintf(kReportWinScript, function_body.c_str());
 }
 
-// A GenerateBidClient that takes a callback to call in OnGenerateBid().
+// A GenerateBidClient that takes a callback to call in OnGenerateBid(), and
+// optionally one for OnBiddingSignalsReceived(). If no callback for
+// OnBiddingSignalsReceived() is provided, just invokes the
+// OnBiddingSignalsReceivedCallback immediately.
 class GenerateBidClientWithCallbacks : public mojom::GenerateBidClient {
  public:
+  using OnBiddingSignalsReceivedCallback = base::OnceCallback<void(
+      const base::flat_map<std::string, double>& priority_vector,
+      base::OnceClosure callback)>;
+
   using GenerateBidCallback =
       base::OnceCallback<void(mojom::BidderWorkletBidPtr bid,
                               uint32_t data_version,
@@ -130,18 +137,28 @@
                               const std::vector<std::string>& errors)>;
 
   explicit GenerateBidClientWithCallbacks(
-      GenerateBidCallback generate_bid_callback)
-      : generate_bid_callback_(std::move(generate_bid_callback)) {}
+      GenerateBidCallback generate_bid_callback,
+      OnBiddingSignalsReceivedCallback on_bidding_signals_received_callback =
+          OnBiddingSignalsReceivedCallback())
+      : on_bidding_signals_received_callback_(
+            std::move(on_bidding_signals_received_callback)),
+        generate_bid_callback_(std::move(generate_bid_callback)) {
+    DCHECK(generate_bid_callback_);
+  }
 
   ~GenerateBidClientWithCallbacks() override = default;
 
-  // Helper that creates a GenerateBidClientWithCallbacks whose lifetime is
-  // managed by a self-owned receiver.
+  // Helper that creates a GenerateBidClientWithCallbacks() using a
+  // SelfOwnedReceived.
   static mojo::PendingAssociatedRemote<mojom::GenerateBidClient> Create(
-      GenerateBidCallback callback) {
+      GenerateBidCallback callback,
+      OnBiddingSignalsReceivedCallback on_bidding_signals_received_callback =
+          OnBiddingSignalsReceivedCallback()) {
     mojo::PendingAssociatedRemote<mojom::GenerateBidClient> client_remote;
     mojo::MakeSelfOwnedAssociatedReceiver(
-        std::make_unique<GenerateBidClientWithCallbacks>(std::move(callback)),
+        std::make_unique<GenerateBidClientWithCallbacks>(
+            std::move(callback),
+            std::move(on_bidding_signals_received_callback)),
         client_remote.InitWithNewEndpointAndPassReceiver());
     return client_remote;
   }
@@ -166,6 +183,22 @@
   }
 
   // mojom::GenerateBidClient implementation:
+
+  void OnBiddingSignalsReceived(
+      const base::flat_map<std::string, double>& priority_vector,
+      base::OnceClosure callback) override {
+    // May only be called once.
+    EXPECT_FALSE(on_bidding_signals_received_invoked_);
+    on_bidding_signals_received_invoked_ = true;
+
+    if (on_bidding_signals_received_callback_) {
+      std::move(on_bidding_signals_received_callback_)
+          .Run(priority_vector, std::move(callback));
+      return;
+    }
+    std::move(callback).Run();
+  }
+
   void OnGenerateBidComplete(mojom::BidderWorkletBidPtr bid,
                              uint32_t data_version,
                              bool has_data_version,
@@ -175,6 +208,9 @@
                              bool has_set_priority,
                              PrivateAggregationRequests pa_requests,
                              const std::vector<std::string>& errors) override {
+    // OnBiddingSignalsReceived() must be called first.
+    EXPECT_TRUE(on_bidding_signals_received_invoked_);
+
     std::move(generate_bid_callback_)
         .Run(std::move(bid), data_version, has_data_version,
              debug_loss_report_url, debug_win_report_url, set_priority,
@@ -182,6 +218,8 @@
   }
 
  private:
+  bool on_bidding_signals_received_invoked_ = false;
+  OnBiddingSignalsReceivedCallback on_bidding_signals_received_callback_;
   GenerateBidCallback generate_bid_callback_;
 };
 
@@ -2834,6 +2872,264 @@
   EXPECT_EQ(observed_requests += 2, url_loader_factory_.total_requests());
 }
 
+// Test that when no trusted signals are fetched, generating bids is delayed
+// until the OnBiddingSignalsReceivedCallback is invoked.
+TEST_F(BidderWorkletTest, GenerateBidOnBiddingSignalsReceivedNoTrustedSignals) {
+  auto bidder_worklet = CreateWorklet();
+  AddJavascriptResponse(
+      &url_loader_factory_, interest_group_bidding_url_,
+      CreateGenerateBidScript(CreateBasicGenerateBidScript()));
+
+  base::RunLoop on_bidding_signals_received_run_loop;
+  base::OnceClosure on_bidding_signals_received_continue_callback;
+  auto on_bidding_signals_received_callback = base::BindLambdaForTesting(
+      [&](const base::flat_map<std::string, double>& priority_vector,
+          base::OnceClosure callback) {
+        EXPECT_TRUE(priority_vector.empty());
+        on_bidding_signals_received_run_loop.Quit();
+        on_bidding_signals_received_continue_callback = std::move(callback);
+      });
+  load_script_run_loop_ = std::make_unique<base::RunLoop>();
+  GenerateBid(bidder_worklet.get(),
+              GenerateBidClientWithCallbacks::Create(
+                  base::BindOnce(&BidderWorkletTest::GenerateBidCallback,
+                                 base::Unretained(this)),
+                  std::move(on_bidding_signals_received_callback)));
+
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+  ASSERT_TRUE(on_bidding_signals_received_continue_callback);
+
+  std::move(on_bidding_signals_received_continue_callback).Run();
+  load_script_run_loop_->Run();
+}
+
+// Test that when signals fail to be feteched, OnBiddingSignalsReceived() is
+// only invoked after the failed fetch completes, and generating bids is delayed
+// until the OnBiddingSignalsReceivedCallback is invoked.
+TEST_F(BidderWorkletTest, GenerateBidOnBiddingSignalsReceivedFetchFails) {
+  interest_group_trusted_bidding_signals_url_ = GURL("https://signals.test/");
+  const GURL kFullSignalsUrl(
+      "https://signals.test/?hostname=top.window.test&interestGroupNames=Fred");
+
+  auto bidder_worklet = CreateWorklet();
+  AddJavascriptResponse(
+      &url_loader_factory_, interest_group_bidding_url_,
+      CreateGenerateBidScript(CreateBasicGenerateBidScript()));
+
+  base::RunLoop on_bidding_signals_received_run_loop;
+  base::OnceClosure on_bidding_signals_received_continue_callback;
+  auto on_bidding_signals_received_callback = base::BindLambdaForTesting(
+      [&](const base::flat_map<std::string, double>& priority_vector,
+          base::OnceClosure callback) {
+        EXPECT_TRUE(priority_vector.empty());
+        on_bidding_signals_received_run_loop.Quit();
+        on_bidding_signals_received_continue_callback = std::move(callback);
+      });
+  load_script_run_loop_ = std::make_unique<base::RunLoop>();
+  GenerateBid(bidder_worklet.get(),
+              GenerateBidClientWithCallbacks::Create(
+                  base::BindOnce(&BidderWorkletTest::GenerateBidCallback,
+                                 base::Unretained(this)),
+                  std::move(on_bidding_signals_received_callback)));
+
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+
+  url_loader_factory_.AddResponse(kFullSignalsUrl.spec(), /*content=*/"",
+                                  net::HTTP_NOT_FOUND);
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+  ASSERT_TRUE(on_bidding_signals_received_continue_callback);
+
+  std::move(on_bidding_signals_received_continue_callback).Run();
+  load_script_run_loop_->Run();
+}
+
+// Test that when signals are successfully fetched, OnBiddingSignalsReceived()
+// is only invoked after the fetch completes, and generating bids is delayed
+// until the OnBiddingSignalsReceivedCallback is invoked.
+TEST_F(BidderWorkletTest,
+       GenerateBidOnBiddingSignalsReceivedNoPriorityVectorRequested) {
+  interest_group_trusted_bidding_signals_url_ = GURL("https://signals.test/");
+  interest_group_trusted_bidding_signals_keys_ = {{"key1"}};
+  const GURL kFullSignalsUrl(
+      "https://signals.test/"
+      "?hostname=top.window.test&keys=key1&interestGroupNames=Fred");
+
+  const char kJson[] = R"({"keys": {"key1": 1}})";
+
+  auto bidder_worklet = CreateWorklet();
+  AddJavascriptResponse(
+      &url_loader_factory_, interest_group_bidding_url_,
+      CreateGenerateBidScript(CreateBasicGenerateBidScript()));
+
+  base::RunLoop on_bidding_signals_received_run_loop;
+  base::OnceClosure on_bidding_signals_received_continue_callback;
+  auto on_bidding_signals_received_callback = base::BindLambdaForTesting(
+      [&](const base::flat_map<std::string, double>& priority_vector,
+          base::OnceClosure callback) {
+        EXPECT_TRUE(priority_vector.empty());
+        on_bidding_signals_received_run_loop.Quit();
+        on_bidding_signals_received_continue_callback = std::move(callback);
+      });
+  load_script_run_loop_ = std::make_unique<base::RunLoop>();
+  GenerateBid(bidder_worklet.get(),
+              GenerateBidClientWithCallbacks::Create(
+                  base::BindOnce(&BidderWorkletTest::GenerateBidCallback,
+                                 base::Unretained(this)),
+                  std::move(on_bidding_signals_received_callback)));
+
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+
+  AddBidderJsonResponse(&url_loader_factory_, kFullSignalsUrl, kJson);
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+  ASSERT_TRUE(on_bidding_signals_received_continue_callback);
+
+  std::move(on_bidding_signals_received_continue_callback).Run();
+  load_script_run_loop_->Run();
+}
+
+// Test that when signals are successfully fetched, but the response includes no
+// priority vector. OnBiddingSignalsReceived() is invoked with a empty priority
+// vector after the fetch completes, and generating bids is delayed until the
+// OnBiddingSignalsReceivedCallback is invoked.
+TEST_F(BidderWorkletTest,
+       GenerateBidOnBiddingSignalsReceivedNoPriorityVectorReceived) {
+  interest_group_trusted_bidding_signals_url_ = GURL("https://signals.test/");
+  const GURL kFullSignalsUrl(
+      "https://signals.test/?hostname=top.window.test&interestGroupNames=Fred");
+
+  const char kJson[] = "{}";
+
+  auto bidder_worklet = CreateWorklet();
+  AddJavascriptResponse(
+      &url_loader_factory_, interest_group_bidding_url_,
+      CreateGenerateBidScript(CreateBasicGenerateBidScript()));
+
+  base::RunLoop on_bidding_signals_received_run_loop;
+  base::OnceClosure on_bidding_signals_received_continue_callback;
+  auto on_bidding_signals_received_callback = base::BindLambdaForTesting(
+      [&](const base::flat_map<std::string, double>& priority_vector,
+          base::OnceClosure callback) {
+        EXPECT_TRUE(priority_vector.empty());
+        on_bidding_signals_received_run_loop.Quit();
+        on_bidding_signals_received_continue_callback = std::move(callback);
+      });
+  load_script_run_loop_ = std::make_unique<base::RunLoop>();
+  GenerateBid(bidder_worklet.get(),
+              GenerateBidClientWithCallbacks::Create(
+                  base::BindOnce(&BidderWorkletTest::GenerateBidCallback,
+                                 base::Unretained(this)),
+                  std::move(on_bidding_signals_received_callback)));
+
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+
+  AddBidderJsonResponse(&url_loader_factory_, kFullSignalsUrl, kJson);
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(on_bidding_signals_received_run_loop.AnyQuitCalled());
+  EXPECT_FALSE(load_script_run_loop_->AnyQuitCalled());
+  ASSERT_TRUE(on_bidding_signals_received_continue_callback);
+
+  std::move(on_bidding_signals_received_continue_callback).Run();
+  load_script_run_loop_->Run();
+}
+
+// Test that cancelling a GenerateBid() call by deleting the GenerateBidClient
+// aborts a pending trusted signals fetch.
+TEST_F(BidderWorkletTest, GenerateBidCancelAbortsSignalsFetch) {
+  interest_group_trusted_bidding_signals_url_ = GURL("https://signals.test/");
+  const GURL kFullSignalsUrl(
+      "https://signals.test/?hostname=top.window.test&interestGroupNames=Fred");
+
+  auto bidder_worklet = CreateWorklet();
+  // This is not strictly needed for this test, but should ensure that only the
+  // JSON fetch is pending.
+  AddJavascriptResponse(
+      &url_loader_factory_, interest_group_bidding_url_,
+      CreateGenerateBidScript(CreateBasicGenerateBidScript()));
+
+  GenerateBidClientWithCallbacks client(
+      GenerateBidClientWithCallbacks::GenerateBidNeverInvokedCallback(),
+      GenerateBidClientWithCallbacks::OnBiddingSignalsReceivedCallback());
+  mojo::AssociatedReceiver<mojom::GenerateBidClient> client_receiver(&client);
+
+  GenerateBid(bidder_worklet.get(),
+              client_receiver.BindNewEndpointAndPassRemote());
+
+  // Wait for the JSON request to be made, and validate it's URL and that the
+  // URLLoaderClient pipe is still connected.
+  task_environment_.RunUntilIdle();
+  ASSERT_EQ(1, url_loader_factory_.NumPending());
+  EXPECT_EQ(kFullSignalsUrl,
+            url_loader_factory_.GetPendingRequest(0)->request.url);
+  ASSERT_TRUE(url_loader_factory_.GetPendingRequest(0)->client.is_connected());
+
+  // Destroy the GenerateBidClient pipe. This should result in the generate bid
+  // call being aborted, and the fetch being cancelled, since only the cancelled
+  // GenerateBid() call was depending on the response.
+  client_receiver.reset();
+  task_environment_.RunUntilIdle();
+  ASSERT_FALSE(url_loader_factory_.GetPendingRequest(0)->client.is_connected());
+}
+
+// Test that cancelling a GenerateBid() call by deleting the GenerateBidClient
+// when Javascript is running doesn't result in a crash.
+TEST_F(BidderWorkletTest, GenerateBidCancelWhileRunningJavascript) {
+  auto bidder_worklet = CreateWorklet();
+
+  // Use a hanging GenerateBid() script so this it (most likely) completes only
+  // after the close pipe message has been received.
+  AddJavascriptResponse(&url_loader_factory_, interest_group_bidding_url_,
+                        CreateGenerateBidScript("while (true);"));
+  // Reduce the script timeout so the test doesn't take too long to run, while
+  // waiting for the loop in the above script to timeout.
+  per_buyer_timeout_ = base::Milliseconds(10);
+
+  base::OnceClosure on_bidding_signals_received_continue_callback;
+  auto on_bidding_signals_received_callback = base::BindLambdaForTesting(
+      [&](const base::flat_map<std::string, double>& priority_vector,
+          base::OnceClosure callback) {
+        EXPECT_TRUE(priority_vector.empty());
+        on_bidding_signals_received_continue_callback = std::move(callback);
+      });
+
+  GenerateBidClientWithCallbacks client(
+      GenerateBidClientWithCallbacks::GenerateBidNeverInvokedCallback(),
+      std::move(on_bidding_signals_received_callback));
+  mojo::AssociatedReceiver<mojom::GenerateBidClient> client_receiver(&client);
+
+  load_script_run_loop_ = std::make_unique<base::RunLoop>();
+  GenerateBid(bidder_worklet.get(),
+              client_receiver.BindNewEndpointAndPassRemote());
+
+  // Wait for for the Javascript to be fetched and OnSignalsReceived to be
+  // invoked.
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(on_bidding_signals_received_continue_callback);
+
+  // Invoking the callback passed to OnBiddingSignalsReceived() will cause a
+  // task to be posted to run the Javascript generateBid() method.
+  std::move(on_bidding_signals_received_continue_callback).Run();
+  // This deletes the BidderWorklet's GenerateBidTask for the already running
+  // Javascript. Once the Javascript completes running and posts a task back to
+  // the main thread, that task should not dereference the deleted
+  // GenerateBidTask, because it uses a weak pointer.
+  client_receiver.reset();
+
+  // Wait until the script is finished. There should be no crash.
+  task_environment_.RunUntilIdle();
+}
+
 TEST_F(BidderWorkletTest, GenerateBidDataVersion) {
   interest_group_trusted_bidding_signals_url_ = GURL("https://signals.test/");
   interest_group_trusted_bidding_signals_keys_.emplace();
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
index 82c0def..ef97e195 100644
--- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
+++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -94,11 +94,44 @@
   mojo_base.mojom.TimeDelta bid_duration;
 };
 
-// Single use client for each GenerateBid() call.
+// Single use client for each GenerateBid() call. Allows deferring generating
+// bids until after a bidder's interest groups have all received priority
+// vectors, which allows for cancelling generate bid calls from lower priority
+// bidders based on data fetched from the trusted bidding signals URL.
+//
+// Needs a full callback interface because Mojo callbacks aren't otherwise
+// cancellable, and one GenerateBid call invokes two callbacks.
 interface GenerateBidClient {
+  // Invoked once the trusted bidding signals have been successfully fetched,
+  // or have failed to be fetched. Will be called even when the trusted bidding
+  // signals url is null, to allow simpler mixing of GenerateBid() calls with
+  // and without them. This allows the caller in the browser process to abort
+  // bid generation in the case that the interest group's new priority
+  // calculated using `priority_vector` results in filtering out the bid.
+  // It's called in the case of no priority vector because even when there's
+  // no change in priority, filtering out due to priority depends on the
+  // priorities of other interest groups owned by the same bidder, so the
+  // browser process needs to know if there's no priority vector before it
+  // can apply priority-based filtering.
+  //
+  // OnGenerateBidComplete() will only be invoked after the
+  // OnBiddingSignalsReceived() callback has been invoked, except on fatal
+  // errors, like failing to fetch the Javascript needed to run a worklet. If
+  // a fatal error occurs before OnBiddingSignalsReceived() has been invoked,
+  // the pipe will be closed without invoking it.
+  //
+  // Arguments:
+  //  `priority_vector` The priorityVector for the interest group received as
+  //   part of the trusted bidding signals, or an empty list, if no signals
+  //   were received, or the signals had not priorityVector for the interest
+  //   group that is generating a bid.
+  OnBiddingSignalsReceived(map<string, double> priority_vector) => ();
+
   // Invoked once GenerateBid completes, either having successfully generated a
   // bid, or having failed to generate one for any reason.
   //
+  // Arguments:
+  //
   // `bid` If the worklet is successfully loaded and chooses to bid in the
   //  auction, contains information about the bid. Null otherwise.
   //
@@ -148,6 +181,11 @@
 // Manages the auction workflow for one loaded FLEDGE bidder worklet.
 // See https://github.com/WICG/turtledove/blob/main/FLEDGE.md
 //
+// Auctions involve running Javascript from multiple origins, so they
+// cannot be run within a single process. This API allows the browser
+// process to load Javascript FLEDGE worklets in other processes and
+// manage their lifetimes.
+//
 // The BidderWorklet is functionally stateless, so methods are idempotent
 // and can be called multiple times, in any order, for multiple auctions
 // using the same worklet. There is no need to wait for one callback to be
@@ -196,8 +234,8 @@
   // `trace_id` ID of a nestable asynchronous trace event of category `fledge`
   //  to use with tracing calls.
   //
-  // `generate_bid_client` On completion, its OnGenerateBidComplete()
-  //  method is called. Associated to retain priority ordering of calls.
+  // `generate_bid_client` Client that receives callbacks as GenerateBid()
+  //  progresses. Associated to retain priority ordering of calls.
   GenerateBid(
       BidderWorkletNonSharedParams bidder_worklet_non_shared_params,
       url.mojom.Origin interest_group_join_origin,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 81a8349..9ac72f4 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1894,6 +1894,7 @@
       "../browser/webauth/webauth_browsertest.cc",
     ]
     deps += [
+      "//components/cbor",
       "//device/base",
       "//device/fido:fido",
       "//device/fido:mocks",
@@ -2771,6 +2772,7 @@
     "//ui/gl:test_support",
     "//ui/latency:test_support",
     "//ui/shell_dialogs:shell_dialogs",
+    "//ui/webui:test_support",
   ]
 
   data_deps = [
diff --git a/content/test/attribution_simulator_impl.cc b/content/test/attribution_simulator_impl.cc
index 3ce3597..39e355f 100644
--- a/content/test/attribution_simulator_impl.cc
+++ b/content/test/attribution_simulator_impl.cc
@@ -75,7 +75,7 @@
   return absl::visit(
       base::Overloaded{
           [](const StorableSource& source) {
-            return source.common_info().impression_time();
+            return source.common_info().source_time();
           },
           [](const AttributionTriggerAndTime& trigger) { return trigger.time; },
           [](const AttributionSimulatorCookie& cookie) {
diff --git a/content/test/data/aggregation_service/databases/README.md b/content/test/data/aggregation_service/databases/README.md
new file mode 100644
index 0000000..5e42c3b
--- /dev/null
+++ b/content/test/data/aggregation_service/databases/README.md
@@ -0,0 +1,8 @@
+# Aggregation Service Sql Database Files
+
+This directory contains sql database schemas for all previous versions of
+databases used by the
+[Aggregation Service](../../../../content/browser/aggregation_service).
+
+The highest version sql file should always reflect the current database
+schema.
diff --git a/content/test/data/aggregation_service/databases/version_1.sql b/content/test/data/aggregation_service/databases/version_1.sql
new file mode 100644
index 0000000..5b3f0e6
--- /dev/null
+++ b/content/test/data/aggregation_service/databases/version_1.sql
@@ -0,0 +1,24 @@
+PRAGMA foreign_keys=OFF;
+
+BEGIN TRANSACTION;
+
+-- For the schemas to be identical, extra whitespace is needed to match the code
+CREATE TABLE urls(    url_id INTEGER PRIMARY KEY NOT NULL,    url TEXT NOT NULL,    fetch_time INTEGER NOT NULL,    expiry_time INTEGER NOT NULL);
+
+CREATE UNIQUE INDEX urls_by_url_idx     ON urls(url);
+CREATE INDEX fetch_time_idx ON urls(fetch_time);
+CREATE INDEX expiry_time_idx ON urls(expiry_time);
+
+CREATE TABLE keys(    url_id INTEGER NOT NULL,    key_id TEXT NOT NULL,    key BLOB NOT NULL,    PRIMARY KEY(url_id, key_id)) WITHOUT ROWID;
+
+CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
+
+INSERT INTO meta VALUES('mmap_status','-1');
+INSERT INTO meta VALUES('version','1');
+INSERT INTO meta VALUES('last_compatible_version','1');
+
+INSERT INTO urls(url, fetch_time, expiry_time) VALUES ('https://url.example/path',13306020080123456,13306624880123456);
+
+INSERT INTO keys(url_id, key_id, key) VALUES (1,'example-key-id',x'1632cfa71abbbc7f8784371967830757005b55c4400160618a07f28f0086bd05');
+
+COMMIT;
diff --git a/content/test/data/aggregation_service/databases/version_2.sql b/content/test/data/aggregation_service/databases/version_2.sql
new file mode 100644
index 0000000..2ade704
--- /dev/null
+++ b/content/test/data/aggregation_service/databases/version_2.sql
@@ -0,0 +1,31 @@
+PRAGMA foreign_keys=OFF;
+
+BEGIN TRANSACTION;
+
+-- For the schemas to be identical, extra whitespace is needed to match the code
+CREATE TABLE urls(    url_id INTEGER PRIMARY KEY NOT NULL,    url TEXT NOT NULL,    fetch_time INTEGER NOT NULL,    expiry_time INTEGER NOT NULL);
+
+CREATE UNIQUE INDEX urls_by_url_idx     ON urls(url);
+CREATE INDEX fetch_time_idx ON urls(fetch_time);
+CREATE INDEX expiry_time_idx ON urls(expiry_time);
+
+CREATE TABLE keys(    url_id INTEGER NOT NULL,    key_id TEXT NOT NULL,    key BLOB NOT NULL,    PRIMARY KEY(url_id, key_id)) WITHOUT ROWID;
+
+CREATE TABLE report_requests(request_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,report_time INTEGER NOT NULL,creation_time INTEGER NOT NULL,reporting_origin TEXT NOT NULL,request_proto BLOB NOT NULL);
+
+CREATE INDEX report_time_idx ON report_requests(report_time);
+CREATE INDEX creation_time_idx ON report_requests(creation_time);
+
+CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
+
+INSERT INTO meta VALUES('mmap_status','-1');
+INSERT INTO meta VALUES('version','2');
+INSERT INTO meta VALUES('last_compatible_version','2');
+
+INSERT INTO urls(url, fetch_time, expiry_time) VALUES ('https://url.example/path',13306020080123456,13306624880123456);
+
+INSERT INTO keys(url_id, key_id, key) VALUES (1,'example-key-id',x'1632cfa71abbbc7f8784371967830757005b55c4400160618a07f28f0086bd05');
+
+INSERT INTO report_requests(report_time,creation_time,reporting_origin,request_proto) VALUES(13306023680123456,13306020080123456,'https://reporting.example',x'1234');
+
+COMMIT;
diff --git a/content/test/data/aggregation_service/databases/version_3.sql b/content/test/data/aggregation_service/databases/version_3.sql
new file mode 100644
index 0000000..792571fd
--- /dev/null
+++ b/content/test/data/aggregation_service/databases/version_3.sql
@@ -0,0 +1,32 @@
+PRAGMA foreign_keys=OFF;
+
+BEGIN TRANSACTION;
+
+-- For the schemas to be identical, extra whitespace is needed to match the code
+CREATE TABLE urls(    url_id INTEGER PRIMARY KEY NOT NULL,    url TEXT NOT NULL,    fetch_time INTEGER NOT NULL,    expiry_time INTEGER NOT NULL);
+
+CREATE UNIQUE INDEX urls_by_url_idx     ON urls(url);
+CREATE INDEX fetch_time_idx ON urls(fetch_time);
+CREATE INDEX expiry_time_idx ON urls(expiry_time);
+
+CREATE TABLE keys(    url_id INTEGER NOT NULL,    key_id TEXT NOT NULL,    key BLOB NOT NULL,    PRIMARY KEY(url_id, key_id)) WITHOUT ROWID;
+
+CREATE TABLE report_requests(request_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,report_time INTEGER NOT NULL,creation_time INTEGER NOT NULL,reporting_origin TEXT NOT NULL,request_proto BLOB NOT NULL);
+
+CREATE INDEX report_time_idx ON report_requests(report_time);
+CREATE INDEX creation_time_idx ON report_requests(creation_time);
+CREATE INDEX reporting_origin_idx ON report_requests(reporting_origin);
+
+CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
+
+INSERT INTO meta VALUES('mmap_status','-1');
+INSERT INTO meta VALUES('version','3');
+INSERT INTO meta VALUES('last_compatible_version','3');
+
+INSERT INTO urls(url, fetch_time, expiry_time) VALUES ('https://url.example/path',13306020080123456,13306624880123456);
+
+INSERT INTO keys(url_id, key_id, key) VALUES (1,'example-key-id',x'1632cfa71abbbc7f8784371967830757005b55c4400160618a07f28f0086bd05');
+
+INSERT INTO report_requests(report_time,creation_time,reporting_origin,request_proto) VALUES(13306023680123456,13306020080123456,'https://reporting.example',x'1234');
+
+COMMIT;
diff --git a/content/test/data/first_party_sets/v0.init_too_old.sql b/content/test/data/first_party_sets/v0.init_too_old.sql
index a30bb86..57c0eb1 100644
--- a/content/test/data/first_party_sets/v0.init_too_old.sql
+++ b/content/test/data/first_party_sets/v0.init_too_old.sql
@@ -2,6 +2,13 @@
 
 BEGIN TRANSACTION;
 
+CREATE TABLE IF NOT EXISTS public_sets(
+  site TEXT NOT NULL,
+  primary_site TEXT NOT NULL,
+  site_type INTEGER NOT NULL,
+  PRIMARY KEY(site)
+) WITHOUT ROWID;
+
 CREATE TABLE IF NOT EXISTS policy_modifications (
    browser_context_id TEXT NOT NULL,
    site TEXT NOT NULL,
@@ -31,6 +38,9 @@
 INSERT INTO meta VALUES('last_compatible_version','1');
 INSERT INTO meta VALUES('run_count','1');
 
+INSERT INTO public_sets VALUES('https://aaa.test', 'https://bbb.test', 1),
+                              ('https://bbb.test', 'https://bbb.test', 0);
+
 -- b0: has sites to clear and has performed the clearing.
 -- b1: has sites to clear but has not performed the clearing.
 -- b2: has policy modifications but has no site to clear.
diff --git a/content/test/data/first_party_sets/v1.init_invalid_run_count.sql b/content/test/data/first_party_sets/v1.init_invalid_run_count.sql
index abb20c2a..04f6704 100644
--- a/content/test/data/first_party_sets/v1.init_invalid_run_count.sql
+++ b/content/test/data/first_party_sets/v1.init_invalid_run_count.sql
@@ -2,6 +2,13 @@
 
 BEGIN TRANSACTION;
 
+CREATE TABLE IF NOT EXISTS public_sets(
+  site TEXT NOT NULL,
+  primary_site TEXT NOT NULL,
+  site_type INTEGER NOT NULL,
+  PRIMARY KEY(site)
+) WITHOUT ROWID;
+
 CREATE TABLE IF NOT EXISTS policy_modifications (
    browser_context_id TEXT NOT NULL,
    site TEXT NOT NULL,
@@ -31,6 +38,9 @@
 INSERT INTO meta VALUES('last_compatible_version','1');
 INSERT INTO meta VALUES('run_count','0');
 
+INSERT INTO public_sets VALUES('https://aaa.test', 'https://bbb.test', 1),
+                              ('https://bbb.test', 'https://bbb.test', 0);
+
 -- b0: has sites to clear and has performed the clearing.
 -- b1: has sites to clear but has not performed the clearing.
 -- b2: has policy modifications but has no site to clear.
diff --git a/content/test/data/first_party_sets/v1.init_too_new.sql b/content/test/data/first_party_sets/v1.init_too_new.sql
index 6b0c76b..6e709e4 100644
--- a/content/test/data/first_party_sets/v1.init_too_new.sql
+++ b/content/test/data/first_party_sets/v1.init_too_new.sql
@@ -2,6 +2,13 @@
 
 BEGIN TRANSACTION;
 
+CREATE TABLE IF NOT EXISTS public_sets(
+  site TEXT NOT NULL,
+  primary_site TEXT NOT NULL,
+  site_type INTEGER NOT NULL,
+  PRIMARY KEY(site)
+) WITHOUT ROWID;
+
 CREATE TABLE IF NOT EXISTS policy_modifications (
    browser_context_id TEXT NOT NULL,
    site TEXT NOT NULL,
@@ -31,6 +38,9 @@
 INSERT INTO meta VALUES('last_compatible_version','2');
 INSERT INTO meta VALUES('run_count','2');
 
+INSERT INTO public_sets VALUES('https://aaa.test', 'https://bbb.test', 1),
+                              ('https://bbb.test', 'https://bbb.test', 0);
+
 -- b0: has sites to clear and has performed the clearing.
 -- b1: has sites to clear but has not performed the clearing.
 -- b2: has policy modifications but has no site to clear.
diff --git a/content/test/data/first_party_sets/v1.sql b/content/test/data/first_party_sets/v1.sql
index 4ddc3041..c3fc4c4f 100644
--- a/content/test/data/first_party_sets/v1.sql
+++ b/content/test/data/first_party_sets/v1.sql
@@ -2,6 +2,13 @@
 
 BEGIN TRANSACTION;
 
+CREATE TABLE IF NOT EXISTS public_sets(
+  site TEXT NOT NULL,
+  primary_site TEXT NOT NULL,
+  site_type INTEGER NOT NULL,
+  PRIMARY KEY(site)
+) WITHOUT ROWID;
+
 CREATE TABLE IF NOT EXISTS policy_modifications (
    browser_context_id TEXT NOT NULL,
    site TEXT NOT NULL,
@@ -31,6 +38,9 @@
 INSERT INTO meta VALUES('last_compatible_version','1');
 INSERT INTO meta VALUES('run_count','1');
 
+INSERT INTO public_sets VALUES('https://aaa.test', 'https://bbb.test', 1),
+                              ('https://bbb.test', 'https://bbb.test', 0);
+
 -- b0: has sites to clear and has performed the clearing.
 -- b1: has sites to clear but has not performed the clearing.
 -- b2: has policy modifications but has no site to clear.
diff --git a/content/test/fake_network.cc b/content/test/fake_network.cc
index 6e4b769..513c869 100644
--- a/content/test/fake_network.cc
+++ b/content/test/fake_network.cc
@@ -112,7 +112,8 @@
            mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle));
   producer_handle->WriteData(response_info.body.data(), &bytes_written,
                              MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
-  client->OnReceiveResponse(std::move(response), std::move(consumer_handle));
+  client->OnReceiveResponse(std::move(response), std::move(consumer_handle),
+                            absl::nullopt);
 
   network::URLLoaderCompletionStatus status;
   status.error_code = response_info.error_code;
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index fcbf451f..578add75 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -192,9 +192,11 @@
 crbug.com/1307787 [ mac ] Pixel_VulkanSwiftShader_WebGPU* [ Skip ]
 crbug.com/1307787 [ win ] Pixel_VulkanSwiftShader_WebGPU* [ Skip ]
 
-# Test is too slow for old phones.
+# Test is too slow for old phones and laptops, and in Debug mode.
 crbug.com/1356246 [ android android-nexus-5 ] Pixel_SVGHuge [ Skip ]
 crbug.com/1356246 [ android android-nexus-5x ] Pixel_SVGHuge [ Skip ]
+crbug.com/1356246 [ mac amd debug ] Pixel_SVGHuge [ Skip ]
+crbug.com/1356246 [ mac nvidia debug ] Pixel_SVGHuge [ Skip ]
 
 ###############################
 # Temporary Skip Expectations #
diff --git a/content/test/ppapi_unittest.cc b/content/test/ppapi_unittest.cc
index 071d5a1..c12c257a 100644
--- a/content/test/ppapi_unittest.cc
+++ b/content/test/ppapi_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include "content/public/common/content_plugin_info.h"
 #include "content/public/renderer/ppapi_gfx_conversion.h"
 #include "content/renderer/pepper/host_globals.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
@@ -82,7 +83,7 @@
   module_ = new PluginModule("Mock plugin", "1.0", base::FilePath(),
                              perms);
   ppapi::PpapiGlobals::Get()->ResetMainThreadMessageLoopForTesting();
-  PepperPluginInfo::EntryPoints entry_points;
+  ContentPluginInfo::EntryPoints entry_points;
   entry_points.get_interface = &MockGetInterface;
   entry_points.initialize_module = &MockInitializeModule;
   ASSERT_TRUE(module_->InitAsInternalPlugin(entry_points));
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc
index 7057af3e..b2cfaa2 100644
--- a/content/test/test_navigation_url_loader.cc
+++ b/content/test/test_navigation_url_loader.cc
@@ -88,7 +88,8 @@
 
 void TestNavigationURLLoader::CallOnResponseStarted(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle response_body) {
+    mojo::ScopedDataPipeConsumerHandle response_body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (!response_head->parsed_headers)
     response_head->parsed_headers = network::mojom::ParsedHeaders::New();
   // Create a bidirectionnal communication pipe between a URLLoader and a
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h
index 33d26e1..45a0b32 100644
--- a/content/test/test_navigation_url_loader.h
+++ b/content/test/test_navigation_url_loader.h
@@ -52,8 +52,10 @@
   void CallOnRequestRedirected(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head);
-  void CallOnResponseStarted(network::mojom::URLResponseHeadPtr response_head,
-                             mojo::ScopedDataPipeConsumerHandle response_body);
+  void CallOnResponseStarted(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle response_body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata);
 
   int redirect_count() { return redirect_count_; }
 
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 5a4a3a4fc4..cf18dcfa 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -508,7 +508,7 @@
   // TODO(carlosk): Ideally, it should be possible someday to
   // fully commit the navigation at this call to CallOnResponseStarted.
   url_loader->CallOnResponseStarted(std::move(response),
-                                    std::move(response_body));
+                                    std::move(response_body), absl::nullopt);
 }
 
 void TestRenderFrameHost::SimulateCommitProcessed(
@@ -624,13 +624,25 @@
   params->should_update_history = true;
   params->did_create_new_entry = did_create_new_entry;
   // See CalculateShouldReplaceCurrentEntry() in RenderFrameHostImpl on why we
-  // calculate "should_replace_current_entry" in this way.
+  // calculate "should_replace_current_entry" in this way. It's also important
+  // to note that CalculateShouldReplaceCurrentEntry relies on params set
+  // elsewhere, however.  ShouldMaintainTrivialSessionHistory reflects how the
+  // renderer would set the should_replace_current_entry param. Specifically,
+  // some features (eg fenced frames or prerendering) only maintain a single
+  // history entry and we want to ensure that should_replace_current_entry is
+  // true in these cases.
   params->should_replace_current_entry = false;
-  if (is_same_document) {
+  if (frame_tree_node()
+          ->navigator()
+          .controller()
+          .ShouldMaintainTrivialSessionHistory(frame_tree_node())) {
+    params->should_replace_current_entry = true;
+  } else if (is_same_document) {
     params->should_replace_current_entry |= (GetLastCommittedURL() == url);
   } else {
     params->should_replace_current_entry |=
-        (!is_main_frame() && frame_tree_node()->is_on_initial_empty_document());
+        (!IsOutermostMainFrame() &&
+         frame_tree_node()->is_on_initial_empty_document());
   }
   params->contents_mime_type = "text/html";
   params->method = "GET";
diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn
index e6d0592..711f30c1 100644
--- a/content/utility/BUILD.gn
+++ b/content/utility/BUILD.gn
@@ -114,7 +114,10 @@
   }
 
   if (is_chromeos_ash && enable_cros_libassistant) {
-    deps += [ "//chromeos/ash/services/libassistant:sandbox_hook" ]
+    deps += [
+      "//chromeos/ash/services/libassistant:sandbox_hook",
+      "//chromeos/assistant/internal:libassistant",
+    ]
   }
 
   # PAC execution is done in process on Android.
diff --git a/device/BUILD.gn b/device/BUILD.gn
index c3c4b338d..b298f641 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -278,6 +278,7 @@
       "bluetooth/floss/bluetooth_socket_floss_unittest.cc",
       "bluetooth/floss/exported_callback_manager_unittest.cc",
       "bluetooth/floss/floss_adapter_client_unittest.cc",
+      "bluetooth/floss/floss_gatt_client_unittest.cc",
       "bluetooth/floss/floss_manager_client_unittest.cc",
       "bluetooth/floss/floss_socket_manager_unittest.cc",
       "bluetooth/test/bluetooth_test_bluez.cc",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 683ef73..51f4135 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -436,6 +436,8 @@
         "floss/bluetooth_adapter_floss.h",
         "floss/bluetooth_device_floss.cc",
         "floss/bluetooth_device_floss.h",
+        "floss/bluetooth_gatt_connection_floss.cc",
+        "floss/bluetooth_gatt_connection_floss.h",
         "floss/bluetooth_pairing_floss.cc",
         "floss/bluetooth_pairing_floss.h",
         "floss/bluetooth_socket_floss.cc",
@@ -449,6 +451,8 @@
         "floss/floss_dbus_manager.h",
         "floss/floss_features.cc",
         "floss/floss_features.h",
+        "floss/floss_gatt_client.cc",
+        "floss/floss_gatt_client.h",
         "floss/floss_manager_client.cc",
         "floss/floss_manager_client.h",
         "floss/floss_socket_manager.cc",
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc
index 699bbb2..407e552 100644
--- a/device/bluetooth/dbus/bluez_dbus_manager.cc
+++ b/device/bluetooth/dbus/bluez_dbus_manager.cc
@@ -239,7 +239,7 @@
   DVLOG(1) << "Floss manager present. Making sure Floss is enabled/disabled.";
   floss_manager_client_ = floss::FlossManagerClient::Create();
   floss_manager_client_->Init(GetSystemBus(), floss::kManagerInterface,
-                              std::string());
+                              /*adapter_index=*/0);
 }
 
 void BluezDBusManager::OnFlossObjectManagerNotSupported(
diff --git a/device/bluetooth/floss/bluetooth_gatt_connection_floss.cc b/device/bluetooth/floss/bluetooth_gatt_connection_floss.cc
new file mode 100644
index 0000000..164152a
--- /dev/null
+++ b/device/bluetooth/floss/bluetooth_gatt_connection_floss.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 "device/bluetooth/floss/bluetooth_gatt_connection_floss.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "device/bluetooth/bluetooth_adapter.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/floss/floss_dbus_manager.h"
+
+namespace floss {
+
+BluetoothGattConnectionFloss::BluetoothGattConnectionFloss(
+    scoped_refptr<device::BluetoothAdapter> adapter,
+    const FlossDeviceId& device_id)
+    : BluetoothGattConnection(adapter.get(), device_id.address) {
+  DCHECK(adapter_.get());
+  DCHECK(!device_id.address.empty());
+
+  id_ = device_id;
+  connected_ = true;
+  floss::FlossDBusManager::Get()->GetAdapterClient()->AddObserver(this);
+}
+
+BluetoothGattConnectionFloss::~BluetoothGattConnectionFloss() {
+  floss::FlossDBusManager::Get()->GetAdapterClient()->RemoveObserver(this);
+  Disconnect();
+}
+
+bool BluetoothGattConnectionFloss::IsConnected() {
+  return connected_;
+}
+
+void BluetoothGattConnectionFloss::Disconnect() {
+  if (!connected_) {
+    DVLOG(1) << "Connection already inactive";
+    return;
+  }
+
+  connected_ = false;
+  BluetoothGattConnection::Disconnect();
+}
+
+void BluetoothGattConnectionFloss::AdapterDeviceDisconnected(
+    const FlossDeviceId& device) {
+  if (device.address != id_.address)
+    return;
+
+  connected_ = false;
+}
+
+}  // namespace floss
diff --git a/device/bluetooth/floss/bluetooth_gatt_connection_floss.h b/device/bluetooth/floss/bluetooth_gatt_connection_floss.h
new file mode 100644
index 0000000..5622e627
--- /dev/null
+++ b/device/bluetooth/floss/bluetooth_gatt_connection_floss.h
@@ -0,0 +1,53 @@
+// 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 DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_GATT_CONNECTION_FLOSS_H_
+#define DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_GATT_CONNECTION_FLOSS_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "device/bluetooth/bluetooth_gatt_connection.h"
+#include "device/bluetooth/floss/floss_adapter_client.h"
+#include "device/bluetooth/floss/floss_dbus_client.h"
+
+namespace device {
+class BluetoothAdapter;
+}  // namespace device
+
+namespace floss {
+
+// BluetoothGattConnectionFloss is the Floss implementation tracking a Gatt
+// connection. It observes the adapter client directly to keep track of
+// connection status.
+class BluetoothGattConnectionFloss
+    : public device::BluetoothGattConnection,
+      public floss::FlossAdapterClient::Observer {
+ public:
+  explicit BluetoothGattConnectionFloss(
+      scoped_refptr<device::BluetoothAdapter> adapter,
+      const FlossDeviceId& device_id);
+
+  BluetoothGattConnectionFloss(const BluetoothGattConnectionFloss&) = delete;
+  BluetoothGattConnectionFloss& operator=(const BluetoothGattConnectionFloss&) =
+      delete;
+
+  ~BluetoothGattConnectionFloss() override;
+
+  // BluetoothGattConnection overrides:
+  bool IsConnected() override;
+  void Disconnect() override;
+
+ private:
+  // floss::FlossAdapterClient::Observer overrides.
+  void AdapterDeviceDisconnected(const FlossDeviceId& device) override;
+
+  /// Cached identity of this connection.
+  FlossDeviceId id_;
+
+  /// Is this gatt connection active?
+  bool connected_;
+};
+}  // namespace floss
+
+#endif  // DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_GATT_CONNECTION_FLOSS_H_
diff --git a/device/bluetooth/floss/fake_floss_adapter_client.cc b/device/bluetooth/floss/fake_floss_adapter_client.cc
index 96984fa5..6aad42f 100644
--- a/device/bluetooth/floss/fake_floss_adapter_client.cc
+++ b/device/bluetooth/floss/fake_floss_adapter_client.cc
@@ -34,7 +34,7 @@
 
 void FakeFlossAdapterClient::Init(dbus::Bus* bus,
                                   const std::string& service_name,
-                                  const std::string& adapter_path) {}
+                                  const int adapter_index) {}
 
 void FakeFlossAdapterClient::StartDiscovery(ResponseCallback<Void> callback) {
   // Fail fast if we're meant to fail discovery
diff --git a/device/bluetooth/floss/fake_floss_adapter_client.h b/device/bluetooth/floss/fake_floss_adapter_client.h
index 9256af8..f44c0e4 100644
--- a/device/bluetooth/floss/fake_floss_adapter_client.h
+++ b/device/bluetooth/floss/fake_floss_adapter_client.h
@@ -33,7 +33,7 @@
   // Fake overrides.
   void Init(dbus::Bus* bus,
             const std::string& service_name,
-            const std::string& adapter_path) override;
+            const int adapter_index) override;
   void StartDiscovery(ResponseCallback<Void> callback) override;
   void CancelDiscovery(ResponseCallback<Void> callback) override;
   void CreateBond(ResponseCallback<bool> callback,
diff --git a/device/bluetooth/floss/fake_floss_socket_manager.cc b/device/bluetooth/floss/fake_floss_socket_manager.cc
index 332e741..0210d02 100644
--- a/device/bluetooth/floss/fake_floss_socket_manager.cc
+++ b/device/bluetooth/floss/fake_floss_socket_manager.cc
@@ -92,7 +92,7 @@
 
 void FakeFlossSocketManager::Init(dbus::Bus* bus,
                                   const std::string& service_name,
-                                  const std::string& adapter_path) {}
+                                  const int adapter_index) {}
 
 void FakeFlossSocketManager::ListenUsingL2cap(
     const Security security_level,
diff --git a/device/bluetooth/floss/fake_floss_socket_manager.h b/device/bluetooth/floss/fake_floss_socket_manager.h
index a6b041a..4151f00 100644
--- a/device/bluetooth/floss/fake_floss_socket_manager.h
+++ b/device/bluetooth/floss/fake_floss_socket_manager.h
@@ -28,7 +28,7 @@
   // Fake overrides.
   void Init(dbus::Bus* bus,
             const std::string& service_name,
-            const std::string& adapter_path) override;
+            const int adapter_index) override;
   void ListenUsingL2cap(const Security security_level,
                         ResponseCallback<BtifStatus> callback,
                         ConnectionStateChanged ready_cb,
diff --git a/device/bluetooth/floss/floss_adapter_client.cc b/device/bluetooth/floss/floss_adapter_client.cc
index 823609c..42c058a 100644
--- a/device/bluetooth/floss/floss_adapter_client.cc
+++ b/device/bluetooth/floss/floss_adapter_client.cc
@@ -157,9 +157,9 @@
 
 void FlossAdapterClient::Init(dbus::Bus* bus,
                               const std::string& service_name,
-                              const std::string& adapter_path) {
+                              const int adapter_index) {
   bus_ = bus;
-  adapter_path_ = dbus::ObjectPath(adapter_path);
+  adapter_path_ = GenerateAdapterPath(adapter_index);
   service_name_ = service_name;
 
   dbus::ObjectProxy* object_proxy =
diff --git a/device/bluetooth/floss/floss_adapter_client.h b/device/bluetooth/floss/floss_adapter_client.h
index 0071400..fcaa173 100644
--- a/device/bluetooth/floss/floss_adapter_client.h
+++ b/device/bluetooth/floss/floss_adapter_client.h
@@ -32,12 +32,6 @@
 // powered on (presence and power management is done by |FlossManagerClient|).
 class DEVICE_BLUETOOTH_EXPORT FlossAdapterClient : public FlossDBusClient {
  public:
-  enum class BluetoothTransport {
-    kAuto = 0,
-    kBrEdr = 1,
-    kLe = 2,
-  };
-
   enum class BluetoothDeviceType {
     kUnknown = 0,
     kBredr = 1,
@@ -249,7 +243,7 @@
   // Initialize the adapter client.
   void Init(dbus::Bus* bus,
             const std::string& service_name,
-            const std::string& adapter_path) override;
+            const int adapter_index) override;
 
  protected:
   friend class FlossAdapterClientTest;
diff --git a/device/bluetooth/floss/floss_adapter_client_unittest.cc b/device/bluetooth/floss/floss_adapter_client_unittest.cc
index d887245..d143df4 100644
--- a/device/bluetooth/floss/floss_adapter_client_unittest.cc
+++ b/device/bluetooth/floss/floss_adapter_client_unittest.cc
@@ -133,7 +133,7 @@
   FlossAdapterClientTest() = default;
 
   void SetUpMocks() {
-    adapter_path_ = FlossManagerClient::GenerateAdapterPath(adapter_index_);
+    adapter_path_ = FlossDBusClient::GenerateAdapterPath(adapter_index_);
     adapter_object_proxy_ = base::MakeRefCounted<::dbus::MockObjectProxy>(
         bus_.get(), kAdapterInterface, adapter_path_);
     exported_callbacks_ = base::MakeRefCounted<::dbus::MockExportedObject>(
@@ -474,7 +474,7 @@
               DoCallMethodWithErrorResponse(
                   HasMemberOf(adapter::kRegisterCallback), _, _))
       .Times(1);
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Make sure the address is initialized correctly
   EXPECT_EQ(test_observer.address_changed_count_, 1);
@@ -490,7 +490,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesAddressChanges) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.address_changed_count_, 1);
 
   SendAddressChangeCallback(
@@ -513,7 +513,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesNameChanges) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   std::string test_name("floss_test_name");
   SendNameChangeCallback(
@@ -526,7 +526,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesDiscoverableChanges) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.discoverable_changed_count_, 1);
 
   SendDiscoverableChangeCallback(
@@ -550,7 +550,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesDiscoveryChanges) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.discovering_changed_count_, 0);
 
   SendDiscoveringChangeCallback(
@@ -580,7 +580,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesFoundDevices) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.found_device_count_, 0);
 
   FlossDeviceId device_id = {.address = "66:55:44:33:22:11", .name = "First"};
@@ -603,7 +603,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesClearedDevices) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.cleared_device_count_, 0);
 
   FlossDeviceId device_id = {.address = "66:55:44:33:22:11", .name = "First"};
@@ -626,7 +626,7 @@
 
 TEST_F(FlossAdapterClientTest, HandlesSsp) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.ssp_request_count_, 0);
 
   FlossDeviceId device_id = {.address = "11:22:33:66:55:44", .name = "Foobar"};
@@ -654,7 +654,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, CreateBond) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   FlossDeviceId bond = {.address = "00:22:44:11:33:55", .name = "James"};
   auto transport = FlossAdapterClient::BluetoothTransport::kBrEdr;
@@ -675,7 +675,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, CallAdapterMethods) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 0 parameters with no return.
   EXPECT_CALL(*adapter_object_proxy_.get(),
@@ -792,7 +792,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, GenericMethodGetConnectionState) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 1 parameter with uint32_t return.
   EXPECT_CALL(*adapter_object_proxy_.get(),
@@ -829,7 +829,7 @@
 
 TEST_F(FlossAdapterClientTest,
        GenericMethodConnectAndDisconnectAllEnabledProfiles) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 1 parameter with no return.
   EXPECT_CALL(*adapter_object_proxy_.get(),
@@ -885,7 +885,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, GenericMethodSetPairingConfirmation) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 2 parameters with no return.
   EXPECT_CALL(*adapter_object_proxy_.get(),
@@ -921,7 +921,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, GenericMethodSetPasskey) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 3 parameters with no return.
   EXPECT_CALL(
@@ -964,7 +964,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, GenericMethodGetRemoteUuids) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 1 parameter with UUID response.
   EXPECT_CALL(*adapter_object_proxy_.get(),
@@ -1007,7 +1007,7 @@
 }
 
 TEST_F(FlossAdapterClientTest, GenericMethodGetRemoteType) {
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
 
   // Method of 1 parameter with BluetoothDeviceType response.
   EXPECT_CALL(
@@ -1046,7 +1046,7 @@
 
 TEST_F(FlossAdapterClientTest, OnAdapterPropertyChanged) {
   TestAdapterObserver test_observer(client_.get());
-  client_->Init(bus_.get(), kAdapterInterface, adapter_path_.value());
+  client_->Init(bus_.get(), kAdapterInterface, adapter_index_);
   EXPECT_EQ(test_observer.found_device_count_, 0);
 
   // Method of no parameters with vector of FlossDeviceId response.
diff --git a/device/bluetooth/floss/floss_dbus_client.cc b/device/bluetooth/floss/floss_dbus_client.cc
index 064ac4f..58de46b3 100644
--- a/device/bluetooth/floss/floss_dbus_client.cc
+++ b/device/bluetooth/floss/floss_dbus_client.cc
@@ -22,6 +22,7 @@
 const char kManagerInterface[] = "org.chromium.bluetooth.Manager";
 const char kManagerObject[] = "/org/chromium/bluetooth/Manager";
 const char kAdapterObjectFormat[] = "/org/chromium/bluetooth/hci%d/adapter";
+const char kGattObjectFormat[] = "/org/chromium/bluetooth/hci%d/gatt";
 
 const char kSocketManagerInterface[] = "org.chromium.bluetooth.SocketManager";
 
@@ -109,6 +110,44 @@
 const char kOnOutgoingConnectionResult[] = "OnOutgoingConnectionResult";
 }  // namespace socket_manager
 
+namespace gatt {
+const char kRegisterClient[] = "RegisterClient";
+const char kUnregisterClient[] = "UnregisterClient";
+const char kClientConnect[] = "ClientConnect";
+const char kClientDisconnect[] = "ClientDisconnect";
+const char kRefreshDevice[] = "RefreshDevice";
+const char kDiscoverServices[] = "DiscoverServices";
+const char kDiscoverServiceByUuid[] = "DiscoverServiceByUuid";
+const char kReadCharacteristic[] = "ReadCharacteristic";
+const char kReadUsingCharacteristicUuid[] = "ReadUsingCharacteristicUuid";
+const char kWriteCharacteristic[] = "WriteCharacteristic";
+const char kReadDescriptor[] = "ReadDescriptor";
+const char kWriteDescriptor[] = "WriteDescriptor";
+const char kRegisterForNotification[] = "RegisterForNotification";
+const char kBeginReliableWrite[] = "BeginReliableWrite";
+const char kEndReliableWrite[] = "EndReliableWrite";
+const char kReadRemoteRssi[] = "ReadRemoteRssi";
+const char kConfigureMtu[] = "ConfigureMtu";
+const char kConnectionParameterUpdate[] = "ConnectionParameterUpdate";
+const char kCallbackInterface[] =
+    "org.chromium.bluetooth.BluetoothGattClientCallback";
+
+const char kOnClientRegistered[] = "OnClientRegistered";
+const char kOnClientConnectionState[] = "OnClientConnectionState";
+const char kOnPhyUpdate[] = "OnPhyUpdate";
+const char kOnPhyRead[] = "OnPhyRead";
+const char kOnSearchComplete[] = "OnSearchComplete";
+const char kOnCharacteristicRead[] = "OnCharacteristicRead";
+const char kOnCharacteristicWrite[] = "OnCharacteristicWrite";
+const char kOnExecuteWrite[] = "OnExecuteWrite";
+const char kOnDescriptorRead[] = "OnDescriptorRead";
+const char kOnNotify[] = "OnNotify";
+const char kOnReadRemoteRssi[] = "OnReadRemoteRssi";
+const char kOnConfigureMtu[] = "OnConfigureMtu";
+const char kOnConnectionUpdated[] = "OnConnectionUpdated";
+const char kOnServiceChanged[] = "OnServiceChanged";
+}  // namespace gatt
+
 namespace {
 constexpr char kDeviceIdNameKey[] = "name";
 constexpr char kDeviceIdAddressKey[] = "address";
@@ -227,6 +266,12 @@
   return info;
 }
 
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<std::vector<uint8_t>>() {
+  static DBusTypeInfo info{"ay", "std::vector<uint8_t>"};
+  return info;
+}
+
 FlossDBusClient::FlossDBusClient() = default;
 FlossDBusClient::~FlossDBusClient() = default;
 
@@ -241,6 +286,17 @@
     "org.chromium.Error.DoesNotExist";
 const char FlossDBusClient::kOptionalValueKey[] = "optional_value";
 
+// static
+dbus::ObjectPath FlossDBusClient::GenerateAdapterPath(int adapter_index) {
+  return dbus::ObjectPath(
+      base::StringPrintf(kAdapterObjectFormat, adapter_index));
+}
+
+// static
+dbus::ObjectPath FlossDBusClient::GenerateGattPath(int adapter_index) {
+  return dbus::ObjectPath(base::StringPrintf(kGattObjectFormat, adapter_index));
+}
+
 // Default error handler for dbus clients is to just print the error right now.
 // TODO(abps) - Deprecate this once error handling is implemented in the upper
 //              layers.
@@ -401,26 +457,6 @@
     absl::optional<base::ScopedFD>* fd);
 
 // static
-// Specialization for vector of anything.
-template <typename T>
-bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
-                                    std::vector<T>* value) {
-  dbus::MessageReader subreader(nullptr);
-  if (!reader->PopArray(&subreader))
-    return false;
-
-  while (subreader.HasMoreData()) {
-    T element;
-    if (!FlossDBusClient::ReadDBusParam<T>(&subreader, &element))
-      return false;
-
-    value->push_back(element);
-  }
-
-  return true;
-}
-
-// static
 template <>
 bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
                                     FlossDeviceId* device) {
@@ -499,6 +535,12 @@
 }
 
 template <>
+void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
+                                     const dbus::ObjectPath& path) {
+  writer->AppendObjectPath(path);
+}
+
+template <>
 void FlossDBusClient::WriteDBusParam(
     dbus::MessageWriter* writer,
     const FlossDBusClient::BtifStatus& status) {
diff --git a/device/bluetooth/floss/floss_dbus_client.h b/device/bluetooth/floss/floss_dbus_client.h
index 2e94a34..1c54f7fb 100644
--- a/device/bluetooth/floss/floss_dbus_client.h
+++ b/device/bluetooth/floss/floss_dbus_client.h
@@ -30,9 +30,11 @@
 extern DEVICE_BLUETOOTH_EXPORT const char kManagerInterface[];
 extern DEVICE_BLUETOOTH_EXPORT const char kManagerObject[];
 extern DEVICE_BLUETOOTH_EXPORT const char kAdapterObjectFormat[];
+extern DEVICE_BLUETOOTH_EXPORT const char kGattObjectFormat[];
 
 // Other interfaces
 extern DEVICE_BLUETOOTH_EXPORT const char kSocketManagerInterface[];
+extern DEVICE_BLUETOOTH_EXPORT const char kGattClientInterface[];
 
 namespace adapter {
 extern DEVICE_BLUETOOTH_EXPORT const char kGetAddress[];
@@ -112,6 +114,43 @@
 extern DEVICE_BLUETOOTH_EXPORT const char kOnOutgoingConnectionResult[];
 }  // namespace socket_manager
 
+namespace gatt {
+extern DEVICE_BLUETOOTH_EXPORT const char kRegisterClient[];
+extern DEVICE_BLUETOOTH_EXPORT const char kUnregisterClient[];
+extern DEVICE_BLUETOOTH_EXPORT const char kClientConnect[];
+extern DEVICE_BLUETOOTH_EXPORT const char kClientDisconnect[];
+extern DEVICE_BLUETOOTH_EXPORT const char kRefreshDevice[];
+extern DEVICE_BLUETOOTH_EXPORT const char kDiscoverServices[];
+extern DEVICE_BLUETOOTH_EXPORT const char kDiscoverServiceByUuid[];
+extern DEVICE_BLUETOOTH_EXPORT const char kReadCharacteristic[];
+extern DEVICE_BLUETOOTH_EXPORT const char kReadUsingCharacteristicUuid[];
+extern DEVICE_BLUETOOTH_EXPORT const char kWriteCharacteristic[];
+extern DEVICE_BLUETOOTH_EXPORT const char kReadDescriptor[];
+extern DEVICE_BLUETOOTH_EXPORT const char kWriteDescriptor[];
+extern DEVICE_BLUETOOTH_EXPORT const char kRegisterForNotification[];
+extern DEVICE_BLUETOOTH_EXPORT const char kBeginReliableWrite[];
+extern DEVICE_BLUETOOTH_EXPORT const char kEndReliableWrite[];
+extern DEVICE_BLUETOOTH_EXPORT const char kReadRemoteRssi[];
+extern DEVICE_BLUETOOTH_EXPORT const char kConfigureMtu[];
+extern DEVICE_BLUETOOTH_EXPORT const char kConnectionParameterUpdate[];
+extern DEVICE_BLUETOOTH_EXPORT const char kCallbackInterface[];
+
+extern DEVICE_BLUETOOTH_EXPORT const char kOnClientRegistered[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnClientConnectionState[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnPhyUpdate[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnPhyRead[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnSearchComplete[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnCharacteristicRead[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnCharacteristicWrite[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnExecuteWrite[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnDescriptorRead[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnNotify[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnReadRemoteRssi[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnConfigureMtu[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnConnectionUpdated[];
+extern DEVICE_BLUETOOTH_EXPORT const char kOnServiceChanged[];
+}  // namespace gatt
+
 // BluetoothDevice structure for DBus apis.
 struct DEVICE_BLUETOOTH_EXPORT FlossDeviceId {
   std::string address;
@@ -228,6 +267,12 @@
     kWakelockError,
   };
 
+  enum class BluetoothTransport {
+    kAuto = 0,
+    kBrEdr = 1,
+    kLe = 2,
+  };
+
   // Error: DBus error.
   static const char kErrorDBus[];
 
@@ -246,6 +291,12 @@
   // Error: does not exist.
   static const char DEVICE_BLUETOOTH_EXPORT kErrorDoesNotExist[];
 
+  // Convert adapter number to adapter object path.
+  static dbus::ObjectPath GenerateAdapterPath(int adapter_index);
+
+  // Convert adapter number to gatt object path.
+  static dbus::ObjectPath GenerateGattPath(int adapter_index);
+
   // Generalized DBus serialization (used for generalized method call
   // invocation).
   template <typename T>
@@ -330,9 +381,24 @@
     return ReadDBusParam(&variant_reader, value);
   }
 
-  // Container type needs to be explicitly listed here.
+  // Specialization for vector of anything.
   template <typename T>
-  static bool ReadDBusParam(dbus::MessageReader* reader, std::vector<T>* value);
+  static bool ReadDBusParam(dbus::MessageReader* reader,
+                            std::vector<T>* value) {
+    dbus::MessageReader subreader(nullptr);
+    if (!reader->PopArray(&subreader))
+      return false;
+
+    while (subreader.HasMoreData()) {
+      T element;
+      if (!ReadDBusParam<T>(&subreader, &element))
+        return false;
+
+      value->emplace_back(std::move(element));
+    }
+
+    return true;
+  }
 
   // Optional container type needs to be explicitly implemented here.
   template <typename T>
@@ -497,7 +563,7 @@
   // Common init signature for all clients.
   virtual void Init(dbus::Bus* bus,
                     const std::string& bluetooth_service_name,
-                    const std::string& bluetooth_adapter_path) = 0;
+                    const int adapter_index) = 0;
 
  protected:
   // Convert a dbus::ErrorResponse into a floss::Error struct.
diff --git a/device/bluetooth/floss/floss_dbus_manager.cc b/device/bluetooth/floss/floss_dbus_manager.cc
index e61a96c..49c8125 100644
--- a/device/bluetooth/floss/floss_dbus_manager.cc
+++ b/device/bluetooth/floss/floss_dbus_manager.cc
@@ -136,7 +136,7 @@
   // Initialize the manager client (which doesn't depend on any specific
   // adapter being present)
   client_bundle_->manager_client()->Init(GetSystemBus(), kManagerInterface,
-                                         std::string());
+                                         kInvalidAdapter);
 
   object_manager_support_known_ = true;
   if (object_manager_support_known_callback_) {
@@ -195,14 +195,11 @@
     return;
   }
 
-  dbus::ObjectPath adapter_path =
-      FlossManagerClient::GenerateAdapterPath(adapter);
-
   // Initialize any adapter clients.
   client_bundle_->adapter_client()->Init(GetSystemBus(), kAdapterService,
-                                         adapter_path.value());
+                                         active_adapter_);
   client_bundle_->socket_manager()->Init(GetSystemBus(), kAdapterService,
-                                         adapter_path.value());
+                                         active_adapter_);
 }
 
 void FlossDBusManagerSetter::SetFlossManagerClient(
diff --git a/device/bluetooth/floss/floss_gatt_client.cc b/device/bluetooth/floss/floss_gatt_client.cc
new file mode 100644
index 0000000..942a454
--- /dev/null
+++ b/device/bluetooth/floss/floss_gatt_client.cc
@@ -0,0 +1,462 @@
+// 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 "device/bluetooth/floss/floss_gatt_client.h"
+
+#include "base/notreached.h"
+
+namespace floss {
+
+namespace {
+// Randomly generated UUID for use in this client.
+constexpr char kDefaultGattClientUuid[] =
+    "e060b902-508c-485f-8b0e-27639c7f2d41";
+
+// Default to requesting eatt support with gatt client.
+constexpr bool kDefaultEattSupport = true;
+
+void HandleResponse(const char* method, DBusResult<Void> result) {
+  if (!result.has_value()) {
+    LOG(ERROR) << "Call failed: " << method << ": " << result.error();
+    return;
+  }
+
+  DVLOG(1) << method << " succeeded.";
+}
+}  // namespace
+
+// Template specializations for dbus parsing
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader, LePhy* phy) {
+  uint32_t value;
+  if (FlossDBusClient::ReadDBusParam(reader, &value)) {
+    *phy = static_cast<LePhy>(value);
+    return true;
+  }
+
+  return false;
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<LePhy>() {
+  static DBusTypeInfo info{"u", "LePhy"};
+  return info;
+}
+
+template <>
+void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
+                                     const LePhy& phy) {
+  uint32_t value = static_cast<uint32_t>(phy);
+  WriteDBusParam(writer, value);
+}
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
+                                    GattStatus* status) {
+  uint32_t value;
+  if (FlossDBusClient::ReadDBusParam(reader, &value)) {
+    *status = static_cast<GattStatus>(value);
+    return true;
+  }
+
+  return false;
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<GattStatus>() {
+  static DBusTypeInfo info{"u", "GattStatus"};
+  return info;
+}
+
+template <>
+void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
+                                     const AuthRequired& auth_req) {
+  uint32_t value = static_cast<uint32_t>(auth_req);
+  WriteDBusParam(writer, value);
+}
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
+                                    WriteType* write_type) {
+  uint32_t value;
+  if (FlossDBusClient::ReadDBusParam(reader, &value)) {
+    *write_type = static_cast<WriteType>(value);
+    return true;
+  }
+
+  return false;
+}
+
+template <>
+void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
+                                     const WriteType& write_type) {
+  uint32_t value = static_cast<uint32_t>(write_type);
+  WriteDBusParam(writer, value);
+}
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
+                                    GattDescriptor* descriptor) {
+  static FlossDBusClient::StructReader<GattDescriptor> struct_reader({
+      {"uuid", CreateFieldReader(&GattDescriptor::uuid)},
+      {"instance_id", CreateFieldReader(&GattDescriptor::instance_id)},
+      {"permissions", CreateFieldReader(&GattDescriptor::permissions)},
+  });
+
+  return struct_reader.ReadDBusParam(reader, descriptor);
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<GattDescriptor>() {
+  static DBusTypeInfo info{"a{sv}", "GattDescriptor"};
+  return info;
+}
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
+                                    GattCharacteristic* characteristic) {
+  static FlossDBusClient::StructReader<GattCharacteristic> struct_reader({
+      {"uuid", CreateFieldReader(&GattCharacteristic::uuid)},
+      {"instance_id", CreateFieldReader(&GattCharacteristic::instance_id)},
+      {"properties", CreateFieldReader(&GattCharacteristic::properties)},
+      {"key_size", CreateFieldReader(&GattCharacteristic::key_size)},
+      {"write_type", CreateFieldReader(&GattCharacteristic::write_type)},
+      {"descriptors", CreateFieldReader(&GattCharacteristic::descriptors)},
+  });
+
+  return struct_reader.ReadDBusParam(reader, characteristic);
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<GattCharacteristic>() {
+  static DBusTypeInfo info{"a{sv}", "GattCharacteristic"};
+  return info;
+}
+
+template <>
+bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
+                                    GattService* service) {
+  static FlossDBusClient::StructReader<GattService> struct_reader({
+      {"uuid", CreateFieldReader(&GattService::uuid)},
+      {"instance_id", CreateFieldReader(&GattService::instance_id)},
+      {"service_type", CreateFieldReader(&GattService::service_type)},
+      {"characteristics", CreateFieldReader(&GattService::characteristics)},
+      {"included_services", CreateFieldReader(&GattService::included_services)},
+  });
+
+  return struct_reader.ReadDBusParam(reader, service);
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<GattService>() {
+  static DBusTypeInfo info{"a{sv}", "GattService"};
+  return info;
+}
+
+template <>
+const DBusTypeInfo& GetDBusTypeInfo<std::vector<GattService>>() {
+  static DBusTypeInfo info{"av", "std::vector<GattService>"};
+  return info;
+}
+
+GattDescriptor::GattDescriptor() = default;
+GattDescriptor::~GattDescriptor() = default;
+
+GattCharacteristic::GattCharacteristic() = default;
+GattCharacteristic::GattCharacteristic(const GattCharacteristic&) = default;
+GattCharacteristic::~GattCharacteristic() = default;
+
+GattService::GattService() = default;
+GattService::GattService(const GattService&) = default;
+GattService::~GattService() = default;
+
+const char FlossGattClient::kExportedCallbacksPath[] =
+    "/org/chromium/bluetooth/gattclient";
+
+// static
+std::unique_ptr<FlossGattClient> FlossGattClient::Create() {
+  return std::make_unique<FlossGattClient>();
+}
+
+FlossGattClient::FlossGattClient() = default;
+FlossGattClient::~FlossGattClient() {
+  if (bus_) {
+    exported_callback_manager_.UnexportCallback(
+        dbus::ObjectPath(kExportedCallbacksPath));
+  }
+}
+
+void FlossGattClient::Connect(ResponseCallback<Void> callback,
+                              const std::string& remote_device,
+                              const BluetoothTransport& transport) {
+  // Gatt client connections occur immediately instead of when next seen.
+  const bool is_direct = true;
+
+  // Opportunistic connections.
+  const bool opportunistic = true;
+
+  // We want a phy to be chosen automatically.
+  const LePhy phy = LePhy::kInvalid;
+
+  CallGattMethod<Void>(std::move(callback), gatt::kClientConnect, client_id_,
+                       remote_device, is_direct, transport, opportunistic, phy);
+}
+
+void FlossGattClient::Disconnect(ResponseCallback<Void> callback,
+                                 const std::string& remote_device) {
+  CallGattMethod<Void>(std::move(callback), gatt::kClientDisconnect, client_id_,
+                       remote_device);
+}
+
+void FlossGattClient::Refresh(ResponseCallback<Void> callback,
+                              const std::string& remote_device) {
+  CallGattMethod<Void>(std::move(callback), gatt::kRefreshDevice, client_id_,
+                       remote_device);
+}
+
+void FlossGattClient::DiscoverAllServices(ResponseCallback<Void> callback,
+                                          const std::string& remote_device) {
+  CallGattMethod<Void>(std::move(callback), gatt::kDiscoverServices, client_id_,
+                       remote_device);
+}
+
+void FlossGattClient::DiscoverServiceByUuid(ResponseCallback<Void> callback,
+                                            const std::string& remote_device,
+                                            const device::BluetoothUUID& uuid) {
+  CallGattMethod<Void>(std::move(callback), gatt::kDiscoverServiceByUuid,
+                       client_id_, remote_device, uuid);
+}
+
+void FlossGattClient::ReadCharacteristic(ResponseCallback<Void> callback,
+                                         const std::string& remote_device,
+                                         const int32_t handle,
+                                         const AuthRequired auth_required) {
+  CallGattMethod<Void>(std::move(callback), gatt::kReadCharacteristic,
+                       client_id_, remote_device, handle, auth_required);
+}
+
+void FlossGattClient::ReadUsingCharacteristicUuid(
+    ResponseCallback<Void> callback,
+    const std::string& remote_device,
+    const device::BluetoothUUID& uuid,
+    const int32_t start_handle,
+    const int32_t end_handle,
+    const AuthRequired auth_required) {
+  CallGattMethod<Void>(std::move(callback), gatt::kReadUsingCharacteristicUuid,
+                       client_id_, remote_device, uuid, start_handle,
+                       end_handle, auth_required);
+}
+
+void FlossGattClient::WriteCharacteristic(ResponseCallback<Void> callback,
+                                          const std::string& remote_device,
+                                          const int32_t handle,
+                                          const WriteType write_type,
+                                          const AuthRequired auth_required,
+                                          const std::vector<uint8_t> data) {
+  CallGattMethod<Void>(std::move(callback), gatt::kWriteCharacteristic,
+                       client_id_, remote_device, handle, write_type,
+                       auth_required, data);
+}
+
+void FlossGattClient::ReadDescriptor(ResponseCallback<Void> callback,
+                                     const std::string& remote_device,
+                                     const int32_t handle,
+                                     const AuthRequired auth_required) {
+  CallGattMethod<Void>(std::move(callback), gatt::kReadDescriptor, client_id_,
+                       remote_device, handle, auth_required);
+}
+
+void FlossGattClient::WriteDescriptor(ResponseCallback<Void> callback,
+                                      const std::string& remote_device,
+                                      const int32_t handle,
+                                      const AuthRequired auth_required,
+                                      const std::vector<uint8_t> data) {
+  CallGattMethod<Void>(std::move(callback), gatt::kWriteDescriptor, client_id_,
+                       remote_device, handle, auth_required, data);
+}
+
+void FlossGattClient::RegisterForNotification(ResponseCallback<Void> callback,
+                                              const std::string& remote_device,
+                                              const int32_t handle) {
+  const bool enable_notification = true;
+  CallGattMethod<Void>(std::move(callback), gatt::kRegisterForNotification,
+                       client_id_, remote_device, handle, enable_notification);
+}
+
+void FlossGattClient::UnregisterNotification(ResponseCallback<Void> callback,
+                                             const std::string& remote_device,
+                                             const int32_t handle) {
+  const bool enable_notification = false;
+  CallGattMethod<Void>(std::move(callback), gatt::kRegisterForNotification,
+                       client_id_, remote_device, handle, enable_notification);
+}
+
+void FlossGattClient::ReadRemoteRssi(ResponseCallback<Void> callback,
+                                     const std::string& remote_device) {
+  CallGattMethod<Void>(std::move(callback), gatt::kReadRemoteRssi, client_id_,
+                       remote_device);
+}
+
+void FlossGattClient::ConfigureMTU(ResponseCallback<Void> callback,
+                                   const std::string& remote_device,
+                                   const int32_t mtu) {
+  CallGattMethod<Void>(std::move(callback), gatt::kConfigureMtu, client_id_,
+                       remote_device, mtu);
+}
+
+void FlossGattClient::Init(dbus::Bus* bus,
+                           const std::string& service_name,
+                           const int adapter_index) {
+  bus_ = bus;
+  service_name_ = service_name;
+  gatt_adapter_path_ = GenerateGattPath(adapter_index);
+
+  dbus::ObjectProxy* object_proxy =
+      bus_->GetObjectProxy(service_name_, gatt_adapter_path_);
+  if (!object_proxy) {
+    LOG(ERROR) << "FlossGattClient couldn't init. Object proxy was null.";
+    return;
+  }
+
+  exported_callback_manager_.Init(bus_.get());
+  exported_callback_manager_.AddMethod(
+      gatt::kOnClientRegistered, &FlossGattClientCallbacks::OnClientRegistered);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnClientConnectionState,
+      &FlossGattClientCallbacks::OnClientConnectionState);
+  exported_callback_manager_.AddMethod(gatt::kOnPhyUpdate,
+                                       &FlossGattClientCallbacks::OnPhyUpdate);
+  exported_callback_manager_.AddMethod(gatt::kOnPhyRead,
+                                       &FlossGattClientCallbacks::OnPhyRead);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnSearchComplete, &FlossGattClientCallbacks::OnSearchComplete);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnCharacteristicRead,
+      &FlossGattClientCallbacks::OnCharacteristicRead);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnCharacteristicWrite,
+      &FlossGattClientCallbacks::OnCharacteristicWrite);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnExecuteWrite, &FlossGattClientCallbacks::OnExecuteWrite);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnDescriptorRead, &FlossGattClientCallbacks::OnDescriptorRead);
+  exported_callback_manager_.AddMethod(gatt::kOnNotify,
+                                       &FlossGattClientCallbacks::OnNotify);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnReadRemoteRssi, &FlossGattClientCallbacks::OnReadRemoteRssi);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnConfigureMtu, &FlossGattClientCallbacks::OnConfigureMtu);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnConnectionUpdated,
+      &FlossGattClientCallbacks::OnConnectionUpdated);
+  exported_callback_manager_.AddMethod(
+      gatt::kOnServiceChanged, &FlossGattClientCallbacks::OnServiceChanged);
+
+  if (!exported_callback_manager_.ExportCallback(
+          dbus::ObjectPath(kExportedCallbacksPath),
+          weak_ptr_factory_.GetWeakPtr())) {
+    LOG(ERROR) << "Unable to successfully export FlossGattClientCallbacks.";
+    return;
+  }
+
+  // Finish registering client. We will get client id via |OnClientRegistered|.
+  CallGattMethod<Void>(
+      base::BindOnce(&HandleResponse, gatt::kRegisterClient),
+      gatt::kRegisterClient, device::BluetoothUUID(kDefaultGattClientUuid),
+      dbus::ObjectPath(kExportedCallbacksPath), kDefaultEattSupport);
+}
+
+void FlossGattClient::OnClientRegistered(int32_t status, int32_t client_id) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnClientConnectionState(int32_t status,
+                                              int32_t client_id,
+                                              bool connected,
+                                              std::string address) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnPhyUpdate(std::string address,
+                                  LePhy tx,
+                                  LePhy rx,
+                                  GattStatus status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnPhyRead(std::string address,
+                                LePhy tx,
+                                LePhy rx,
+                                GattStatus status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnSearchComplete(std::string address,
+                                       std::vector<GattService> services,
+                                       int32_t status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnCharacteristicRead(std::string address,
+                                           int32_t status,
+                                           int32_t handle,
+                                           std::vector<uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnCharacteristicWrite(std::string address,
+                                            int32_t status,
+                                            int32_t handle) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnExecuteWrite(std::string address, int32_t status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnDescriptorRead(std::string address,
+                                       int32_t status,
+                                       int32_t handle,
+                                       std::vector<uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnDescriptorWrite(std::string address,
+                                        int32_t status,
+                                        int32_t handle) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnNotify(std::string address,
+                               int32_t handle,
+                               std::vector<uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnReadRemoteRssi(std::string address,
+                                       int32_t rssi,
+                                       int32_t status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnConfigureMtu(std::string address,
+                                     int32_t mtu,
+                                     int32_t status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnConnectionUpdated(std::string address,
+                                          int32_t interval,
+                                          int32_t latency,
+                                          int32_t timeout,
+                                          int32_t status) {
+  NOTIMPLEMENTED();
+}
+
+void FlossGattClient::OnServiceChanged(std::string address) {
+  NOTIMPLEMENTED();
+}
+
+}  // namespace floss
diff --git a/device/bluetooth/floss/floss_gatt_client.h b/device/bluetooth/floss/floss_gatt_client.h
new file mode 100644
index 0000000..c1b3144
--- /dev/null
+++ b/device/bluetooth/floss/floss_gatt_client.h
@@ -0,0 +1,387 @@
+// 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 DEVICE_BLUETOOTH_FLOSS_FLOSS_GATT_CLIENT_H_
+#define DEVICE_BLUETOOTH_FLOSS_FLOSS_GATT_CLIENT_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/floss/exported_callback_manager.h"
+#include "device/bluetooth/floss/floss_dbus_client.h"
+#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
+
+namespace floss {
+
+// Authentication requirements for GATT.
+enum class AuthRequired {
+  kNoAuth = 0,  // No authentication required.
+  kNoMitm,      // Encrypted but not authenticated.
+  kReqMitm,     // Encrypted and authenticated.
+
+  // Same as above but signed + encrypted.
+  kSignedNoMitm,
+  kSignedReqMitm,
+};
+
+enum class WriteType {
+  kInvalid = 0,
+  kWriteNoResponse,
+  kWrite,
+  kWritePrepare,
+};
+
+enum class LePhy {
+  kInvalid = 0,
+  kPhy1m = 1,
+  kPhy2m = 2,
+  kPhyCoded = 3,
+};
+
+// Status for many GATT apis. Due to complexity here, only kSuccess should be
+// used for comparisons.
+enum class GattStatus {
+  kSuccess = 0,
+  kInvalidHandle,
+  kReadNotPermitted,
+  kWriteNotPermitted,
+  kInvalidPdu,
+  kInsufficientAuthentication,
+  kReqNotSupported,
+  kInvalidOffset,
+  kInsufficientAuthorization,
+  kPrepareQueueFull,
+  kNotFound,
+  kNotLong,
+  kInsufficientKeySize,
+  kInvalidAttributeLen,
+  kUnlikelyError,
+  kInsufficientEncryption,
+  kUnsupportedGroupType,
+  kInsufficientResources,
+  kDatabaseOutOfSync,
+  kValueNotAllowed,
+  // Big jump here
+  kTooShort = 0x7f,
+  kNoResources,
+  kInternalError,
+  kWrongState,
+  kDbFull,
+  kBusy,
+  kError,
+  kCommandStarted,
+  kIllegalParameter,
+  kPending,
+  kAuthFailed,
+  kMore,
+  kInvalidConfig,
+  kServiceStarted,
+  kEncryptedNoMitm,
+  kNotEncrypted,
+  kCongested,
+  kDupReg,
+  kAlreadyOpen,
+  kCancel,
+  // 0xE0 - 0xFC reserved for future use.
+  kCccCfgErr = 0xFD,
+  kPrcInProgress = 0xFE,
+  kOutOfRange = 0xFF,
+};
+
+struct GattDescriptor {
+  device::BluetoothUUID uuid;
+  int32_t instance_id;
+  int32_t permissions;
+
+  GattDescriptor();
+  ~GattDescriptor();
+};
+
+struct GattCharacteristic {
+  device::BluetoothUUID uuid;
+  int32_t instance_id;
+  int32_t properties;
+  int32_t permissions;
+  int32_t key_size;
+  WriteType write_type;
+  std::vector<GattDescriptor> descriptors;
+
+  GattCharacteristic();
+  GattCharacteristic(const GattCharacteristic&);
+  ~GattCharacteristic();
+};
+
+struct GattService {
+  device::BluetoothUUID uuid;
+  int32_t instance_id;
+  int32_t service_type;
+  std::vector<GattCharacteristic> characteristics;
+  std::vector<GattService> included_services;
+
+  GattService();
+  GattService(const GattService&);
+  ~GattService();
+};
+
+// Callback functions expected to be imported by the GATT client.
+class FlossGattClientCallbacks {
+ public:
+  // A client has completed registration for callbacks. Subsequent uses should
+  // use this client id.
+  virtual void OnClientRegistered(int32_t status, int32_t client_id) = 0;
+
+  // A client connection has changed state.
+  virtual void OnClientConnectionState(int32_t status,
+                                       int32_t client_id,
+                                       bool connected,
+                                       std::string address) = 0;
+
+  // The PHY used for a connection has changed states.
+  virtual void OnPhyUpdate(std::string address,
+                           LePhy tx,
+                           LePhy rx,
+                           GattStatus status) = 0;
+
+  // Result of reading the currently used PHY.
+  virtual void OnPhyRead(std::string address,
+                         LePhy tx,
+                         LePhy rx,
+                         GattStatus status) = 0;
+
+  // Service resolution completed and GATT db available.
+  virtual void OnSearchComplete(std::string address,
+                                std::vector<GattService> services,
+                                int32_t status) = 0;
+
+  // Result of reading a characteristic.
+  virtual void OnCharacteristicRead(std::string address,
+                                    int32_t status,
+                                    int32_t handle,
+                                    std::vector<uint8_t> data) = 0;
+
+  // Result of writing a characteristic.
+  virtual void OnCharacteristicWrite(std::string address,
+                                     int32_t status,
+                                     int32_t handle) = 0;
+
+  // Reliable write completed.
+  virtual void OnExecuteWrite(std::string address, int32_t status) = 0;
+
+  // Result of reading a descriptor.
+  virtual void OnDescriptorRead(std::string address,
+                                int32_t status,
+                                int32_t handle,
+                                std::vector<uint8_t> data) = 0;
+
+  // Result of writing to a descriptor.
+  virtual void OnDescriptorWrite(std::string address,
+                                 int32_t status,
+                                 int32_t handle) = 0;
+
+  // Notification or indication of a handle on a remote device.
+  virtual void OnNotify(std::string address,
+                        int32_t handle,
+                        std::vector<uint8_t> data) = 0;
+
+  // Result of reading remote rssi.
+  virtual void OnReadRemoteRssi(std::string address,
+                                int32_t rssi,
+                                int32_t status) = 0;
+
+  // Result of setting connection mtu.
+  virtual void OnConfigureMtu(std::string address,
+                              int32_t mtu,
+                              int32_t status) = 0;
+
+  // Change to connection parameters.
+  virtual void OnConnectionUpdated(std::string address,
+                                   int32_t interval,
+                                   int32_t latency,
+                                   int32_t timeout,
+                                   int32_t status) = 0;
+
+  // Notification when there is an addition/removal/change of a GATT service.
+  virtual void OnServiceChanged(std::string address) = 0;
+};
+
+class DEVICE_BLUETOOTH_EXPORT FlossGattClient
+    : public FlossDBusClient,
+      public FlossGattClientCallbacks {
+ public:
+  static const char kExportedCallbacksPath[];
+
+  // Creates the instance.
+  static std::unique_ptr<FlossGattClient> Create();
+
+  FlossGattClient();
+  ~FlossGattClient() override;
+
+  FlossGattClient(const FlossGattClient&) = delete;
+  FlossGattClient& operator=(const FlossGattClient&) = delete;
+
+  // Create a GATT client connection to a remote device on given transport.
+  virtual void Connect(ResponseCallback<Void> callback,
+                       const std::string& remote_device,
+                       const BluetoothTransport& transport);
+
+  // Disconnect GATT for given device.
+  virtual void Disconnect(ResponseCallback<Void> callback,
+                          const std::string& remote_device);
+
+  // Clears the attribute cache of a device.
+  virtual void Refresh(ResponseCallback<Void> callback,
+                       const std::string& remote_device);
+
+  // Enumerates all GATT services on an already connected device.
+  virtual void DiscoverAllServices(ResponseCallback<Void> callback,
+                                   const std::string& remote_device);
+
+  // Search for a GATT service on a connected device with a UUID.
+  virtual void DiscoverServiceByUuid(ResponseCallback<Void> callback,
+                                     const std::string& remote_device,
+                                     const device::BluetoothUUID& uuid);
+
+  // Reads a characteristic on a connected device with given |handle|.
+  virtual void ReadCharacteristic(ResponseCallback<Void> callback,
+                                  const std::string& remote_device,
+                                  const int32_t handle,
+                                  const AuthRequired auth_required);
+
+  // Reads a characteristic on a connected device between |start_handle| and
+  // |end_handle| that matches the given |uuid|.
+  virtual void ReadUsingCharacteristicUuid(ResponseCallback<Void> callback,
+                                           const std::string& remote_device,
+                                           const device::BluetoothUUID& uuid,
+                                           const int32_t start_handle,
+                                           const int32_t end_handle,
+                                           const AuthRequired auth_required);
+
+  // Writes a characteristic on a connected device with given |handle|.
+  virtual void WriteCharacteristic(ResponseCallback<Void> callback,
+                                   const std::string& remote_device,
+                                   const int32_t handle,
+                                   const WriteType write_type,
+                                   const AuthRequired auth_required,
+                                   const std::vector<uint8_t> data);
+
+  // Reads the descriptor for a given characteristic |handle|.
+  virtual void ReadDescriptor(ResponseCallback<Void> callback,
+                              const std::string& remote_device,
+                              const int32_t handle,
+                              const AuthRequired auth_required);
+
+  // Writes a descriptor for a given characteristic |handle|.
+  virtual void WriteDescriptor(ResponseCallback<Void> callback,
+                               const std::string& remote_device,
+                               const int32_t handle,
+                               const AuthRequired auth_required,
+                               const std::vector<uint8_t> data);
+
+  // Register for updates on a specific characteristic.
+  virtual void RegisterForNotification(ResponseCallback<Void> callback,
+                                       const std::string& remote_device,
+                                       const int32_t handle);
+
+  // Unregister for updates on a specific characteristic.
+  virtual void UnregisterNotification(ResponseCallback<Void> callback,
+                                      const std::string& remote_device,
+                                      const int32_t handle);
+
+  // Request RSSI for the connected device.
+  virtual void ReadRemoteRssi(ResponseCallback<Void> callback,
+                              const std::string& remote_device);
+
+  // Configures the MTU for a connected device.
+  virtual void ConfigureMTU(ResponseCallback<Void> callback,
+                            const std::string& remote_device,
+                            const int32_t mtu);
+
+  // Initialize the gatt client for the given adapter.
+  void Init(dbus::Bus* bus,
+            const std::string& service_name,
+            const int adapter_index) override;
+
+ protected:
+  // FlossGattClientCallbacks overrides
+  void OnClientRegistered(int32_t status, int32_t client_id) override;
+  void OnClientConnectionState(int32_t status,
+                               int32_t client_id,
+                               bool connected,
+                               std::string address) override;
+  void OnPhyUpdate(std::string address,
+                   LePhy tx,
+                   LePhy rx,
+                   GattStatus status) override;
+  void OnPhyRead(std::string address,
+                 LePhy tx,
+                 LePhy rx,
+                 GattStatus status) override;
+  void OnSearchComplete(std::string address,
+                        std::vector<GattService> services,
+                        int32_t status) override;
+  void OnCharacteristicRead(std::string address,
+                            int32_t status,
+                            int32_t handle,
+                            std::vector<uint8_t> data) override;
+  void OnCharacteristicWrite(std::string address,
+                             int32_t status,
+                             int32_t handle) override;
+  void OnExecuteWrite(std::string address, int32_t status) override;
+  void OnDescriptorRead(std::string address,
+                        int32_t status,
+                        int32_t handle,
+                        std::vector<uint8_t> data) override;
+  void OnDescriptorWrite(std::string address,
+                         int32_t status,
+                         int32_t handle) override;
+  void OnNotify(std::string address,
+                int32_t handle,
+                std::vector<uint8_t> data) override;
+  void OnReadRemoteRssi(std::string address,
+                        int32_t rssi,
+                        int32_t status) override;
+  void OnConfigureMtu(std::string address,
+                      int32_t mtu,
+                      int32_t status) override;
+  void OnConnectionUpdated(std::string address,
+                           int32_t interval,
+                           int32_t latency,
+                           int32_t timeout,
+                           int32_t status) override;
+  void OnServiceChanged(std::string address) override;
+
+  // Managed by FlossDBusManager - we keep local pointer to access object proxy.
+  base::raw_ptr<dbus::Bus> bus_ = nullptr;
+
+  // Path used for gatt api calls by this class.
+  dbus::ObjectPath gatt_adapter_path_;
+
+  // Service which implements the GattClient interface.
+  std::string service_name_;
+
+ private:
+  template <typename R, typename... Args>
+  void CallGattMethod(ResponseCallback<R> callback,
+                      const char* member,
+                      Args... args) {
+    CallMethod(std::move(callback), bus_, service_name_, kAdapterInterface,
+               gatt_adapter_path_, member, args...);
+  }
+
+  // Id given for registering as a client against Floss. Used in many apis.
+  uint32_t client_id_ = 0;
+
+  // Exported callbacks for interacting with daemon.
+  ExportedCallbackManager<FlossGattClientCallbacks> exported_callback_manager_{
+      gatt::kCallbackInterface};
+
+  base::WeakPtrFactory<FlossGattClient> weak_ptr_factory_{this};
+};
+
+}  // namespace floss
+
+#endif  // DEVICE_BLUETOOTH_FLOSS_FLOSS_GATT_CLIENT_H_
diff --git a/device/bluetooth/floss/floss_gatt_client_unittest.cc b/device/bluetooth/floss/floss_gatt_client_unittest.cc
new file mode 100644
index 0000000..27bcae5a
--- /dev/null
+++ b/device/bluetooth/floss/floss_gatt_client_unittest.cc
@@ -0,0 +1,31 @@
+// 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 "device/bluetooth/floss/floss_gatt_client.h"
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace floss {
+
+class FlossGattClientTest : public testing::Test {
+ public:
+  void SetUp() override { client_ = FlossGattClient::Create(); }
+
+  void TearDown() override { client_.reset(); }
+
+  std::unique_ptr<FlossGattClient> client_;
+
+  base::test::TaskEnvironment task_environment_;
+  base::WeakPtrFactory<FlossGattClientTest> weak_ptr_factory_{this};
+};
+
+TEST_F(FlossGattClientTest, BasicTest) {}
+
+}  // namespace floss
diff --git a/device/bluetooth/floss/floss_manager_client.cc b/device/bluetooth/floss/floss_manager_client.cc
index 5e79c03b..0bf82b0 100644
--- a/device/bluetooth/floss/floss_manager_client.cc
+++ b/device/bluetooth/floss/floss_manager_client.cc
@@ -306,11 +306,11 @@
   }
 }
 
-// The manager can manage multiple adapters so ignore the adapter path given
+// The manager can manage multiple adapters so ignore the adapter index given
 // here. It is unused.
 void FlossManagerClient::Init(dbus::Bus* bus,
                               const std::string& service_name,
-                              const std::string& adapter_path) {
+                              const int adapter_index) {
   bus_ = bus;
   service_name_ = service_name;
 
@@ -594,11 +594,6 @@
 }
 
 // static
-dbus::ObjectPath FlossManagerClient::GenerateAdapterPath(int adapter) {
-  return dbus::ObjectPath(base::StringPrintf(kAdapterObjectFormat, adapter));
-}
-
-// static
 std::unique_ptr<FlossManagerClient> FlossManagerClient::Create() {
   return std::make_unique<FlossManagerClient>();
 }
diff --git a/device/bluetooth/floss/floss_manager_client.h b/device/bluetooth/floss/floss_manager_client.h
index 52cc5c32..94734768 100644
--- a/device/bluetooth/floss/floss_manager_client.h
+++ b/device/bluetooth/floss/floss_manager_client.h
@@ -77,9 +77,6 @@
     base::WeakPtrFactory<PoweredCallback> weak_ptr_factory_{this};
   };
 
-  // Convert adapter number to object path.
-  static dbus::ObjectPath GenerateAdapterPath(int adapter);
-
   // Creates the instance.
   static std::unique_ptr<FlossManagerClient> Create();
 
@@ -115,7 +112,7 @@
   // Initializes the manager client.
   void Init(dbus::Bus* bus,
             const std::string& service_name,
-            const std::string& adapter_path) override;
+            const int adapter_index) override;
 
  protected:
   friend class FlossManagerClientTest;
diff --git a/device/bluetooth/floss/floss_manager_client_unittest.cc b/device/bluetooth/floss/floss_manager_client_unittest.cc
index ff3fc08..bfac172 100644
--- a/device/bluetooth/floss/floss_manager_client_unittest.cc
+++ b/device/bluetooth/floss/floss_manager_client_unittest.cc
@@ -308,7 +308,7 @@
 // Make sure adapter presence is updated on init
 TEST_F(FlossManagerClientTest, QueriesAdapterPresenceOnInit) {
   TestManagerObserver observer(client_.get());
-  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_index=*/-1);
   EXPECT_EQ(observer.manager_present_count_, 1);
   EXPECT_TRUE(observer.manager_present_);
 
@@ -325,7 +325,7 @@
 // Make sure adapter presence is plumbed through callbacks
 TEST_F(FlossManagerClientTest, VerifyAdapterPresent) {
   TestManagerObserver observer(client_.get());
-  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_index=*/-1);
   EXPECT_EQ(observer.adapter_present_count_, 2);
   EXPECT_EQ(observer.adapter_enabled_changed_count_, 2);
   EXPECT_TRUE(observer.adapter_present_[0]);
@@ -356,7 +356,7 @@
 // Make sure adapter powered is plumbed through callbacks
 TEST_F(FlossManagerClientTest, VerifyAdapterEnabled) {
   TestManagerObserver observer(client_.get());
-  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_index=*/-1);
   // Pre-conditions
   EXPECT_FALSE(client_->GetAdapterEnabled(0));
   EXPECT_TRUE(client_->GetAdapterEnabled(5));
@@ -401,7 +401,7 @@
 // Make sure manager presence is correctly detected
 TEST_F(FlossManagerClientTest, HandleManagerPresence) {
   TestManagerObserver observer(client_.get());
-  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_index=*/-1);
   dbus::ObjectPath opath = dbus::ObjectPath(kManagerObject);
   EXPECT_EQ(observer.manager_present_count_, 1);
 
@@ -453,7 +453,7 @@
 
   TestManagerObserver observer(client_.get());
   floss_enabled_target_ = false;
-  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_index=*/-1);
 
   // First confirm we had it set to False
   EXPECT_EQ(method_called_[manager::kSetFlossEnabled], 1);
diff --git a/device/bluetooth/floss/floss_socket_manager.cc b/device/bluetooth/floss/floss_socket_manager.cc
index 5539546e..b12939386 100644
--- a/device/bluetooth/floss/floss_socket_manager.cc
+++ b/device/bluetooth/floss/floss_socket_manager.cc
@@ -431,10 +431,10 @@
 
 void FlossSocketManager::Init(dbus::Bus* bus,
                               const std::string& service_name,
-                              const std::string& adapter_path) {
+                              const int adapter_index) {
   bus_ = bus;
   service_name_ = service_name;
-  adapter_path_ = dbus::ObjectPath(adapter_path);
+  adapter_path_ = GenerateAdapterPath(adapter_index);
 
   dbus::ObjectProxy* object_proxy =
       bus_->GetObjectProxy(service_name_, adapter_path_);
diff --git a/device/bluetooth/floss/floss_socket_manager.h b/device/bluetooth/floss/floss_socket_manager.h
index f532059..64bf9d9 100644
--- a/device/bluetooth/floss/floss_socket_manager.h
+++ b/device/bluetooth/floss/floss_socket_manager.h
@@ -173,7 +173,7 @@
   // Initializes the socket manager with given adapter.
   void Init(dbus::Bus* bus,
             const std::string& service_name,
-            const std::string& adapter_path) override;
+            const int adapter_index) override;
 
  protected:
   friend class FlossSocketManagerTest;
diff --git a/device/bluetooth/floss/floss_socket_manager_unittest.cc b/device/bluetooth/floss/floss_socket_manager_unittest.cc
index 9806aaa..10e5279 100644
--- a/device/bluetooth/floss/floss_socket_manager_unittest.cc
+++ b/device/bluetooth/floss/floss_socket_manager_unittest.cc
@@ -39,7 +39,7 @@
   FlossSocketManagerTest() = default;
 
   void SetUpMocks() {
-    adapter_path_ = FlossManagerClient::GenerateAdapterPath(adapter_index_);
+    adapter_path_ = FlossDBusClient::GenerateAdapterPath(adapter_index_);
     sockmgr_proxy_ = base::MakeRefCounted<::dbus::MockObjectProxy>(
         bus_.get(), kSocketManagerInterface, adapter_path_);
     exported_callbacks_ = base::MakeRefCounted<::dbus::MockExportedObject>(
@@ -80,7 +80,7 @@
   }
 
   void Init() {
-    sockmgr_->Init(bus_.get(), kSocketManagerInterface, adapter_path_.value());
+    sockmgr_->Init(bus_.get(), kSocketManagerInterface, adapter_index_);
   }
 
   void SetupListeningSocket() {
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index c957ea2..4b08ec99 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -137,6 +137,8 @@
       "ctap_make_credential_request.cc",
       "ctap_make_credential_request.h",
       "device_operation.h",
+      "device_public_key_extension.cc",
+      "device_public_key_extension.h",
       "device_response_converter.cc",
       "device_response_converter.h",
       "fido_authenticator.cc",
diff --git a/device/fido/authenticator_get_assertion_response.h b/device/fido/authenticator_get_assertion_response.h
index 08cebda..6a1347e6 100644
--- a/device/fido/authenticator_get_assertion_response.h
+++ b/device/fido/authenticator_get_assertion_response.h
@@ -78,6 +78,11 @@
   // The transport used to generate this response. This is unknown when using
   // the Windows WebAuthn API.
   absl::optional<FidoTransportProtocol> transport_used;
+
+  // device_public_key_signature contains the optional signature from the
+  // device-bound key. See
+  // https://github.com/fido-alliance/fido-2-specs/pull/1346
+  absl::optional<std::vector<uint8_t>> device_public_key_signature;
 };
 
 }  // namespace device
diff --git a/device/fido/authenticator_make_credential_response.cc b/device/fido/authenticator_make_credential_response.cc
index df62188..852a487 100644
--- a/device/fido/authenticator_make_credential_response.cc
+++ b/device/fido/authenticator_make_credential_response.cc
@@ -11,6 +11,7 @@
 #include "device/fido/attestation_statement_formats.h"
 #include "device/fido/attested_credential_data.h"
 #include "device/fido/authenticator_data.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/fido_parsing_utils.h"
 #include "device/fido/p256_public_key.h"
 #include "device/fido/public_key.h"
@@ -98,6 +99,26 @@
       .IsAttestationCertificateInappropriatelyIdentifying();
 }
 
+absl::optional<device::DevicePublicKeyOutput>
+AuthenticatorMakeCredentialResponse::GetDevicePublicKeyResponse() const {
+  const absl::optional<cbor::Value>& maybe_extensions =
+      attestation_object_.authenticator_data().extensions();
+  if (!maybe_extensions) {
+    return absl::nullopt;
+  }
+
+  DCHECK(maybe_extensions->is_map());
+  const cbor::Value::MapValue& extensions = maybe_extensions->GetMap();
+  const auto device_public_key_it =
+      extensions.find(cbor::Value(device::kExtensionDevicePublicKey));
+  if (device_public_key_it == extensions.end()) {
+    return absl::nullopt;
+  }
+
+  return device::DevicePublicKeyOutput::FromExtension(
+      device_public_key_it->second);
+}
+
 const std::array<uint8_t, kRpIdHashLength>&
 AuthenticatorMakeCredentialResponse::GetRpIdHash() const {
   return attestation_object_.rp_id_hash();
@@ -121,6 +142,12 @@
   if (response.large_blob_key()) {
     map.emplace(5, cbor::Value(*response.large_blob_key()));
   }
+  if (response.device_public_key_signature.has_value()) {
+    cbor::Value::MapValue unsigned_extension_outputs;
+    unsigned_extension_outputs.emplace(kExtensionDevicePublicKey,
+                                       *response.device_public_key_signature);
+    map.emplace(6, std::move(unsigned_extension_outputs));
+  }
   auto encoded_bytes = cbor::Writer::Write(cbor::Value(std::move(map)));
   DCHECK(encoded_bytes);
   return std::move(*encoded_bytes);
diff --git a/device/fido/authenticator_make_credential_response.h b/device/fido/authenticator_make_credential_response.h
index 9aae4db5..df2706a5 100644
--- a/device/fido/authenticator_make_credential_response.h
+++ b/device/fido/authenticator_make_credential_response.h
@@ -20,6 +20,8 @@
 
 namespace device {
 
+struct DevicePublicKeyOutput;
+
 // Attestation object which includes attestation format, authentication
 // data, and attestation statement returned by the authenticator as a response
 // to MakeCredential request.
@@ -64,6 +66,10 @@
   // not intended to be trackable.)
   bool IsAttestationCertificateInappropriatelyIdentifying();
 
+  // Returns the output the the devicePubKey extension, if any.
+  absl::optional<device::DevicePublicKeyOutput> GetDevicePublicKeyResponse()
+      const;
+
   const std::array<uint8_t, kRpIdHashLength>& GetRpIdHash() const;
 
   const AttestationObject& attestation_object() const {
@@ -101,6 +107,11 @@
   // authenticator, if known.
   absl::optional<base::flat_set<FidoTransportProtocol>> transports;
 
+  // device_public_key_signature contains the optional signature from the
+  // device-bound key. See
+  // https://github.com/fido-alliance/fido-2-specs/pull/1346
+  absl::optional<std::vector<uint8_t>> device_public_key_signature;
+
  private:
   AttestationObject attestation_object_;
 
diff --git a/device/fido/ctap_get_assertion_request.cc b/device/fido/ctap_get_assertion_request.cc
index 625cafa..b142b35b 100644
--- a/device/fido/ctap_get_assertion_request.cc
+++ b/device/fido/ctap_get_assertion_request.cc
@@ -175,6 +175,14 @@
           return absl::nullopt;
         }
         request.get_cred_blob = true;
+      } else if (extension_id == kExtensionDevicePublicKey) {
+        // There's not currently any support for the ep bit in assertion
+        // requests so DPK requests are assumed to be ep=1 only.
+        request.device_public_key = DevicePublicKeyRequest::FromCBOR(
+            extension.second, /* ep_approved_by_browser= */ false);
+        if (!request.device_public_key) {
+          return absl::nullopt;
+        }
       }
     }
   }
@@ -286,6 +294,11 @@
     extensions.emplace(kExtensionCredBlob, true);
   }
 
+  if (request.device_public_key) {
+    extensions.emplace(kExtensionDevicePublicKey,
+                       request.device_public_key->ToCBOR());
+  }
+
   if (!extensions.empty()) {
     cbor_map[cbor::Value(4)] = cbor::Value(std::move(extensions));
   }
diff --git a/device/fido/ctap_get_assertion_request.h b/device/fido/ctap_get_assertion_request.h
index aa7f688e..0ec6b53 100644
--- a/device/fido/ctap_get_assertion_request.h
+++ b/device/fido/ctap_get_assertion_request.h
@@ -15,6 +15,7 @@
 #include "base/containers/span.h"
 #include "crypto/sha2.h"
 #include "device/fido/cable/cable_discovery_data.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/large_blob.h"
 #include "device/fido/pin.h"
@@ -131,6 +132,10 @@
   // Indicates whether the request was created in an off-the-record
   // BrowserContext (e.g. Incognito or Guest mode in Chrome).
   bool is_off_the_record_context = false;
+
+  // device_public_key contains parameters for the devicePubKey extension
+  // https://github.com/w3c/webauthn/pull/1663
+  absl::optional<DevicePublicKeyRequest> device_public_key;
 };
 
 struct CtapGetNextAssertionRequest {};
diff --git a/device/fido/ctap_make_credential_request.cc b/device/fido/ctap_make_credential_request.cc
index 970a155..34d2706 100644
--- a/device/fido/ctap_make_credential_request.cc
+++ b/device/fido/ctap_make_credential_request.cc
@@ -108,6 +108,25 @@
     request.exclude_list = std::move(exclude_list);
   }
 
+  const auto enterprise_attestation_it = request_map.find(cbor::Value(10));
+  if (enterprise_attestation_it != request_map.end()) {
+    if (!enterprise_attestation_it->second.is_unsigned()) {
+      return absl::nullopt;
+    }
+    switch (enterprise_attestation_it->second.GetUnsigned()) {
+      case 1:
+        request.attestation_preference = AttestationConveyancePreference::
+            kEnterpriseIfRPListedOnAuthenticator;
+        break;
+      case 2:
+        request.attestation_preference =
+            AttestationConveyancePreference::kEnterpriseApprovedByBrowser;
+        break;
+      default:
+        return absl::nullopt;
+    }
+  }
+
   const auto extensions_it = request_map.find(cbor::Value(6));
   if (extensions_it != request_map.end()) {
     if (!extensions_it->second.is_map()) {
@@ -164,6 +183,14 @@
           return absl::nullopt;
         }
         request.min_pin_length_requested = extension.second.GetBool();
+      } else if (extension_name == kExtensionDevicePublicKey) {
+        request.device_public_key = DevicePublicKeyRequest::FromCBOR(
+            extension.second,
+            request.attestation_preference ==
+                AttestationConveyancePreference::kEnterpriseApprovedByBrowser);
+        if (!request.device_public_key) {
+          return absl::nullopt;
+        }
       }
     }
   }
@@ -216,25 +243,6 @@
     request.pin_protocol = *pin_protocol;
   }
 
-  const auto enterprise_attestation_it = request_map.find(cbor::Value(10));
-  if (enterprise_attestation_it != request_map.end()) {
-    if (!enterprise_attestation_it->second.is_unsigned()) {
-      return absl::nullopt;
-    }
-    switch (enterprise_attestation_it->second.GetUnsigned()) {
-      case 1:
-        request.attestation_preference = AttestationConveyancePreference::
-            kEnterpriseIfRPListedOnAuthenticator;
-        break;
-      case 2:
-        request.attestation_preference =
-            AttestationConveyancePreference::kEnterpriseApprovedByBrowser;
-        break;
-      default:
-        return absl::nullopt;
-    }
-  }
-
   return request;
 }
 
@@ -302,6 +310,11 @@
     extensions.emplace(kExtensionMinPINLength, true);
   }
 
+  if (request.device_public_key) {
+    extensions.emplace(kExtensionDevicePublicKey,
+                       request.device_public_key->ToCBOR());
+  }
+
   if (!extensions.empty()) {
     cbor_map[cbor::Value(6)] = cbor::Value(std::move(extensions));
   }
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h
index b6bc96d..f0c14b1f 100644
--- a/device/fido/ctap_make_credential_request.h
+++ b/device/fido/ctap_make_credential_request.h
@@ -13,6 +13,7 @@
 
 #include "base/component_export.h"
 #include "device/fido/authenticator_selection_criteria.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/pin.h"
 #include "device/fido/public_key_credential_descriptor.h"
@@ -126,6 +127,10 @@
   // cred_blob contains an optional credBlob extension.
   // https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension
   absl::optional<std::vector<uint8_t>> cred_blob;
+
+  // device_public_key contains parameters for the devicePubKey extension
+  // https://github.com/w3c/webauthn/pull/1663
+  absl::optional<DevicePublicKeyRequest> device_public_key;
 };
 
 // MakeCredentialOptions contains higher-level request parameters that aren't
diff --git a/device/fido/device_public_key_extension.cc b/device/fido/device_public_key_extension.cc
new file mode 100644
index 0000000..9c56bd5
--- /dev/null
+++ b/device/fido/device_public_key_extension.cc
@@ -0,0 +1,228 @@
+// 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 "device/fido/device_public_key_extension.h"
+
+#include "components/cbor/reader.h"
+#include "device/fido/fido_constants.h"
+
+namespace device {
+
+DevicePublicKeyRequest::DevicePublicKeyRequest() = default;
+DevicePublicKeyRequest::DevicePublicKeyRequest(DevicePublicKeyRequest&&) =
+    default;
+DevicePublicKeyRequest::DevicePublicKeyRequest(const DevicePublicKeyRequest&) =
+    default;
+DevicePublicKeyRequest::~DevicePublicKeyRequest() = default;
+DevicePublicKeyRequest& DevicePublicKeyRequest::operator=(
+    const DevicePublicKeyRequest&) = default;
+
+bool DevicePublicKeyRequest::operator==(
+    const DevicePublicKeyRequest& other) const {
+  return this->attestation == other.attestation &&
+         this->attestation_formats == other.attestation_formats;
+}
+
+// static
+absl::optional<DevicePublicKeyRequest> DevicePublicKeyRequest::FromCBOR(
+    const cbor::Value& map_value,
+    bool ep_bit) {
+  if (!map_value.is_map()) {
+    return absl::nullopt;
+  }
+  const cbor::Value::MapValue& map = map_value.GetMap();
+
+  auto it = map.find(cbor::Value(kDevicePublicKeyAttestationKey));
+  if (it == map.end() || !it->second.is_string()) {
+    return absl::nullopt;
+  }
+
+  const std::string& attestation_str = it->second.GetString();
+  AttestationConveyancePreference attestation;
+  if (attestation_str == "none") {
+    attestation = AttestationConveyancePreference::kNone;
+  } else if (attestation_str == "indirect") {
+    attestation = AttestationConveyancePreference::kIndirect;
+  } else if (attestation_str == "direct") {
+    attestation = AttestationConveyancePreference::kDirect;
+  } else if (attestation_str == "enterprise") {
+    if (ep_bit) {
+      attestation =
+          AttestationConveyancePreference::kEnterpriseApprovedByBrowser;
+    } else {
+      attestation =
+          AttestationConveyancePreference::kEnterpriseIfRPListedOnAuthenticator;
+    }
+  } else {
+    return absl::nullopt;
+  }
+
+  it = map.find(cbor::Value(kDevicePublicKeyAttestationFormatsKey));
+  if (it == map.end() || !it->second.is_array()) {
+    return absl::nullopt;
+  }
+
+  std::vector<std::string> attestation_formats;
+  for (const cbor::Value& format : it->second.GetArray()) {
+    if (!format.is_string()) {
+      return absl::nullopt;
+    }
+    attestation_formats.emplace_back(format.GetString());
+  }
+
+  DevicePublicKeyRequest request;
+  request.attestation = attestation;
+  request.attestation_formats = std::move(attestation_formats);
+  return request;
+}
+
+cbor::Value DevicePublicKeyRequest::ToCBOR() const {
+  const char* attestation_str;
+  switch (this->attestation) {
+    case AttestationConveyancePreference::kNone:
+      attestation_str = "none";
+      break;
+    case AttestationConveyancePreference::kIndirect:
+      attestation_str = "indirect";
+      break;
+    case AttestationConveyancePreference::kDirect:
+      attestation_str = "direct";
+      break;
+    case AttestationConveyancePreference::kEnterpriseApprovedByBrowser:
+    case AttestationConveyancePreference::kEnterpriseIfRPListedOnAuthenticator:
+      attestation_str = "enterprise";
+      break;
+  }
+
+  cbor::Value::ArrayValue formats;
+  for (const std::string& format : this->attestation_formats) {
+    formats.emplace_back(format);
+  }
+
+  cbor::Value::MapValue map;
+  map.emplace(kDevicePublicKeyAttestationKey, attestation_str);
+  map.emplace(kDevicePublicKeyAttestationFormatsKey,
+              cbor::Value(std::move(formats)));
+
+  return cbor::Value(std::move(map));
+}
+
+DevicePublicKeyOutput::DevicePublicKeyOutput() = default;
+DevicePublicKeyOutput::DevicePublicKeyOutput(DevicePublicKeyOutput&&) = default;
+DevicePublicKeyOutput::~DevicePublicKeyOutput() = default;
+
+// static
+absl::optional<DevicePublicKeyOutput> DevicePublicKeyOutput::FromExtension(
+    const cbor::Value& value) {
+  if (!value.is_bytestring()) {
+    return absl::nullopt;
+  }
+
+  absl::optional<cbor::Value> parsed_output =
+      cbor::Reader::Read(value.GetBytestring());
+  if (!parsed_output || !parsed_output->is_map()) {
+    return absl::nullopt;
+  }
+
+  const cbor::Value::MapValue& map = parsed_output->GetMap();
+  DevicePublicKeyOutput ret;
+
+  auto it = map.find(cbor::Value(kDevicePublicKeyAAGUIDKey));
+  if (it == map.end() || !it->second.is_bytestring() ||
+      it->second.GetBytestring().size() != std::size(ret.aaguid)) {
+    return absl::nullopt;
+  }
+  memcpy(ret.aaguid.data(), it->second.GetBytestring().data(),
+         std::size(ret.aaguid));
+
+  it = map.find(cbor::Value(kDevicePublicKeyDPKKey));
+  if (it == map.end() || !it->second.is_bytestring()) {
+    return absl::nullopt;
+  }
+  absl::optional<cbor::Value> dpk =
+      cbor::Reader::Read(it->second.GetBytestring());
+  if (!dpk || !dpk->is_map()) {
+    return absl::nullopt;
+  }
+  ret.dpk = std::move(*dpk);
+
+  it = map.find(cbor::Value(kDevicePublicKeyScopeKey));
+  if (it == map.end() || !it->second.is_integer()) {
+    return absl::nullopt;
+  }
+  int64_t scope = it->second.GetInteger();
+  if (scope < 0 || scope > std::numeric_limits<decltype(ret.scope)>::max()) {
+    return absl::nullopt;
+  }
+  ret.scope = scope;
+
+  it = map.find(cbor::Value(kDevicePublicKeyNonceKey));
+  if (it == map.end() || !it->second.is_bytestring() ||
+      it->second.GetBytestring().size() > 32) {
+    return absl::nullopt;
+  }
+  ret.nonce = it->second.GetBytestring();
+
+  it = map.find(cbor::Value(kFormatKey));
+  if (it == map.end() || !it->second.is_string()) {
+    return absl::nullopt;
+  }
+  ret.attestation_format = it->second.GetString();
+
+  it = map.find(cbor::Value(kAttestationStatementKey));
+  if (it == map.end()) {
+    return absl::nullopt;
+  }
+  ret.attestation = it->second.Clone();
+
+  it = map.find(cbor::Value(kDevicePublicKeyEPKey));
+  if (it != map.end()) {
+    if (!it->second.is_bool()) {
+      return absl::nullopt;
+    }
+    ret.enterprise_attestation_returned = it->second.GetBool();
+  }
+
+  static const std::array<uint8_t, sizeof(ret.aaguid)> kZeroAAGUID = {0};
+  if (ret.attestation_format == "none" &&
+      (ret.aaguid != kZeroAAGUID || !ret.attestation.is_map() ||
+       !ret.attestation.GetMap().empty() ||
+       ret.enterprise_attestation_returned)) {
+    return absl::nullopt;
+  }
+
+  return ret;
+}
+
+absl::optional<const char*> CheckDevicePublicKeyExtensionForErrors(
+    const cbor::Value& extension_value,
+    AttestationConveyancePreference requested_attestation) {
+  absl::optional<DevicePublicKeyOutput> output =
+      DevicePublicKeyOutput::FromExtension(extension_value);
+  if (!output) {
+    return "invalid devicePubKey extension output";
+  }
+  if (requested_attestation == AttestationConveyancePreference::kNone &&
+      output->attestation_format != kNoneAttestationValue) {
+    return "DPK contained unsolicited attestation";
+  }
+  if (output->enterprise_attestation_returned &&
+      (requested_attestation != AttestationConveyancePreference::
+                                    kEnterpriseIfRPListedOnAuthenticator &&
+       requested_attestation !=
+           AttestationConveyancePreference::kEnterpriseApprovedByBrowser)) {
+    return "DPK enterprise attestation returned but not requested.";
+  }
+  if (requested_attestation == AttestationConveyancePreference::
+                                   kEnterpriseIfRPListedOnAuthenticator &&
+      !output->enterprise_attestation_returned &&
+      output->attestation_format != "none") {
+    return "Failed enterprise attestation request didn't result in 'none' "
+           "attestation";
+  }
+
+  return absl::nullopt;
+}
+
+}  // namespace device
diff --git a/device/fido/device_public_key_extension.h b/device/fido/device_public_key_extension.h
new file mode 100644
index 0000000..091e47dd
--- /dev/null
+++ b/device/fido/device_public_key_extension.h
@@ -0,0 +1,75 @@
+// 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 DEVICE_FIDO_DEVICE_PUBLIC_KEY_EXTENSION_H_
+#define DEVICE_FIDO_DEVICE_PUBLIC_KEY_EXTENSION_H_
+
+#include <array>
+#include <string>
+#include <vector>
+
+#include "base/component_export.h"
+#include "components/cbor/values.h"
+#include "device/fido/fido_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace device {
+
+// DevicePublicKeyRequest reflects the RP-provided `devicePubKey` extension in
+// a create() or get() request. See https://github.com/w3c/webauthn/pull/1663.
+struct COMPONENT_EXPORT(DEVICE_FIDO) DevicePublicKeyRequest {
+  DevicePublicKeyRequest();
+  DevicePublicKeyRequest(DevicePublicKeyRequest&&);
+  DevicePublicKeyRequest(const DevicePublicKeyRequest&);
+  ~DevicePublicKeyRequest();
+  DevicePublicKeyRequest& operator=(const DevicePublicKeyRequest&);
+  bool operator==(const DevicePublicKeyRequest&) const;
+
+  // FromCBOR parses a `DevicePublicKeyRequest` from the given CBOR map, which
+  // should be the extension contents. The `ep_approved_by_browser` argument
+  // controls whether "enterprise" attestation is interpreted as "only if the
+  // authenticator recognises the RP ID" or whether the browser has approved it
+  // for all cases.
+  static absl::optional<DevicePublicKeyRequest> FromCBOR(
+      const cbor::Value& map,
+      bool ep_approved_by_browser);
+
+  cbor::Value ToCBOR() const;
+
+  AttestationConveyancePreference attestation =
+      AttestationConveyancePreference::kNone;
+  std::vector<std::string> attestation_formats;
+};
+
+// DevicePublicKeyOutput reflects the output of the `devicePubKey` extension in
+// a create() or get() call. The contents of the CBOR bytestring are parsed and
+// expanded into this structure.
+struct COMPONENT_EXPORT(DEVICE_FIDO) DevicePublicKeyOutput {
+  DevicePublicKeyOutput();
+  DevicePublicKeyOutput(DevicePublicKeyOutput&&);
+  ~DevicePublicKeyOutput();
+
+  static absl::optional<DevicePublicKeyOutput> FromExtension(
+      const cbor::Value& value);
+
+  std::array<uint8_t, 16> aaguid = {0};
+  cbor::Value dpk;
+  unsigned scope = 0;
+  std::vector<uint8_t> nonce;
+  std::string attestation_format;
+  cbor::Value attestation;
+  bool enterprise_attestation_returned = false;
+};
+
+// CheckDevicePublicKeyExtensionForErrors checks that `extension_value` is a
+// sensible extension response given that `requested_attestation` was the DPK
+// attestation level in the request. It returns an error message on failure
+// or `absl::nullopt` on success.
+absl::optional<const char*> CheckDevicePublicKeyExtensionForErrors(
+    const cbor::Value& extension_value,
+    AttestationConveyancePreference requested_attestation);
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_DEVICE_PUBLIC_KEY_EXTENSION_H_
diff --git a/device/fido/device_response_converter.cc b/device/fido/device_response_converter.cc
index 6bd096a..cdba2d71 100644
--- a/device/fido/device_response_converter.cc
+++ b/device/fido/device_response_converter.cc
@@ -115,6 +115,25 @@
         base::make_span<kLargeBlobKeyLength>(it->second.GetBytestring()));
   }
 
+  it = decoded_map.find(CBOR(0x06));
+  if (it != decoded_map.end()) {
+    if (!it->second.is_map()) {
+      return absl::nullopt;
+    }
+    const auto& unsigned_extension_outputs_map = it->second.GetMap();
+    for (const auto& map_it : unsigned_extension_outputs_map) {
+      if (!map_it.first.is_string()) {
+        return absl::nullopt;
+      }
+      if (map_it.first.GetString() == kExtensionDevicePublicKey) {
+        if (!map_it.second.is_bytestring()) {
+          return absl::nullopt;
+        }
+        response.device_public_key_signature = map_it.second.GetBytestring();
+      }
+    }
+  }
+
   return response;
 }
 
@@ -193,6 +212,25 @@
            response.large_blob_key->size());
   }
 
+  it = response_map.find(CBOR(0x08));
+  if (it != response_map.end()) {
+    if (!it->second.is_map()) {
+      return absl::nullopt;
+    }
+    const auto& unsigned_extension_outputs_map = it->second.GetMap();
+    for (const auto& map_it : unsigned_extension_outputs_map) {
+      if (!map_it.first.is_string()) {
+        return absl::nullopt;
+      }
+      if (map_it.first.GetString() == kExtensionDevicePublicKey) {
+        if (!map_it.second.is_bytestring()) {
+          return absl::nullopt;
+        }
+        response.device_public_key_signature = map_it.second.GetBytestring();
+      }
+    }
+  }
+
   return response;
 }
 
diff --git a/device/fido/fido_authenticator.cc b/device/fido/fido_authenticator.cc
index c660eaf..6b1ec03 100644
--- a/device/fido/fido_authenticator.cc
+++ b/device/fido/fido_authenticator.cc
@@ -227,4 +227,8 @@
   return false;
 }
 
+bool FidoAuthenticator::SupportsDevicePublicKey() const {
+  return false;
+}
+
 }  // namespace device
diff --git a/device/fido/fido_authenticator.h b/device/fido/fido_authenticator.h
index 5fccf5e..18257a1 100644
--- a/device/fido/fido_authenticator.h
+++ b/device/fido/fido_authenticator.h
@@ -301,6 +301,7 @@
   virtual bool SupportsHMACSecretExtension() const;
   virtual bool SupportsEnterpriseAttestation() const;
   virtual bool SupportsCredBlobOfSize(size_t num_bytes) const;
+  virtual bool SupportsDevicePublicKey() const;
   virtual const absl::optional<AuthenticatorSupportedOptions>& Options()
       const = 0;
   virtual absl::optional<FidoTransportProtocol> AuthenticatorTransport()
diff --git a/device/fido/fido_constants.cc b/device/fido/fido_constants.cc
index 94c10a5..aa8e403 100644
--- a/device/fido/fido_constants.cc
+++ b/device/fido/fido_constants.cc
@@ -76,6 +76,15 @@
 const char kExtensionLargeBlobKey[] = "largeBlobKey";
 const char kExtensionCredBlob[] = "credBlob";
 const char kExtensionMinPINLength[] = "minPinLength";
+const char kExtensionDevicePublicKey[] = "devicePubKey";
+
+const char kDevicePublicKeyAttestationKey[] = "attestation";
+const char kDevicePublicKeyAttestationFormatsKey[] = "attestationFormats";
+const char kDevicePublicKeyAAGUIDKey[] = "aaguid";
+const char kDevicePublicKeyDPKKey[] = "dpk";
+const char kDevicePublicKeyScopeKey[] = "scope";
+const char kDevicePublicKeyNonceKey[] = "nonce";
+const char kDevicePublicKeyEPKey[] = "epAtt";
 
 const base::TimeDelta kBleDevicePairingModeWaitingInterval = base::Seconds(2);
 
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h
index 0e9357c..f61522b1 100644
--- a/device/fido/fido_constants.h
+++ b/device/fido/fido_constants.h
@@ -452,6 +452,18 @@
 COMPONENT_EXPORT(DEVICE_FIDO) extern const char kExtensionLargeBlobKey[];
 COMPONENT_EXPORT(DEVICE_FIDO) extern const char kExtensionCredBlob[];
 COMPONENT_EXPORT(DEVICE_FIDO) extern const char kExtensionMinPINLength[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kExtensionDevicePublicKey[];
+
+// Map keys for the device public key extension.
+COMPONENT_EXPORT(DEVICE_FIDO)
+extern const char kDevicePublicKeyAttestationKey[];
+COMPONENT_EXPORT(DEVICE_FIDO)
+extern const char kDevicePublicKeyAttestationFormatsKey[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kDevicePublicKeyAAGUIDKey[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kDevicePublicKeyDPKKey[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kDevicePublicKeyScopeKey[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kDevicePublicKeyNonceKey[];
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kDevicePublicKeyEPKey[];
 
 // Maximum number of seconds the browser waits for Bluetooth authenticator to
 // send packets that advertises that the device is in pairing mode before
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc
index e1d431c..5eaa8644 100644
--- a/device/fido/fido_device_authenticator.cc
+++ b/device/fido/fido_device_authenticator.cc
@@ -1086,6 +1086,14 @@
          num_bytes <= get_info_response->max_cred_blob_length.value();
 }
 
+bool FidoDeviceAuthenticator::SupportsDevicePublicKey() const {
+  const absl::optional<AuthenticatorGetInfoResponse>& get_info_response =
+      device_->device_info();
+  return get_info_response && get_info_response->extensions &&
+         base::Contains(*get_info_response->extensions,
+                        kExtensionDevicePublicKey);
+}
+
 const absl::optional<AuthenticatorSupportedOptions>&
 FidoDeviceAuthenticator::Options() const {
   return options_;
diff --git a/device/fido/fido_device_authenticator.h b/device/fido/fido_device_authenticator.h
index 9b97e6ec..50e24511 100644
--- a/device/fido/fido_device_authenticator.h
+++ b/device/fido/fido_device_authenticator.h
@@ -133,6 +133,7 @@
   bool SupportsHMACSecretExtension() const override;
   bool SupportsEnterpriseAttestation() const override;
   bool SupportsCredBlobOfSize(size_t num_bytes) const override;
+  bool SupportsDevicePublicKey() const override;
   const absl::optional<AuthenticatorSupportedOptions>& Options() const override;
   absl::optional<FidoTransportProtocol> AuthenticatorTransport() const override;
   bool IsInPairingMode() const override;
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc
index 292e0ea..ebb13b08 100644
--- a/device/fido/get_assertion_request_handler.cc
+++ b/device/fido/get_assertion_request_handler.cc
@@ -21,6 +21,7 @@
 #include "components/cbor/diagnostic_writer.h"
 #include "components/device_event_log/device_event_log.h"
 #include "device/fido/cable/fido_cable_discovery.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/discoverable_credential_metadata.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_authenticator.h"
@@ -124,6 +125,18 @@
       if (!request.get_cred_blob || !it.second.is_bytestring()) {
         return false;
       }
+    } else if (ext_name == kExtensionDevicePublicKey) {
+      if (!request.device_public_key) {
+        FIDO_LOG(ERROR) << "unsolicited devicePubKey extension output";
+        return false;
+      }
+      const absl::optional<const char*> error =
+          CheckDevicePublicKeyExtensionForErrors(
+              it.second, request.device_public_key->attestation);
+      if (error.has_value()) {
+        FIDO_LOG(ERROR) << error.value();
+        return false;
+      }
     } else {
       // Authenticators may not return unknown extensions.
       return false;
@@ -200,6 +213,15 @@
     return false;
   }
 
+  const bool has_dpk_extension =
+      extensions &&
+      extensions->GetMap().count(cbor::Value(kExtensionDevicePublicKey));
+  if (has_dpk_extension != response.device_public_key_signature.has_value()) {
+    FIDO_LOG(ERROR)
+        << "DPK extension isn't coherent with presence of DPK signature";
+    return false;
+  }
+
   return true;
 }
 
@@ -268,6 +290,9 @@
   if (request.get_cred_blob && !authenticator.SupportsCredBlobOfSize(0)) {
     specialized_request.get_cred_blob = false;
   }
+  if (request.device_public_key && !authenticator.SupportsDevicePublicKey()) {
+    specialized_request.device_public_key.reset();
+  }
   return specialized_request;
 }
 
diff --git a/device/fido/make_credential_request_handler.cc b/device/fido/make_credential_request_handler.cc
index 3d7b1cc..db44e2d9 100644
--- a/device/fido/make_credential_request_handler.cc
+++ b/device/fido/make_credential_request_handler.cc
@@ -18,6 +18,7 @@
 #include "build/chromeos_buildflags.h"
 #include "components/cbor/diagnostic_writer.h"
 #include "components/device_event_log/device_event_log.h"
+#include "device/fido/device_public_key_extension.h"
 #include "device/fido/fido_authenticator.h"
 #include "device/fido/fido_discovery_factory.h"
 #include "device/fido/fido_parsing_utils.h"
@@ -308,6 +309,18 @@
       if (!request.min_pin_length_requested || !it.second.is_unsigned()) {
         return false;
       }
+    } else if (ext_name == kExtensionDevicePublicKey) {
+      if (!request.device_public_key) {
+        FIDO_LOG(ERROR) << "unsolicited devicePubKey extension output";
+        return false;
+      }
+      const absl::optional<const char*> error =
+          CheckDevicePublicKeyExtensionForErrors(
+              it.second, request.device_public_key->attestation);
+      if (error.has_value()) {
+        FIDO_LOG(ERROR) << error.value();
+        return false;
+      }
     } else {
       // Authenticators may not return unknown extensions.
       return false;
@@ -338,6 +351,15 @@
     return false;
   }
 
+  const bool has_dpk_extension =
+      extensions &&
+      extensions->GetMap().count(cbor::Value(kExtensionDevicePublicKey));
+  if (has_dpk_extension != response.device_public_key_signature.has_value()) {
+    FIDO_LOG(ERROR)
+        << "DPK extension isn't coherent with presence of DPK signature";
+    return false;
+  }
+
   if (response.enterprise_attestation_returned &&
       (request.attestation_preference !=
            AttestationConveyancePreference::
@@ -1046,6 +1068,10 @@
       !authenticator->SupportsCredBlobOfSize(request->cred_blob->size())) {
     request->cred_blob.reset();
   }
+
+  if (request->device_public_key && !authenticator->SupportsDevicePublicKey()) {
+    request->device_public_key.reset();
+  }
 }
 
 }  // namespace device
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc
index 591b1ac..7059ffd 100644
--- a/device/fido/virtual_ctap2_device.cc
+++ b/device/fido/virtual_ctap2_device.cc
@@ -163,7 +163,8 @@
     base::span<const uint8_t> signature,
     AuthenticatorData authenticator_data,
     bool enterprise_attestation_requested,
-    absl::optional<std::array<uint8_t, kLargeBlobKeyLength>> large_blob_key) {
+    absl::optional<std::array<uint8_t, kLargeBlobKeyLength>> large_blob_key,
+    const absl::optional<std::vector<uint8_t>>& dpk_signature) {
   cbor::Value::MapValue attestation_map;
   attestation_map.emplace("alg", -7);
   attestation_map.emplace("sig", fido_parsing_utils::Materialize(signature));
@@ -185,6 +186,8 @@
   if (large_blob_key) {
     make_credential_response.set_large_blob_key(*large_blob_key);
   }
+  make_credential_response.device_public_key_signature =
+      std::move(dpk_signature);
   return AsCTAPStyleCBORBytes(make_credential_response);
 }
 
@@ -437,7 +440,14 @@
     response_map.emplace(6, true);
   }
   if (response.large_blob_key) {
-    response_map.emplace(0x07, cbor::Value(*response.large_blob_key));
+    response_map.emplace(7, cbor::Value(*response.large_blob_key));
+  }
+  if (response.device_public_key_signature) {
+    cbor::Value::MapValue unsigned_extension_outputs;
+    unsigned_extension_outputs.emplace(
+        kExtensionDevicePublicKey,
+        cbor::Value(*response.device_public_key_signature));
+    response_map.emplace(8, cbor::Value(std::move(unsigned_extension_outputs)));
   }
 
   return WriteCBOR(cbor::Value(std::move(response_map)), allow_invalid_utf8);
@@ -623,6 +633,10 @@
     extensions.emplace_back(device::kExtensionMinPINLength);
   }
 
+  if (config.device_public_key_support) {
+    extensions.emplace_back(device::kExtensionDevicePublicKey);
+  }
+
   if (!extensions.empty()) {
     device_info_->extensions.emplace(std::move(extensions));
   }
@@ -1013,6 +1027,61 @@
   return CtapDeviceResponseCode::kSuccess;
 }
 
+absl::optional<cbor::Value> VirtualCtap2Device::HandleDevicePublicKey(
+    const DevicePublicKeyRequest& request,
+    const std::string& rp_id,
+    const uint32_t primary_credential_cose_algorithm,
+    absl::optional<std::unique_ptr<PrivateKey>>* const private_key) {
+  if (!private_key->has_value()) {
+    switch (primary_credential_cose_algorithm) {
+      case static_cast<uint32_t>(CoseAlgorithmIdentifier::kEs256):
+        *private_key = PrivateKey::FreshP256Key();
+        break;
+      case static_cast<uint32_t>(CoseAlgorithmIdentifier::kRs256):
+        *private_key = PrivateKey::FreshRSAKey();
+        break;
+      case static_cast<uint32_t>(CoseAlgorithmIdentifier::kEdDSA):
+        *private_key = PrivateKey::FreshEd25519Key();
+        break;
+      default:
+        CHECK(false) << "Unknown primary credential algorithm";
+        break;
+    }
+  }
+
+  const bool attestation =
+      config_.device_public_key_always_return_attestation ||
+      (request.attestation != AttestationConveyancePreference::kNone &&
+       config_.device_public_key_support_attestation);
+  const bool enterprise_attestation =
+      attestation &&
+      (config_.device_public_key_always_return_enterprise_attestation ||
+       (config_.device_public_key_support_enterprise_attestation &&
+        (request.attestation ==
+             AttestationConveyancePreference::kEnterpriseApprovedByBrowser ||
+         (request.attestation == AttestationConveyancePreference::
+                                     kEnterpriseIfRPListedOnAuthenticator &&
+          base::Contains(config_.enterprise_attestation_rps, rp_id)))));
+
+  static const uint8_t kAAGUID[16] = {0};
+  cbor::Value::MapValue output;
+  output.emplace(
+      kDevicePublicKeyAAGUIDKey,
+      attestation ? kDeviceAaguid : base::span<const uint8_t>(kAAGUID));
+  output.emplace(kDevicePublicKeyDPKKey,
+                 private_key->value()->GetPublicKey()->cose_key_bytes);
+  output.emplace(kDevicePublicKeyScopeKey, 0);
+  output.emplace(kDevicePublicKeyNonceKey, base::span<const uint8_t>());
+  output.emplace(kFormatKey, attestation ? "packed" : "none");
+  output.emplace(kAttestationStatementKey, cbor::Value::MapValue());
+  if (enterprise_attestation) {
+    output.emplace(kDevicePublicKeyEPKey, true);
+  }
+
+  return cbor::Value(
+      cbor::Writer::Write(cbor::Value(std::move(output))).value());
+}
+
 absl::optional<CtapDeviceResponseCode> VirtualCtap2Device::OnMakeCredential(
     base::span<const uint8_t> request_bytes,
     std::vector<uint8_t>* response) {
@@ -1216,6 +1285,24 @@
                            static_cast<int>(mutable_state()->min_pin_length));
   }
 
+  absl::optional<std::unique_ptr<PrivateKey>> device_key;
+  if (request.device_public_key) {
+    if (!config_.device_public_key_support) {
+      DLOG(ERROR) << "Rejecting makeCredential due to unexpected devicePubKey "
+                     "extension";
+      return CtapDeviceResponseCode::kCtap2ErrUnsupportedExtension;
+    }
+    absl::optional<cbor::Value> dpk_result = HandleDevicePublicKey(
+        *request.device_public_key, request.rp.id,
+        private_key->GetPublicKey()->algorithm, &device_key);
+    if (!dpk_result) {
+      return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
+    }
+    if (!config_.device_public_key_drop_extension_response) {
+      extensions_map.emplace(kExtensionDevicePublicKey, std::move(*dpk_result));
+    }
+  }
+
   if (config_.add_extra_extension) {
     extensions_map.emplace(cbor::Value("unsolicited"), cbor::Value(42));
   }
@@ -1232,6 +1319,11 @@
   std::vector<uint8_t> sign_buffer =
       ConstructSignatureBuffer(authenticator_data, request.client_data_hash);
 
+  absl::optional<std::vector<uint8_t>> dpk_sig;
+  if (device_key && !config_.device_public_key_drop_signature) {
+    dpk_sig = device_key.value()->Sign(sign_buffer);
+  }
+
   // Sign with attestation key.
   // Note: Non-deterministic, you need to mock this out if you rely on
   // deterministic behavior.
@@ -1281,7 +1373,7 @@
 
   *response = ConstructMakeCredentialResponse(
       std::move(attestation_cert), sig, std::move(authenticator_data),
-      enterprise_attestation_requested, large_blob_key);
+      enterprise_attestation_requested, large_blob_key, dpk_sig);
   RegistrationData registration(std::move(private_key), rp_id_hash,
                                 1 /* signature counter */);
 
@@ -1306,6 +1398,7 @@
   }
 
   registration.protection = cred_protect;
+  registration.device_key = std::move(device_key);
 
   if (request.hmac_secret) {
     registration.hmac_key.emplace();
@@ -1576,6 +1669,25 @@
           registration.second->cred_blob.value_or(std::vector<uint8_t>()));
     }
 
+    if (request.device_public_key) {
+      if (!config_.device_public_key_support) {
+        DLOG(ERROR) << "Rejecting getAssertion due to unexpected devicePubKey "
+                       "extension";
+        return CtapDeviceResponseCode::kCtap2ErrUnsupportedExtension;
+      }
+      absl::optional<cbor::Value> dpk_result = HandleDevicePublicKey(
+          *request.device_public_key, request.rp_id,
+          registration.second->private_key->GetPublicKey()->algorithm,
+          &registration.second->device_key);
+      if (!dpk_result) {
+        return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
+      }
+      if (!config_.device_public_key_drop_extension_response) {
+        extensions_map.emplace(kExtensionDevicePublicKey,
+                               std::move(*dpk_result));
+      }
+    }
+
     absl::optional<cbor::Value> extensions;
     if (!extensions_map.empty()) {
       extensions.emplace(std::move(extensions_map));
@@ -1586,22 +1698,20 @@
         registration.second->counter, std::move(opt_attested_cred_data),
         std::move(extensions));
 
-    const std::vector<uint8_t> signature_buffer =
-        ConstructSignatureBuffer(authenticator_data, request.client_data_hash);
-
-    std::vector<uint8_t> signature;
+    std::vector<uint8_t> signature_buffer;
     if (config_.always_uv && !user_verified) {
       // Requests without user presence and with up=0 produce bogus signatures.
       DCHECK(!request.user_presence_required);
-      signature =
-          registration.second->private_key->Sign(std::vector<uint8_t>{0});
+      signature_buffer.push_back(0);
     } else {
-      signature = registration.second->private_key->Sign(signature_buffer);
+      signature_buffer = ConstructSignatureBuffer(authenticator_data,
+                                                  request.client_data_hash);
     }
 
-    AuthenticatorGetAssertionResponse assertion(
-        std::move(authenticator_data),
-        fido_parsing_utils::Materialize(signature));
+    const std::vector<uint8_t> signature =
+        registration.second->private_key->Sign(signature_buffer);
+    AuthenticatorGetAssertionResponse assertion(std::move(authenticator_data),
+                                                signature);
 
     bool include_credential;
     switch (config_.include_credential_in_assertion_response) {
@@ -1639,6 +1749,12 @@
       }
     }
 
+    if (request.device_public_key &&
+        !config_.device_public_key_drop_signature) {
+      assertion.device_public_key_signature =
+          registration.second->device_key.value()->Sign(signature_buffer);
+    }
+
     if (!done_first) {
       if (found_registrations.size() > 1) {
         DCHECK_LT(found_registrations.size(), 256u);
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h
index c0a1d0c..f49b01c 100644
--- a/device/fido/virtual_ctap2_device.h
+++ b/device/fido/virtual_ctap2_device.h
@@ -90,6 +90,28 @@
     // transports_in_get_info, if not empty, contains the transports that will
     // be reported via getInfo.
     std::vector<FidoTransportProtocol> transports_in_get_info;
+    // device_public_key_support controls whether the devicePubKey extension is
+    // supported. See https://github.com/w3c/webauthn/pull/1663
+    bool device_public_key_support = false;
+    // device_public_key_support_attestation controls whether a DPK attestation
+    // will ever be returned.
+    bool device_public_key_support_attestation = false;
+    // device_public_key_always_return_attestation causes the DPK response to
+    // always contain an attestation, no matter the request.
+    bool device_public_key_always_return_attestation = false;
+    // device_public_key_enterprise_attestation, if true, causes enterprise
+    // attestation requests to be honoured if the RP ID is in
+    // |enterprise_attestation_rps|.
+    bool device_public_key_support_enterprise_attestation = false;
+    // device_public_key_always_return_attestation causes the DPK response to
+    // always signal that an attestation is an enterprise attestation.
+    bool device_public_key_always_return_enterprise_attestation = false;
+    // device_public_key_drop_extension_response causes the extension output
+    // (but not the signature) to be omitted.
+    bool device_public_key_drop_extension_response = false;
+    // device_public_key_drop_signature causes the signature (but not the
+    // extension output) to be omitted.
+    bool device_public_key_drop_signature = false;
 
     IncludeCredential include_credential_in_assertion_response =
         IncludeCredential::ONLY_IF_NEEDED;
@@ -299,6 +321,11 @@
       UserVerificationRequirement user_verification,
       bool user_presence_required,
       bool* out_user_verified);
+  absl::optional<cbor::Value> HandleDevicePublicKey(
+      const DevicePublicKeyRequest& request,
+      const std::string& rp_id,
+      const uint32_t primary_credential_cose_algorithm,
+      absl::optional<std::unique_ptr<PrivateKey>>* const private_key);
   absl::optional<CtapDeviceResponseCode> OnMakeCredential(
       base::span<const uint8_t> request,
       std::vector<uint8_t>* response);
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h
index 71333bb..cd640958 100644
--- a/device/fido/virtual_fido_device.h
+++ b/device/fido/virtual_fido_device.h
@@ -121,6 +121,10 @@
 
     absl::optional<std::array<uint8_t, 32>> large_blob_key;
     absl::optional<std::vector<uint8_t>> cred_blob;
+
+    // device_bound_key contains the optional device-bound key for this
+    // credential, thus simulating a multi-device credential.
+    absl::optional<std::unique_ptr<PrivateKey>> device_key;
   };
 
   // Stores the state of the device. Since |U2fDevice| objects only persist for
diff --git a/docs/clangd.md b/docs/clangd.md
index ff4326ae..18653160 100644
--- a/docs/clangd.md
+++ b/docs/clangd.md
@@ -8,7 +8,7 @@
 
 ## Quick Start
 
-* **Googlers**: clangd is available by default on glinux (`/usr/bin/clangd`)
+* [Get clangd](#getting-clangd)
 * Make sure generated ninja files are up-to-date
 * Optional: build chrome normally to get generated headers
 * Generate compilation database (note: it's not regenerated automatically):
@@ -24,25 +24,44 @@
 
 ## Getting clangd
 
-See [instructions](https://clangd.llvm.org/installation.html#installing-clangd).
+For the best results, you should use a clangd that exactly matches the version
+of Clang used by Chromium. This avoids problems like mismatched versions of
+compiler diagnostics.
 
-**Googlers:** clangd has been installed on your glinux by default, just use
-`/usr/bin/clangd`.
+The easiest way to do this is to set the `checkout_clangd` var in `.gclient`:
 
-Alternative: download clangd from the official [Releases](https://github.com/clangd/clangd/releases)
-page.
+```
+solutions = [
+  {
+    "url": "https://chromium.googlesource.com/chromium/src.git",
+    "managed": False,
+    "name": "src",
+    "custom_deps": {},
+    "custom_vars": {
+      "checkout_clangd": True,
+    },
+  },
+]
+```
 
-Note: clangd 10.0.0 does not work with Chromium; use one of the more recent
-pre-release versions of 11 or later on the Releases page.
+After this, `gclient` will keep the binary at
+`third_party/llvm-build/Release+Asserts/bin/clangd` in sync with the version of
+Clang used by Chromium.
 
-If you prefer to build clangd locally, use the following command to build from
-LLVM source, and you will get the binary at
-`out/Default/tools/clang/third_party/llvm/build/bin/clangd`.
+Alternatively, you may use the `build_clang_tools_extra.py` script to build
+clangd from source:
 
 ```
 tools/clang/scripts/build_clang_tools_extra.py --fetch out/Default clangd
 ```
 
+The resulting binary will be at
+`out/Default/tools/clang/third_party/llvm/build/bin/clangd`.
+
+Once you have an appropriate clangd binary, you must configure your editor to
+use it, either by placing it first on your `PATH`, or through editor-specific
+configuration.
+
 ## Setting Up
 
 1. Make sure generated ninja files are up-to-date.
diff --git a/docs/security/updates.md b/docs/security/updates.md
index 6004728..09742f4f 100644
--- a/docs/security/updates.md
+++ b/docs/security/updates.md
@@ -1,5 +1,7 @@
 # Chrome Security Update FAQ
 
+_Bookmark this page as https://g.co/chrome/security-update-faq_
+
 ## TL:DR
 
 Almost all Chrome updates contain security fixes, and should be prioritized
diff --git a/docs/updater/design_doc.md b/docs/updater/design_doc.md
index 51c724c6..3bcdbcc0 100644
--- a/docs/updater/design_doc.md
+++ b/docs/updater/design_doc.md
@@ -4,29 +4,25 @@
 
 [TOC]
 
-## Objective
-The objective is to create an updater for desktop client software using Chromium
-code and tools. The updater is an open-source drop-in replacement for Google
-Update/Omaha and can be customized by 3rd party embedders for updating
-non-Google client software.
-
-The desktop platforms include Windows, macOS, Linux.
-
 ## Overview
+Chromium updater is an program that keeps itself and other programs up to date
+by downloading new versions of software over the Internet. The updater is an
+open-source drop-in replacement for Google Update/Omaha and can be customized
+by 3rd party embedders for updating non-Google client software.
+
 The updater is responsible for:
-*   Installing applications. (On applicable platforms.)
-*   Automatically and silently keeping those applications (and itself)
-    up-to-date.
+*   Installing applications.
+*   Silently keeping those applications (and itself) up-to-date.
 *   Providing those applications with services to manage their installation.
 *   Providing update servers with anonymous telemetry about those applications.
 *   Detecting the uninstallation of those applications, and automatically
     removing itself when all other applications have been uninstalled.
 
-The behavior of the updater is mostly platform-independent. However, platform-
-specific modules exist to translate cross-platform concepts (such as IPC
-interfaces) to platform-specific technologies (such as COM or XPC).
-Additionally, some updater behavior related to installs and uninstalls are
-tailored to platform conventions.
+The updater is written for Windows, macOS, Linux. The behavior of the updater
+is mostly platform-independent. However, platform-specific modules exist to
+translate cross-platform concepts (such as IPC interfaces) to platform-specific
+technologies (such as COM or XPC). Additionally, some updater behavior related
+to installs and uninstalls are tailored to platform conventions.
 
 The updater is layered atop //components/update\_client, which implements a
 cross-platform mechanism to interact with an Omaha server for the purpose of
@@ -38,7 +34,7 @@
 instructions. It applies updates the server instructs it to, and then reports
 the results of the operation back to Omaha servers.
 
-## Detailed Design
+## Updater Design
 Once installed, the updater operates as a collection of processes that are
 launched on-demand and orchestrate their operations over IPC. The *server
 process* hosts an engine that conducts most of the work of updating software,
@@ -54,7 +50,7 @@
 installed system-wide, owned by root (or the system user) and run by individual
 users, but this requires the updater to maintain root privileges in order to
 update it. Therefore, in a system-wide installation, the server process runs as
-root (or at high integrity). A system-wide installation of the updater and any
+root (or at high integrity). One system-wide installation of the updater and any
 number of per-user installations of the updater can coexist and operate
 independently on the same system.
 
@@ -84,13 +80,249 @@
     macOS.)
 *   The updater downloads an update for itself and installs it.
 
+#### Updater States
+![Updater state flowchart](images/updater_states.svg)
+
+Only one instance per installation is `Active` at any time. Only the active
+instance is allowed to update applications or modify any of the updater's state.
+The state of the updater (including the list of applications registered for
+updates, the time of the last update check, and more) is stored in a "global
+prefs" file. Access to the global prefs file is protected by a global
+(cross-process) lock.
+
+Each instance of the updater also has its own separate local prefs file. Local
+prefs store information specific to the instance that owns them.
+
+##### Qualification
+Instances are installed in the `Unqualified` state. Unqualified instances of
+the updater perform a self-test before activating. Each instance registers a
+"qualification app" with itself (using local prefs) and checks the Internet for
+updates to that application. The Internet responds with an update, which the
+updater downloads and applies. If this all succeeds, the updater transitions to
+the `Qualified` state and exits.
+
+The qualification app installer is a no-op installer that simply exits with no
+error, but could be customized in the future to do additional checks.
+
+Qualification is skipped (along with any other pre-active states) if there is
+no active instance of the updater.
+
+##### Activation
+When an instance transitions to the active state, it acquires the updater's
+lock on the global prefs file, writes and flushes the "swapping" bit to that
+prefs file, and then replaces any non-side-by-side elements of the installation
+(such as COM or launchd registrations, Omaha 3 or Keystone shims, and more)
+with its own. Then, it clears the "swapping" bit, flushes the prefs file again,
+and starts listening for instructions on the RPC channels. The swapping bit
+ensures that the an updater will recover and restart activation if the program
+is interrupted mid-activation.
+
+##### Deactivation
+When a newer instance of the updater activates, formerly active instances will
+discover that they have been replaced when they start up. These instances
+uninstall themselves.
+
+##### Locking
+Read and write access to the global prefs file is controlled by a lock. The lock
+must also be held while the updater performs any non-side-by-side operation
+(such as installing an update for a registered application). The lock is per-
+process. The updater uses a polling strategy to acquire the lock, sleeping for
+a short time between polls.
+
+### Installing Applications
+Applications are installed by the active updater instance primarily by
+downloading application-specific installer executables from the Internet and
+running them. The updater passes the installer certain arguments or environment
+variables depending on the instructions received from the Internet and reads the
+installer's exit code as an indicator of success or failure. On some platforms,
+more sophisticated APIs to communicate installer progress or error codes are
+available.
+
+Fetching the application installer from the Internet ensures that the user gets
+the latest version of the application. But in some cases it is better to install
+applications without a dependency on the Internet. Therefore, some applications
+offer "offline" installers. These offline installers are wrapped in an updater
+installer. They install the updater, place the application installer on the
+disk in a secure location, and then act as a client and instruct the updater
+server to run the application installer.
+
+During the installation process, the updater displays a UI that communicates
+the installation progress to the user. The language of the UI is based on the
+system's primary langague.
+
+In some scenarios, the application has already been installed on the system by
+another mechanism, but needs to register itself with the updater. The updater
+exposes a registration API that allow applications to register themselves as
+present on the system with the updater.
+
+Regardless of how the application is installed or registered, at the end of the
+process the updater knows the application's identity, current version, brand
+code (if any), and has a means to check whether the application has been
+uninstalled (an existence checker).
+
+### Updating Applications
+Each instance of the updater has its own timed scheduler that invokes the
+updater to check for updates. The scheduler creates a `--wake` client every
+hour, which invokes the `RunPeriodicTasks` RPC on the corresponding server.
+
+If the server is inactive, it qualifies, activates, or uninstalls, as
+described above. If the server is active, it checks that registered applications
+are still installed, updates enterprise policies, and potentially checks for
+updates. The updater will not check for updates if the last check was less than
+five hours ago. (This period can be altered by enterprise policy and is
+subject to some randomization to avoid synchronized load on the Internet.)
+
+#### Telemetry
+To keep the updater simple, the decision about whether to apply an update or not
+is made remotely. Updaters contact Internet servers and provide them with
+information about the registered applications, operating system, hardware
+capabilities, and more, and trust the server's response about whether to apply
+an update, using the [Omaha Protocol](protocol_3_1.md).
+
+Applications may signal the updater when they are actively used using a
+platform-specific "Actives API". Updaters will transmit to the server whether
+or not each application has been actively used since the previous communication
+in order to enable the server to compute aggregate and anonymous counts of the
+population of users.
+
+Updaters also report the outcome of any installations or updates, including
+error codes, download attempts, and timing to the server. Servers may use this
+information to detect problems with updates, cease serving bad installers, or
+balance load among multiple download sources.
+
+Some telemetry is guarded behind usage-stats opt-in. If the user has opted-in
+to transmitting crash reports and usage stats for any software registered with
+the updater, the updater will transmit its own usage stats and crash reports as
+well.
+
+### Uninstalling Applications
+The updater detects the uninstallation of applications by using existence
+checkers registered with the updater at installation or registration. When an
+application is uninstalled, the updater transmits an uninstall ping to the
+Internet recording the uninstallation.
+
+When all managed applications are uninstalled, the updater will uninstall
+itself, leaving behind only a log file. Applications may trigger immediate
+uninstallation of the updater by running an updater `--wake` client.
+
+Additionally, the updater can be uninstalled by hand using `--uninstall`, even
+if registered applications are still present.
+
+## Advanced Topics
+
+### Recovering the Updater
+To avoid a single point of failure in the update system, some applications have
+a backup updater build into the application that is capable of reinstalling the
+updater. Google Chrome contains a "Recovery Component" that is capable of
+downloading and reinstalling a new version of the updater if a problem with the
+updater is detected or if the version of Chrome becomes too old.
+
+For system-wide installations, recovery must be performed at high integrity.
+Google Chrome installs an
+[elevator service](../../chrome/elevation_service/README.md) for this purpose.
+
+### UI Strings & Localization
+The strings for the metainstaller live in the //chrome/app/chromium_strings.grd
+and //chrome/app/google_chrome_strings.grd files. This allows the updater
+strings to utilize the Chromium repo's translation process instead of generating
+its own. Having it in existing grd files also eliminates the need to onboard
+updater specific grd files.
+
+During the build process, the updater strings are embedded directly into the
+metainstaller binary via `generate_embedded_i18n`. `generate_embedded_i18n` also
+allows an `extractor_datafile`, which can define specific strings to pick out
+from the originating grd file. This way, the metainstaller only has the strings
+specific to the updater and not any of the other strings within the grd file.
+When the `generate_embedded_i18n` is complete, it generates an
+`updater_installer_strings.h` header, which contains macro definitions of the
+message ids and the offsets. The strings are mapped with their var name appended
+with `_BASE`. Then the  `_BASE` appended macros are defined to be the first
+localization id in the list, in which case it is `_AF`.
+
+An example from the `updater_installer_strings.h`
+```
+#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AF 1600
+#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AM 1601
+
+...
+
+#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AF
+
+...
+
+#define DO_STRING_MAPPING \
+  HANDLE_STRING(IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE, IDS_BUNDLE_INSTALLED_SUCCESSFULLY) \
+```
+
+Within the metainstaller, an l10_util.h/cc has three functions to get localized
+strings.
+```
+GetLocalizedString(int base_message_id)
+GetLocalizedStringF(int base_message_id, const std::wstring& replacement)
+GetLocalizedStringF(int base_message_id, std::vector<std::wstring> replacements)
+```
+
+One function for getting the literal string and two functions to get formatted
+strings. `GetLocalizedString()` uses the base id plus the offset based on the
+language to look through the binary's string table to get the correct, localized
+string. The formatted strings utilize GetLocalizedString() to get the string and
+then uses `base::ReplaceStringPlaceholders()` to remove the `$i` placeholders
+within the string. With regards to picking the correct language to utilize for
+the localized string, `base::win::i18n::GetUserPreferredUILanguageList()` is
+used to get the preferred UI languages from MUI. If there are multiple languages
+in the list, the first language in the list is picked.
+
+## Testing
+In addition to unit testing individual sections of code, the updater provides
+integration tests that install and manipulate the updater on the system running
+the test.
+
+Testing is possible by programmatically controlling certain parameters of the
+updater. These parameters are hardcoded in the production builds but they can
+be modified in test builds. For this reason, the updater build scripts define
+two separate set of targets. One target produces binaries suitable to
+releasing. The other target produces test binaries, which are suffixed by
+`_test`. The test binaries link the test hooks code, which slightly alters the
+behavior of the updater to facilitate testing it.
+
+Some tests require two versions of the updater. For this reason, an older
+version of the updater is checked into `//third_party/updater`. Updaters for
+each architecture and platform, Google-branded and Chromium-branded, are
+available there. These versions of the updater are sourced from Chromium or
+Google's official build output, brought in through CIPD and 3pp.
+
+The updater has its own
+[console page](https://ci.chromium.org/p/chromium/g/chromium.updater/console),
+which describes the set of continuous integration builders.
+
+## Release
+The updater is built by Chrome's official builders and uploaded to the
+unsigned builds bucket along with Chrome. It is versioned along with Chrome. The
+primary build output is `updater.zip`, which contains the updater executables,
+the signing scripts, and other updater-related artifacts.
+
+Google's signing infrastructure unpacks the updater.zip and operates on it to
+generate signed executables, which are then released through Omaha similar to
+Chrome.
+
+TODO(crbug.com/1035895): Decide on and document branching & versioning.
+
+TODO(crbug.com/1035895): Document A/B release qualification process.
+
+## Tools
+TODO(crbug.com/1035895): Document tagger.
+
+## Windows-Specific Notes
+
+### Installer
+
 #### Updater Installer Types
-The updater is distributed via the following installer types:
+Windows updater installers come in two types:
 *   Online Installers
 *   Offline Installers
 
 ##### Online Installers
-An online installer installs the updater and then acts as a client process and
+An online installer installs the updater and then acts as a client process that
 commands the server process to install the application the user desired.
 
 Online installers are composed of three parts: a *tag*, a *metainstaller*, and
@@ -101,12 +333,6 @@
 executable which communicates the installation parameters for the software the
 user is trying to install.
 
-###### Tagging
-TODO(crbug.com/1035895): Document tagging format, process, contents.
-
-###### Updater Resource Extraction
-TODO(crbug.com/1035895): Document updater resource compression.
-
 Online installers are typically run by the end user after being downloaded from
 the Internet. When the installer is executed, the OS launches it at
 [medium integrity](https://docs.microsoft.com/en-us/windows/win32/secauthz/mandatory-integrity-control).
@@ -138,8 +364,7 @@
            /sessionid "{E85204C6-6F2F-40BF-9E6C-4952208BB977}"
            /offlinedir "C:\Users\chrome-bot\AppData\Local\ForgedPath"]
 ```
-Please note DOS style command line switch is also supported for backward
-compatibility.
+DOS style command line switches are also supported for backward compatibility.
 
 ##### Manifest file
 The offline install process looks for `OfflineManifest.gup` in the
@@ -189,107 +414,6 @@
 data. That means the install data is extracted and passed to the app
 installer. See [installdataindex](#installdataindex) below for details.
 
-TODO(crbug.com/1035895): Document the standalone installer.
-
-TODO(crbug.com/1035895): Document bundling the updater with apps.
-
-#### Updater States
-![Updater state flowchart](images/updater_states.svg)
-
-Instances are installed in the `Unqualified` state. Whenever an instance’s
-server starts up, it checks whether it should transition to a new state. Only
-the server instance in the `Active` state is permitted to make changes to the
-various applications managed by the updater. When an updater enters the
-`Active` state, previously active updaters will discover when they next start
-up that they should transition out of the `Active` state and uninstall
-themselves.
-
-##### Qualification
-Before activating, unqualified instances of the updater first perform a
-self-test. The instance registers a "qualification app" with itself and checks
-for updates to that application with the production update server. The
-production server responds with an update, and the updater downloads the update
-and applies it, running the qualification app installer. If this all succeeds,
-the updater transitions to the qualified state and exits.
-
-The qualification app installer is a no-op installer that simply exits with no
-error.
-
-Qualification is skipped (along with any other pre-active states) if there is
-no active instance of the updater.
-
-##### Activation
-When an instance transitions to the active state, it acquires the lock on the
-global prefs file, writes and flushes the "swapping" bit to the file, and then
-replaces any non-side-by-side elements of the installation (such as COM or
-launchd registrations, Omaha 3 or Keystone shims, and more) with its own. Then,
-it clears the "swapping" bit and starts listening for instructions on the RPC
-channels. The swapping bit ensures that the an updater will recover and repair
-the system even if the program is interrupted mid-activation. The full algorithm
-is:
-
-```
-on_startup:
-  acquire_scoped_global_prefs_lock()
-
-  if global_prefs.has_active_version():
-    if global_prefs.active_version > this_version:
-      uninstall_self()
-      exit
-    if !local_prefs.qualified:
-      if qualify():
-        local_prefs.qualified = true
-      exit
-    if this_version > global_prefs.active_version or global_prefs.swapping:
-      activate()
-  else
-    activate()
-
-activate:
-  global_prefs.swapping = true
-  global_prefs.flush()
-  replace_active_version()
-  if !global_prefs.imported_legacy_updaters:
-    import_data_from_legacy_updaters()
-    global_prefs.imported_legacy_updaters = true
-  global_prefs.active_version = this.version
-  global_prefs.swapping = false
-  global_prefs.flush()
-```
-
-##### Storage
-The updater maintains its state in a set of "prefs" files, which are
-dictionaries serialized to the disk as JSON.
-
-The global prefs file is shared across all instances of the updater. It contains
-data about the registered applications and the active updater's state.
-
-Each instance of the updater also has its own separate local prefs file. Local
-prefs store information specific to the instance that owns them.
-
-##### Locking
-Read and write access to the global prefs file is controlled by a lock. The lock
-must also be held while the updater performs any non-side-by-side operation
-(such as installing an update for a registered application). The lock is per-
-process. The updater will periodically poll for the lock, sleeping for a short
-time between polls.
-
-On Windows, the lock is implemented as a kernel mutex.
-
-On macOS, the lock is implemented using `bootstrap_check_in()`, interpreting
-ownership of receive rights on a Mach service name as ownership of a lock.
-
-### Installing Applications
-TODO(crbug.com/1035895): Describe app installs.
-
-TODO(crbug.com/1035895): Describe installer APIs (per platform).
-
-TODO(crbug.com/1035895): Document UI, accessibility, internationalization.
-
-TODO(crbug.com/1035895): Document relevant enterprise policies.
-
-TODO(crbug.com/1035895): Document registration API.
-
 #### Dynamic Install Parameters
 
 ##### `needsadmin`
@@ -481,18 +605,63 @@
 * This installerdata is not persisted anywhere else, and it is not sent as a
 part of pings to the update server.
 
-### Updating Applications
-For every updater install, there is a timed scheduler that invokes the updater
-to check for updates. The default period is for the scheduler to call `--wake`
-on the updater every hour. Once the updater wakes, it will check if it has been
-long enough since the last update check to try again. The default is every 5
-hours to do an update check.
 
-#### Windows
+### Locking
+On Windows, the global prefs lock is implemented as a kernel mutex.
+
+### Application Commands
+
+The Application Command feature allows installed Updater-managed applications to
+pre-register and then later run command lines. This provides applications in a
+system-wide installation a mechanism to silently elevate functionality. The
+command lines can also include replaceable parameters substituted at runtime.
+
+For legacy reasons:
+* the interface is called `IAppCommandWeb` because it was meant to be used from
+an ActiveX control on a webpage at one point, and
+* it is derived from `IDispatch` for the same reason, to be used from script.
+
+For more information, please see the
+[functional spec](functional_spec.md#Application-Commands).
+
+### Existence Checking
+On Windows, programs create a key at
+`(HKLM|HKCU)\\Software\\Company\\Update\\Clients\\AppID` during installation.
+They remove this key when their uninstallers are run. If the key has been
+removed, the updater considers the application to have been uninstalled.
+
+### Periodic Task Scheduling
 Windows utilizes the Task Scheduler and the Windows Task Scheduler API to create
 a scheduler.
 
-#### Mac
+### Legacy State
+TODO(crbug.com/1035895): Document usage of O3 registry on Windows.
+
+#### IPC
+TODO(crbug.com/1035895): Document COM.
+
+### Network
+On Windows, the updater uses WinHTTP to implement the network.
+
+## macOS-Specific Notes
+
+### Installer
+On macOS, the updater is most commonly bundled within an application's .app
+bundle and installed on the first run of the application.
+
+### Locking
+On macOS, the global prefs lock is implemented using `bootstrap_check_in()`,
+interpreting ownership of receive rights on a Mach service name as ownership of
+a lock.
+
+### Existence Checking
+On POSIX, the most common means of uninstalling a program is to delete the
+program's application bundle from disk. When a program registers itself with
+the updater, it provides the path to the application bundle. If the bundle has
+been removed (or is owned by a user different from the updater), the updater
+considers it uninstalled and ceases attempting to update it.
+
+### Periodic Task Scheduling
 On Mac, the scheduler is implemented via LaunchAgents (for user-level installs)
 and LaunchDaemons (for system-level installs). The scheduled task is defined by
 the `org.chromium.ChromiumUpdater.wake.1.2.3.4.plist`, which contains a Label
@@ -524,42 +693,10 @@
 </plist>
 ```
 
-TODO(crbug.com/1035895): Document differential updates.
-
-TODO(crbug.com/1035895): Document recovery.
-
-TODO(crbug.com/1035895): Document actives API & user count telemetry.
-
-TODO(crbug.com/1035895): Document relevant enterprise policies.
-
-TODO(crbug.com/1035895): Document ticket promotion (macOS).
-
-TODO(crbug.com/1035895): Document usage-stats opt-in.
-
-TODO(crbug.com/1035895): Document EULA/ToS acceptance.
-
-### Uninstalling Applications
-TODO(crbug.com/1035895): Document uninstallation API.
-
-TODO(crbug.com/1035895): Document file-based existence checker on macOS.
-
-TODO(crbug.com/1035895): Document registry-based existence checker on Windows.
-
-TODO(crbug.com/1035895): Document updater uninstallation.
-
-### Advanced Topics
-
-#### State
-TODO(crbug.com/1035895): Document prefs (global & local).
-
-TODO(crbug.com/1035895): Document usage of registry on Windows.
-
+### Legacy State
 TODO(crbug.com/1035895): Document usage of Keystone tickets on macOS.
 
-#### IPC
-TODO(crbug.com/1035895): Document COM.
-
-##### XPC
+### IPC
 On Mac, the IPC utilized for the updater is XPC, which is the macOS native IPC
 system controlled by launchd. The main portion to utilize XPC is to create
 launch agent plists under `${HOME}/Library/LaunchAgents` for user level installs
@@ -589,116 +726,5 @@
 Helper tool is installed, the browser can make an XPC connection to it and
 invoke a call to start the system-level updater installation process.
 
-TODO(crbug.com/1035895): Document any IPC fallbacks that exist.
-
-#### Network
-TODO(crbug.com/1035895): Document network stack (per platform).
-
-TODO(crbug.com/1035895): Document CUP.
-
-TODO(crbug.com/1035895): Document anti-DoS headers.
-
-TODO(crbug.com/1035895): Document X-Retry-After behavior.
-
-TODO(crbug.com/1035895): Document proxy behavior.
-
-## Testing
-TODO(crbug.com/1035895): Document testing strategies, framework.
-
-TODO(crbug.com/1035895): Document test build.
-
-Testing is possible by programmatically controlling certain parameters of the
-updater. These parameters are hardcoded in the production builds but they can
-be modified in test builds. For this reason, the updater build scripts define
-two separate set of targets. One target produces binaries suitable to
-releasing. The other target produces test binaries, which are suffixed by
-`_test`. The test binaries link the test hooks code, which slightly alters the
-behavior of the updater to facilitate testing it.
-
-TODO(crbug.com/1035895): Document external constants override.
-
-TODO(crbug.com/1035895): Document builders & test machines.
-
-TODO(crbug.com/1035895): Document old updater in third\_party.
-
-TODO(crbug.com/1035895): Document manual testing tools.
-
-## Release
-TODO(crbug.com/1035895): Document build.
-
-TODO(crbug.com/1035895): Document signing.
-
-TODO(crbug.com/1035895): Document branching & versioning.
-
-TODO(crbug.com/1035895): Document A/B release qualification process.
-
-## Tools
-TODO(crbug.com/1035895): Document tagger.
-
-## Metainstaller
-
-### UI Strings & Localization
-The strings for the metainstaller live in the //chrome/app/chromium_strings.grd
-and //chrome/app/google_chrome_strings.grd files. This allows the updater
-strings to utilize the Chromium repo's translation process instead of generating
-its own. Having it in existing grd files also eliminates the need to onboard
-updater specific grd files.
-
-During the build process, the updater strings are embedded directly into the
-metainstaller binary via `generate_embedded_i18n`. `generate_embedded_i18n` also
-allows an `extractor_datafile`, which can define specific strings to pick out
-from the originating grd file. This way, the metainstaller only has the strings
-specific to the updater and not any of the other strings within the grd file.
-When the `generate_embedded_i18n` is complete, it generates an
-`updater_installer_strings.h` header, which contains macro definitions of the
-message ids and the offsets. The strings are mapped with their var name appended
-with `_BASE`. Then the  `_BASE` appended macros are defined to be the first
-localization id in the list, in which case it is `_AF`.
-
-An example from the `updater_installer_strings.h`
-```
-#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AF 1600
-#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AM 1601
-
-...
-
-#define IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE IDS_BUNDLE_INSTALLED_SUCCESSFULLY_AF
-
-...
-
-#define DO_STRING_MAPPING \
-  HANDLE_STRING(IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE, IDS_BUNDLE_INSTALLED_SUCCESSFULLY) \
-```
-
-Within the metainstaller, an l10_util.h/cc has three functions to get localized
-strings.
-```
-GetLocalizedString(int base_message_id)
-GetLocalizedStringF(int base_message_id, const std::wstring& replacement)
-GetLocalizedStringF(int base_message_id, std::vector<std::wstring> replacements)
-```
-
-One function for getting the literal string and two functions to get formatted
-strings. `GetLocalizedString()` uses the base id plus the offset based on the
-language to look through the binary's string table to get the correct, localized
-string. The formatted strings utilize GetLocalizedString() to get the string and
-then uses `base::ReplaceStringPlaceholders()` to remove the `$i` placeholders
-within the string. With regards to picking the correct language to utilize for
-the localized string, `base::win::i18n::GetUserPreferredUILanguageList()` is
-used to get the preferred UI languages from MUI. If there are multiple languages
-in the list, the first language in the list is picked.
-
-## Application Commands
-
-The Application Command feature allows installed Updater-managed applications to
-pre-register and then later run command lines (elevated for system
-applications). The command lines can also include replaceable parameters
-substituted at runtime.
-
-For legacy reasons:
-* the interface is called `IAppCommandWeb` because it was meant to be used from
-an ActiveX control on a webpage at one point, and
-* it is derived from `IDispatch` for the same reason, to be used from script.
-
-For more information, please see the
-[functional spec](functional_spec.md#Application-Commands).
+### Network
+On macOS, the updater uses NSURLSession to implement the network.
diff --git a/extensions/browser/api/dns/dns_api.cc b/extensions/browser/api/dns/dns_api.cc
index 6e5bb6b..1d15f3b 100644
--- a/extensions/browser/api/dns/dns_api.cc
+++ b/extensions/browser/api/dns/dns_api.cc
@@ -32,17 +32,17 @@
   std::unique_ptr<Resolve::Params> params(Resolve::Params::Create(args()));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  // Yes, we are passing zero as the port. There are some interesting but not
-  // presently relevant reasons why HostResolver asks for the port of the
-  // hostname you'd like to resolve, even though it doesn't use that value in
-  // determining its answer.
+  // Intentionally pass host only (no scheme or non-zero port) to only get a
+  // basic resolution for the hostname itself.
   net::HostPortPair host_port_pair(params->hostname, 0);
   url::Origin origin = extension_->origin();
   browser_context()
       ->GetDefaultStoragePartition()
       ->GetNetworkContext()
-      ->ResolveHost(host_port_pair, net::NetworkIsolationKey(origin, origin),
-                    nullptr, receiver_.BindNewPipeAndPassRemote());
+      ->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                        std::move(host_port_pair)),
+                    net::NetworkIsolationKey(origin, origin), nullptr,
+                    receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(
       base::BindOnce(&DnsResolveFunction::OnComplete, base::Unretained(this),
                      net::ERR_NAME_NOT_RESOLVED,
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc
index 25af213..a5083c3 100644
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
@@ -7,6 +7,7 @@
 #include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -175,7 +176,7 @@
       : target_id_(GetTargetIdCrashKey(), info.target_id),
         source_endpoint_(info.source_endpoint),
         source_origin_(GetSourceOriginCrashKey(),
-                       base::OptionalOrNullptr(info.source_origin)),
+                       base::OptionalToPtr(info.source_origin)),
         source_url_(GetSourceUrlCrashKey(),
                     info.source_url.possibly_invalid_spec()) {}
 
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc
index 10dffdf9..04ba475 100644
--- a/extensions/browser/api/socket/socket_api.cc
+++ b/extensions/browser/api/socket/socket_api.cc
@@ -223,9 +223,11 @@
   network::mojom::ResolveHostParametersPtr params =
       network::mojom::ResolveHostParameters::New();
   params->dns_query_type = dns_query_type;
+  // Intentionally using a HostPortPair because scheme isn't specified.
   host_resolver_->ResolveHost(
-      host_port_pair, net::NetworkIsolationKey(origin, origin),
-      std::move(params), receiver_.BindNewPipeAndPassRemote());
+      network::mojom::HostResolverHost::NewHostPortPair(host_port_pair),
+      net::NetworkIsolationKey(origin, origin), std::move(params),
+      receiver_.BindNewPipeAndPassRemote());
   receiver_.set_disconnect_handler(
       base::BindOnce(&SocketExtensionWithDnsLookupFunction::OnComplete,
                      base::Unretained(this), net::ERR_NAME_NOT_RESOLVED,
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index f2c4ff74..e8a7953 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -401,7 +401,8 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TRACE_EVENT_WITH_FLOW0(
       "extensions",
       "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
@@ -411,6 +412,7 @@
       TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
 
   current_body_ = std::move(body);
+  current_cached_metadata_ = std::move(cached_metadata);
   if (current_request_uses_header_client_) {
     // Use the cookie headers we got from OnHeadersReceived as that'll contain
     // Set-Cookie if it existed. Re-adding cookie headers here does not
@@ -482,11 +484,6 @@
 }
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
-    OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  target_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
-void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     OnTransferSizeUpdated(int32_t transfer_size_diff) {
   target_client_->OnTransferSizeUpdated(transfer_size_diff);
 }
@@ -1200,7 +1197,8 @@
   ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
       factory_->browser_context_, &info_.value(), net::OK);
   target_client_->OnReceiveResponse(current_response_.Clone(),
-                                    std::move(current_body_));
+                                    std::move(current_body_),
+                                    std::move(current_cached_metadata_));
 }
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
index 858b612..f2ad0ef 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -109,14 +109,15 @@
     // network::mojom::URLLoaderClient:
     void OnReceiveEarlyHints(
         network::mojom::EarlyHintsPtr early_hints) override;
-    void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                           mojo::ScopedDataPipeConsumerHandle body) override;
+    void OnReceiveResponse(
+        network::mojom::URLResponseHeadPtr head,
+        mojo::ScopedDataPipeConsumerHandle body,
+        absl::optional<mojo_base::BigBuffer> cached_metadata) override;
     void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                            network::mojom::URLResponseHeadPtr head) override;
     void OnUploadProgress(int64_t current_position,
                           int64_t total_size,
                           OnUploadProgressCallback callback) override;
-    void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
     void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
     void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
@@ -227,6 +228,7 @@
     // ExtensionWebRequestEventRouter) through much of the request's lifetime.
     network::mojom::URLResponseHeadPtr current_response_;
     mojo::ScopedDataPipeConsumerHandle current_body_;
+    absl::optional<mojo_base::BigBuffer> current_cached_metadata_;
     scoped_refptr<net::HttpResponseHeaders> override_headers_;
     GURL redirect_url_;
 
diff --git a/extensions/browser/content_hash_reader.cc b/extensions/browser/content_hash_reader.cc
index 2c266ceb..1f49f3b 100644
--- a/extensions/browser/content_hash_reader.cc
+++ b/extensions/browser/content_hash_reader.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "crypto/sha2.h"
 #include "extensions/browser/computed_hashes.h"
@@ -52,7 +53,7 @@
 
   ContentHash::TreeHashVerificationResult verification =
       content_hash->VerifyTreeHashRoot(relative_path,
-                                       base::OptionalOrNullptr(root));
+                                       base::OptionalToPtr(root));
 
   // Extensions sometimes request resources that do not have an entry in
   // computed_hashes.json or verified_content.json. This can happen, for
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc
index fcbc722..1d5eb1c 100644
--- a/extensions/browser/extension_protocols.cc
+++ b/extensions/browser/extension_protocols.cc
@@ -134,9 +134,12 @@
     real_client_->OnReceiveEarlyHints(std::move(early_hints));
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
-    real_client_->OnReceiveResponse(std::move(response_head), std::move(body));
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
+    real_client_->OnReceiveResponse(std::move(response_head), std::move(body),
+                                    std::move(cached_metadata));
   }
 
   void OnReceiveRedirect(
@@ -152,10 +155,6 @@
                                    std::move(ack_callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    real_client_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     real_client_->OnTransferSizeUpdated(transfer_size_diff);
   }
@@ -746,7 +745,8 @@
       return;
     }
 
-    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle));
+    client_->OnReceiveResponse(std::move(head), std::move(consumer_handle),
+                               absl::nullopt);
 
     CompleteRequestAndDeleteThis(net::OK);
   }
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index 6e1dc99..6fd6712d 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -578,7 +578,7 @@
   // with std::u16string
   std::string utf8_error;
   if (!extension_l10n_util::LocalizeExtension(
-          extension_root_, final_manifest_dict.get(),
+          extension_root_, &final_manifest_dict->GetDict(),
           extension_l10n_util::GzippedMessagesPermission::kDisallow,
           &utf8_error)) {
     ReportFailure(
diff --git a/extensions/common/api/automation.idl b/extensions/common/api/automation.idl
index b07449a..f415d34 100644
--- a/extensions/common/api/automation.idl
+++ b/extensions/common/api/automation.idl
@@ -926,6 +926,12 @@
     // Accessible Name Calculation</a> process.
     DOMString? name;
 
+    // Explains what will happen when the doDefault action is performed.
+    DOMString? doDefaultLabel;
+
+    // Explains what will happen when the long click action is performed.
+    DOMString? longClickLabel;
+
     // The tooltip of the node, if any.
     DOMString? tooltip;
 
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc
index ac0f563..7200132 100644
--- a/extensions/common/extension_api.cc
+++ b/extensions/common/extension_api.cc
@@ -34,9 +34,8 @@
 
 const char* const kChildKinds[] = {"functions", "events"};
 
-std::unique_ptr<base::DictionaryValue> LoadSchemaDictionary(
-    const std::string& name,
-    const base::StringPiece& schema) {
+base::Value::Dict LoadSchemaDictionary(const std::string& name,
+                                       const base::StringPiece& schema) {
   auto result = base::JSONReader::ReadAndReturnValueWithError(schema);
 
   // Tracking down http://crbug.com/121424
@@ -48,34 +47,31 @@
   CHECK(result.has_value())
       << result.error().message << " for schema " << schema;
   CHECK(result->is_dict()) << " for schema " << schema;
-  return base::DictionaryValue::From(
-      base::Value::ToUniquePtrValue(std::move(*result)));
+  return std::move(result->GetDict());
 }
 
-const base::DictionaryValue* FindListItem(const base::ListValue* list,
-                                          const std::string& property_name,
-                                          const std::string& property_value) {
-  for (const base::Value& item_value : list->GetList()) {
-    CHECK(item_value.is_dict()) << property_value << "/" << property_name;
-    const base::DictionaryValue* item =
-        static_cast<const base::DictionaryValue*>(&item_value);
-    std::string value;
-    if (item->GetString(property_name, &value) && value == property_value)
+const base::Value::Dict* FindListItem(const base::Value::List& list,
+                                      const std::string& property_name,
+                                      const std::string& property_value) {
+  for (const base::Value& item_value : list) {
+    const base::Value::Dict* item = item_value.GetIfDict();
+    CHECK(item) << property_value << "/" << property_name;
+    const std::string* value = item->FindStringByDottedPath(property_name);
+    if (value && *value == property_value)
       return item;
   }
 
   return NULL;
 }
 
-const base::DictionaryValue* GetSchemaChild(
-    const base::DictionaryValue* schema_node,
-    const std::string& child_name) {
-  const base::DictionaryValue* child_node = NULL;
-  for (size_t i = 0; i < std::size(kChildKinds); ++i) {
-    const base::ListValue* list_node = NULL;
-    if (!schema_node->GetList(kChildKinds[i], &list_node))
+const base::Value::Dict* GetSchemaChild(const base::Value::Dict& schema_node,
+                                        const std::string& child_name) {
+  for (const char* kind : kChildKinds) {
+    const base::Value::List* list_node = schema_node.FindList(kind);
+    if (!list_node)
       continue;
-    child_node = FindListItem(list_node, "name", child_name);
+    const base::Value::Dict* child_node =
+        FindListItem(*list_node, "name", child_name);
     if (child_node)
       return child_node;
   }
@@ -138,11 +134,10 @@
 void ExtensionAPI::LoadSchema(const std::string& name,
                               const base::StringPiece& schema) {
   lock_.AssertAcquired();
-  std::unique_ptr<base::DictionaryValue> schema_dict(
-      LoadSchemaDictionary(name, schema));
-  std::string schema_namespace;
-  CHECK(schema_dict->GetString("namespace", &schema_namespace));
-  schemas_[schema_namespace] = std::move(schema_dict);
+  base::Value::Dict schema_dict(LoadSchemaDictionary(name, schema));
+  const std::string* schema_namespace = schema_dict.FindString("namespace");
+  CHECK(schema_namespace);
+  schemas_[*schema_namespace] = std::move(schema_dict);
 }
 
 ExtensionAPI::ExtensionAPI() = default;
@@ -229,16 +224,15 @@
   return GetSchemaStringPieceUnsafe(api_name);
 }
 
-const base::DictionaryValue* ExtensionAPI::GetSchema(
-    const std::string& full_name) {
+const base::Value::Dict* ExtensionAPI::GetSchema(const std::string& full_name) {
   base::AutoLock lock(lock_);
   std::string child_name;
   std::string api_name = GetAPINameFromFullNameUnsafe(full_name, &child_name);
 
-  const base::DictionaryValue* result = NULL;
+  const base::Value::Dict* result = nullptr;
   auto maybe_schema = schemas_.find(api_name);
   if (maybe_schema != schemas_.end()) {
-    result = maybe_schema->second.get();
+    result = &maybe_schema->second;
   } else {
     base::StringPiece schema_string = GetSchemaStringPieceUnsafe(api_name);
     if (schema_string.empty())
@@ -247,11 +241,11 @@
 
     maybe_schema = schemas_.find(api_name);
     CHECK(schemas_.end() != maybe_schema);
-    result = maybe_schema->second.get();
+    result = &maybe_schema->second;
   }
 
   if (!child_name.empty())
-    result = GetSchemaChild(result, child_name);
+    result = GetSchemaChild(*result, child_name);
 
   return result;
 }
diff --git a/extensions/common/extension_api.h b/extensions/common/extension_api.h
index ee1fcd83..22c51429 100644
--- a/extensions/common/extension_api.h
+++ b/extensions/common/extension_api.h
@@ -20,10 +20,6 @@
 #include "extensions/common/features/feature_provider.h"
 #include "extensions/common/url_pattern_set.h"
 
-namespace base {
-class DictionaryValue;
-}
-
 class GURL;
 
 namespace extensions {
@@ -134,7 +130,7 @@
   // Ownership remains with this object.
   // TODO(devlin): Now that we use GetSchemaStringPiece() in the renderer, we
   // may not really need this anymore.
-  const base::DictionaryValue* GetSchema(const std::string& full_name);
+  const base::Value::Dict* GetSchema(const std::string& full_name);
 
   // Splits a full name from the extension API into its API and child name
   // parts. Some examples:
@@ -186,8 +182,7 @@
   base::Lock lock_;
 
   // Schemas for each namespace.
-  using SchemaMap =
-      std::map<std::string, std::unique_ptr<const base::DictionaryValue>>;
+  using SchemaMap = std::map<std::string, base::Value::Dict>;
   SchemaMap schemas_ GUARDED_BY(lock_);
 
   // FeatureProviders used for resolving dependencies.
diff --git a/extensions/common/extension_l10n_util.cc b/extensions/common/extension_l10n_util.cc
index 35b0422e..a9195f2 100644
--- a/extensions/common/extension_l10n_util.cc
+++ b/extensions/common/extension_l10n_util.cc
@@ -47,7 +47,7 @@
 // or there was parsing error we return null and set |error|. If
 // |gzip_permission| is kAllowForTrustedSource, this will also look for a .gz
 // version of the file and if found will decompresses it into a string first.
-std::unique_ptr<base::DictionaryValue> LoadMessageFile(
+std::unique_ptr<base::Value::Dict> LoadMessageFile(
     const base::FilePath& locale_path,
     const std::string& locale,
     std::string* error,
@@ -55,11 +55,15 @@
   base::FilePath file_path =
       locale_path.AppendASCII(locale).Append(extensions::kMessagesFilename);
 
-  std::unique_ptr<base::DictionaryValue> dictionary;
+  std::unique_ptr<base::Value::Dict> dictionary;
   if (base::PathExists(file_path)) {
     JSONFileValueDeserializer messages_deserializer(file_path);
-    dictionary = base::DictionaryValue::From(
-        messages_deserializer.Deserialize(nullptr, error));
+    std::unique_ptr<base::Value> value =
+        messages_deserializer.Deserialize(nullptr, error);
+    if (value) {
+      dictionary =
+          std::make_unique<base::Value::Dict>(std::move(value->GetDict()));
+    }
   } else if (gzip_permission == extension_l10n_util::GzippedMessagesPermission::
                                     kAllowForTrustedSource ||
              g_allow_gzipped_messages_for_test) {
@@ -80,8 +84,12 @@
         return dictionary;
       }
       JSONStringValueDeserializer messages_deserializer(data);
-      dictionary = base::DictionaryValue::From(
-          messages_deserializer.Deserialize(nullptr, error));
+      std::unique_ptr<base::Value> value =
+          messages_deserializer.Deserialize(nullptr, error);
+      if (value) {
+        dictionary =
+            std::make_unique<base::Value::Dict>(std::move(value->GetDict()));
+      }
     }
   } else {
     LOG(ERROR) << "Unable to load message file: " << locale_path.AsUTF8Unsafe();
@@ -106,29 +114,29 @@
 // Localizes manifest value of string type for a given key.
 bool LocalizeManifestValue(const std::string& key,
                            const extensions::MessageBundle& messages,
-                           base::Value* manifest,
+                           base::Value::Dict* manifest,
                            std::string* error) {
-  std::string* result = manifest->FindStringPath(key);
+  std::string* result = manifest->FindStringByDottedPath(key);
   if (!result)
     return true;
 
   if (!messages.ReplaceMessages(result, error))
     return false;
 
-  manifest->SetStringPath(key, *result);
+  manifest->SetByDottedPath(key, *result);
   return true;
 }
 
 // Localizes manifest value of list type for a given key.
 bool LocalizeManifestListValue(const std::string& key,
                                const extensions::MessageBundle& messages,
-                               base::DictionaryValue* manifest,
+                               base::Value::Dict* manifest,
                                std::string* error) {
-  base::ListValue* list_value = nullptr;
-  if (!manifest->GetList(key, &list_value))
+  base::Value::List* list_value = manifest->FindListByDottedPath(key);
+  if (!list_value)
     return true;
 
-  for (base::Value& item : list_value->GetList()) {
+  for (base::Value& item : *list_value) {
     if (item.is_string()) {
       std::string result = item.GetString();
       if (!messages.ReplaceMessages(&result, error)) {
@@ -191,10 +199,10 @@
   GetPreferredLocale() = locale;
 }
 
-std::string GetDefaultLocaleFromManifest(const base::DictionaryValue& manifest,
+std::string GetDefaultLocaleFromManifest(const base::Value::Dict& manifest,
                                          std::string* error) {
   if (const std::string* default_locale =
-          manifest.FindStringKey(keys::kDefaultLocale)) {
+          manifest.FindString(keys::kDefaultLocale)) {
     return *default_locale;
   }
 
@@ -202,26 +210,23 @@
   return std::string();
 }
 
-bool ShouldRelocalizeManifest(const base::DictionaryValue* manifest) {
-  if (!manifest)
-    return false;
-
-  if (!manifest->FindKey(keys::kDefaultLocale))
+bool ShouldRelocalizeManifest(const base::Value::Dict& manifest) {
+  if (!manifest.Find(keys::kDefaultLocale))
     return false;
 
   std::string manifest_current_locale;
   const std::string* manifest_current_locale_in =
-      manifest->FindStringKey(keys::kCurrentLocale);
+      manifest.FindString(keys::kCurrentLocale);
   if (manifest_current_locale_in)
     manifest_current_locale = *manifest_current_locale_in;
   return manifest_current_locale != LocaleForLocalization();
 }
 
 bool LocalizeManifest(const extensions::MessageBundle& messages,
-                      base::DictionaryValue* manifest,
+                      base::Value::Dict* manifest,
                       std::string* error) {
   // Initialize name.
-  const std::string* result = manifest->FindStringKey(keys::kName);
+  const std::string* result = manifest->FindString(keys::kName);
   if (!result) {
     *error = errors::kInvalidName;
     return false;
@@ -266,30 +271,34 @@
   if (!LocalizeManifestValue(keys::kOmniboxKeyword, messages, manifest, error))
     return false;
 
-  base::ListValue* file_handlers = NULL;
-  if (manifest->GetList(keys::kFileBrowserHandlers, &file_handlers)) {
-    for (base::Value& handler : file_handlers->GetList()) {
-      if (!handler.is_dict()) {
+  base::Value::List* file_handlers =
+      manifest->FindListByDottedPath(keys::kFileBrowserHandlers);
+  if (file_handlers) {
+    for (base::Value& handler : *file_handlers) {
+      base::Value::Dict* dict = handler.GetIfDict();
+      if (!dict) {
         *error = errors::kInvalidFileBrowserHandler;
         return false;
       }
-      if (!LocalizeManifestValue(keys::kActionDefaultTitle, messages, &handler,
+      if (!LocalizeManifestValue(keys::kActionDefaultTitle, messages, dict,
                                  error))
         return false;
     }
   }
 
   // Initialize all input_components
-  base::ListValue* input_components = NULL;
-  if (manifest->GetList(keys::kInputComponents, &input_components)) {
-    for (base::Value& module : input_components->GetList()) {
-      if (!module.is_dict()) {
+  base::Value::List* input_components =
+      manifest->FindListByDottedPath(keys::kInputComponents);
+  if (input_components) {
+    for (base::Value& module : *input_components) {
+      base::Value::Dict* dict = module.GetIfDict();
+      if (!dict) {
         *error = errors::kInvalidInputComponents;
         return false;
       }
-      if (!LocalizeManifestValue(keys::kName, messages, &module, error))
+      if (!LocalizeManifestValue(keys::kName, messages, dict, error))
         return false;
-      if (!LocalizeManifestValue(keys::kDescription, messages, &module, error))
+      if (!LocalizeManifestValue(keys::kDescription, messages, dict, error))
         return false;
     }
   }
@@ -303,27 +312,24 @@
     return false;
 
   // Initialize description of commmands.
-  base::DictionaryValue* commands_handler = NULL;
-  if (manifest->GetDictionary(keys::kCommands, &commands_handler)) {
-    for (base::DictionaryValue::Iterator iter(*commands_handler);
-         !iter.IsAtEnd();
-         iter.Advance()) {
+  base::Value::Dict* commands_handler =
+      manifest->FindDictByDottedPath(keys::kCommands);
+  if (commands_handler) {
+    for (auto iter : *commands_handler) {
       std::string key =
-          base::StringPrintf("commands.%s.description", iter.key().c_str());
+          base::StringPrintf("commands.%s.description", iter.first.c_str());
       if (!LocalizeManifestValue(key, messages, manifest, error))
         return false;
     }
   }
 
   // Initialize search_provider fields.
-  base::DictionaryValue* search_provider = NULL;
-  if (manifest->GetDictionary(keys::kOverrideSearchProvider,
-                              &search_provider)) {
-    for (base::DictionaryValue::Iterator iter(*search_provider);
-         !iter.IsAtEnd();
-         iter.Advance()) {
+  base::Value::Dict* search_provider =
+      manifest->FindDictByDottedPath(keys::kOverrideSearchProvider);
+  if (search_provider) {
+    for (auto iter : *search_provider) {
       std::string key = base::StrCat(
-          {keys::kOverrideSearchProvider, ".", iter.key().c_str()});
+          {keys::kOverrideSearchProvider, ".", iter.first.c_str()});
       bool success =
           (key == keys::kSettingsOverrideAlternateUrls)
               ? LocalizeManifestListValue(key, messages, manifest, error)
@@ -345,12 +351,12 @@
 
   // Add desired locale key to the manifest, so we can overwrite prefs
   // with new manifest when chrome locale changes.
-  manifest->SetStringKey(keys::kCurrentLocale, LocaleForLocalization());
+  manifest->Set(keys::kCurrentLocale, LocaleForLocalization());
   return true;
 }
 
 bool LocalizeExtension(const base::FilePath& extension_path,
-                       base::DictionaryValue* manifest,
+                       base::Value::Dict* manifest,
                        GzippedMessagesPermission gzip_permission,
                        std::string* error) {
   DCHECK(manifest);
@@ -484,23 +490,23 @@
         locale_path.AppendASCII(all_fallback_locales[i]);
     if (!base::PathExists(this_locale_path))
       continue;
-    std::unique_ptr<base::DictionaryValue> catalog = LoadMessageFile(
+    std::unique_ptr<base::Value::Dict> catalog = LoadMessageFile(
         locale_path, all_fallback_locales[i], error, gzip_permission);
     if (!catalog.get()) {
       // If locale is valid, but messages.json is corrupted or missing, return
       // an error.
       return nullptr;
     }
-    catalogs.push_back(std::move(catalog->GetDict()));
+    catalogs.push_back(std::move(*catalog));
   }
 
   return extensions::MessageBundle::Create(catalogs, error);
 }
 
 bool ValidateExtensionLocales(const base::FilePath& extension_path,
-                              const base::DictionaryValue* manifest,
+                              const base::Value::Dict& manifest,
                               std::string* error) {
-  std::string default_locale = GetDefaultLocaleFromManifest(*manifest, error);
+  std::string default_locale = GetDefaultLocaleFromManifest(manifest, error);
 
   if (default_locale.empty())
     return true;
@@ -514,9 +520,8 @@
   for (auto locale = valid_locales.cbegin(); locale != valid_locales.cend();
        ++locale) {
     std::string locale_error;
-    std::unique_ptr<base::DictionaryValue> catalog =
-        LoadMessageFile(locale_path, *locale, &locale_error,
-                        GzippedMessagesPermission::kDisallow);
+    LoadMessageFile(locale_path, *locale, &locale_error,
+                    GzippedMessagesPermission::kDisallow);
     if (!locale_error.empty()) {
       if (!error->empty())
         error->append(" ");
@@ -530,7 +535,7 @@
 bool ShouldSkipValidation(const base::FilePath& locales_path,
                           const base::FilePath& locale_path,
                           const std::set<std::string>& all_locales) {
-  // Since we use this string as a key in a DictionaryValue, be paranoid about
+  // Since we use this string as a key in a Value::Dict, be paranoid about
   // skipping any strings with '.'. This happens sometimes, for example with
   // '.svn' directories.
   base::FilePath relative_path;
diff --git a/extensions/common/extension_l10n_util.h b/extensions/common/extension_l10n_util.h
index 74f1de8d..fb0d809 100644
--- a/extensions/common/extension_l10n_util.h
+++ b/extensions/common/extension_l10n_util.h
@@ -13,11 +13,11 @@
 
 #include "base/auto_reset.h"
 #include "base/strings/string_piece.h"
+#include "base/values.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/mojom/manifest.mojom-shared.h"
 
 namespace base {
-class DictionaryValue;
 class FilePath;
 }
 
@@ -62,24 +62,24 @@
 
 // Returns default locale in form "en-US" or "sr" or empty string if
 // "default_locale" section was not defined in the manifest.json file.
-std::string GetDefaultLocaleFromManifest(const base::DictionaryValue& manifest,
+std::string GetDefaultLocaleFromManifest(const base::Value::Dict& manifest,
                                          std::string* error);
 
 // Returns true iff the extension was localized, and the current locale
 // doesn't match the locale written into info.extension_manifest.
-bool ShouldRelocalizeManifest(const base::DictionaryValue* manifest);
+bool ShouldRelocalizeManifest(const base::Value::Dict& manifest);
 
 // Localize extension name, description, browser_action and other fields
 // in the manifest.
 bool LocalizeManifest(const extensions::MessageBundle& messages,
-                      base::DictionaryValue* manifest,
+                      base::Value::Dict* manifest,
                       std::string* error);
 
 // Load message catalogs, localize manifest and attach message bundle to the
 // extension. |gzip_permission| will be passed to LoadMessageCatalogs
 // (see below for details).
 bool LocalizeExtension(const base::FilePath& extension_path,
-                       base::DictionaryValue* manifest,
+                       base::Value::Dict* manifest,
                        GzippedMessagesPermission gzip_permission,
                        std::string* error);
 
@@ -132,7 +132,7 @@
 // Loads message catalogs for all locales to check for validity. Used for
 // validating unpacked extensions.
 bool ValidateExtensionLocales(const base::FilePath& extension_path,
-                              const base::DictionaryValue* manifest,
+                              const base::Value::Dict& manifest,
                               std::string* error);
 
 // Returns true if directory has "." in the name (for .svn) or if it doesn't
diff --git a/extensions/common/extension_l10n_util_unittest.cc b/extensions/common/extension_l10n_util_unittest.cc
index c239415..7e3d8d1 100644
--- a/extensions/common/extension_l10n_util_unittest.cc
+++ b/extensions/common/extension_l10n_util_unittest.cc
@@ -44,11 +44,11 @@
   ASSERT_EQ(static_cast<int>(data.length()),
             base::WriteFile(messages_file, data.c_str(), data.length()));
 
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en");
   std::string error;
-  EXPECT_FALSE(extension_l10n_util::ValidateExtensionLocales(
-      temp.GetPath(), &manifest, &error));
+  EXPECT_FALSE(extension_l10n_util::ValidateExtensionLocales(temp.GetPath(),
+                                                             manifest, &error));
   EXPECT_THAT(
       error,
       testing::HasSubstr(base::UTF16ToUTF8(messages_file.LossyDisplayName())));
@@ -351,7 +351,7 @@
 }
 
 TEST(ExtensionL10nUtil, LocalizeEmptyManifest) {
-  base::DictionaryValue manifest;
+  base::Value::Dict manifest;
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
@@ -361,103 +361,106 @@
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithoutNameMsgAndEmptyDescription) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "no __MSG");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "no __MSG");
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("no __MSG", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("no __MSG", *result);
 
-  EXPECT_FALSE(manifest.FindKey(keys::kDescription));
+  EXPECT_FALSE(manifest.Find(keys::kDescription));
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithNameMsgAndEmptyDescription) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  EXPECT_FALSE(manifest.FindKey(keys::kDescription));
+  EXPECT_FALSE(manifest.Find(keys::kDescription));
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithLocalLaunchURL) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "name");
-  manifest.SetStringPath(keys::kLaunchLocalPath, "__MSG_launch_local_path__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "name");
+  manifest.SetByDottedPath(keys::kLaunchLocalPath, "__MSG_launch_local_path__");
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kLaunchLocalPath, &result));
-  EXPECT_EQ("main.html", result);
+  const std::string* result =
+      manifest.FindStringByDottedPath(keys::kLaunchLocalPath);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("main.html", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithHostedLaunchURL) {
-  base::DictionaryValue manifest;
-  manifest.SetStringPath(keys::kName, "name");
-  manifest.SetStringPath(keys::kLaunchWebURL, "__MSG_launch_web_url__");
+  base::Value::Dict manifest;
+  manifest.SetByDottedPath(keys::kName, "name");
+  manifest.SetByDottedPath(keys::kLaunchWebURL, "__MSG_launch_web_url__");
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kLaunchWebURL, &result));
-  EXPECT_EQ("http://www.google.com/", result);
+  const std::string* result =
+      manifest.FindStringByDottedPath(keys::kLaunchWebURL);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("http://www.google.com/", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithBadNameMsg) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name_is_bad__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name_is_bad__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
 
   EXPECT_FALSE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("__MSG_name_is_bad__", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("__MSG_name_is_bad__", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("__MSG_description__", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("__MSG_description__", *result);
 
   EXPECT_EQ("Variable __MSG_name_is_bad__ used but not defined.", error);
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionDefaultTitleMsgs) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
   std::string action_title(keys::kBrowserAction);
   action_title.append(".");
   action_title.append(keys::kActionDefaultTitle);
-  manifest.SetStringPath(action_title, "__MSG_title__");
+  manifest.SetByDottedPath(action_title, "__MSG_title__");
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -465,24 +468,26 @@
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("description", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("description", *result);
 
-  ASSERT_TRUE(manifest.GetString(action_title, &result));
-  EXPECT_EQ("action title", result);
+  result = manifest.FindStringByDottedPath(action_title);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("action title", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionOmniboxMsgs) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
-  manifest.SetStringPath(keys::kOmniboxKeyword, "__MSG_omnibox_keyword__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
+  manifest.SetByDottedPath(keys::kOmniboxKeyword, "__MSG_omnibox_keyword__");
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -490,29 +495,31 @@
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("description", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("description", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kOmniboxKeyword, &result));
-  EXPECT_EQ("omnibox keyword", result);
+  result = manifest.FindStringByDottedPath(keys::kOmniboxKeyword);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("omnibox keyword", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionFileHandlerTitle) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
 
-  base::DictionaryValue handler;
-  handler.SetStringKey(keys::kActionDefaultTitle, "__MSG_file_handler_title__");
-  base::Value handlers(base::Value::Type::LIST);
+  base::Value::Dict handler;
+  handler.Set(keys::kActionDefaultTitle, "__MSG_file_handler_title__");
+  base::Value::List handlers;
   handlers.Append(std::move(handler));
-  manifest.SetKey(keys::kFileBrowserHandlers, std::move(handlers));
+  manifest.Set(keys::kFileBrowserHandlers, std::move(handlers));
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -520,40 +527,40 @@
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("description", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("description", *result);
 
-  base::ListValue* handlers_raw = nullptr;
-  manifest.GetList(keys::kFileBrowserHandlers, &handlers_raw);
-  base::DictionaryValue* handler_raw = nullptr;
-  handlers_raw->GetList()[0].GetAsDictionary(&handler_raw);
-  ASSERT_TRUE(handler_raw->GetString(keys::kActionDefaultTitle, &result));
-  EXPECT_EQ("file handler title", result);
+  base::Value::List* handlers_raw =
+      manifest.FindList(keys::kFileBrowserHandlers);
+  ASSERT_TRUE(handlers_raw);
+  ASSERT_EQ(handlers_raw->size(), 1u);
+  base::Value::Dict* handler_raw = (*handlers_raw)[0].GetIfDict();
+  result = handler_raw->FindString(keys::kActionDefaultTitle);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("file handler title", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionCommandDescription) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
-  base::Value commands(base::Value::Type::DICTIONARY);
-  std::string commands_title(keys::kCommands);
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
+  base::Value::Dict commands;
 
-  base::DictionaryValue first_command;
-  first_command.SetStringKey(keys::kDescription,
-                             "__MSG_first_command_description__");
-  commands.SetKey("first_command", std::move(first_command));
+  base::Value::Dict first_command;
+  first_command.Set(keys::kDescription, "__MSG_first_command_description__");
+  commands.Set("first_command", std::move(first_command));
 
-  base::DictionaryValue second_command;
-  second_command.SetStringKey(keys::kDescription,
-                              "__MSG_second_command_description__");
-  commands.SetKey("second_command", std::move(second_command));
-  manifest.SetKey(commands_title, std::move(commands));
+  base::Value::Dict second_command;
+  second_command.Set(keys::kDescription, "__MSG_second_command_description__");
+  commands.Set("second_command", std::move(second_command));
+  manifest.Set(keys::kCommands, std::move(commands));
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -561,28 +568,31 @@
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("description", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("description", *result);
 
-  ASSERT_TRUE(
-      manifest.GetString("commands.first_command.description", &result));
-  EXPECT_EQ("first command", result);
+  result =
+      manifest.FindStringByDottedPath("commands.first_command.description");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("first command", *result);
 
-  ASSERT_TRUE(
-      manifest.GetString("commands.second_command.description", &result));
-  EXPECT_EQ("second command", result);
+  result =
+      manifest.FindStringByDottedPath("commands.second_command.description");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("second command", *result);
 
   EXPECT_TRUE(error.empty());
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithShortName) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "extension name");
-  manifest.SetStringKey(keys::kShortName, "__MSG_short_name__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "extension name");
+  manifest.Set(keys::kShortName, "__MSG_short_name__");
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -591,15 +601,15 @@
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
   EXPECT_TRUE(error.empty());
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
-  EXPECT_EQ("short_name", result);
+  const std::string* result = manifest.FindString(keys::kShortName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("short_name", *result);
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithBadShortName) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "extension name");
-  manifest.SetStringKey(keys::kShortName, "__MSG_short_name_bad__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "extension name");
+  manifest.Set(keys::kShortName, "__MSG_short_name_bad__");
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -608,30 +618,32 @@
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
   EXPECT_FALSE(error.empty());
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
-  EXPECT_EQ("__MSG_short_name_bad__", result);
+  const std::string* result = manifest.FindString(keys::kShortName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("__MSG_short_name_bad__", *result);
 }
 
 TEST(ExtensionL10nUtil, LocalizeManifestWithSearchProviderMsgs) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kName, "__MSG_name__");
-  manifest.SetStringKey(keys::kDescription, "__MSG_description__");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kName, "__MSG_name__");
+  manifest.Set(keys::kDescription, "__MSG_description__");
 
-  base::Value search_provider(base::Value::Type::DICTIONARY);
-  search_provider.SetStringKey("name", "__MSG_country__");
-  search_provider.SetStringKey("keyword", "__MSG_omnibox_keyword__");
-  search_provider.SetStringKey("search_url", "http://www.foo.__MSG_country__");
-  search_provider.SetStringKey("favicon_url", "http://www.foo.__MSG_country__");
-  search_provider.SetStringKey("suggest_url", "http://www.foo.__MSG_country__");
-  manifest.SetPath(keys::kOverrideSearchProvider, std::move(search_provider));
+  base::Value::Dict search_provider;
+  search_provider.Set("name", "__MSG_country__");
+  search_provider.Set("keyword", "__MSG_omnibox_keyword__");
+  search_provider.Set("search_url", "http://www.foo.__MSG_country__");
+  search_provider.Set("favicon_url", "http://www.foo.__MSG_country__");
+  search_provider.Set("suggest_url", "http://www.foo.__MSG_country__");
+  manifest.SetByDottedPath(keys::kOverrideSearchProvider,
+                           std::move(search_provider));
 
-  manifest.SetStringPath(keys::kOverrideHomepage,
-                         "http://www.foo.__MSG_country__");
+  manifest.SetByDottedPath(keys::kOverrideHomepage,
+                           "http://www.foo.__MSG_country__");
 
-  base::Value startup_pages(base::Value::Type::LIST);
+  base::Value::List startup_pages;
   startup_pages.Append("http://www.foo.__MSG_country__");
-  manifest.SetPath(keys::kOverrideStartupPage, std::move(startup_pages));
+  manifest.SetByDottedPath(keys::kOverrideStartupPage,
+                           std::move(startup_pages));
 
   std::string error;
   std::unique_ptr<MessageBundle> messages(CreateManifestBundle());
@@ -639,97 +651,99 @@
   EXPECT_TRUE(
       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
 
-  std::string result;
-  ASSERT_TRUE(manifest.GetString(keys::kName, &result));
-  EXPECT_EQ("name", result);
+  const std::string* result = manifest.FindString(keys::kName);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("name", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
-  EXPECT_EQ("description", result);
+  result = manifest.FindString(keys::kDescription);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("description", *result);
 
   std::string key_prefix(keys::kOverrideSearchProvider);
   key_prefix += '.';
-  ASSERT_TRUE(manifest.GetString(key_prefix + "name", &result));
-  EXPECT_EQ("de", result);
+  result = manifest.FindStringByDottedPath(key_prefix + "name");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("de", *result);
 
-  ASSERT_TRUE(manifest.GetString(key_prefix + "keyword", &result));
-  EXPECT_EQ("omnibox keyword", result);
+  result = manifest.FindStringByDottedPath(key_prefix + "keyword");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("omnibox keyword", *result);
 
-  ASSERT_TRUE(manifest.GetString(key_prefix + "search_url", &result));
-  EXPECT_EQ("http://www.foo.de", result);
+  result = manifest.FindStringByDottedPath(key_prefix + "search_url");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("http://www.foo.de", *result);
 
-  ASSERT_TRUE(manifest.GetString(key_prefix + "favicon_url", &result));
-  EXPECT_EQ("http://www.foo.de", result);
+  result = manifest.FindStringByDottedPath(key_prefix + "favicon_url");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("http://www.foo.de", *result);
 
-  ASSERT_TRUE(manifest.GetString(key_prefix + "suggest_url", &result));
-  EXPECT_EQ("http://www.foo.de", result);
+  result = manifest.FindStringByDottedPath(key_prefix + "suggest_url");
+  ASSERT_TRUE(result);
+  EXPECT_EQ("http://www.foo.de", *result);
 
-  ASSERT_TRUE(manifest.GetString(keys::kOverrideHomepage, &result));
-  EXPECT_EQ("http://www.foo.de", result);
+  result = manifest.FindStringByDottedPath(keys::kOverrideHomepage);
+  ASSERT_TRUE(result);
+  EXPECT_EQ("http://www.foo.de", *result);
 
-  base::ListValue* startup_pages_raw = nullptr;
-  ASSERT_TRUE(manifest.GetList(keys::kOverrideStartupPage, &startup_pages_raw));
-  base::Value::List& startup_pages_raw_list = startup_pages_raw->GetList();
-  ASSERT_FALSE(startup_pages_raw_list.empty());
-  ASSERT_TRUE(startup_pages_raw_list[0].is_string());
-  EXPECT_EQ("http://www.foo.de", startup_pages_raw_list[0].GetString());
+  base::Value::List* startup_pages_raw =
+      manifest.FindListByDottedPath(keys::kOverrideStartupPage);
+  ASSERT_TRUE(startup_pages_raw);
+  ASSERT_FALSE(startup_pages_raw->empty());
+  ASSERT_TRUE((*startup_pages_raw)[0].is_string());
+  EXPECT_EQ("http://www.foo.de", (*startup_pages_raw)[0].GetString());
 
   EXPECT_TRUE(error.empty());
 }
 
-// Tests that we don't relocalize with a null manifest.
-TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithNullManifest) {
-  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(NULL));
-}
-
 // Tests that we don't relocalize with default and current locales missing.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestEmptyManifest) {
-  base::DictionaryValue manifest;
-  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  base::Value::Dict manifest;
+  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we relocalize without a current locale.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithDefaultLocale) {
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en_US");
-  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en_US");
+  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we don't relocalize without a default locale.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithCurrentLocale) {
   extension_l10n_util::ScopedLocaleForTest scoped_locale("en-US");
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kCurrentLocale, "en_US");
-  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  base::Value::Dict manifest;
+  manifest.Set(keys::kCurrentLocale, "en_US");
+  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we don't relocalize with same current_locale as system locale.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestSameCurrentLocale) {
   extension_l10n_util::ScopedLocaleForTest scoped_locale("en-US");
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en_US");
-  manifest.SetStringKey(keys::kCurrentLocale, "en_US");
-  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en_US");
+  manifest.Set(keys::kCurrentLocale, "en_US");
+  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we relocalize with a different current_locale.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestDifferentCurrentLocale) {
   extension_l10n_util::ScopedLocaleForTest scoped_locale("en-US");
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en_US");
-  manifest.SetStringKey(keys::kCurrentLocale, "sr");
-  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en_US");
+  manifest.Set(keys::kCurrentLocale, "sr");
+  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we don't relocalize with the same current_locale as preferred
 // locale.
 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestSameCurrentLocaleAsPreferred) {
   extension_l10n_util::ScopedLocaleForTest scoped_locale("en-GB", "en-CA");
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en_US");
-  manifest.SetStringKey(keys::kCurrentLocale, "en_CA");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en_US");
+  manifest.Set(keys::kCurrentLocale, "en_CA");
 
   // Preferred and current locale are both en_CA.
-  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 // Tests that we relocalize with a different current_locale from the preferred
@@ -737,13 +751,13 @@
 TEST(ExtensionL10nUtil,
      ShouldRelocalizeManifestDifferentCurrentLocaleThanPreferred) {
   extension_l10n_util::ScopedLocaleForTest scoped_locale("en-GB", "en-CA");
-  base::DictionaryValue manifest;
-  manifest.SetStringKey(keys::kDefaultLocale, "en_US");
-  manifest.SetStringKey(keys::kCurrentLocale, "en_GB");
+  base::Value::Dict manifest;
+  manifest.Set(keys::kDefaultLocale, "en_US");
+  manifest.Set(keys::kCurrentLocale, "en_GB");
 
   // Requires relocalization as the preferred (en_CA) differs from current
   // (en_GB).
-  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
+  EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(manifest));
 }
 
 TEST(ExtensionL10nUtil, GetAllFallbackLocales) {
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc
index 5eac693..702ea21 100644
--- a/extensions/common/file_util.cc
+++ b/extensions/common/file_util.cc
@@ -227,7 +227,7 @@
     return nullptr;
 
   if (!extension_l10n_util::LocalizeExtension(
-          extension_path, manifest.get(),
+          extension_path, &manifest->GetDict(),
           extension_l10n_util::GetGzippedMessagesPermissionForLocation(
               location),
           error)) {
diff --git a/extensions/common/manifest_test.cc b/extensions/common/manifest_test.cc
index 42dd1e8..999a52e 100644
--- a/extensions/common/manifest_test.cc
+++ b/extensions/common/manifest_test.cc
@@ -58,7 +58,7 @@
     base::DictionaryValue* manifest_dictionary = nullptr;
     manifest->GetAsDictionary(&manifest_dictionary);
     extension_l10n_util::LocalizeExtension(
-        extension_path, manifest_dictionary,
+        extension_path, &manifest_dictionary->GetDict(),
         extension_l10n_util::GzippedMessagesPermission::kDisallow, error);
   }
 
diff --git a/extensions/renderer/bindings/api_binding.cc b/extensions/renderer/bindings/api_binding.cc
index 9c8f3660..5122217 100644
--- a/extensions/renderer/bindings/api_binding.cc
+++ b/extensions/renderer/bindings/api_binding.cc
@@ -63,15 +63,17 @@
 }
 
 std::unique_ptr<APISignature> GetAPISignatureFromDictionary(
-    const base::Value* dict,
+    const base::Value::Dict* dict,
     BindingAccessChecker* access_checker,
     const std::string& api_name) {
-  const base::Value* params =
-      dict->FindKeyOfType("parameters", base::Value::Type::LIST);
+  const base::Value* params = dict->Find("parameters");
+  if (params && !params->is_list())
+    params = nullptr;
   CHECK(params);
 
-  const base::Value* returns_async =
-      dict->FindKeyOfType("returns_async", base::Value::Type::DICTIONARY);
+  const base::Value* returns_async = dict->Find("returns_async");
+  if (returns_async && !returns_async->is_dict())
+    returns_async = nullptr;
 
   return APISignature::CreateFromValues(*params, returns_async, access_checker,
                                         api_name, false /*is_event_signature*/);
@@ -164,7 +166,7 @@
 struct APIBinding::CustomPropertyData {
   CustomPropertyData(const std::string& type_name,
                      const std::string& property_name,
-                     const base::ListValue* property_values,
+                     const base::Value::List* property_values,
                      const CreateCustomType& create_custom_type)
       : type_name(type_name),
         property_name(property_name),
@@ -177,16 +179,16 @@
   // chrome.storage.local.
   std::string property_name;
   // Values curried into this particular type from the schema.
-  const base::ListValue* property_values;
+  const base::Value::List* property_values;
 
   CreateCustomType create_custom_type;
 };
 
 APIBinding::APIBinding(const std::string& api_name,
-                       const base::ListValue* function_definitions,
-                       const base::ListValue* type_definitions,
-                       const base::ListValue* event_definitions,
-                       const base::DictionaryValue* property_definitions,
+                       const base::Value::List* function_definitions,
+                       const base::Value::List* type_definitions,
+                       const base::Value::List* event_definitions,
+                       const base::Value::Dict* property_definitions,
                        CreateCustomType create_custom_type,
                        OnSilentRequest on_silent_request,
                        std::unique_ptr<APIBindingHooks> binding_hooks,
@@ -210,55 +212,58 @@
   // construction.
 
   if (function_definitions) {
-    for (const auto& func : function_definitions->GetList()) {
-      const base::DictionaryValue* func_dict = nullptr;
-      CHECK(func.GetAsDictionary(&func_dict));
-      std::string name;
-      CHECK(func_dict->GetString("name", &name));
+    for (const auto& func : *function_definitions) {
+      const base::Value::Dict* func_dict = func.GetIfDict();
+      CHECK(func_dict);
+      const std::string* name = func_dict->FindString("name");
+      CHECK(name);
       std::string full_name =
-          base::StringPrintf("%s.%s", api_name_.c_str(), name.c_str());
+          base::StringPrintf("%s.%s", api_name_.c_str(), name->c_str());
 
       auto signature =
           GetAPISignatureFromDictionary(func_dict, access_checker, full_name);
 
-      methods_[name] = std::make_unique<MethodData>(full_name, signature.get());
+      methods_[*name] =
+          std::make_unique<MethodData>(full_name, signature.get());
       type_refs->AddAPIMethodSignature(full_name, std::move(signature));
     }
   }
 
   if (type_definitions) {
-    for (const auto& type : type_definitions->GetList()) {
-      const base::DictionaryValue* type_dict = nullptr;
-      CHECK(type.GetAsDictionary(&type_dict));
-      std::string id;
-      CHECK(type_dict->GetString("id", &id));
-      auto argument_spec = std::make_unique<ArgumentSpec>(*type_dict);
+    for (const auto& type : *type_definitions) {
+      const base::Value::Dict* type_dict = type.GetIfDict();
+      CHECK(type_dict);
+      const std::string* id = type_dict->FindString("id");
+      CHECK(id);
+      auto argument_spec = std::make_unique<ArgumentSpec>(type);
       const std::set<std::string>& enum_values = argument_spec->enum_values();
       if (!enum_values.empty()) {
         // Type names may be prefixed by the api name. If so, remove the prefix.
         absl::optional<std::string> stripped_id;
-        if (base::StartsWith(id, api_name_, base::CompareCase::SENSITIVE))
-          stripped_id = id.substr(api_name_.size() + 1);  // +1 for trailing '.'
+        if (base::StartsWith(*id, api_name_, base::CompareCase::SENSITIVE))
+          stripped_id =
+              id->substr(api_name_.size() + 1);  // +1 for trailing '.'
         std::vector<EnumEntry>& entries =
-            enums_[stripped_id ? *stripped_id : id];
+            enums_[stripped_id ? *stripped_id : *id];
         entries.reserve(enum_values.size());
         for (const auto& enum_value : enum_values) {
           entries.push_back(
               std::make_pair(enum_value, GetJSEnumEntryName(enum_value)));
         }
       }
-      type_refs->AddSpec(id, std::move(argument_spec));
+      type_refs->AddSpec(*id, std::move(argument_spec));
       // Some types, like storage.StorageArea, have functions associated with
       // them. Cache the function signatures in the type map.
-      const base::ListValue* type_functions = nullptr;
-      if (type_dict->GetList("functions", &type_functions)) {
-        for (const auto& func : type_functions->GetList()) {
-          const base::DictionaryValue* func_dict = nullptr;
-          CHECK(func.GetAsDictionary(&func_dict));
-          std::string function_name;
-          CHECK(func_dict->GetString("name", &function_name));
+      const base::Value::List* type_functions =
+          type_dict->FindList("functions");
+      if (type_functions) {
+        for (const auto& func : *type_functions) {
+          const base::Value::Dict* func_dict = func.GetIfDict();
+          CHECK(func_dict);
+          const std::string* function_name = func_dict->FindString("name");
+          CHECK(function_name);
           std::string full_name =
-              base::StringPrintf("%s.%s", id.c_str(), function_name.c_str());
+              base::StringPrintf("%s.%s", id->c_str(), function_name->c_str());
 
           auto signature = GetAPISignatureFromDictionary(
               func_dict, access_checker, full_name);
@@ -270,43 +275,42 @@
   }
 
   if (event_definitions) {
-    events_.reserve(event_definitions->GetList().size());
-    for (const auto& event : event_definitions->GetList()) {
-      const base::DictionaryValue* event_dict = nullptr;
-      CHECK(event.GetAsDictionary(&event_dict));
-      std::string name;
-      CHECK(event_dict->GetString("name", &name));
+    events_.reserve(event_definitions->size());
+    for (const auto& event : *event_definitions) {
+      const base::Value::Dict* event_dict = event.GetIfDict();
+      CHECK(event_dict);
+      const std::string* name = event_dict->FindString("name");
+      CHECK(name);
       std::string full_name =
-          base::StringPrintf("%s.%s", api_name_.c_str(), name.c_str());
-      const base::ListValue* filters = nullptr;
-      bool supports_filters = event_dict->GetList("filters", &filters) &&
-                              !filters->GetList().empty();
+          base::StringPrintf("%s.%s", api_name_.c_str(), name->c_str());
+      const base::Value::List* filters = event_dict->FindList("filters");
+      bool supports_filters = filters && !filters->empty();
 
       std::vector<std::string> rule_actions;
       std::vector<std::string> rule_conditions;
-      const base::DictionaryValue* options = nullptr;
+      const base::Value::Dict* options = event_dict->FindDict("options");
       bool supports_rules = false;
       bool notify_on_change = true;
       bool supports_lazy_listeners = true;
       int max_listeners = binding::kNoListenerMax;
-      if (event_dict->GetDictionary("options", &options)) {
+      if (options) {
         // TODO(devlin): For some reason, schemas indicate supporting filters
         // either through having a 'filters' property *or* through having
         // a 'supportsFilters' property. We should clean that up.
         supports_filters |=
-            options->FindBoolKey("supportsFilters").value_or(false);
-        supports_rules = options->FindBoolKey("supportsRules").value_or(false);
+            options->FindBool("supportsFilters").value_or(false);
+        supports_rules = options->FindBool("supportsRules").value_or(false);
         if (supports_rules) {
           absl::optional<bool> supports_listeners =
-              options->FindBoolKey("supportsListeners");
+              options->FindBool("supportsListeners");
           DCHECK(supports_listeners);
           DCHECK(!*supports_listeners)
               << "Events cannot support rules and listeners.";
           auto get_values = [options](base::StringPiece name,
                                       std::vector<std::string>* out_value) {
-            const base::ListValue* list = nullptr;
-            CHECK(options->GetList(name, &list));
-            for (const auto& entry : list->GetList()) {
+            const base::Value::List* list = options->FindList(name);
+            CHECK(list);
+            for (const auto& entry : *list) {
               DCHECK(entry.is_string());
               out_value->push_back(entry.GetString());
             }
@@ -316,15 +320,15 @@
         }
 
         absl::optional<int> max_listeners_option =
-            options->FindIntKey("maxListeners");
+            options->FindInt("maxListeners");
         if (max_listeners_option)
           max_listeners = *max_listeners_option;
-        absl::optional<bool> unmanaged = options->FindBoolKey("unmanaged");
+        absl::optional<bool> unmanaged = options->FindBool("unmanaged");
         if (unmanaged)
           notify_on_change = !*unmanaged;
 
         absl::optional<bool> supports_lazy_listeners_value =
-            options->FindBoolKey("supportsLazyListeners");
+            options->FindBool("supportsLazyListeners");
         if (supports_lazy_listeners_value) {
           supports_lazy_listeners = *supports_lazy_listeners_value;
           DCHECK(!supports_lazy_listeners)
@@ -333,8 +337,9 @@
       }
 
       if (binding::IsResponseValidationEnabled()) {
-        const base::Value* params =
-            event_dict->FindKeyOfType("parameters", base::Value::Type::LIST);
+        const base::Value* params = event_dict->Find("parameters");
+        if (params && !params->is_list())
+          params = nullptr;
         // NOTE: At least in tests, events may omit "parameters". It's unclear
         // if real schemas do, too. For now, sub in an empty list if necessary.
         // TODO(devlin): Track this down and CHECK(params).
@@ -342,16 +347,15 @@
         std::unique_ptr<APISignature> event_signature =
             APISignature::CreateFromValues(
                 params ? *params : empty_params, nullptr /*returns_async*/,
-                access_checker, name, true /*is_event_signature*/);
+                access_checker, *name, true /*is_event_signature*/);
         DCHECK(!event_signature->has_async_return());
         type_refs_->AddEventSignature(full_name, std::move(event_signature));
       }
 
       events_.push_back(std::make_unique<EventData>(
-          std::move(name), std::move(full_name), supports_filters,
-          supports_rules, supports_lazy_listeners, max_listeners,
-          notify_on_change, std::move(rule_actions), std::move(rule_conditions),
-          this));
+          *name, std::move(full_name), supports_filters, supports_rules,
+          supports_lazy_listeners, max_listeners, notify_on_change,
+          std::move(rule_actions), std::move(rule_conditions), this));
     }
   }
 }
@@ -457,79 +461,78 @@
 void APIBinding::DecorateTemplateWithProperties(
     v8::Isolate* isolate,
     v8::Local<v8::ObjectTemplate> object_template,
-    const base::DictionaryValue& properties,
+    const base::Value::Dict& properties,
     bool is_root) {
   static const char kValueKey[] = "value";
-  for (base::DictionaryValue::Iterator iter(properties); !iter.IsAtEnd();
-       iter.Advance()) {
-    const base::DictionaryValue* dict = nullptr;
-    CHECK(iter.value().GetAsDictionary(&dict));
-    if (dict->FindBoolKey("optional")) {
+  for (auto item : properties) {
+    const base::Value::Dict* dict = item.second.GetIfDict();
+    CHECK(dict);
+    if (dict->FindBool("optional")) {
       // TODO(devlin): What does optional even mean here? It's only used, it
       // seems, for lastError and inIncognitoContext, which are both handled
       // with custom bindings. Investigate, and remove.
       continue;
     }
 
-    const base::ListValue* platforms = nullptr;
+    const base::Value::List* platforms = dict->FindList("platforms");
     // TODO(devlin): Availability should be specified in the features files,
     // not the API schema files.
-    if (dict->GetList("platforms", &platforms)) {
+    if (platforms) {
       std::string this_platform = binding::GetPlatformString();
       auto is_this_platform = [&this_platform](const base::Value& platform) {
         return platform.is_string() && platform.GetString() == this_platform;
       };
-      if (base::ranges::none_of(platforms->GetList(), is_this_platform))
+      if (base::ranges::none_of(*platforms, is_this_platform))
         continue;
     }
 
-    v8::Local<v8::String> v8_key = gin::StringToSymbol(isolate, iter.key());
-    std::string ref;
-    if (dict->GetString("$ref", &ref)) {
-      const base::ListValue* property_values = nullptr;
-      CHECK(dict->GetList("value", &property_values));
+    v8::Local<v8::String> v8_key = gin::StringToSymbol(isolate, item.first);
+    const std::string* ref = dict->FindString("$ref");
+    if (ref) {
+      const base::Value::List* property_values = dict->FindList("value");
+      CHECK(property_values);
       auto property_data = std::make_unique<CustomPropertyData>(
-          ref, iter.key(), property_values, create_custom_type_);
+          *ref, item.first, property_values, create_custom_type_);
       object_template->SetLazyDataProperty(
           v8_key, &APIBinding::GetCustomPropertyObject,
           v8::External::New(isolate, property_data.get()));
       custom_properties_.push_back(std::move(property_data));
       if (is_root)
-        root_properties_.insert(iter.key());
+        root_properties_.insert(item.first);
       continue;
     }
 
-    std::string type;
-    CHECK(dict->GetString("type", &type));
-    if (type != "object" && !dict->FindKey(kValueKey)) {
+    const std::string* type = dict->FindString("type");
+    CHECK(type);
+    if (*type != "object" && !dict->Find(kValueKey)) {
       // TODO(devlin): What does a fundamental property not having a value mean?
       // It doesn't seem useful, and looks like it's only used by runtime.id,
       // which is set by custom bindings. Investigate, and remove.
       continue;
     }
-    if (type == "integer") {
-      absl::optional<int> val = dict->FindIntKey(kValueKey);
+    if (*type == "integer") {
+      absl::optional<int> val = dict->FindInt(kValueKey);
       CHECK(val);
       object_template->Set(v8_key, v8::Integer::New(isolate, *val));
-    } else if (type == "boolean") {
-      absl::optional<bool> val = dict->FindBoolKey(kValueKey);
+    } else if (*type == "boolean") {
+      absl::optional<bool> val = dict->FindBool(kValueKey);
       CHECK(val);
       object_template->Set(v8_key, v8::Boolean::New(isolate, *val));
-    } else if (type == "string") {
-      std::string val;
-      CHECK(dict->GetString(kValueKey, &val)) << iter.key();
-      object_template->Set(v8_key, gin::StringToSymbol(isolate, val));
-    } else if (type == "object" || !ref.empty()) {
+    } else if (*type == "string") {
+      const std::string* val = dict->FindString(kValueKey);
+      CHECK(val) << item.first;
+      object_template->Set(v8_key, gin::StringToSymbol(isolate, *val));
+    } else if (*type == "object" || !ref->empty()) {
       v8::Local<v8::ObjectTemplate> property_template =
           v8::ObjectTemplate::New(isolate);
-      const base::DictionaryValue* property_dict = nullptr;
-      CHECK(dict->GetDictionary("properties", &property_dict));
+      const base::Value::Dict* property_dict = dict->FindDict("properties");
+      CHECK(property_dict);
       DecorateTemplateWithProperties(isolate, property_template, *property_dict,
                                      /*is_root=*/false);
       object_template->Set(v8_key, property_template);
     }
     if (is_root)
-      root_properties_.insert(iter.key());
+      root_properties_.insert(item.first);
   }
 }
 
diff --git a/extensions/renderer/bindings/api_binding.h b/extensions/renderer/bindings/api_binding.h
index d27ee36..b92227d5 100644
--- a/extensions/renderer/bindings/api_binding.h
+++ b/extensions/renderer/bindings/api_binding.h
@@ -13,13 +13,10 @@
 #include "base/containers/flat_set.h"
 #include "base/memory/weak_ptr.h"
 #include "base/supports_user_data.h"
+#include "base/values.h"
 #include "extensions/renderer/bindings/argument_spec.h"
 #include "v8/include/v8.h"
 
-namespace base {
-class ListValue;
-}
-
 namespace gin {
 class Arguments;
 }
@@ -50,7 +47,7 @@
       v8::Isolate* isolate,
       const std::string& type_name,
       const std::string& property_name,
-      const base::ListValue* property_values)>;
+      const base::Value::List* property_values)>;
 
   // Called when a request is handled without notifying the browser.
   using OnSilentRequest = base::RepeatingCallback<void(
@@ -65,10 +62,10 @@
   // |function_definitions|, |type_definitions| and |event_definitions|
   // may be null if the API does not specify any of that category.
   APIBinding(const std::string& name,
-             const base::ListValue* function_definitions,
-             const base::ListValue* type_definitions,
-             const base::ListValue* event_definitions,
-             const base::DictionaryValue* property_definitions,
+             const base::Value::List* function_definitions,
+             const base::Value::List* type_definitions,
+             const base::Value::List* event_definitions,
+             const base::Value::Dict* property_definitions,
              CreateCustomType create_custom_type,
              OnSilentRequest on_silent_request,
              std::unique_ptr<APIBindingHooks> binding_hooks,
@@ -103,7 +100,7 @@
   void DecorateTemplateWithProperties(
       v8::Isolate* isolate,
       v8::Local<v8::ObjectTemplate> object_template,
-      const base::DictionaryValue& properties,
+      const base::Value::Dict& properties,
       bool is_root);
 
   // Handler for getting the v8::Object associated with an event on the API.
@@ -144,7 +141,7 @@
   std::map<std::string, std::vector<EnumEntry>> enums_;
 
   // The associated properties of the API, if any.
-  const base::DictionaryValue* property_definitions_;
+  const base::Value::Dict* property_definitions_;
   // The names of all the "root properties" added to the API; i.e., properties
   // exposed on the API object itself.
   base::flat_set<std::string> root_properties_;
diff --git a/extensions/renderer/bindings/api_binding_test_util.cc b/extensions/renderer/bindings/api_binding_test_util.cc
index 8946d87..c5335da 100644
--- a/extensions/renderer/bindings/api_binding_test_util.cc
+++ b/extensions/renderer/bindings/api_binding_test_util.cc
@@ -108,9 +108,9 @@
   return base::DictionaryValue::From(DeprecatedValueFromString(str));
 }
 
-std::string ValueToString(const base::Value& value) {
+std::string ValueToString(const base::ValueView& value_view) {
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(value, &json));
+  EXPECT_TRUE(base::JSONWriter::Write(value_view, &json));
   return json;
 }
 
diff --git a/extensions/renderer/bindings/api_binding_test_util.h b/extensions/renderer/bindings/api_binding_test_util.h
index bebc1eae..6842fe5 100644
--- a/extensions/renderer/bindings/api_binding_test_util.h
+++ b/extensions/renderer/bindings/api_binding_test_util.h
@@ -32,11 +32,6 @@
 // DEPRECATED: prefer `ValueFromString`.
 std::unique_ptr<base::Value> DeprecatedValueFromString(base::StringPiece str);
 
-// As above, but returning a ListValue.
-// DEPRECATED: prefer `ListValueFromString`.
-std::unique_ptr<base::ListValue> DeprecatedListValueFromString(
-    base::StringPiece str);
-
 // As above, but returning a DictionaryValue.
 // DEPRECATED: prefer `DictValueFromString`.
 std::unique_ptr<base::DictionaryValue> DeprecatedDictionaryValueFromString(
@@ -44,7 +39,7 @@
 
 // Converts the given |value| to a JSON string. EXPECTs the conversion to
 // succeed.
-std::string ValueToString(const base::Value& value);
+std::string ValueToString(const base::ValueView&);
 
 // Converts the given |value| to a string. Returns "empty", "undefined", "null",
 // or "function" for unserializable values. Note this differs from
diff --git a/extensions/renderer/bindings/api_binding_unittest.cc b/extensions/renderer/bindings/api_binding_unittest.cc
index 5f549cf6..f636611 100644
--- a/extensions/renderer/bindings/api_binding_unittest.cc
+++ b/extensions/renderer/bindings/api_binding_unittest.cc
@@ -211,23 +211,19 @@
   }
 
   void SetFunctions(const char* functions) {
-    binding_functions_ = DeprecatedListValueFromString(functions);
-    ASSERT_TRUE(binding_functions_);
+    binding_functions_ = ListValueFromString(functions);
   }
 
   void SetEvents(const char* events) {
-    binding_events_ = DeprecatedListValueFromString(events);
-    ASSERT_TRUE(binding_events_);
+    binding_events_ = ListValueFromString(events);
   }
 
   void SetTypes(const char* types) {
-    binding_types_ = DeprecatedListValueFromString(types);
-    ASSERT_TRUE(binding_types_);
+    binding_types_ = ListValueFromString(types);
   }
 
   void SetProperties(const char* properties) {
-    binding_properties_ = DeprecatedDictionaryValueFromString(properties);
-    ASSERT_TRUE(binding_properties_);
+    binding_properties_ = DictValueFromString(properties);
   }
 
   void SetHooks(std::unique_ptr<APIBindingHooks> hooks) {
@@ -311,11 +307,10 @@
     access_checker_ = std::make_unique<BindingAccessChecker>(
         api_availability_callback_, promise_availability_callback_);
     binding_ = std::make_unique<APIBinding>(
-        kBindingName, binding_functions_.get(), binding_types_.get(),
-        binding_events_.get(), binding_properties_.get(), create_custom_type_,
-        on_silent_request_, std::move(binding_hooks_), &type_refs_,
-        request_handler_.get(), event_handler_.get(), access_checker_.get());
-    EXPECT_EQ(!binding_types_.get(), type_refs_.empty());
+        kBindingName, &binding_functions_, &binding_types_, &binding_events_,
+        &binding_properties_, create_custom_type_, on_silent_request_,
+        std::move(binding_hooks_), &type_refs_, request_handler_.get(),
+        event_handler_.get(), access_checker_.get());
   }
 
   v8::Local<v8::Value> ExpectPass(
@@ -386,10 +381,10 @@
   std::unique_ptr<BindingAccessChecker> access_checker_;
   APITypeReferenceMap type_refs_;
 
-  std::unique_ptr<base::ListValue> binding_functions_;
-  std::unique_ptr<base::ListValue> binding_events_;
-  std::unique_ptr<base::ListValue> binding_types_;
-  std::unique_ptr<base::DictionaryValue> binding_properties_;
+  base::Value::List binding_functions_;
+  base::Value::List binding_events_;
+  base::Value::List binding_types_;
+  base::Value::Dict binding_properties_;
   std::unique_ptr<APIBindingHooks> binding_hooks_;
   std::unique_ptr<APIBindingHooksDelegate> binding_hooks_delegate_;
   APIBinding::CreateCustomType create_custom_type_;
@@ -802,7 +797,7 @@
   auto create_custom_type = [](v8::Isolate* isolate,
                                const std::string& type_name,
                                const std::string& property_name,
-                               const base::ListValue* property_values) {
+                               const base::Value::List* property_values) {
     v8::Local<v8::Context> context = isolate->GetCurrentContext();
     v8::Local<v8::Object> result = v8::Object::New(isolate);
     if (type_name == "AlphaRef") {
diff --git a/extensions/renderer/bindings/api_bindings_system.cc b/extensions/renderer/bindings/api_bindings_system.cc
index 243935f..b0b7f60 100644
--- a/extensions/renderer/bindings/api_bindings_system.cc
+++ b/extensions/renderer/bindings/api_bindings_system.cc
@@ -66,16 +66,14 @@
 
 std::unique_ptr<APIBinding> APIBindingsSystem::CreateNewAPIBinding(
     const std::string& api_name) {
-  const base::DictionaryValue& api_schema = get_api_schema_.Run(api_name);
+  const base::Value::Dict& api_schema = get_api_schema_.Run(api_name);
 
-  const base::ListValue* function_definitions = nullptr;
-  api_schema.GetList("functions", &function_definitions);
-  const base::ListValue* type_definitions = nullptr;
-  api_schema.GetList("types", &type_definitions);
-  const base::ListValue* event_definitions = nullptr;
-  api_schema.GetList("events", &event_definitions);
-  const base::DictionaryValue* property_definitions = nullptr;
-  api_schema.GetDictionary("properties", &property_definitions);
+  const base::Value::List* function_definitions =
+      api_schema.FindList("functions");
+  const base::Value::List* type_definitions = api_schema.FindList("types");
+  const base::Value::List* event_definitions = api_schema.FindList("events");
+  const base::Value::Dict* property_definitions =
+      api_schema.FindDict("properties");
 
   // Find the hooks for the API. If none exist, an empty set will be created so
   // we can use JS custom bindings.
@@ -160,7 +158,7 @@
     v8::Isolate* isolate,
     const std::string& type_name,
     const std::string& property_name,
-    const base::ListValue* property_values) {
+    const base::Value::List* property_values) {
   auto iter = custom_types_.find(type_name);
   DCHECK(iter != custom_types_.end()) << "Custom type not found: " << type_name;
   return iter->second.Run(isolate, property_name, property_values,
diff --git a/extensions/renderer/bindings/api_bindings_system.h b/extensions/renderer/bindings/api_bindings_system.h
index 387510f7..5f244a9 100644
--- a/extensions/renderer/bindings/api_bindings_system.h
+++ b/extensions/renderer/bindings/api_bindings_system.h
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/values.h"
 #include "extensions/common/mojom/event_dispatcher.mojom-forward.h"
 #include "extensions/renderer/bindings/api_binding.h"
 #include "extensions/renderer/bindings/api_binding_types.h"
@@ -20,11 +21,6 @@
 #include "extensions/renderer/bindings/binding_access_checker.h"
 #include "extensions/renderer/bindings/exception_handler.h"
 
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
 namespace extensions {
 class APIBindingHooks;
 class InteractionProvider;
@@ -35,11 +31,11 @@
 class APIBindingsSystem {
  public:
   using GetAPISchemaMethod =
-      base::RepeatingCallback<const base::DictionaryValue&(const std::string&)>;
+      base::RepeatingCallback<const base::Value::Dict&(const std::string&)>;
   using CustomTypeHandler = base::RepeatingCallback<v8::Local<v8::Object>(
       v8::Isolate* isolate,
       const std::string& property_name,
-      const base::ListValue* property_values,
+      const base::Value::List* property_values,
       APIRequestHandler* request_handler,
       APIEventHandler* event_handler,
       APITypeReferenceMap* type_refs,
@@ -120,7 +116,7 @@
       v8::Isolate* isolate,
       const std::string& type_name,
       const std::string& property_name,
-      const base::ListValue* property_values);
+      const base::Value::List* property_values);
 
   // The map of cached API reference types.
   APITypeReferenceMap type_reference_map_;
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.cc b/extensions/renderer/bindings/api_bindings_system_unittest.cc
index 2c4603f..b2d8a848 100644
--- a/extensions/renderer/bindings/api_bindings_system_unittest.cc
+++ b/extensions/renderer/bindings/api_bindings_system_unittest.cc
@@ -135,9 +135,7 @@
 
   // Create the fake API schemas.
   for (const auto& api : GetAPIs()) {
-    std::unique_ptr<base::DictionaryValue> api_schema =
-        DeprecatedDictionaryValueFromString(api.spec);
-    ASSERT_TRUE(api_schema);
+    base::Value::Dict api_schema = DictValueFromString(api.spec);
     api_schemas_[api.name] = std::move(api_schema);
   }
 
@@ -194,10 +192,10 @@
   console_errors_.push_back(error);
 }
 
-const base::DictionaryValue& APIBindingsSystemTest::GetAPISchema(
+const base::Value::Dict& APIBindingsSystemTest::GetAPISchema(
     const std::string& api_name) {
   EXPECT_TRUE(base::Contains(api_schemas_, api_name));
-  return *api_schemas_[api_name];
+  return api_schemas_[api_name];
 }
 
 void APIBindingsSystemTest::OnAPIRequest(
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.h b/extensions/renderer/bindings/api_bindings_system_unittest.h
index f69d7df..217ab94 100644
--- a/extensions/renderer/bindings/api_bindings_system_unittest.h
+++ b/extensions/renderer/bindings/api_bindings_system_unittest.h
@@ -62,7 +62,7 @@
 
   // Returns the DictionaryValue representing the schema with the given API
   // name.
-  const base::DictionaryValue& GetAPISchema(const std::string& api_name);
+  const base::Value::Dict& GetAPISchema(const std::string& api_name);
 
   // Callback for event listeners changing.
   void OnEventListenersChanged(const std::string& event_name,
@@ -99,7 +99,7 @@
 
  private:
   // The API schemas for the fake APIs.
-  std::map<std::string, std::unique_ptr<base::DictionaryValue>> api_schemas_;
+  std::map<std::string, base::Value::Dict> api_schemas_;
 
   // The APIBindingsSystem associated with the test. Safe to use across multiple
   // contexts.
diff --git a/extensions/renderer/chrome_setting.cc b/extensions/renderer/chrome_setting.cc
index 28242e4..bf68980 100644
--- a/extensions/renderer/chrome_setting.cc
+++ b/extensions/renderer/chrome_setting.cc
@@ -23,15 +23,14 @@
 v8::Local<v8::Object> ChromeSetting::Create(
     v8::Isolate* isolate,
     const std::string& property_name,
-    const base::ListValue* property_values,
+    const base::Value::List* property_values,
     APIRequestHandler* request_handler,
     APIEventHandler* event_handler,
     APITypeReferenceMap* type_refs,
     const BindingAccessChecker* access_checker) {
-  const base::Value::List& property_values_list = property_values->GetList();
-  CHECK_GE(property_values_list.size(), 2u);
-  const std::string& pref_name = property_values_list[0u].GetString();
-  const base::Value& value_spec = property_values_list[1u];
+  CHECK_GE(property_values->size(), 2u);
+  const std::string& pref_name = (*property_values)[0u].GetString();
+  const base::Value& value_spec = (*property_values)[1u];
   CHECK(value_spec.is_dict());
 
   gin::Handle<ChromeSetting> handle = gin::CreateHandle(
diff --git a/extensions/renderer/chrome_setting.h b/extensions/renderer/chrome_setting.h
index 58f93641..e0f2082 100644
--- a/extensions/renderer/chrome_setting.h
+++ b/extensions/renderer/chrome_setting.h
@@ -7,15 +7,11 @@
 
 #include <string>
 
+#include "base/values.h"
 #include "extensions/renderer/bindings/argument_spec.h"
 #include "gin/wrappable.h"
 #include "v8/include/v8-forward.h"
 
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
 namespace gin {
 class Arguments;
 }
@@ -37,7 +33,7 @@
   static v8::Local<v8::Object> Create(
       v8::Isolate* isolate,
       const std::string& property_name,
-      const base::ListValue* property_values,
+      const base::Value::List* property_values,
       APIRequestHandler* request_handler,
       APIEventHandler* event_handler,
       APITypeReferenceMap* type_refs,
diff --git a/extensions/renderer/content_setting.cc b/extensions/renderer/content_setting.cc
index 743311b1..399a40b 100644
--- a/extensions/renderer/content_setting.cc
+++ b/extensions/renderer/content_setting.cc
@@ -54,15 +54,14 @@
 v8::Local<v8::Object> ContentSetting::Create(
     v8::Isolate* isolate,
     const std::string& property_name,
-    const base::ListValue* property_values,
+    const base::Value::List* property_values,
     APIRequestHandler* request_handler,
     APIEventHandler* event_handler,
     APITypeReferenceMap* type_refs,
     const BindingAccessChecker* access_checker) {
-  const base::Value::List& property_values_list = property_values->GetList();
-  CHECK_GE(property_values_list.size(), 2u);
-  const std::string& pref_name = property_values_list[0].GetString();
-  const base::Value& value_spec = property_values_list[1u];
+  CHECK_GE(property_values->size(), 2u);
+  const std::string& pref_name = (*property_values)[0].GetString();
+  const base::Value& value_spec = (*property_values)[1u];
   CHECK(value_spec.is_dict());
 
   gin::Handle<ContentSetting> handle = gin::CreateHandle(
diff --git a/extensions/renderer/content_setting.h b/extensions/renderer/content_setting.h
index d082a60..39a8bcee 100644
--- a/extensions/renderer/content_setting.h
+++ b/extensions/renderer/content_setting.h
@@ -7,15 +7,11 @@
 
 #include <string>
 
+#include "base/values.h"
 #include "extensions/renderer/bindings/argument_spec.h"
 #include "gin/wrappable.h"
 #include "v8/include/v8-forward.h"
 
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
 namespace gin {
 class Arguments;
 }
@@ -38,7 +34,7 @@
   static v8::Local<v8::Object> Create(
       v8::Isolate* isolate,
       const std::string& property_name,
-      const base::ListValue* property_values,
+      const base::Value::List* property_values,
       APIRequestHandler* request_handler,
       APIEventHandler* event_handler,
       APITypeReferenceMap* type_refs,
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc
index 35033fc2..fccbc93 100644
--- a/extensions/renderer/native_extension_bindings_system.cc
+++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -187,8 +187,8 @@
 }
 
 // Returns the API schema indicated by |api_name|.
-const base::DictionaryValue& GetAPISchema(const std::string& api_name) {
-  const base::DictionaryValue* schema =
+const base::Value::Dict& GetAPISchema(const std::string& api_name) {
+  const base::Value::Dict* schema =
       ExtensionAPI::GetSharedInstance()->GetSchema(api_name);
   CHECK(schema) << api_name;
   return *schema;
diff --git a/extensions/renderer/resources/automation/automation_node.js b/extensions/renderer/resources/automation/automation_node.js
index 633d300..00d83fe 100644
--- a/extensions/renderer/resources/automation/automation_node.js
+++ b/extensions/renderer/resources/automation/automation_node.js
@@ -1506,6 +1506,7 @@
   'containerLiveStatus',
   'description',
   'display',
+  'doDefaultLabel',
   'fontFamily',
   'htmlTag',
   'imageDataUrl',
@@ -1513,6 +1514,7 @@
   'language',
   'liveRelevant',
   'liveStatus',
+  'longClickLabel',
   'placeholder',
   'roleDescription',
   'tooltip',
diff --git a/extensions/renderer/storage_area.cc b/extensions/renderer/storage_area.cc
index d6151a3..6f0b1ff 100644
--- a/extensions/renderer/storage_area.cc
+++ b/extensions/renderer/storage_area.cc
@@ -243,7 +243,7 @@
 v8::Local<v8::Object> StorageArea::CreateStorageArea(
     v8::Isolate* isolate,
     const std::string& property_name,
-    const base::ListValue* property_values,
+    const base::Value::List*,
     APIRequestHandler* request_handler,
     APIEventHandler* event_handler,
     APITypeReferenceMap* type_refs,
diff --git a/extensions/renderer/storage_area.h b/extensions/renderer/storage_area.h
index 675d9c9..31610b2 100644
--- a/extensions/renderer/storage_area.h
+++ b/extensions/renderer/storage_area.h
@@ -8,12 +8,9 @@
 #include <string>
 
 #include "base/strings/string_piece.h"
+#include "base/values.h"
 #include "v8/include/v8-forward.h"
 
-namespace base {
-class ListValue;
-}
-
 namespace gin {
 class Arguments;
 }
@@ -43,7 +40,7 @@
   static v8::Local<v8::Object> CreateStorageArea(
       v8::Isolate* isolate,
       const std::string& property_name,
-      const base::ListValue* property_values,
+      const base::Value::List* property_values,
       APIRequestHandler* request_handler,
       APIEventHandler* event_handler,
       APITypeReferenceMap* type_refs,
diff --git a/extensions/renderer/web_request_hooks.cc b/extensions/renderer/web_request_hooks.cc
index a08dea9..2f35803 100644
--- a/extensions/renderer/web_request_hooks.cc
+++ b/extensions/renderer/web_request_hooks.cc
@@ -63,11 +63,12 @@
   // The JS validates that the extra parameters passed to the web request event
   // match the expected schema. We need to initialize the event with that
   // schema.
-  const base::DictionaryValue* event_spec =
+  const base::Value::Dict* event_spec =
       ExtensionAPI::GetSharedInstance()->GetSchema(event_name);
   DCHECK(event_spec);
-  const base::ListValue* extra_params = nullptr;
-  CHECK(event_spec->GetList("extraParameters", &extra_params));
+  const base::Value::List* extra_params =
+      event_spec->FindList("extraParameters");
+  CHECK(extra_params);
   v8::Local<v8::Value> extra_parameters_spec =
       content::V8ValueConverter::Create()->ToV8Value(*extra_params, context);
 
diff --git a/extensions/shell/common/shell_content_client.cc b/extensions/shell/common/shell_content_client.cc
index 18deacb1..77d5f6d5 100644
--- a/extensions/shell/common/shell_content_client.cc
+++ b/extensions/shell/common/shell_content_client.cc
@@ -18,7 +18,7 @@
 #include "base/path_service.h"
 #include "components/nacl/common/nacl_constants.h"              // nogncheck
 #include "components/nacl/renderer/plugin/ppapi_entrypoints.h"  // nogncheck
-#include "content/public/common/pepper_plugin_info.h"           // nogncheck
+#include "content/public/common/content_plugin_info.h"          // nogncheck
 #include "ppapi/shared_impl/ppapi_permissions.h"                // nogncheck
 #endif
 
@@ -44,14 +44,14 @@
 ShellContentClient::~ShellContentClient() {
 }
 
-void ShellContentClient::AddPepperPlugins(
-    std::vector<content::PepperPluginInfo>* plugins) {
+void ShellContentClient::AddPlugins(
+    std::vector<content::ContentPluginInfo>* plugins) {
 #if BUILDFLAG(ENABLE_NACL)
   base::FilePath path;
   if (!GetNaClPluginPath(&path))
     return;
 
-  content::PepperPluginInfo nacl;
+  content::ContentPluginInfo nacl;
   // The nacl plugin is now built into the binary.
   nacl.is_internal = true;
   nacl.path = path;
diff --git a/extensions/shell/common/shell_content_client.h b/extensions/shell/common/shell_content_client.h
index a8140d9d..48d9fbe 100644
--- a/extensions/shell/common/shell_content_client.h
+++ b/extensions/shell/common/shell_content_client.h
@@ -5,9 +5,7 @@
 #ifndef EXTENSIONS_SHELL_COMMON_SHELL_CONTENT_CLIENT_H_
 #define EXTENSIONS_SHELL_COMMON_SHELL_CONTENT_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "content/public/common/content_client.h"
-#include "url/url_util.h"
 
 namespace extensions {
 
@@ -20,8 +18,7 @@
 
   ~ShellContentClient() override;
 
-  void AddPepperPlugins(
-      std::vector<content::PepperPluginInfo>* plugins) override;
+  void AddPlugins(std::vector<content::ContentPluginInfo>* plugins) override;
   void AddAdditionalSchemes(Schemes* schemes) override;
   std::u16string GetLocalizedString(int message_id) override;
   base::StringPiece GetDataResource(
diff --git a/fuchsia_web/webengine/browser/content_directory_loader_factory.cc b/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
index 904dd47..8d286f3 100644
--- a/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
+++ b/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
@@ -245,7 +245,8 @@
       return;
     }
 
-    client_->OnReceiveResponse(std::move(response), std::move(consumer_handle));
+    client_->OnReceiveResponse(std::move(response), std::move(consumer_handle),
+                               absl::nullopt);
 
     // Start reading the contents of |mmap_| into the response DataPipe.
     body_writer_ =
diff --git a/gin/v8_isolate_memory_dump_provider.cc b/gin/v8_isolate_memory_dump_provider.cc
index fcc8659..ee4db5e 100644
--- a/gin/v8_isolate_memory_dump_provider.cc
+++ b/gin/v8_isolate_memory_dump_provider.cc
@@ -183,7 +183,6 @@
 
   std::string space_name_prefix = dump_base_name + "/heap";
 
-  size_t known_spaces_used_size = 0;
   size_t known_spaces_size = 0;
   size_t known_spaces_physical_size = 0;
   size_t number_of_spaces = isolate_holder_->isolate()->NumberOfHeapSpaces();
@@ -196,7 +195,6 @@
     const size_t space_physical_size = space_statistics.physical_space_size();
 
     known_spaces_size += space_size;
-    known_spaces_used_size += space_used_size;
     known_spaces_physical_size += space_physical_size;
 
     std::string space_dump_name = dump_base_name + "/heap/" +
@@ -217,11 +215,9 @@
                           space_used_size);
   }
 
-  // Sanity checks that all spaces are accounted for in GetHeapSpaceStatistics.
+  // Sanity check that all spaces are accounted for in GetHeapSpaceStatistics.
   // Background threads may be running and allocating concurrently, so the sum
-  // of space sizes may be exceed the total heap size that was sampled earlier.
-  DCHECK_LE(heap_statistics.total_physical_size(), known_spaces_physical_size);
-  DCHECK_LE(heap_statistics.used_heap_size(), known_spaces_used_size);
+  // of space sizes may exceed the total heap size that was sampled earlier.
   DCHECK_LE(heap_statistics.total_heap_size(), known_spaces_size);
 
   // If V8 zaps garbage, all the memory mapped regions become resident,
@@ -230,9 +226,13 @@
   if (heap_statistics.does_zap_garbage()) {
     auto* zap_dump = process_memory_dump->CreateAllocatorDump(
         dump_base_name + "/zapped_for_debug" + dump_name_suffix);
+    size_t zapped_size_for_debugging =
+        known_spaces_size >= known_spaces_physical_size
+            ? known_spaces_size - known_spaces_physical_size
+            : 0;
     zap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
                         base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                        known_spaces_size - known_spaces_physical_size);
+                        zapped_size_for_debugging);
   }
 
   // Dump statistics about malloced memory.
diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc
index 8ec8028..0372315 100644
--- a/google_apis/gaia/gaia_auth_fetcher.cc
+++ b/google_apis/gaia/gaia_auth_fetcher.cc
@@ -21,6 +21,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
 #include "google_apis/gaia/gaia_auth_util.h"
@@ -111,7 +112,7 @@
   absl::optional<base::Value> message_value = base::JSONReader::Read(data);
   if (message_value && message_value->is_dict()) {
     response_dict = std::make_unique<base::DictionaryValue>();
-    response_dict->MergeDictionary(base::OptionalOrNullptr(message_value));
+    response_dict->MergeDictionary(base::OptionalToPtr(message_value));
   }
   return response_dict;
 }
diff --git a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc
index 7db29af..02b389e 100644
--- a/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/video_surface_texture_image_backing.cc
@@ -109,10 +109,15 @@
     auto* video_backing =
         static_cast<VideoSurfaceTextureImageBacking*>(backing());
     video_backing->BeginGLReadAccess(texture_->service_id());
+    GetTexture()->SetLevelImageState(GetTexture()->target(), 0,
+                                     gles2::Texture::BOUND);
     return true;
   }
 
-  void EndAccess() override {}
+  void EndAccess() override {
+    GetTexture()->SetLevelImageState(GetTexture()->target(), 0,
+                                     gles2::Texture::UNBOUND);
+  }
 
  private:
   std::unique_ptr<gles2::AbstractTexture> texture_;
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 44d94a60..64c2ea5 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -1938,10 +1938,6 @@
   Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
   DCHECK_EQ(info.target, target);
   DCHECK_EQ(info.level, level);
-  // Workaround for StreamTexture which must be re-copied on each access.
-  // TODO(ericrk): Remove this once SharedImage transition is complete.
-  if (info.image && !info.image->HasMutableState())
-    return;
   info.image_state = state;
 }
 
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index fcacccf..27e97983 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -183,7 +183,7 @@
 
 #if defined(ARCH_CPU_ARM64)
 const base::Feature kDisableFlushWorkaroundForMacCrash{
-    "DisableFlushWorkaroundForMacCrash", base::FEATURE_DISABLED_BY_DEFAULT};
+    "DisableFlushWorkaroundForMacCrash", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 #endif
 
diff --git a/gpu/ipc/service/stream_texture_android.cc b/gpu/ipc/service/stream_texture_android.cc
index da216a2f..455beb8 100644
--- a/gpu/ipc/service/stream_texture_android.cc
+++ b/gpu/ipc/service/stream_texture_android.cc
@@ -328,10 +328,6 @@
   // TODO(ericrk): Add OnMemoryDump for GLImages. crbug.com/514914
 }
 
-bool StreamTexture::HasMutableState() const {
-  return false;
-}
-
 std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
 StreamTexture::GetAHardwareBuffer() {
   DCHECK(texture_owner_);
diff --git a/gpu/ipc/service/stream_texture_android.h b/gpu/ipc/service/stream_texture_android.h
index 1b7c30c1..e00287a 100644
--- a/gpu/ipc/service/stream_texture_android.h
+++ b/gpu/ipc/service/stream_texture_android.h
@@ -79,7 +79,6 @@
   void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
                     uint64_t process_tracing_id,
                     const std::string& dump_name) override;
-  bool HasMutableState() const override;
   std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
   GetAHardwareBuffer() override;
 
diff --git a/gpu/vulkan/vulkan_device_queue.cc b/gpu/vulkan/vulkan_device_queue.cc
index 6c9396ca..45049c7 100644
--- a/gpu/vulkan/vulkan_device_queue.cc
+++ b/gpu/vulkan/vulkan_device_queue.cc
@@ -47,8 +47,6 @@
   DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), owned_vk_device_);
   DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
   DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
-  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), owned_vma_allocator_);
-  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), vma_allocator_);
 
   if (VK_NULL_HANDLE == vk_instance_)
     return false;
@@ -304,9 +302,7 @@
       VK_MAX_MEMORY_HEAPS,
       heap_memory_limit ? heap_memory_limit : VK_WHOLE_SIZE);
   vma::CreateAllocator(vk_physical_device_, vk_device_, vk_instance_,
-                       heap_size_limit.data(), &owned_vma_allocator_);
-  vma_allocator_ = owned_vma_allocator_;
-
+                       heap_size_limit.data(), &vma_allocator_);
   cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);
 
   allow_protected_memory_ = allow_protected_memory;
@@ -322,7 +318,6 @@
   DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), owned_vk_device_);
   DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
   DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
-  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), owned_vma_allocator_);
 
   vk_physical_device_ = vk_physical_device;
   vk_device_ = vk_device;
@@ -330,11 +325,8 @@
   vk_queue_index_ = vk_queue_index;
   enabled_extensions_ = std::move(enabled_extensions);
 
-  if (vma_allocator_ == VK_NULL_HANDLE) {
-    vma::CreateAllocator(vk_physical_device_, vk_device_, vk_instance_, nullptr,
-                         &owned_vma_allocator_);
-    vma_allocator_ = owned_vma_allocator_;
-  }
+  vma::CreateAllocator(vk_physical_device_, vk_device_, vk_instance_, nullptr,
+                       &vma_allocator_);
 
   cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);
   return true;
@@ -399,8 +391,7 @@
     VkQueue vk_queue,
     uint32_t vk_queue_index,
     gfx::ExtensionSet enabled_extensions,
-    const VkPhysicalDeviceFeatures2& vk_physical_device_features2,
-    VmaAllocator vma_allocator) {
+    const VkPhysicalDeviceFeatures2& vk_physical_device_features2) {
   // Currently VulkanDeviceQueue for drdc thread(aka CompositorGpuThread) uses
   // the same vulkan queue as the gpu main thread. Now since both gpu main and
   // drdc threads would be accessing/submitting work to the same queue, all the
@@ -416,9 +407,6 @@
   GetVulkanFunctionPointers()->per_queue_lock_map[vk_queue] =
       std::make_unique<base::Lock>();
   enabled_device_features_2_ = vk_physical_device_features2;
-
-  // Note that CompositorGpuThread uses same vma allocator as gpu main thread.
-  vma_allocator_ = vma_allocator;
   return InitCommon(vk_physical_device, vk_device, vk_queue, vk_queue_index,
                     enabled_extensions);
 }
@@ -429,12 +417,12 @@
     cleanup_helper_.reset();
   }
 
-  if (owned_vma_allocator_ != VK_NULL_HANDLE) {
-    vma::DestroyAllocator(owned_vma_allocator_);
-    owned_vma_allocator_ = VK_NULL_HANDLE;
+  if (vma_allocator_ != VK_NULL_HANDLE) {
+    vma::DestroyAllocator(vma_allocator_);
+    vma_allocator_ = VK_NULL_HANDLE;
   }
 
-  if (owned_vk_device_ != VK_NULL_HANDLE) {
+  if (VK_NULL_HANDLE != owned_vk_device_) {
     vkDestroyDevice(owned_vk_device_, nullptr);
     owned_vk_device_ = VK_NULL_HANDLE;
 
@@ -451,7 +439,6 @@
   vk_queue_ = VK_NULL_HANDLE;
   vk_queue_index_ = 0;
   vk_physical_device_ = VK_NULL_HANDLE;
-  vma_allocator_ = VK_NULL_HANDLE;
 }
 
 std::unique_ptr<VulkanCommandPool> VulkanDeviceQueue::CreateCommandPool() {
diff --git a/gpu/vulkan/vulkan_device_queue.h b/gpu/vulkan/vulkan_device_queue.h
index 35ad1bf..fb19191 100644
--- a/gpu/vulkan/vulkan_device_queue.h
+++ b/gpu/vulkan/vulkan_device_queue.h
@@ -71,8 +71,7 @@
       VkQueue vk_queue,
       uint32_t vk_queue_index,
       gfx::ExtensionSet enabled_extensions,
-      const VkPhysicalDeviceFeatures2& vk_physical_device_features2,
-      VmaAllocator vma_allocator);
+      const VkPhysicalDeviceFeatures2& vk_physical_device_features2);
 
   const gfx::ExtensionSet& enabled_extensions() const {
     return enabled_extensions_;
@@ -147,7 +146,6 @@
   uint32_t vk_queue_index_ = 0;
   VkInstance vk_instance_ = VK_NULL_HANDLE;
   raw_ptr<VulkanInstance> instance_ = nullptr;
-  VmaAllocator owned_vma_allocator_ = VK_NULL_HANDLE;
   VmaAllocator vma_allocator_ = VK_NULL_HANDLE;
   std::unique_ptr<VulkanFenceHelper> cleanup_helper_;
   VkPhysicalDeviceFeatures2 enabled_device_features_2_{
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 2a44aec2..39ed030 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -306,6 +306,8 @@
     "app/headless_shell_switches.h",
     "lib/headless_content_client.cc",
     "lib/headless_content_client.h",
+    "lib/headless_content_main_delegate.cc",
+    "lib/headless_content_main_delegate.h",
     "public/headless_browser.cc",
     "public/headless_browser.h",
     "public/headless_export.h",
@@ -505,8 +507,6 @@
     sources += [
       "lib/browser/headless_content_browser_client.cc",
       "lib/browser/headless_content_browser_client.h",
-      "lib/headless_content_main_delegate.cc",
-      "lib/headless_content_main_delegate.h",
       "lib/renderer/headless_content_renderer_client.cc",
       "lib/renderer/headless_content_renderer_client.h",
       "lib/utility/headless_content_utility_client.cc",
@@ -627,8 +627,6 @@
     sources = [
       "lib/browser/headless_web_contents_impl.cc",
       "lib/browser/headless_web_contents_impl.h",
-      "lib/headless_content_main_delegate.cc",
-      "lib/headless_content_main_delegate.h",
       "lib/renderer/headless_content_renderer_client.cc",
       "lib/renderer/headless_content_renderer_client.h",
       "lib/utility/headless_content_utility_client.cc",
diff --git a/infra/config/dev/dev.star b/infra/config/dev/dev.star
index b1b78f6..c3c3a68e 100644
--- a/infra/config/dev/dev.star
+++ b/infra/config/dev/dev.star
@@ -33,6 +33,22 @@
         ),
     ],
     bindings = [
+        # Roles for LUCI Analysis.
+        luci.binding(
+            roles = "role/analysis.reader",
+            groups = "all",
+        ),
+        luci.binding(
+            roles = "role/analysis.queryUser",
+            groups = "authenticated-users",
+        ),
+        luci.binding(
+            roles = "role/analysis.editor",
+            groups = "project-chromium-committers",
+        ),
+        # Roles for Weetbix.
+        # TODO(b/243488110): Delete when renaming to
+        # LUCI Analysis complete.
         luci.binding(
             roles = "role/weetbix.reader",
             groups = "all",
diff --git "a/infra/config/generated/builders/ci/Android arm Builder \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/Android arm Builder \050dbg\051/properties.json"
index bab675c..ffa80e2 100644
--- "a/infra/config/generated/builders/ci/Android arm Builder \050dbg\051/properties.json"
+++ "b/infra/config/generated/builders/ci/Android arm Builder \050dbg\051/properties.json"
@@ -69,43 +69,6 @@
               },
               "run_tests_serially": true
             }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "android-12l-x86-rel",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-android-archive",
-              "builder_group": "chromium.android",
-              "execution_mode": "TEST",
-              "legacy_android_config": {
-                "config": "main_builder_mb"
-              },
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "download_vr_test_apks"
-                ],
-                "build_config": "Release",
-                "config": "android",
-                "target_bits": 32,
-                "target_platform": "android"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "android",
-                  "enable_reclient"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Android arm Builder (dbg)",
-                "project": "chromium"
-              },
-              "run_tests_serially": true
-            }
           }
         ]
       },
@@ -121,11 +84,6 @@
           "bucket": "ci",
           "builder": "Marshmallow Tablet Tester",
           "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "android-12l-x86-rel",
-          "project": "chromium"
         }
       ],
       "mirroring_builder_group_and_names": [
diff --git "a/infra/config/generated/builders/ci/Android x64 Builder \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/Android x64 Builder \050dbg\051/properties.json"
index 414ccdd..0d2f27d 100644
--- "a/infra/config/generated/builders/ci/Android x64 Builder \050dbg\051/properties.json"
+++ "b/infra/config/generated/builders/ci/Android x64 Builder \050dbg\051/properties.json"
@@ -66,6 +66,43 @@
           {
             "builder_id": {
               "bucket": "ci",
+              "builder": "android-12l-x64-dbg-tests",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-android-archive",
+              "builder_group": "chromium.android",
+              "execution_mode": "TEST",
+              "legacy_android_config": {
+                "config": "main_builder_mb"
+              },
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "download_vr_test_apks"
+                ],
+                "build_config": "Debug",
+                "config": "android",
+                "target_bits": 64,
+                "target_platform": "android"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "android",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              },
+              "parent": {
+                "bucket": "ci",
+                "builder": "Android x64 Builder (dbg)",
+                "project": "chromium"
+              },
+              "run_tests_serially": true
+            }
+          },
+          {
+            "builder_id": {
+              "bucket": "ci",
               "builder": "android-webview-12-x64-dbg-tests",
               "project": "chromium"
             },
@@ -112,6 +149,11 @@
         },
         {
           "bucket": "ci",
+          "builder": "android-12l-x64-dbg-tests",
+          "project": "chromium"
+        },
+        {
+          "bucket": "ci",
           "builder": "android-webview-12-x64-dbg-tests",
           "project": "chromium"
         }
@@ -122,6 +164,10 @@
           "group": "tryserver.chromium.android"
         },
         {
+          "builder": "android-12l-x64-dbg",
+          "group": "tryserver.chromium.android"
+        },
+        {
           "builder": "android-webview-12-x64-dbg",
           "group": "tryserver.chromium.android"
         },
diff --git a/infra/config/generated/builders/ci/android-12l-x86-rel/properties.json b/infra/config/generated/builders/ci/android-12l-x64-dbg-tests/properties.json
similarity index 82%
rename from infra/config/generated/builders/ci/android-12l-x86-rel/properties.json
rename to infra/config/generated/builders/ci/android-12l-x64-dbg-tests/properties.json
index 98ed15e2..8b7b40f 100644
--- a/infra/config/generated/builders/ci/android-12l-x86-rel/properties.json
+++ b/infra/config/generated/builders/ci/android-12l-x64-dbg-tests/properties.json
@@ -6,7 +6,7 @@
           {
             "builder_id": {
               "bucket": "ci",
-              "builder": "Android arm Builder (dbg)",
+              "builder": "Android x64 Builder (dbg)",
               "project": "chromium"
             },
             "builder_spec": {
@@ -14,15 +14,12 @@
               "builder_group": "chromium.android",
               "execution_mode": "COMPILE_AND_TEST",
               "legacy_android_config": {
-                "config": "main_builder_mb"
+                "config": "x64_builder_mb"
               },
               "legacy_chromium_config": {
-                "apply_configs": [
-                  "download_vr_test_apks"
-                ],
                 "build_config": "Debug",
                 "config": "android",
-                "target_bits": 32,
+                "target_bits": 64,
                 "target_platform": "android"
               },
               "legacy_gclient_config": {
@@ -37,7 +34,7 @@
           {
             "builder_id": {
               "bucket": "ci",
-              "builder": "android-12l-x86-rel",
+              "builder": "android-12l-x64-dbg-tests",
               "project": "chromium"
             },
             "builder_spec": {
@@ -51,9 +48,9 @@
                 "apply_configs": [
                   "download_vr_test_apks"
                 ],
-                "build_config": "Release",
+                "build_config": "Debug",
                 "config": "android",
-                "target_bits": 32,
+                "target_bits": 64,
                 "target_platform": "android"
               },
               "legacy_gclient_config": {
@@ -65,7 +62,7 @@
               },
               "parent": {
                 "bucket": "ci",
-                "builder": "Android arm Builder (dbg)",
+                "builder": "Android x64 Builder (dbg)",
                 "project": "chromium"
               },
               "run_tests_serially": true
@@ -76,17 +73,17 @@
       "builder_ids": [
         {
           "bucket": "ci",
-          "builder": "android-12l-x86-rel",
+          "builder": "android-12l-x64-dbg-tests",
           "project": "chromium"
         }
       ],
       "mirroring_builder_group_and_names": [
         {
-          "builder": "android-12l-x86-rel",
+          "builder": "android-12l-x64-dbg",
           "group": "tryserver.chromium.android"
         },
         {
-          "builder": "android_compile_dbg",
+          "builder": "android_compile_x64_dbg",
           "group": "tryserver.chromium.android"
         }
       ]
diff --git a/infra/config/generated/builders/try/android-12l-x86-rel/properties.json b/infra/config/generated/builders/try/android-12l-x64-dbg/properties.json
similarity index 83%
rename from infra/config/generated/builders/try/android-12l-x86-rel/properties.json
rename to infra/config/generated/builders/try/android-12l-x64-dbg/properties.json
index c0a673a9..bfa8f9b7 100644
--- a/infra/config/generated/builders/try/android-12l-x86-rel/properties.json
+++ b/infra/config/generated/builders/try/android-12l-x64-dbg/properties.json
@@ -6,7 +6,7 @@
           {
             "builder_id": {
               "bucket": "ci",
-              "builder": "Android arm Builder (dbg)",
+              "builder": "Android x64 Builder (dbg)",
               "project": "chromium"
             },
             "builder_spec": {
@@ -14,15 +14,12 @@
               "builder_group": "chromium.android",
               "execution_mode": "COMPILE_AND_TEST",
               "legacy_android_config": {
-                "config": "main_builder_mb"
+                "config": "x64_builder_mb"
               },
               "legacy_chromium_config": {
-                "apply_configs": [
-                  "download_vr_test_apks"
-                ],
                 "build_config": "Debug",
                 "config": "android",
-                "target_bits": 32,
+                "target_bits": 64,
                 "target_platform": "android"
               },
               "legacy_gclient_config": {
@@ -37,7 +34,7 @@
           {
             "builder_id": {
               "bucket": "ci",
-              "builder": "android-12l-x86-rel",
+              "builder": "android-12l-x64-dbg-tests",
               "project": "chromium"
             },
             "builder_spec": {
@@ -51,9 +48,9 @@
                 "apply_configs": [
                   "download_vr_test_apks"
                 ],
-                "build_config": "Release",
+                "build_config": "Debug",
                 "config": "android",
-                "target_bits": 32,
+                "target_bits": 64,
                 "target_platform": "android"
               },
               "legacy_gclient_config": {
@@ -65,7 +62,7 @@
               },
               "parent": {
                 "bucket": "ci",
-                "builder": "Android arm Builder (dbg)",
+                "builder": "Android x64 Builder (dbg)",
                 "project": "chromium"
               },
               "run_tests_serially": true
@@ -76,14 +73,14 @@
       "builder_ids": [
         {
           "bucket": "ci",
-          "builder": "Android arm Builder (dbg)",
+          "builder": "Android x64 Builder (dbg)",
           "project": "chromium"
         }
       ],
       "builder_ids_in_scope_for_testing": [
         {
           "bucket": "ci",
-          "builder": "android-12l-x86-rel",
+          "builder": "android-12l-x64-dbg-tests",
           "project": "chromium"
         }
       ]
diff --git a/infra/config/generated/builders/try/android_compile_dbg/properties.json b/infra/config/generated/builders/try/android_compile_dbg/properties.json
index a014bf4..932a561 100644
--- a/infra/config/generated/builders/try/android_compile_dbg/properties.json
+++ b/infra/config/generated/builders/try/android_compile_dbg/properties.json
@@ -69,43 +69,6 @@
               },
               "run_tests_serially": true
             }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "android-12l-x86-rel",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-android-archive",
-              "builder_group": "chromium.android",
-              "execution_mode": "TEST",
-              "legacy_android_config": {
-                "config": "main_builder_mb"
-              },
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "download_vr_test_apks"
-                ],
-                "build_config": "Release",
-                "config": "android",
-                "target_bits": 32,
-                "target_platform": "android"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "android",
-                  "enable_reclient"
-                ],
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Android arm Builder (dbg)",
-                "project": "chromium"
-              },
-              "run_tests_serially": true
-            }
           }
         ]
       },
@@ -121,11 +84,6 @@
           "bucket": "ci",
           "builder": "Marshmallow Tablet Tester",
           "project": "chromium"
-        },
-        {
-          "bucket": "ci",
-          "builder": "android-12l-x86-rel",
-          "project": "chromium"
         }
       ],
       "is_compile_only": true
diff --git a/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json b/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json
index 52a0298..5174943 100644
--- a/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json
+++ b/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json
@@ -66,6 +66,43 @@
           {
             "builder_id": {
               "bucket": "ci",
+              "builder": "android-12l-x64-dbg-tests",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-android-archive",
+              "builder_group": "chromium.android",
+              "execution_mode": "TEST",
+              "legacy_android_config": {
+                "config": "main_builder_mb"
+              },
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "download_vr_test_apks"
+                ],
+                "build_config": "Debug",
+                "config": "android",
+                "target_bits": 64,
+                "target_platform": "android"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "android",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              },
+              "parent": {
+                "bucket": "ci",
+                "builder": "Android x64 Builder (dbg)",
+                "project": "chromium"
+              },
+              "run_tests_serially": true
+            }
+          },
+          {
+            "builder_id": {
+              "bucket": "ci",
               "builder": "android-webview-12-x64-dbg-tests",
               "project": "chromium"
             },
@@ -112,6 +149,11 @@
         },
         {
           "bucket": "ci",
+          "builder": "android-12l-x64-dbg-tests",
+          "project": "chromium"
+        },
+        {
+          "bucket": "ci",
           "builder": "android-webview-12-x64-dbg-tests",
           "project": "chromium"
         }
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md
index 9c3c631..af8cc8d 100644
--- a/infra/config/generated/cq-builders.md
+++ b/infra/config/generated/cq-builders.md
@@ -490,7 +490,7 @@
 * [android-12-x64-rel](https://ci.chromium.org/p/chromium/builders/try/android-12-x64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-12-x64-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-12-x64-rel""))
   * Experiment percentage: 100.0
 
-* [android-12l-x86-rel](https://ci.chromium.org/p/chromium/builders/try/android-12l-x86-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-12l-x86-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-12l-x86-rel""))
+* [android-12l-x64-dbg](https://ci.chromium.org/p/chromium/builders/try/android-12l-x64-dbg) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-12l-x64-dbg"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-12l-x64-dbg""))
   * Experiment percentage: 2.0
 
 * [android-marshmallow-x86-rel-reclient](https://ci.chromium.org/p/chromium/builders/try/android-marshmallow-x86-rel-reclient) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-marshmallow-x86-rel-reclient"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-marshmallow-x86-rel-reclient""))
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 4e00eb52..f07d37b7b 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -351,7 +351,7 @@
         includable_only: true
       }
       builders {
-        name: "chromium/try/android-12l-x86-rel"
+        name: "chromium/try/android-12l-x64-dbg"
         experiment_percentage: 2
         location_regexp: ".*"
         location_regexp_exclude: ".+/[+]/docs/.+"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index a231ab3..68ce0d07 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -23467,7 +23467,7 @@
       }
     }
     builders {
-      name: "android-12l-x86-rel"
+      name: "android-12l-x64-dbg-tests"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cores:8"
@@ -23493,7 +23493,7 @@
         '    }'
         '  },'
         '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/android-12l-x86-rel/properties.json",'
+        '    "properties_file": "infra/config/generated/builders/ci/android-12l-x64-dbg-tests/properties.json",'
         '    "top_level_project": {'
         '      "ref": "refs/heads/main",'
         '      "repo": {'
@@ -50229,6 +50229,7 @@
         '  "led_builder_is_bootstrapped": true,'
         '  "recipe": "reviver/chromium/runner"'
         '}'
+      execution_timeout_secs: 21600
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.recipes.use_python3"
@@ -50916,7 +50917,7 @@
       description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-12-x64-rel\">android-12-x64-rel</a>."
     }
     builders {
-      name: "android-12l-x86-rel"
+      name: "android-12l-x64-dbg"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cores:8"
@@ -50941,7 +50942,7 @@
         '    }'
         '  },'
         '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/android-12l-x86-rel/properties.json",'
+        '    "properties_file": "infra/config/generated/builders/try/android-12l-x64-dbg/properties.json",'
         '    "top_level_project": {'
         '      "ref": "refs/heads/main",'
         '      "repo": {'
@@ -51427,6 +51428,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -53034,6 +53039,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -53309,6 +53318,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -53584,6 +53597,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -54488,6 +54505,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -56830,6 +56851,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -57408,6 +57433,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -58137,6 +58166,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -58412,6 +58445,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -60712,6 +60749,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -60805,6 +60846,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -60898,6 +60943,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -65999,6 +66048,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -67012,6 +67065,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -67194,6 +67251,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -69079,6 +69140,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -70594,6 +70659,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -70954,6 +71023,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -72594,6 +72667,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -73414,6 +73491,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -74600,6 +74681,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -76021,6 +76106,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -79788,6 +79877,10 @@
         key: "luci.recipes.use_python3"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
@@ -80933,6 +81026,10 @@
         key: "remove_src_checkout_experiment"
         value: 100
       }
+      experiments {
+        key: "weetbix.retry_weak_exonerations"
+        value: 100
+      }
       resultdb {
         enable: true
         bq_exports {
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 52bd174..343897a 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -3804,7 +3804,7 @@
     short_name: "P"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/android-12l-x86-rel"
+    name: "buildbucket/luci.chromium.ci/android-12l-x64-dbg-tests"
     category: "tester|tablet"
     short_name: "12L"
   }
@@ -16319,7 +16319,7 @@
     name: "buildbucket/luci.chromium.try/android-12-x64-rel-compilator"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/android-12l-x86-rel"
+    name: "buildbucket/luci.chromium.try/android-12l-x64-dbg"
   }
   builders {
     name: "buildbucket/luci.chromium.try/android-angle-chromium-try"
@@ -17476,7 +17476,7 @@
     name: "buildbucket/luci.chromium.try/android-12-x64-rel-compilator"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/android-12l-x86-rel"
+    name: "buildbucket/luci.chromium.try/android-12l-x64-dbg"
   }
   builders {
     name: "buildbucket/luci.chromium.try/android-arm64-all-targets-dbg"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index cb7ecd7cd..714291d 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -4200,7 +4200,7 @@
   }
 }
 job {
-  id: "android-12l-x86-rel"
+  id: "android-12l-x64-dbg-tests"
   realm: "ci"
   acls {
     role: TRIGGERER
@@ -4210,7 +4210,7 @@
   buildbucket {
     server: "cr-buildbucket.appspot.com"
     bucket: "ci"
-    builder: "android-12l-x86-rel"
+    builder: "android-12l-x64-dbg-tests"
   }
 }
 job {
diff --git a/infra/config/generated/luci/realms-dev.cfg b/infra/config/generated/luci/realms-dev.cfg
index f73bd2e..4f5eac8b 100644
--- a/infra/config/generated/luci/realms-dev.cfg
+++ b/infra/config/generated/luci/realms-dev.cfg
@@ -7,6 +7,18 @@
 realms {
   name: "@root"
   bindings {
+    role: "role/analysis.editor"
+    principals: "group:project-chromium-committers"
+  }
+  bindings {
+    role: "role/analysis.queryUser"
+    principals: "group:authenticated-users"
+  }
+  bindings {
+    role: "role/analysis.reader"
+    principals: "group:all"
+  }
+  bindings {
     role: "role/configs.reader"
     principals: "group:all"
   }
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 7c2ce5cc..d855e28 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -7,6 +7,18 @@
 realms {
   name: "@root"
   bindings {
+    role: "role/analysis.editor"
+    principals: "group:project-chromium-committers"
+  }
+  bindings {
+    role: "role/analysis.queryUser"
+    principals: "group:authenticated-users"
+  }
+  bindings {
+    role: "role/analysis.reader"
+    principals: "group:all"
+  }
+  bindings {
     role: "role/configs.reader"
     principals: "group:all"
   }
@@ -151,7 +163,7 @@
         values: "Win7 Tests (1)"
         values: "android-12-x64-dbg-tests"
         values: "android-12-x64-fyi-rel"
-        values: "android-12l-x86-rel"
+        values: "android-12l-x64-dbg-tests"
         values: "android-cronet-x86-dbg-10-tests"
         values: "android-cronet-x86-dbg-11-tests"
         values: "android-cronet-x86-dbg-lollipop-tests"
diff --git a/infra/config/main.star b/infra/config/main.star
index a587a8e..690a827 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -104,6 +104,22 @@
             roles = "role/configs.validator",
             groups = "project-chromium-try-task-accounts",
         ),
+        # Roles for LUCI Analysis.
+        luci.binding(
+            roles = "role/analysis.reader",
+            groups = "all",
+        ),
+        luci.binding(
+            roles = "role/analysis.queryUser",
+            groups = "authenticated-users",
+        ),
+        luci.binding(
+            roles = "role/analysis.editor",
+            groups = "project-chromium-committers",
+        ),
+        # Roles for Weetbix.
+        # TODO(b/243488110): Delete when renaming to
+        # LUCI Analysis complete.
         luci.binding(
             roles = "role/weetbix.reader",
             groups = "all",
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.star b/infra/config/subprojects/chromium/ci/chromium.android.star
index b1a1f89..c11a60f 100644
--- a/infra/config/subprojects/chromium/ci/chromium.android.star
+++ b/infra/config/subprojects/chromium/ci/chromium.android.star
@@ -684,7 +684,7 @@
 )
 
 ci.builder(
-    name = "android-12l-x86-rel",
+    name = "android-12l-x64-dbg-tests",
     builder_spec = builder_config.builder_spec(
         execution_mode = builder_config.execution_mode.TEST,
         gclient_config = builder_config.gclient_config(
@@ -699,8 +699,8 @@
             apply_configs = [
                 "download_vr_test_apks",
             ],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 32,
+            build_config = builder_config.build_config.DEBUG,
+            target_bits = 64,
             target_platform = builder_config.target_platform.ANDROID,
         ),
         android_config = builder_config.android_config(
@@ -716,7 +716,7 @@
     # TODO: This can be reduced when builder works.
     execution_timeout = 4 * time.hour,
     sheriff_rotations = args.ignore_default(None),
-    triggered_by = ["ci/Android arm Builder (dbg)"],
+    triggered_by = ["ci/Android x64 Builder (dbg)"],
 )
 
 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 51de9f9d..0e07da6 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -73,9 +73,10 @@
 )
 
 try_.builder(
-    name = "android-12l-x86-rel",
+    name = "android-12l-x64-dbg",
     mirrors = [
-        "ci/android-12l-x86-rel",
+        "ci/Android x64 Builder (dbg)",
+        "ci/android-12l-x64-dbg-tests",
     ],
     tryjob = try_.job(
         experiment_percentage = 2,
@@ -121,6 +122,7 @@
     },
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     tryjob = try_.job(),
     ssd = True,
@@ -261,6 +263,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -291,6 +294,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -324,6 +328,7 @@
     ),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -427,6 +432,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -673,6 +679,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -703,6 +710,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index ca535177..4dca0dd 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -60,6 +60,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
@@ -87,6 +88,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -107,6 +109,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -160,6 +163,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -251,6 +255,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
@@ -292,6 +297,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
index 72f6d86..2266c43 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
@@ -107,6 +107,7 @@
     ],
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -121,6 +122,7 @@
     ],
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -135,5 +137,6 @@
     ],
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index 90987ca07..6776076d 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -214,6 +214,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -309,6 +310,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -374,6 +376,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
@@ -535,6 +538,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
index 91a8dd2..12f3ee8 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -103,6 +103,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
@@ -323,6 +324,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
index 05e4702..378cf158 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -63,6 +63,7 @@
     tryjob = try_.job(),
     experiments = {
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
 )
 
@@ -186,6 +187,7 @@
     experiments = {
         "remove_src_checkout_experiment": 100,
         "enable_weetbix_queries": 100,
+        "weetbix.retry_weak_exonerations": 100,
     },
     use_orchestrator_pool = True,
 )
diff --git a/infra/config/subprojects/reviver/reviver.star b/infra/config/subprojects/reviver/reviver.star
index fe97b8b..d5f21623 100644
--- a/infra/config/subprojects/reviver/reviver.star
+++ b/infra/config/subprojects/reviver/reviver.star
@@ -84,6 +84,7 @@
     name = "runner",
     executable = "recipe:reviver/chromium/runner",
     auto_builder_dimension = False,
+    execution_timeout = 6 * time.hour,
     # TODO(crbug/1346396) Figure out what machines the runnner should run on
     pool = ci.DEFAULT_POOL,
     # TODO(crbug/1346396) Remove this once the reviver service account has
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent_unittest.mm
index 64a7a556..818bcc2 100644
--- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent_unittest.mm
+++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent_unittest.mm
@@ -78,20 +78,20 @@
 // Tests that an event logged by the BrowserAgent is returned with events for
 // the associated `browser_state_`.
 TEST_F(BreadcrumbManagerBrowserAgentTest, LogEvent) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   BreadcrumbManagerBrowserAgent::CreateForBrowser(browser_.get());
 
   InsertWebState(browser_.get());
 
-  EXPECT_EQ(1ul, breadcrumb_service_->GetEvents(0).size());
+  EXPECT_EQ(1ul, breadcrumb_service_->GetEvents().size());
 }
 
 // Tests that events logged through BrowserAgents associated with different
 // Browser instances are returned with events for the associated
 // `browser_state_` and are uniquely identifiable.
 TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   BreadcrumbManagerBrowserAgent::CreateForBrowser(browser_.get());
 
@@ -106,7 +106,7 @@
   // Insert WebState into `browser2`.
   InsertWebState(browser2.get());
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   EXPECT_EQ(2ul, events.size());
 
   // Seperately compare the start and end of the event strings to ensure
@@ -140,7 +140,7 @@
         InsertWebState(browser_.get());
       }));
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos, events.front().find("Inserted 2 tabs"))
       << events.front();
@@ -154,7 +154,7 @@
         /*index=*/0, WebStateList::ClosingFlags::CLOSE_NO_FLAGS);
   }));
 
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find("Closed 2 tabs"))
       << events.back();
@@ -177,7 +177,7 @@
       /*default_text_field_value=*/nil));
   queue->CancelAllRequests();
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -203,7 +203,7 @@
       /*default_text_field_value=*/nil));
   queue->CancelAllRequests();
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -229,7 +229,7 @@
       /*default_text_field_value=*/nil));
   queue->CancelAllRequests();
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -252,7 +252,7 @@
           GURL::EmptyGURL(), "message", "default text"));
   queue->CancelAllRequests();
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -275,7 +275,7 @@
       /*is_repeated_request=*/false));
   queue->CancelAllRequests();
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -297,7 +297,7 @@
   queue->AddRequest(
       OverlayRequest::CreateWithConfig<ConfirmDownloadReplacingRequest>());
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find(kBreadcrumbOverlay))
@@ -309,13 +309,13 @@
 
   // Switching tabs should log new overlay presentations.
   InsertWebState(browser_.get());
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find("Insert active Tab"))
       << events.back();
 
   browser_->GetWebStateList()->ActivateWebStateAt(0);
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(4ul, events.size());
   auto activation = std::next(events.begin(), 2);
   EXPECT_NE(std::string::npos, activation->find(kBreadcrumbOverlay))
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm
index 3caf6780..8057b7c 100644
--- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm
+++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm
@@ -98,18 +98,17 @@
 // every observer method is correctly called as that is done in the
 // WebStateObserverTest tests.
 TEST_F(BreadcrumbManagerTabHelperTest, EventsLogged) {
-
-  EXPECT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  EXPECT_EQ(0ul, breadcrumb_service_->GetEvents().size());
   web::FakeNavigationContext context;
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbDidStartNavigation))
       << events.back();
 
   first_web_state_.OnNavigationFinished(&context);
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbDidFinishNavigation))
@@ -125,7 +124,7 @@
   BreadcrumbManagerTabHelper::CreateForWebState(&second_web_state_);
   second_web_state_.OnNavigationStarted(&context);
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_STRNE(events.front().c_str(), events.back().c_str());
   EXPECT_NE(std::string::npos,
@@ -138,12 +137,12 @@
 
 // Tests metadata for www.google.com navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, GoogleNavigationStart) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetUrl(GURL("https://www.google.com"));
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -153,12 +152,12 @@
 
 // Tests metadata for https://play.google.com/ navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, GooglePlayNavigationStart) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetUrl(GURL("https://play.google.com/"));
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   // #google is useful to indicate SRP. There is no need to know URLs of other
@@ -170,12 +169,12 @@
 
 // Tests metadata for chrome://newtab NTP navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, ChromeNewTabNavigationStart) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetUrl(GURL(kChromeUINewTabURL));
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -190,12 +189,12 @@
 
 // Tests metadata for about://newtab NTP navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, AboutNewTabNavigationStart) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetUrl(GURL("about://newtab"));
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -210,12 +209,12 @@
 
 // Tests metadata for about://newtab/ NTP navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, AboutNewTabNavigationStart2) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetUrl(GURL("about://newtab/"));
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -230,12 +229,12 @@
 
 // Tests unique ID in DidStartNavigation and DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, NavigationUniqueId) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   // DidStartNavigation
   web::FakeNavigationContext context;
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -246,7 +245,7 @@
 
   // DidFinishNavigation
   first_web_state_.OnNavigationFinished(&context);
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -257,13 +256,13 @@
 
 // Tests renderer initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, RendererInitiatedByUser) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetIsRendererInitiated(true);
   context.SetHasUserGesture(true);
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find("#link")) << events.back();
@@ -281,14 +280,14 @@
 
 // Tests renderer initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, RendererInitiatedByScript) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetIsRendererInitiated(true);
   context.SetHasUserGesture(false);
   context.SetPageTransition(ui::PAGE_TRANSITION_RELOAD);
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find("#reload")) << events.back();
@@ -306,13 +305,13 @@
 
 // Tests browser initiated metadata in DidStartNavigation.
 TEST_F(BreadcrumbManagerTabHelperTest, BrowserInitiatedByScript) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetIsRendererInitiated(false);
   context.SetPageTransition(ui::PAGE_TRANSITION_TYPED);
   first_web_state_.OnNavigationStarted(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos, events.back().find("#typed")) << events.back();
@@ -330,12 +329,12 @@
 
 // Tests download navigation.
 TEST_F(BreadcrumbManagerTabHelperTest, Download) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   context.SetIsDownload(true);
   first_web_state_.OnNavigationFinished(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -348,11 +347,11 @@
 
 // Tests PDF load.
 TEST_F(BreadcrumbManagerTabHelperTest, PdfLoad) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   first_web_state_.SetContentsMimeType("application/pdf");
   first_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -365,10 +364,10 @@
 
 // Tests page load succeess.
 TEST_F(BreadcrumbManagerTabHelperTest, PageLoadSuccess) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   first_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -381,10 +380,10 @@
 
 // Tests page load failure.
 TEST_F(BreadcrumbManagerTabHelperTest, PageLoadFailure) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   first_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::FAILURE);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -397,11 +396,11 @@
 
 // Tests NTP page load.
 TEST_F(BreadcrumbManagerTabHelperTest, NtpPageLoad) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   first_web_state_.SetCurrentURL(GURL(kChromeUINewTabURL));
   first_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -421,7 +420,7 @@
 
 // Tests navigation error.
 TEST_F(BreadcrumbManagerTabHelperTest, NavigationError) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   web::FakeNavigationContext context;
   NSError* error = web::testing::CreateTestNetError([NSError
@@ -430,7 +429,7 @@
              userInfo:nil]);
   context.SetError(error);
   first_web_state_.OnNavigationFinished(&context);
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
 
   EXPECT_NE(std::string::npos,
@@ -446,23 +445,23 @@
   auto navigation_manager = std::make_unique<web::FakeNavigationManager>();
   web::FakeNavigationManager* navigation_manager_ptr = navigation_manager.get();
   first_web_state_.SetNavigationManager(std::move(navigation_manager));
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   // Empty navigation manager.
   first_web_state_.OnVisibleSecurityStateChanged();
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   // Default navigation item.
   auto visible_item = web::NavigationItem::Create();
   navigation_manager_ptr->SetVisibleItem(visible_item.get());
   first_web_state_.OnVisibleSecurityStateChanged();
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   // Mixed content.
   web::SSLStatus& status = visible_item->GetSSL();
   status.content_status = web::SSLStatus::DISPLAYED_INSECURE_CONTENT;
   first_web_state_.OnVisibleSecurityStateChanged();
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbMixedContent))
@@ -475,7 +474,7 @@
   status.content_status = web::SSLStatus::NORMAL_CONTENT;
   status.security_style = web::SECURITY_STYLE_AUTHENTICATION_BROKEN;
   first_web_state_.OnVisibleSecurityStateChanged();
-  events = breadcrumb_service_->GetEvents(0);
+  events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_EQ(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbMixedContent))
@@ -487,7 +486,7 @@
 
 // Tests that adding an infobar logs the expected breadcrumb.
 TEST_F(BreadcrumbManagerTabHelperTest, AddInfobar) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   InfoBarDelegate::InfoBarIdentifier identifier =
       InfoBarDelegate::InfoBarIdentifier::SESSION_CRASHED_INFOBAR_DELEGATE_IOS;
@@ -498,7 +497,7 @@
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->AddInfoBar(std::move(infobar));
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -508,7 +507,7 @@
 
 // Tests that infobar breadcrumbs specify the infobar type.
 TEST_F(BreadcrumbManagerTabHelperTest, InfobarTypes) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   // Add and remove first infobar.
   InfoBarDelegate::InfoBarIdentifier first_identifier =
@@ -532,7 +531,7 @@
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->AddInfoBar(std::move(second_infobar));
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(3ul, events.size());
   EXPECT_NE(events.front(), events.back());
   EXPECT_NE(std::string::npos, events.front().find(base::StringPrintf(
@@ -548,7 +547,7 @@
 // Tests that removing an infobar without animation logs the expected breadcrumb
 // event.
 TEST_F(BreadcrumbManagerTabHelperTest, RemoveInfobarNotAnimated) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   InfoBarDelegate::InfoBarIdentifier identifier =
       InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
@@ -562,7 +561,7 @@
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->RemoveAllInfoBars(/*animate=*/false);
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -576,7 +575,7 @@
 // Tests that removing an infobar with animation logs the expected breadcrumb
 // event.
 TEST_F(BreadcrumbManagerTabHelperTest, RemoveInfobarAnimated) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   InfoBarDelegate::InfoBarIdentifier identifier =
       InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR;
@@ -590,7 +589,7 @@
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->RemoveAllInfoBars(/*animate=*/true);
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(base::StringPrintf(
@@ -603,7 +602,7 @@
 
 // Tests that replacing an infobar logs the expected breadcrumb event.
 TEST_F(BreadcrumbManagerTabHelperTest, ReplaceInfobar) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->AddInfoBar(std::make_unique<FakeInfobarIOS>());
@@ -612,7 +611,7 @@
       ->AddInfoBar(std::make_unique<FakeInfobarIOS>(),
                    /*replace_existing=*/true);
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(2ul, events.size());
 
   InfoBarDelegate::InfoBarIdentifier identifier =
@@ -626,7 +625,7 @@
 // Tests that replacing an infobar many times only logs the replaced infobar
 // breadcrumb at major increments.
 TEST_F(BreadcrumbManagerTabHelperTest, SequentialInfobarReplacements) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   InfoBarManagerImpl::FromWebState(&first_web_state_)
       ->AddInfoBar(std::make_unique<FakeInfobarIOS>());
@@ -637,7 +636,7 @@
                      /*replace_existing=*/true);
   }
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   // Replacing the infobar 500 times should only log breadcrumbs on the 1st,
   // 2nd, 5th, 20th, 100th, 200th replacement.
   ASSERT_EQ(7ul, events.size());
@@ -653,13 +652,13 @@
 
 // Tests Zoom event.
 TEST_F(BreadcrumbManagerTabHelperTest, Zoom) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   [scroll_view_.delegate scrollViewDidEndZooming:scroll_view_
                                         withView:nil
                                          atScale:0];
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos, events.back().find(breadcrumbs::kBreadcrumbZoom))
       << events.back();
@@ -667,12 +666,12 @@
 
 // Tests Scroll event.
 TEST_F(BreadcrumbManagerTabHelperTest, Scroll) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   [scroll_view_.delegate scrollViewDidEndDragging:scroll_view_
                                    willDecelerate:YES];
 
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(1ul, events.size());
   EXPECT_NE(std::string::npos,
             events.back().find(breadcrumbs::kBreadcrumbScroll))
@@ -681,7 +680,7 @@
 
 // Tests batching sequential Scroll events.
 TEST_F(BreadcrumbManagerTabHelperTest, MultipleScrolls) {
-  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents(0).size());
+  ASSERT_EQ(0ul, breadcrumb_service_->GetEvents().size());
 
   for (int scroll = 0; scroll < 500; scroll++) {
     [scroll_view_.delegate scrollViewDidEndDragging:scroll_view_
@@ -690,7 +689,7 @@
 
   // Scrolling 500 times should only log breadcrumbs on the 1st, 2nd, 5th, 20th,
   // 100th and 200th time.
-  std::list<std::string> events = breadcrumb_service_->GetEvents(0);
+  std::list<std::string> events = breadcrumb_service_->GetEvents();
   ASSERT_EQ(6ul, events.size());
 
   // The events should contain the number of times the info has been replaced.
diff --git a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm
index 229d5b4..144eb3c 100644
--- a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm
+++ b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm
@@ -122,7 +122,7 @@
     if (![value isKindOfClass:[NSString class]]) {
       return NO;
     }
-    const std::list<std::string> events = breadcrumb_service->GetEvents(0);
+    const std::list<std::string> events = breadcrumb_service->GetEvents();
     std::string expected_breadcrumbs;
     for (const auto& event : events) {
       expected_breadcrumbs += event + "\n";
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index d9fa928..5e53f82 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1069,10 +1069,6 @@
     {"omnibox-https-upgrades", flag_descriptions::kOmniboxHttpsUpgradesName,
      flag_descriptions::kOmniboxHttpsUpgradesDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(omnibox::kDefaultTypedNavigationsToHttps)},
-    {"smart-sorting-new-destinations",
-     flag_descriptions::kSmartSortingNewDestinationsName,
-     flag_descriptions::kSmartSortingNewDestinationsDescription,
-     flags_ui::kOsIos, FEATURE_VALUE_TYPE(kSmartSortingNewDestinations)},
     {"smart-sorting-new-overflow-menu",
      flag_descriptions::kSmartSortingNewOverflowMenuName,
      flag_descriptions::kSmartSortingNewOverflowMenuDescription,
@@ -1086,13 +1082,6 @@
      flag_descriptions::kAutofillEnableRankingFormulaDescription,
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableRankingFormula)},
-    {"autofill-remove-card-expiry-from-downstream-suggestion",
-     flag_descriptions::kAutofillRemoveCardExpiryFromDownstreamSuggestionName,
-     flag_descriptions::
-         kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription,
-     flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(autofill::features::
-                            kAutofillRemoveCardExpiryFromDownstreamSuggestion)},
     {"enable-feed-ablation", flag_descriptions::kEnableFeedAblationName,
      flag_descriptions::kEnableFeedAblationDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kEnableFeedAblation)},
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 5e391210..8bc29339 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -97,12 +97,6 @@
 const char kAutofillPruneSuggestionsDescription[] =
     "Further limits the number of suggestions in the Autofill dropdown.";
 
-const char kAutofillRemoveCardExpiryFromDownstreamSuggestionName[] =
-    "Remove card expiration date from the Autofill card suggestions";
-const char kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription[] =
-    "When enabled, card expiration date will no longer be displayed in a card "
-    "suggestion";
-
 const char kAutofillSaveCardDismissOnNavigationName[] =
     "Save Card Dismiss on Navigation";
 const char kAutofillSaveCardDismissOnNavigationDescription[] =
@@ -628,11 +622,6 @@
     "Annotates web forms with Autofill field type predictions as placeholder "
     "text.";
 
-const char kSmartSortingNewDestinationsName[] =
-    "Smart Sorting new destinations added to the overflow menu.";
-const char kSmartSortingNewDestinationsDescription[] =
-    "Enables smart sorting new destinations added to the overflow menu.";
-
 const char kSmartSortingNewOverflowMenuName[] =
     "Smart Sorting the new Overflow Menu";
 const char kSmartSortingNewOverflowMenuDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 8513670..6031327 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -83,12 +83,6 @@
 extern const char kAutofillPruneSuggestionsName[];
 extern const char kAutofillPruneSuggestionsDescription[];
 
-// Title and description for the flag to control removing card expiration date
-// from the downstream suggestions.
-extern const char kAutofillRemoveCardExpiryFromDownstreamSuggestionName[];
-extern const char
-    kAutofillRemoveCardExpiryFromDownstreamSuggestionDescription[];
-
 // Title and description for the flag to control dismissing the Save Card
 // Infobar on Navigation.
 extern const char kAutofillSaveCardDismissOnNavigationName[];
@@ -571,11 +565,6 @@
 extern const char kShowAutofillTypePredictionsName[];
 extern const char kShowAutofillTypePredictionsDescription[];
 
-// Title and description for the flag to enable smart sorting new destinations
-// added to the overflow menu.
-extern const char kSmartSortingNewDestinationsName[];
-extern const char kSmartSortingNewDestinationsDescription[];
-
 // Title and description for the flag to enable smart sorting the new overflow
 // menu.
 extern const char kSmartSortingNewOverflowMenuName[];
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index a4d2dd90..eda26b9 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -12,6 +12,7 @@
 #include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#import "base/types/optional_util.h"
 #include "components/autofill/core/browser/logging/log_manager.h"
 #include "components/autofill/core/browser/logging/log_router.h"
 #include "components/keyed_service/core/service_access_type.h"
@@ -300,7 +301,7 @@
   if (!metrics_recorder_) {
     metrics_recorder_.emplace(GetUkmSourceId());
   }
-  return base::OptionalOrNullptr(metrics_recorder_);
+  return base::OptionalToPtr(metrics_recorder_);
 }
 
 signin::IdentityManager* IOSChromePasswordManagerClient::GetIdentityManager() {
diff --git a/ios/chrome/browser/policy/browser_signin_policy_handler.cc b/ios/chrome/browser/policy/browser_signin_policy_handler.cc
index 31553d4..d2888b2 100644
--- a/ios/chrome/browser/policy/browser_signin_policy_handler.cc
+++ b/ios/chrome/browser/policy/browser_signin_policy_handler.cc
@@ -30,7 +30,7 @@
 bool BrowserSigninPolicyHandler::CheckPolicySettings(
     const policy::PolicyMap& policies,
     policy::PolicyErrorMap* errors) {
-  // |GetValueUnsafe| is used to differentiate between the policy value being
+  // `GetValueUnsafe` is used to differentiate between the policy value being
   // unset vs being set with an incorrect type.
   const base::Value* value = policies.GetValueUnsafe(policy_name());
   if (!value)
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector.h b/ios/chrome/browser/policy/browser_state_policy_connector.h
index b5330bdc..77cf6e1 100644
--- a/ios/chrome/browser/policy/browser_state_policy_connector.h
+++ b/ios/chrome/browser/policy/browser_state_policy_connector.h
@@ -50,7 +50,7 @@
  private:
   friend class BrowserStatePolicyConnectorMock;
 
-  // |policy_providers_| contains a list of the policy providers available for
+  // `policy_providers_` contains a list of the policy providers available for
   // the PolicyService of this connector, in decreasing order of priority.
   //
   // Note: All the providers appended to this vector must eventually become
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector.mm b/ios/chrome/browser/policy/browser_state_policy_connector.mm
index 06174057..8ecd2fa2 100644
--- a/ios/chrome/browser/policy/browser_state_policy_connector.mm
+++ b/ios/chrome/browser/policy/browser_state_policy_connector.mm
@@ -22,7 +22,7 @@
   schema_registry_ = schema_registry;
 
   // The object returned by GetPlatformConnector() may or may not be in the list
-  // returned by GetPolicyProviders().  Explicitly add it to |policy_providers_|
+  // returned by GetPolicyProviders().  Explicitly add it to `policy_providers_`
   // here in case it will not be added by the loop below (for example, this
   // could happen if the platform provider is overridden for testing)..
   policy::ConfigurationPolicyProvider* platform_provider =
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm b/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm
index e7143fd..cb3795a 100644
--- a/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm
+++ b/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm
@@ -17,9 +17,9 @@
     policy::ConfigurationPolicyProvider* user_policy_provider) {
   auto connector = std::make_unique<BrowserStatePolicyConnector>();
 
-  // Since extensions are not supported on iOS, the |schema_registry| here has
+  // Since extensions are not supported on iOS, the `schema_registry` here has
   // the same registered components as the registry owned by
-  // |browser_policy_connector|, despite being a separate instance. The two
+  // `browser_policy_connector`, despite being a separate instance. The two
   // levels of registry (owned by ApplicationContext vs owned by BrowserState)
   // are maintained to keep a parallel structure with Desktop.
   connector->Init(schema_registry, browser_policy_connector,
diff --git a/ios/chrome/browser/policy/cloud/user_policy_signin_service.h b/ios/chrome/browser/policy/cloud/user_policy_signin_service.h
index ffc7947..0b94896 100644
--- a/ios/chrome/browser/policy/cloud/user_policy_signin_service.h
+++ b/ios/chrome/browser/policy/cloud/user_policy_signin_service.h
@@ -22,7 +22,7 @@
 class UserPolicySigninService : public UserPolicySigninServiceBase,
                                 public signin::IdentityManager::Observer {
  public:
-  // Creates a UserPolicySigninService associated with the |browser_state|.
+  // Creates a UserPolicySigninService associated with the `browser_state`.
   UserPolicySigninService(
       PrefService* browser_state_prefs,
       PrefService* local_state,
diff --git a/ios/chrome/browser/policy/cloud/user_policy_signin_service.mm b/ios/chrome/browser/policy/cloud/user_policy_signin_service.mm
index 9367c52..1d892e8 100644
--- a/ios/chrome/browser/policy/cloud/user_policy_signin_service.mm
+++ b/ios/chrome/browser/policy/cloud/user_policy_signin_service.mm
@@ -29,7 +29,7 @@
 // chrome/browser/signin/account_id_from_account_info.h to components/ to be
 // able to reuse the helper here.
 //
-// Gets the AccountId from the provided |account_info|.
+// Gets the AccountId from the provided `account_info`.
 AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info) {
   if (account_info.email.empty() || account_info.gaia.empty())
     return EmptyAccountId();
diff --git a/ios/chrome/browser/policy/cloud/user_policy_signin_service_factory.h b/ios/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
index 80cfc70..b411363 100644
--- a/ios/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
+++ b/ios/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
@@ -32,7 +32,7 @@
   // Returns an instance of the UserPolicySigninServiceFactory singleton.
   static UserPolicySigninServiceFactory* GetInstance();
 
-  // Returns the instance of UserPolicySigninService for the |context|.
+  // Returns the instance of UserPolicySigninService for the `context`.
   static UserPolicySigninService* GetForBrowserState(
       web::BrowserState* context);
 
diff --git a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.h b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.h
index 64cb3e9..2f2689dd 100644
--- a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.h
+++ b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.h
@@ -14,7 +14,7 @@
 
 // Builds a policy handler list.
 // All un-released policies will be ignored by default unless
-// |allow_future_policies| is True.
+// `allow_future_policies` is True.
 std::unique_ptr<policy::ConfigurationPolicyHandlerList> BuildPolicyHandlerList(
     bool allow_future_policies,
     const policy::Schema& chrome_schema);
diff --git a/ios/chrome/browser/policy/enterprise_policy_test_helper.h b/ios/chrome/browser/policy/enterprise_policy_test_helper.h
index 77ff103..2ce10f72 100644
--- a/ios/chrome/browser/policy/enterprise_policy_test_helper.h
+++ b/ios/chrome/browser/policy/enterprise_policy_test_helper.h
@@ -19,17 +19,17 @@
 // state configured with that policy.
 class EnterprisePolicyTestHelper {
  public:
-  // Creates a new instance using |state_directory_path| as storage for the
+  // Creates a new instance using `state_directory_path` as storage for the
   // backing state.
   explicit EnterprisePolicyTestHelper(
       const base::FilePath& state_directory_path);
   ~EnterprisePolicyTestHelper();
 
-  // Returns the browser state configured with |policy_provider_|.
+  // Returns the browser state configured with `policy_provider_`.
   TestChromeBrowserState* GetBrowserState() const;
   // Returns the backing local state.
   PrefService* GetLocalState();
-  // Returns the policy provider attached to |browser_state_|.
+  // Returns the policy provider attached to `browser_state_`.
   policy::MockConfigurationPolicyProvider* GetPolicyProvider();
   // Returns the browser policy connector.
   BrowserPolicyConnectorIOS* GetBrowserPolicyConnector();
@@ -37,13 +37,13 @@
  private:
   // The enterprise configuration policy provider.
   testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_;
-  // The application-level policy connector. Must outlive |local_state_|.
+  // The application-level policy connector. Must outlive `local_state_`.
   std::unique_ptr<BrowserPolicyConnectorIOS> browser_policy_connector_;
   // The local state PrefService managed by policy.
   std::unique_ptr<PrefService> local_state_;
-  // The BrowserState-level policy connector. Must outlive |pref_service_|.
+  // The BrowserState-level policy connector. Must outlive `pref_service_`.
   std::unique_ptr<BrowserStatePolicyConnector> browser_state_policy_connector_;
-  // The browser state configured with the |policy_provider_|.
+  // The browser state configured with the `policy_provider_`.
   std::unique_ptr<TestChromeBrowserState> browser_state_;
 
   EnterprisePolicyTestHelper& operator=(const EnterprisePolicyTestHelper&) =
diff --git a/ios/chrome/browser/policy/new_tab_page_location_policy_handler.cc b/ios/chrome/browser/policy/new_tab_page_location_policy_handler.cc
index 4727b363..6f74ae6 100644
--- a/ios/chrome/browser/policy/new_tab_page_location_policy_handler.cc
+++ b/ios/chrome/browser/policy/new_tab_page_location_policy_handler.cc
@@ -56,7 +56,7 @@
     policy::PolicyErrorMap* errors) {
   if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors))
     return false;
-  // |GetValueUnsafe| is used to differentiate between the policy value being
+  // `GetValueUnsafe` is used to differentiate between the policy value being
   // unset vs being set with an incorrect type.
   const base::Value* value = policies.GetValueUnsafe(policy_name());
   if (NewTabPageLocationPolicyHandler::ValidateNewTabPageLocationURL(value)) {
diff --git a/ios/chrome/browser/policy/policy_app_interface.h b/ios/chrome/browser/policy/policy_app_interface.h
index 6bbdd83..9bd088e 100644
--- a/ios/chrome/browser/policy/policy_app_interface.h
+++ b/ios/chrome/browser/policy/policy_app_interface.h
@@ -9,12 +9,12 @@
 
 @interface PolicyAppInterface : NSObject
 
-// Returns a JSON-encoded representation of the value for the given |policyKey|.
+// Returns a JSON-encoded representation of the value for the given `policyKey`.
 // Looks for the policy in the platform policy provider under the CHROME policy
 // namespace.
 + (NSString*)valueForPlatformPolicy:(NSString*)policyKey;
 
-// Sets the value of the policy with the |policyKey| key to the given value. The
+// Sets the value of the policy with the `policyKey` key to the given value. The
 // value must be serialized to JSON.
 + (void)setPolicyValue:(NSString*)jsonValue forKey:(NSString*)policyKey;
 
@@ -24,7 +24,7 @@
 // Clear the policies from all providers.
 + (void)clearAllPoliciesInMemory;
 
-// Returns YES if the given |URL| is blocked by the URLBlocklist and
+// Returns YES if the given `URL` is blocked by the URLBlocklist and
 // URLAllowlist policies.
 + (BOOL)isURLBlocked:(NSString*)URL;
 
diff --git a/ios/chrome/browser/policy/policy_app_interface.mm b/ios/chrome/browser/policy/policy_app_interface.mm
index 401c560..9a2c318 100644
--- a/ios/chrome/browser/policy/policy_app_interface.mm
+++ b/ios/chrome/browser/policy/policy_app_interface.mm
@@ -55,8 +55,8 @@
 // "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.cc"
 const base::FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Policy");
 
-// Returns a JSON-encoded string representing the given |base::Value|. If
-// |value| is nullptr, returns a string representing a |base::Value| of type
+// Returns a JSON-encoded string representing the given `base::Value`. If
+// `value` is nullptr, returns a string representing a `base::Value` of type
 // NONE.
 NSString* SerializeValue(const base::Value* value) {
   base::Value none_value(base::Value::Type::NONE);
@@ -72,9 +72,9 @@
   return base::SysUTF8ToNSString(serialized_value);
 }
 
-// Takes a JSON-encoded string representing a |base::Value|, and deserializes
-// into a |base::Value| pointer. If nullptr is given, returns a pointer to a
-// |base::Value| of type NONE.
+// Takes a JSON-encoded string representing a `base::Value`, and deserializes
+// into a `base::Value` pointer. If nullptr is given, returns a pointer to a
+// `base::Value` of type NONE.
 absl::optional<base::Value> DeserializeValue(NSString* json_value) {
   if (!json_value) {
     return base::Value(base::Value::Type::NONE);
@@ -110,7 +110,7 @@
   const policy::PolicyBundle& policyBundle = platformProvider->policies();
   const policy::PolicyMap& policyMap = policyBundle.Get(
       policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, ""));
-  // |GetValueUnsafe| is used due to multiple policy types being handled.
+  // `GetValueUnsafe` is used due to multiple policy types being handled.
   return SerializeValue(policyMap.GetValueUnsafe(key));
 }
 
diff --git a/ios/chrome/browser/policy/policy_conversions_client_ios.h b/ios/chrome/browser/policy/policy_conversions_client_ios.h
index c4b6543..411f945 100644
--- a/ios/chrome/browser/policy/policy_conversions_client_ios.h
+++ b/ios/chrome/browser/policy/policy_conversions_client_ios.h
@@ -19,7 +19,7 @@
 class PolicyConversionsClientIOS : public policy::PolicyConversionsClient {
  public:
   // Creates a PolicyConversionsClientIOS which retrieves BrowserState-specific
-  // policy information from the given |browser_state|.
+  // policy information from the given `browser_state`.
   explicit PolicyConversionsClientIOS(web::BrowserState* browser_state);
 
   PolicyConversionsClientIOS(const PolicyConversionsClientIOS&) = delete;
diff --git a/ios/chrome/browser/policy/policy_earl_grey_utils.h b/ios/chrome/browser/policy/policy_earl_grey_utils.h
index 135667103..499812a 100644
--- a/ios/chrome/browser/policy/policy_earl_grey_utils.h
+++ b/ios/chrome/browser/policy/policy_earl_grey_utils.h
@@ -18,27 +18,27 @@
 // CHROME policy namespace.
 std::string GetValueForPlatformPolicy(const std::string& policy_key);
 
-// Sets the value of the policy with the |policy_key| key to the given boolean
+// Sets the value of the policy with the `policy_key` key to the given boolean
 // value.
 void SetPolicy(bool enabled, const std::string& policy_key);
 
-// Sets the value of the policy with the |policy_key| key to the given integer
+// Sets the value of the policy with the `policy_key` key to the given integer
 // value.
 void SetPolicy(int value, const std::string& policy_key);
 
-// Sets the value of the policy with the |policy_key| key to the given string
+// Sets the value of the policy with the `policy_key` key to the given string
 // value.
 void SetPolicyWithStringValue(const std::string& value,
                               const std::string& policy_key);
 
-// Sets the value of the policy with the |policy_key| key to the given value.
+// Sets the value of the policy with the `policy_key` key to the given value.
 // The value must be serialized as a JSON string.
 // Prefer using the other type-specific helpers instead of this generic helper
 // if possible.
 void SetPolicy(const std::string& json_value, const std::string& policy_key);
 
-// Sets the value of the policy with the |policy_key| key to the given value.
-// The value must be wrapped in a |base::Value|.
+// Sets the value of the policy with the `policy_key` key to the given value.
+// The value must be wrapped in a `base::Value`.
 // Prefer using the other type-specific helpers instead of this generic helper
 // if possible.
 void SetPolicy(base::Value value, const std::string& policy_key);
diff --git a/ios/chrome/browser/policy/policy_earl_grey_utils.mm b/ios/chrome/browser/policy/policy_earl_grey_utils.mm
index f8e01b17..bc94baf 100644
--- a/ios/chrome/browser/policy/policy_earl_grey_utils.mm
+++ b/ios/chrome/browser/policy/policy_earl_grey_utils.mm
@@ -13,8 +13,8 @@
 #endif
 
 namespace {
-// Returns a JSON-encoded string representing the given |base::Value|. If
-// |value| is nullptr, returns a string representing a |base::Value| of type
+// Returns a JSON-encoded string representing the given `base::Value`. If
+// `value` is nullptr, returns a string representing a `base::Value` of type
 // NONE.
 std::string SerializeValue(const base::Value value) {
   std::string serialized_value;
diff --git a/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm b/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm
index 32a5d74..be34b1c 100644
--- a/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm
+++ b/ios/chrome/browser/policy/policy_incognito_mode_availability_egtest.mm
@@ -50,8 +50,8 @@
 }
 
 // Tests the enabled state of an item.
-// |parentMatcher| is the container matcher of the |item|.
-// |availability| is the expected availability.
+// `parentMatcher` is the container matcher of the `item`.
+// `availability` is the expected availability.
 void AssertItemEnabledState(id<GREYMatcher> item,
                             id<GREYMatcher> parentMatcher,
                             bool enabled) {
diff --git a/ios/chrome/browser/policy/policy_platform_provider_egtest.mm b/ios/chrome/browser/policy/policy_platform_provider_egtest.mm
index 75408fe..31f618f 100644
--- a/ios/chrome/browser/policy/policy_platform_provider_egtest.mm
+++ b/ios/chrome/browser/policy/policy_platform_provider_egtest.mm
@@ -38,8 +38,8 @@
 }
 
 // Returns an AppLaunchConfiguration containing the given policy data.
-// |policy_data| must be in XML format. |policy_data| is passed to the
-// application regardless of whether |disable_policy| is true or false..
+// `policy_data` must be in XML format. `policy_data` is passed to the
+// application regardless of whether `disable_policy` is true or false..
 AppLaunchConfiguration GenerateAppLaunchConfiguration(std::string policy_data,
                                                       bool enable_cbcm) {
   AppLaunchConfiguration config;
diff --git a/ios/chrome/browser/policy/policy_unittest.mm b/ios/chrome/browser/policy/policy_unittest.mm
index e6d3559..247d5ef 100644
--- a/ios/chrome/browser/policy/policy_unittest.mm
+++ b/ios/chrome/browser/policy/policy_unittest.mm
@@ -59,7 +59,7 @@
   // Enterprise policy boilerplate configuration.
   std::unique_ptr<EnterprisePolicyTestHelper> enterprise_policy_helper_;
 
-  // The path to |policy_test_cases.json|.
+  // The path to `policy_test_cases.json`.
   base::FilePath policy_test_cases_path_;
 };
 
diff --git a/ios/chrome/browser/policy/policy_watcher_browser_agent.h b/ios/chrome/browser/policy/policy_watcher_browser_agent.h
index 9e8f7fc9..5ce7596 100644
--- a/ios/chrome/browser/policy/policy_watcher_browser_agent.h
+++ b/ios/chrome/browser/policy/policy_watcher_browser_agent.h
@@ -37,7 +37,7 @@
   void SignInUIDismissed();
 
   // Starts observing the kSigninAllowed pref and trigger a SignOut if the pref
-  // has changed before the BrowserAgent start the observation. |handler| is
+  // has changed before the BrowserAgent start the observation. `handler` is
   // used to send UI commands when the SignOut is done.
   void Initialize(id<PolicyChangeCommands> handler);
 
@@ -47,18 +47,18 @@
 
   explicit PolicyWatcherBrowserAgent(Browser* browser);
 
-  // Handler for changes to kSigninAllowed. When the pref changes to |false|,
+  // Handler for changes to kSigninAllowed. When the pref changes to `false`,
   // sends a command to the SceneController to dismiss any in-progress sign-in
   // UI.
   void ForceSignOutIfSigninDisabled();
 
-  // Handler for change to kSyncManaged. When the pref changes to |true|,
+  // Handler for change to kSyncManaged. When the pref changes to `true`,
   // sends a command to the handler to show a prompt.
   void ShowSyncDisabledPromptIfNeeded();
 
   // Handler for changes to kAllowChromeDataInBackups. Excludes the entire app
-  // container from iCloud backup when the pref changes to |false|, and removes
-  // this exclusion when the pref changs to |true|.
+  // container from iCloud backup when the pref changes to `false`, and removes
+  // this exclusion when the pref changs to `true`.
   void UpdateAppContainerBackupExclusion();
 
   // Callback called when the sign out is complete.
diff --git a/ios/chrome/browser/policy/reporting/profile_report_generator_ios_unittest.mm b/ios/chrome/browser/policy/reporting/profile_report_generator_ios_unittest.mm
index 61b61d5..eee3a23 100644
--- a/ios/chrome/browser/policy/reporting/profile_report_generator_ios_unittest.mm
+++ b/ios/chrome/browser/policy/reporting/profile_report_generator_ios_unittest.mm
@@ -162,7 +162,7 @@
   ASSERT_TRUE(report);
   EXPECT_EQ(2, report->chrome_policies_size());
 
-  // Make sure policies are no longer reported when |set_policies_enabled| is
+  // Make sure policies are no longer reported when `set_policies_enabled` is
   // set to false.
   generator_.set_policies_enabled(false);
   report = GenerateReport();
@@ -170,7 +170,7 @@
   EXPECT_EQ(0, report->chrome_policies_size());
 
   // Make sure policies are once again being reported after setting
-  // |set_policies_enabled| back to true.
+  // `set_policies_enabled` back to true.
   generator_.set_policies_enabled(true);
   report = GenerateReport();
   ASSERT_TRUE(report);
diff --git a/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc b/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc
index f62822f..49699a3f 100644
--- a/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc
+++ b/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc
@@ -30,7 +30,7 @@
 bool RestrictAccountsPolicyHandler::CheckPolicySettings(
     const policy::PolicyMap& policies,
     policy::PolicyErrorMap* errors) {
-  // |GetValueUnsafe| is used to differentiate between the policy value being
+  // `GetValueUnsafe` is used to differentiate between the policy value being
   // unset vs being set with an incorrect type.
   const base::Value* value = policies.GetValueUnsafe(policy_name());
   if (!value)
diff --git a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm
index 20ce85cc..755f6d7 100644
--- a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm
+++ b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm
@@ -22,7 +22,7 @@
 
 namespace {
 
-// Waits until |url| has the expected blocked state.
+// Waits until `url` has the expected blocked state.
 void WaitForURLBlockedStatus(const GURL& url, bool blocked) {
   NSString* nsurl = base::SysUTF8ToNSString(url.spec());
   GREYAssertTrue(base::test::ios::WaitUntilConditionOrTimeout(
diff --git a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h
index c8f0538..26d45a9 100644
--- a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h
+++ b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h
@@ -22,12 +22,12 @@
       std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager);
   ~PolicyBlocklistService() override;
 
-  // Returns the blocking state for |url|.
+  // Returns the blocking state for `url`.
   policy::URLBlocklist::URLBlocklistState GetURLBlocklistState(
       const GURL& url) const;
 
  private:
-  // The URLBlocklistManager associated with |browser_state|.
+  // The URLBlocklistManager associated with `browser_state`.
   std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager_;
 
   PolicyBlocklistService(const PolicyBlocklistService&) = delete;
diff --git a/ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h b/ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h
index 21fa71a8..695b809 100644
--- a/ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h
+++ b/ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h
@@ -31,9 +31,9 @@
 }
 
 // Factory methods that create and initialize a new instance of a PrefService
-// for Chrome on iOS with the applicable PrefStores. The |pref_filename| points
+// for Chrome on iOS with the applicable PrefStores. The `pref_filename` points
 // to the user preference file. This is the usual way to create a new
-// PrefService. |pref_registry| keeps the list of registered prefs and their
+// PrefService. `pref_registry` keeps the list of registered prefs and their
 // default values.
 std::unique_ptr<PrefService> CreateLocalState(
     const base::FilePath& pref_filename,
@@ -49,7 +49,7 @@
     policy::PolicyService* policy_service,
     policy::BrowserPolicyConnector* policy_connector);
 
-// Creates an incognito copy of |pref_service| that shares most prefs but uses
+// Creates an incognito copy of `pref_service` that shares most prefs but uses
 // a fresh non-persistent overlay for the user pref store.
 std::unique_ptr<sync_preferences::PrefServiceSyncable>
 CreateIncognitoBrowserStatePrefs(
diff --git a/ios/chrome/browser/prerender/fake_prerender_service.h b/ios/chrome/browser/prerender/fake_prerender_service.h
index 9b13cc2..63877df 100644
--- a/ios/chrome/browser/prerender/fake_prerender_service.h
+++ b/ios/chrome/browser/prerender/fake_prerender_service.h
@@ -16,7 +16,7 @@
   ~FakePrerenderService() override;
 
   // Sets the WebState being prerendered.  Subsequent calls to
-  // IsWebStatePrerendered() will return true for |web_state|.
+  // IsWebStatePrerendered() will return true for `web_state`.
   void set_prerender_web_state(web::WebState* web_state) {
     prerender_web_state_ = web_state;
   }
diff --git a/ios/chrome/browser/prerender/preload_controller.h b/ios/chrome/browser/prerender/preload_controller.h
index 1e9fffe0..535bd0d5 100644
--- a/ios/chrome/browser/prerender/preload_controller.h
+++ b/ios/chrome/browser/prerender/preload_controller.h
@@ -44,15 +44,15 @@
 // destroyed.
 - (void)browserStateDestroyed;
 
-// Prerenders the given |url| with the given |transition|.  Normally, prerender
+// Prerenders the given `url` with the given `transition`.  Normally, prerender
 // requests are fulfilled after a short delay, to prevent unnecessary prerenders
-// while the user is typing.  If |immediately| is YES, this method starts
-// prerendering immediately, with no delay. |currentWebState| is used to create
-// a new WebState for the prerender with the same session. |immediately| should
+// while the user is typing.  If `immediately` is YES, this method starts
+// prerendering immediately, with no delay. `currentWebState` is used to create
+// a new WebState for the prerender with the same session. `immediately` should
 // be set to YES only when there is a very high confidence that the user will
-// navigate to the given |url|.
+// navigate to the given `url`.
 //
-// If there is already an existing request for |url|, this method does nothing
+// If there is already an existing request for `url`, this method does nothing
 // and does not reset the delay timer.  If there is an existing request for a
 // different URL, this method cancels that request and queues this request
 // instead.
@@ -65,7 +65,7 @@
 // Cancels any outstanding prerender requests and destroys any prerendered Tabs.
 - (void)cancelPrerender;
 
-// Returns whether |webState| is the WebState used for pre-rendering.
+// Returns whether `webState` is the WebState used for pre-rendering.
 - (BOOL)isWebStatePrerendered:(web::WebState*)webState;
 
 // Returns the currently prerendered WebState, or nil if none exists.  After
diff --git a/ios/chrome/browser/prerender/preload_controller.mm b/ios/chrome/browser/prerender/preload_controller.mm
index c29c2399..1ecd6520 100644
--- a/ios/chrome/browser/prerender/preload_controller.mm
+++ b/ios/chrome/browser/prerender/preload_controller.mm
@@ -89,7 +89,7 @@
   return trial && trial->group_name() == kPrerenderTabEvictionTrialGroup;
 }
 
-// Returns whether |url| can be prerendered.
+// Returns whether `url` can be prerendered.
 bool CanPrerenderURL(const GURL& url) {
   // Prerendering is only enabled for http and https URLs.
   return url.is_valid() &&
@@ -250,7 +250,7 @@
   std::unique_ptr<web::JavaScriptDialogPresenter> _dialogPresenter;
 
   // A weak pointer to the webState that will be replaced with the prerendered
-  // one. This is needed by |startPrerender| to build the new webstate with the
+  // one. This is needed by `startPrerender` to build the new webstate with the
   // same sessions.
   web::WebState* _webStateToReplace;
 
@@ -260,7 +260,7 @@
 // The ChromeBrowserState passed on initialization.
 @property(nonatomic) ChromeBrowserState* browserState;
 
-// Redefine property as readwrite.  The URL that is prerendered in |_webState|.
+// Redefine property as readwrite.  The URL that is prerendered in `_webState`.
 // This can be different from the value returned by WebState last committed
 // navigation item, for example in cases where there was a redirect.
 //
@@ -299,10 +299,10 @@
 // Called to start any scheduled prerendering requests.
 - (void)startPrerender;
 
-// Destroys the preview Tab and resets |prerenderURL_| to the empty URL.
+// Destroys the preview Tab and resets `prerenderURL_` to the empty URL.
 - (void)destroyPreviewContents;
 
-// Removes any scheduled prerender requests and resets |scheduledURL| to the
+// Removes any scheduled prerender requests and resets `scheduledURL` to the
 // empty URL.
 - (void)removeScheduledPrerenderRequests;
 
@@ -427,7 +427,7 @@
 
   [self removeScheduledPrerenderRequests];
   _webStateToReplace = currentWebState;
-  // Observing the |_webStateToReplace| to make sure that if it's destructed
+  // Observing the `_webStateToReplace` to make sure that if it's destructed
   // the pre-rendering will be canceled.
   if (_webStateToReplace) {
     _webStateToReplace->AddObserver(_webStateToReplaceObserver.get());
@@ -556,7 +556,7 @@
 
 - (void)webState:(web::WebState*)webState
     didFinishNavigation:(web::NavigationContext*)navigation {
-  // the |_webStateToReplace| is observed for destruction event only.
+  // the `_webStateToReplace` is observed for destruction event only.
   if (_webStateToReplace == webState)
     return;
   DCHECK_EQ(webState, _webState.get());
@@ -566,7 +566,7 @@
 
 - (void)webState:(web::WebState*)webState
     didLoadPageWithSuccess:(BOOL)loadSuccess {
-  // the |_webStateToReplace| is observed for destruction event only.
+  // the `_webStateToReplace` is observed for destruction event only.
   if (_webStateToReplace == webState)
     return;
 
@@ -682,7 +682,7 @@
   [self destroyPreviewContents];
   self.prerenderedURL = self.scheduledURL;
   std::unique_ptr<PrerenderRequest> request = std::move(_scheduledRequest);
-  // No need to observer the destruction of the |_webStateToReplace| anymore
+  // No need to observer the destruction of the `_webStateToReplace` anymore
   // as it will be used here.
   if (_webStateToReplace) {
     _webStateToReplace->RemoveObserver(_webStateToReplaceObserver.get());
diff --git a/ios/chrome/browser/prerender/preload_controller_unittest.mm b/ios/chrome/browser/prerender/preload_controller_unittest.mm
index 7949cfe..379d9c7 100644
--- a/ios/chrome/browser/prerender/preload_controller_unittest.mm
+++ b/ios/chrome/browser/prerender/preload_controller_unittest.mm
@@ -34,7 +34,7 @@
   TestNetworkChangeNotifier& operator=(const TestNetworkChangeNotifier&) =
       delete;
 
-  // Simulates a change of the connection type to |type|. This will notify any
+  // Simulates a change of the connection type to `type`. This will notify any
   // objects that are NetworkChangeNotifiers.
   void SimulateNetworkConnectionChange(
       net::NetworkChangeNotifier::ConnectionType type) {
diff --git a/ios/chrome/browser/prerender/prerender_egtest.mm b/ios/chrome/browser/prerender/prerender_egtest.mm
index ee99b4f1..d990f0a 100644
--- a/ios/chrome/browser/prerender/prerender_egtest.mm
+++ b/ios/chrome/browser/prerender/prerender_egtest.mm
@@ -302,7 +302,7 @@
 - (void)setUp {
   _variant = std::string(kIOSOmniboxUpdatedPopupUIVariation1);
 
-  // |appConfigurationForTestCase| is called during [super setUp], and
+  // `appConfigurationForTestCase` is called during [super setUp], and
   // depends on _variant.
   [super setUp];
 }
@@ -323,7 +323,7 @@
 - (void)setUp {
   _variant = std::string(kIOSOmniboxUpdatedPopupUIVariation2);
 
-  // |appConfigurationForTestCase| is called during [super setUp], and
+  // `appConfigurationForTestCase` is called during [super setUp], and
   // depends on _variant.
   [super setUp];
 }
diff --git a/ios/chrome/browser/prerender/prerender_service.h b/ios/chrome/browser/prerender/prerender_service.h
index 5aae78f..b6d646c 100644
--- a/ios/chrome/browser/prerender/prerender_service.h
+++ b/ios/chrome/browser/prerender/prerender_service.h
@@ -25,19 +25,19 @@
   // Sets the delegate that will provide information to this service.
   virtual void SetDelegate(id<PreloadControllerDelegate> delegate) = 0;
 
-  // Prerenders the given |url| with the given |transition|.  Normally,
+  // Prerenders the given `url` with the given `transition`.  Normally,
   // prerender requests are fulfilled after a short delay, to prevent
-  // unnecessary prerenders while the user is typing.  If |immediately| is YES,
+  // unnecessary prerenders while the user is typing.  If `immediately` is YES,
   // this method starts prerendering immediately, with no delay.
-  // |web_state_to_replace| is provided so that the new prerendered web state
-  // can have the same session data.  |immediately| should be set to YES only
+  // `web_state_to_replace` is provided so that the new prerendered web state
+  // can have the same session data.  `immediately` should be set to YES only
   // when there is a very high confidence that the user will navigate to the
-  // given |url|.
-  // TODO(crbug.com/1140583): passing |web_state_to_replace| is a workaround for
+  // given `url`.
+  // TODO(crbug.com/1140583): passing `web_state_to_replace` is a workaround for
   // not having prerender service per browser, remove it once prerenderService
   // is a browser agent.
   //
-  // If there is already an existing request for |url|, this method does nothing
+  // If there is already an existing request for `url`, this method does nothing
   // and does not reset the delay timer.  If there is an existing request for a
   // different URL, this method cancels that request and queues this request
   // instead.
@@ -47,8 +47,8 @@
                               web::WebState* web_state_to_replace,
                               bool immediately) = 0;
 
-  // If |url| is prerendered, loads the prerendered web state into
-  // |browser|'s WebStateList at the active index, replacing the existing active
+  // If `url` is prerendered, loads the prerendered web state into
+  // `browser`'s WebStateList at the active index, replacing the existing active
   // WebState and saving the session. If not, or if it isn't possible to replace
   // the active web state, cancels the active preload. Metrics and snapshots are
   // appropriately updated. Returns true if the active webstate was replaced,
@@ -57,17 +57,17 @@
                                        ui::PageTransition transition,
                                        Browser* browser) = 0;
 
-  // |true| while a prerendered webstate is being inserted into a webStateList.
+  // `true` while a prerendered webstate is being inserted into a webStateList.
   virtual bool IsLoadingPrerender() = 0;
 
   // Cancels any outstanding prerender requests and destroys any prerendered
   // pages.
   virtual void CancelPrerender() = 0;
 
-  // Returns true if there is a prerender for the given |url|.
+  // Returns true if there is a prerender for the given `url`.
   virtual bool HasPrerenderForUrl(const GURL& url) = 0;
 
-  // Returns true if the given |web_state| is being prerendered.
+  // Returns true if the given `web_state` is being prerendered.
   virtual bool IsWebStatePrerendered(web::WebState* web_state) = 0;
 };
 
diff --git a/ios/chrome/browser/safe_mode/safe_mode_util.h b/ios/chrome/browser/safe_mode/safe_mode_util.h
index 326f5bf..fc58325 100644
--- a/ios/chrome/browser/safe_mode/safe_mode_util.h
+++ b/ios/chrome/browser/safe_mode/safe_mode_util.h
@@ -12,7 +12,7 @@
 
 // Returns a list of the paths of all images (e.g., dynamic libraries)
 // currently loaded.
-// If |path_filter| is non-NULL, only paths starting with |path_filter| will be
+// If `path_filter` is non-NULL, only paths starting with `path_filter` will be
 // returned.
 std::vector<std::string> GetLoadedImages(const char* path_filter);
 
diff --git a/ios/chrome/browser/screenshot/screenshot_delegate.h b/ios/chrome/browser/screenshot/screenshot_delegate.h
index ec6a4ff..2f85319 100644
--- a/ios/chrome/browser/screenshot/screenshot_delegate.h
+++ b/ios/chrome/browser/screenshot/screenshot_delegate.h
@@ -16,7 +16,7 @@
 // PDF content of the captured window scene.
 @interface ScreenshotDelegate : NSObject <UIScreenshotServiceDelegate>
 
-// Init the ScreenshotDelegate and set the |browserInterfaceProvider| to
+// Init the ScreenshotDelegate and set the `browserInterfaceProvider` to
 // generate PDF screenshots from.
 - (instancetype)initWithBrowserInterfaceProvider:
     (id<BrowserInterfaceProvider>)browserInterfaceProvider
diff --git a/ios/chrome/browser/search_engines/extension_search_engine_data_updater.h b/ios/chrome/browser/search_engines/extension_search_engine_data_updater.h
index fe332dd..4a626c7 100644
--- a/ios/chrome/browser/search_engines/extension_search_engine_data_updater.h
+++ b/ios/chrome/browser/search_engines/extension_search_engine_data_updater.h
@@ -10,7 +10,7 @@
 class TemplateURLService;
 
 // Extensions need to know data about the current default search provider. This
-// class observes that change and writes the necessary data to |NSUserDefaults|.
+// class observes that change and writes the necessary data to `NSUserDefaults`.
 class ExtensionSearchEngineDataUpdater : public TemplateURLServiceObserver {
  public:
   explicit ExtensionSearchEngineDataUpdater(TemplateURLService* urlService);
diff --git a/ios/chrome/browser/search_engines/search_engine_java_script_feature.h b/ios/chrome/browser/search_engines/search_engine_java_script_feature.h
index 0e99ec6b..bb57fc4 100644
--- a/ios/chrome/browser/search_engines/search_engine_java_script_feature.h
+++ b/ios/chrome/browser/search_engines/search_engine_java_script_feature.h
@@ -15,7 +15,7 @@
 
 class SearchEngineJavaScriptFeatureDelegate {
  public:
-  // Saves the page |url| generated from a <form> submission to create the
+  // Saves the page `url` generated from a <form> submission to create the
   // TemplateURL when the submission leads to a successful navigation.
   virtual void SetSearchableUrl(web::WebState* web_state, GURL url) = 0;
 
@@ -30,7 +30,7 @@
  public:
   static SearchEngineJavaScriptFeature* GetInstance();
 
-  // Sets |delegate| as the receiver for search engine url messages.
+  // Sets `delegate` as the receiver for search engine url messages.
   void SetDelegate(SearchEngineJavaScriptFeatureDelegate* delegate);
 
  private:
diff --git a/ios/chrome/browser/search_engines/search_engine_js_unittest.mm b/ios/chrome/browser/search_engines/search_engine_js_unittest.mm
index ee72398e..2ac85ad 100644
--- a/ios/chrome/browser/search_engines/search_engine_js_unittest.mm
+++ b/ios/chrome/browser/search_engines/search_engine_js_unittest.mm
@@ -69,13 +69,13 @@
     web_state_->SetKeepRenderProcessAlive(true);
   }
 
-  // Stores paramaeters passed to |SetSearchableUrl|.
+  // Stores paramaeters passed to `SetSearchableUrl`.
   struct ReceivedSearchableUrl {
     web::WebState* web_state;
     GURL searchable_url;
   };
 
-  // Stores paramaeters passed to |AddTemplateURLByOSDD|.
+  // Stores paramaeters passed to `AddTemplateURLByOSDD`.
   struct ReceivedTemplateUrlByOsdd {
     web::WebState* web_state;
     GURL template_page_url;
@@ -118,9 +118,9 @@
   web::WebTaskEnvironment task_environment_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
   std::unique_ptr<web::WebState> web_state_;
-  // Details about the last received |SetSearchableUrl| call.
+  // Details about the last received `SetSearchableUrl` call.
   ReceivedSearchableUrl last_received_searchable_url_;
-  // Details about the last received |AddTemplateURLByOSDD| call.
+  // Details about the last received `AddTemplateURLByOSDD` call.
   ReceivedTemplateUrlByOsdd last_received_template_url_by_osdd_;
 };
 
diff --git a/ios/chrome/browser/search_engines/search_engine_tab_helper.h b/ios/chrome/browser/search_engines/search_engine_tab_helper.h
index 2699b8e..8cec774 100644
--- a/ios/chrome/browser/search_engines/search_engine_tab_helper.h
+++ b/ios/chrome/browser/search_engines/search_engine_tab_helper.h
@@ -41,7 +41,7 @@
 
   ~SearchEngineTabHelper() override;
 
-  // Saves the page |url| generated from a <form> submission to create the
+  // Saves the page `url` generated from a <form> submission to create the
   // TemplateURL when the submission leads to a successful navigation.
   void SetSearchableUrl(GURL url);
 
@@ -53,7 +53,7 @@
 
   explicit SearchEngineTabHelper(web::WebState* web_state);
 
-  // Adds a TemplateURL by |searchable_url|.
+  // Adds a TemplateURL by `searchable_url`.
   void AddTemplateURLBySearchableURL(const GURL& searchable_url);
 
   // WebStateObserver implementation.
@@ -68,7 +68,7 @@
                         bool icon_url_changed,
                         const gfx::Image& image) override;
 
-  // Manages observation relationship between |this| and WebFaviconDriver.
+  // Manages observation relationship between `this` and WebFaviconDriver.
   base::ScopedObservation<favicon::FaviconDriver,
                           favicon::FaviconDriverObserver>
       favicon_driver_observation_{this};
diff --git a/ios/chrome/browser/search_engines/search_engine_tab_helper.mm b/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
index 97544465..94ec73c3 100644
--- a/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
+++ b/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
@@ -25,13 +25,13 @@
 
 namespace {
 
-// Returns true if the |item|'s transition type is FORM_SUBMIT.
+// Returns true if the `item`'s transition type is FORM_SUBMIT.
 bool IsFormSubmit(const web::NavigationItem* item) {
   return ui::PageTransitionCoreTypeIs(item->GetTransitionType(),
                                       ui::PAGE_TRANSITION_FORM_SUBMIT);
 }
 
-// Generates a keyword from |item|. This code is based on:
+// Generates a keyword from `item`. This code is based on:
 // https://cs.chromium.org/chromium/src/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
 std::u16string GenerateKeywordFromNavigationItem(
     const web::NavigationItem* item) {
@@ -97,9 +97,9 @@
     url_service->UpdateProviderFavicons(potential_search_url, icon_url);
 }
 
-// When the page is loaded, checks if |searchable_url_| has a value generated
+// When the page is loaded, checks if `searchable_url_` has a value generated
 // from the <form> submission before the navigation. If true, and the navigation
-// is successful, adds a TemplateURL by |searchable_url_|. |searchable_url_|
+// is successful, adds a TemplateURL by `searchable_url_`. `searchable_url_`
 // will be set to empty in the end.
 void SearchEngineTabHelper::DidFinishNavigation(
     web::WebState* web_state,
@@ -127,7 +127,7 @@
   // keyword.
 
   // Make sure that the page is the current page and other basic checks.
-  // When |page_url| has file: scheme, this method doesn't work because of
+  // When `page_url` has file: scheme, this method doesn't work because of
   // http://b/issue?id=863583. For that reason, this doesn't check and allow
   // urls referring to osdd urls with same schemes.
   if (!osdd_url.is_valid() || !osdd_url.SchemeIsHTTPOrHTTPS())
@@ -159,7 +159,7 @@
     return;
 
   // Download the OpenSearch description document. If this is successful, a
-  // new keyword will be created when done. For |render_frame_id| arg, it's used
+  // new keyword will be created when done. For `render_frame_id` arg, it's used
   // by network::ResourceRequest::render_frame_id, we don't use Blink so leave
   // it to be the default value defined here:
   //   https://cs.chromium.org/chromium/src/services/network/public/cpp/resource_request.h?rcl=39c6fbea496641a6514e34c0ab689871d14e6d52&l=194;
@@ -171,7 +171,7 @@
                          /* request_id */ 0);
 }
 
-// Creates a TemplateURL by |searchable_url| and adds it to TemplateURLService.
+// Creates a TemplateURL by `searchable_url` and adds it to TemplateURLService.
 // This code is based on:
 // https://cs.chromium.org/chromium/src/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
 void SearchEngineTabHelper::AddTemplateURLBySearchableURL(
diff --git a/ios/chrome/browser/search_engines/template_url_service_client_impl.cc b/ios/chrome/browser/search_engines/template_url_service_client_impl.cc
index 82820f3..23e545d 100644
--- a/ios/chrome/browser/search_engines/template_url_service_client_impl.cc
+++ b/ios/chrome/browser/search_engines/template_url_service_client_impl.cc
@@ -28,10 +28,10 @@
 
 void TemplateURLServiceClientImpl::Shutdown() {
   // TemplateURLServiceClientImpl is owned by TemplateURLService which is a
-  // KeyedService with a dependency on HistoryService, thus |history_service_|
+  // KeyedService with a dependency on HistoryService, thus `history_service_`
   // outlives the ChromeTemplateURLServiceClient.
   //
-  // Remove self from |history_service_| observers in the shutdown phase of the
+  // Remove self from `history_service_` observers in the shutdown phase of the
   // two-phases since KeyedService are not supposed to use a dependend service
   // after the Shutdown call.
   if (history_service_) {
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.h b/ios/chrome/browser/snapshots/snapshot_cache.h
index 48597def..7d16b5f 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache.h
+++ b/ios/chrome/browser/snapshots/snapshot_cache.h
@@ -22,12 +22,12 @@
 @interface SnapshotCache : NSObject
 
 // Track snapshot IDs to not release on low memory and to reload on
-// |UIApplicationDidBecomeActiveNotification|.
+// `UIApplicationDidBecomeActiveNotification`.
 @property(nonatomic, strong) NSSet* pinnedIDs;
 
-// Designated initializer. |storagePath| is the file path where all images
-// managed by this SnapshotCache is stored. |storagePath| is not guaranteed to
-// exist. The contents of |storagePath| are entirely managed by this
+// Designated initializer. `storagePath` is the file path where all images
+// managed by this SnapshotCache is stored. `storagePath` is not guaranteed to
+// exist. The contents of `storagePath` are entirely managed by this
 // SnapshotCache.
 - (instancetype)initWithStoragePath:(const base::FilePath&)storagePath
     NS_DESIGNATED_INITIALIZER;
@@ -36,15 +36,15 @@
 // The scale that should be used for snapshots.
 - (CGFloat)snapshotScaleForDevice;
 
-// Retrieve a cached snapshot for the |snapshotID| and return it via the
+// Retrieve a cached snapshot for the `snapshotID` and return it via the
 // callback if it exists. The callback is guaranteed to be called synchronously
 // if the image is in memory. It will be called asynchronously if the image is
 // on disk or with nil if the image is not present at all.
 - (void)retrieveImageForSnapshotID:(NSString*)snapshotID
                           callback:(void (^)(UIImage*))callback;
 
-// Request the grey snapshot for |snapshotID|. If the image is already loaded in
-// memory, this will immediately call back on |callback|.
+// Request the grey snapshot for `snapshotID`. If the image is already loaded in
+// memory, this will immediately call back on `callback`.
 - (void)retrieveGreyImageForSnapshotID:(NSString*)snapshotID
                               callback:(void (^)(UIImage*))callback;
 
@@ -56,19 +56,19 @@
 // Removes all images from the LRU and disk.
 - (void)removeAllImages;
 
-// Moves all images for |snapshotIDs| from |sourcePath| to the current storage
-// path of this snapshot cache. Deletes the folder |sourcePath| after migration,
+// Moves all images for `snapshotIDs` from `sourcePath` to the current storage
+// path of this snapshot cache. Deletes the folder `sourcePath` after migration,
 // regardless of remaining files (which may be obsolete snapshots).
 - (void)migrateSnapshotsWithIDs:(NSSet<NSString*>*)snapshotIDs
                  fromSourcePath:(const base::FilePath&)sourcePath;
 
-// Purge the cache of snapshots that are older than |date|. The snapshots for
-// |liveSnapshotIDs| will be kept. This will be done asynchronously on a
+// Purge the cache of snapshots that are older than `date`. The snapshots for
+// `liveSnapshotIDs` will be kept. This will be done asynchronously on a
 // background thread.
 - (void)purgeCacheOlderThan:(const base::Time&)date
                     keeping:(NSSet*)liveSnapshotIDs;
 
-// Hint that the snapshot for |snapshotID| will likely be saved to disk when the
+// Hint that the snapshot for `snapshotID` will likely be saved to disk when the
 // application is backgrounded.  The snapshot is then saved in memory, so it
 // does not need to be read off disk.
 - (void)willBeSavedGreyWhenBackgrounding:(NSString*)snapshotID;
@@ -77,13 +77,13 @@
 - (void)createGreyCache:(NSArray*)snapshotIDs;
 // Release all images in grey cache.
 - (void)removeGreyCache;
-// Request the grey snapshot for |snapshotID|. If the image is already loaded
-// this will immediately call back on |callback|. Otherwise, only use |callback|
+// Request the grey snapshot for `snapshotID`. If the image is already loaded
+// this will immediately call back on `callback`. Otherwise, only use `callback`
 // for the most recent caller. The callback is not guaranteed to be called.
 - (void)greyImageForSnapshotID:(NSString*)snapshotID
                       callback:(void (^)(UIImage*))callback;
 
-// Write a grey copy of the snapshot for |snapshotID| to disk, but if and only
+// Write a grey copy of the snapshot for `snapshotID` to disk, but if and only
 // if a color version of the snapshot already exists in memory or on disk.
 - (void)saveGreyInBackgroundForSnapshotID:(NSString*)snapshotID;
 
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm
index 295738e..336d1e3 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache.mm
@@ -76,8 +76,8 @@
 // starting to evict elements.
 const NSUInteger kLRUCacheMaxCapacity = 6;
 
-// Returns the path of the image for |snapshot_id|, in |cache_directory|,
-// of type |image_type| and scale |image_scale|.
+// Returns the path of the image for `snapshot_id`, in `cache_directory`,
+// of type `image_type` and scale `image_scale`.
 base::FilePath ImagePath(NSString* snapshot_id,
                          ImageType image_type,
                          ImageScale image_scale,
@@ -540,7 +540,7 @@
   _backgroundingColorImage = [_lruCache objectForKey:snapshotID];
 }
 
-// Remove all but adjacent UIImages from |lruCache_|.
+// Remove all but adjacent UIImages from `lruCache_`.
 - (void)handleLowMemory {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
   NSMutableDictionary<NSString*, UIImage*>* dictionary =
@@ -556,13 +556,13 @@
                   forKey:snapshotID];
 }
 
-// Remove all UIImages from |lruCache_|.
+// Remove all UIImages from `lruCache_`.
 - (void)handleEnterBackground {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
   [_lruCache removeAllObjects];
 }
 
-// Restore adjacent UIImages to |lruCache_|.
+// Restore adjacent UIImages to `lruCache_`.
 - (void)handleBecomeActive {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
   for (NSString* snapshotID in self.pinnedIDs)
@@ -571,8 +571,8 @@
                             }];
 }
 
-// Save grey image to |greyImageDictionary_| and call into most recent
-// |_mostRecentGreyBlock| if |_mostRecentGreySnapshotID| matches |snapshotID|.
+// Save grey image to `greyImageDictionary_` and call into most recent
+// `_mostRecentGreyBlock` if `_mostRecentGreySnapshotID` matches `snapshotID`.
 - (void)saveGreyImage:(UIImage*)greyImage forSnapshotID:(NSString*)snapshotID {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
   if (greyImage)
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_internal.h b/ios/chrome/browser/snapshots/snapshot_cache_internal.h
index ee2fa0f2..ea84557 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_internal.h
+++ b/ios/chrome/browser/snapshots/snapshot_cache_internal.h
@@ -14,9 +14,9 @@
 @class NSString;
 
 @interface SnapshotCache (Internal)
-// Returns filepath to the color snapshot of |snapshotID|.
+// Returns filepath to the color snapshot of `snapshotID`.
 - (base::FilePath)imagePathForSnapshotID:(NSString*)snapshotID;
-// Returns filepath to the greyscale snapshot of |snapshotID|.
+// Returns filepath to the greyscale snapshot of `snapshotID`.
 - (base::FilePath)greyImagePathForSnapshotID:(NSString*)snapshotID;
 @end
 
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_observer.h b/ios/chrome/browser/snapshots/snapshot_cache_observer.h
index 34788b2..6d7e1931 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_observer.h
+++ b/ios/chrome/browser/snapshots/snapshot_cache_observer.h
@@ -12,8 +12,8 @@
 // Interface for listening to events occurring to the SnapshotCache.
 @protocol SnapshotCacheObserver
 @optional
-// Tells the observing object that the |snapshotCache| was updated with a new
-// snapshot corresponding to |identifier|.
+// Tells the observing object that the `snapshotCache` was updated with a new
+// snapshot corresponding to `identifier`.
 - (void)snapshotCache:(SnapshotCache*)snapshotCache
     didUpdateSnapshotForIdentifier:(NSString*)identifier;
 @end
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
index e4ea8f4..1f6c26d 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
@@ -84,7 +84,7 @@
 
   SnapshotCache* GetSnapshotCache() { return snapshotCache_; }
 
-  // Adds a fake snapshot file into |directory| using |snapshot_id| in the
+  // Adds a fake snapshot file into `directory` using `snapshot_id` in the
   // filename.
   base::FilePath AddSnapshotFileToDirectory(const base::FilePath directory,
                                             NSString* snapshot_id) {
@@ -112,7 +112,7 @@
     return UIGraphicsGetImageFromCurrentImageContext();
   }
 
-  // Generates an image of |size|, filled with a random color.
+  // Generates an image of `size`, filled with a random color.
   UIImage* GenerateRandomImage(CGSize size) {
     UIGraphicsBeginImageContextWithOptions(size, /*opaque=*/NO,
                                            UIScreen.mainScreen.scale);
@@ -165,13 +165,13 @@
     EXPECT_FALSE(foundImage);
   }
 
-  // Loads kSnapshotCount color images into the cache.  If |waitForFilesOnDisk|
+  // Loads kSnapshotCount color images into the cache.  If `waitForFilesOnDisk`
   // is YES, will not return until the images have been written to disk.
   void LoadAllColorImagesIntoCache(bool waitForFilesOnDisk) {
     LoadColorImagesIntoCache(kSnapshotCount, waitForFilesOnDisk);
   }
 
-  // Loads |count| color images into the cache.  If |waitForFilesOnDisk|
+  // Loads `count` color images into the cache.  If `waitForFilesOnDisk`
   // is YES, will not return until the images have been written to disk.
   void LoadColorImagesIntoCache(NSUInteger count, bool waitForFilesOnDisk) {
     SnapshotCache* cache = GetSnapshotCache();
@@ -194,7 +194,7 @@
     }
   }
 
-  // Waits for the first |count| grey images for |snapshotIDs_| to be placed in
+  // Waits for the first `count` grey images for `snapshotIDs_` to be placed in
   // the cache.
   void WaitForGreyImagesInCache(NSUInteger count) {
     SnapshotCache* cache = GetSnapshotCache();
@@ -573,7 +573,7 @@
     [cache saveGreyInBackgroundForSnapshotID:[snapshotIDs_ objectAtIndex:i]];
   }
 
-  // Waits for the grey images for |snapshotIDs_| to be written to disk, which
+  // Waits for the grey images for `snapshotIDs_` to be written to disk, which
   // happens in a background thread.
   FlushRunLoops();
 
@@ -652,7 +652,7 @@
 }
 
 // Tests that image immediately deletes when calling
-// |-removeImageWithSnapshotID:|.
+// `-removeImageWithSnapshotID:`.
 TEST_F(SnapshotCacheTest, ImageDeleted) {
   SnapshotCache* cache = GetSnapshotCache();
   UIImage* image =
@@ -665,7 +665,7 @@
   EXPECT_FALSE(base::PathExists(image_path));
 }
 
-// Tests that all images are deleted when calling |-removeAllImages|.
+// Tests that all images are deleted when calling `-removeAllImages`.
 TEST_F(SnapshotCacheTest, AllImagesDeleted) {
   SnapshotCache* cache = GetSnapshotCache();
   UIImage* image =
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.h b/ios/chrome/browser/snapshots/snapshot_generator.h
index 0810282..beb272dd3 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator.h
+++ b/ios/chrome/browser/snapshots/snapshot_generator.h
@@ -28,13 +28,13 @@
 
 - (instancetype)init NS_UNAVAILABLE;
 
-// Gets a color snapshot for the current page, calling |callback| once it has
-// been retrieved. Invokes |callback| with nil if a snapshot does not exist.
+// Gets a color snapshot for the current page, calling `callback` once it has
+// been retrieved. Invokes `callback` with nil if a snapshot does not exist.
 - (void)retrieveSnapshot:(void (^)(UIImage*))callback;
 
-// Gets a grey snapshot for the current page, calling |callback| once it has
+// Gets a grey snapshot for the current page, calling `callback` once it has
 // been retrieved or regenerated. If the snapshot cannot be generated, the
-// |callback| will be called with nil.
+// `callback` will be called with nil.
 - (void)retrieveGreySnapshot:(void (^)(UIImage*))callback;
 
 // Generates a new snapshot, updates the snapshot cache, and returns the new
@@ -42,13 +42,13 @@
 - (UIImage*)updateSnapshot;
 
 // Asynchronously generates a new snapshot, updates the snapshot cache, and runs
-// |callback| with the new snapshot image. It is an error to call this method if
+// `callback` with the new snapshot image. It is an error to call this method if
 // the web state is showing anything other (e.g., native content) than a web
 // view.
 - (void)updateWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion;
 
 // Generates a new snapshot and returns the new snapshot image. This does not
-// update the snapshot cache. If |shouldAddOverlay| is YES, overlays (e.g.,
+// update the snapshot cache. If `shouldAddOverlay` is YES, overlays (e.g.,
 // infobars, the download manager, and sad tab view) are also captured in the
 // snapshot image.
 - (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay;
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm
index 14e2b29f..10fa70f 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator.mm
+++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -38,7 +38,7 @@
   NSArray<UIView*>* overlays;
 };
 
-// Returns YES if |view| or any view it contains is a WKWebView.
+// Returns YES if `view` or any view it contains is a WKWebView.
 BOOL ViewHierarchyContainsWKWebView(UIView* view) {
   if ([view isKindOfClass:[WKWebView class]])
     return YES;
@@ -196,14 +196,14 @@
                canTakeSnapshotForWebState:self.webState];
 }
 
-// Returns a snapshot of |baseView| with |frameInBaseView|.
+// Returns a snapshot of `baseView` with `frameInBaseView`.
 - (UIImage*)snapshotBaseView:(UIView*)baseView
              frameInBaseView:(CGRect)frameInBaseView {
   DCHECK(baseView);
   DCHECK(!CGRectIsEmpty(frameInBaseView));
 
   // Disable the automatic view dimming UIKit performs if a view is presented
-  // modally over |baseView|.
+  // modally over `baseView`.
   baseView.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
 
   // Note: When not using device scale, the output image size may slightly
@@ -218,19 +218,19 @@
                         -frameInBaseView.origin.y);
   BOOL snapshotSuccess = YES;
 
-  // |drawViewHierarchyInRect:| has undefined behavior when the view is not
+  // `drawViewHierarchyInRect:` has undefined behavior when the view is not
   // in the visible view hierarchy. In practice, when this method is called
   // on a view that is part of view controller containment and not in the view
   // hierarchy, an UIViewControllerHierarchyInconsistency exception will be
   // thrown.
   if (baseView.window && ViewHierarchyContainsWKWebView(baseView)) {
-    // TODO(crbug.com/636188): |-drawViewHierarchyInRect:afterScreenUpdates:| is
+    // TODO(crbug.com/636188): `-drawViewHierarchyInRect:afterScreenUpdates:` is
     // buggy causing GPU glitches, screen redraws during animations, broken
     // pinch to dismiss on tablet, etc.
     snapshotSuccess = [baseView drawViewHierarchyInRect:baseView.bounds
                                      afterScreenUpdates:YES];
   } else {
-    // |-renderInContext:| is buggy for WKWebView, which is used for some
+    // `-renderInContext:` is buggy for WKWebView, which is used for some
     // Chromium pages such as "No internet" or "Site can't be reached".
     [[baseView layer] renderInContext:context];
   }
@@ -248,8 +248,8 @@
   return image;
 }
 
-// Returns an image of the |baseImage| overlaid with |overlays| with the given
-// |frameInWindow|.
+// Returns an image of the `baseImage` overlaid with `overlays` with the given
+// `frameInWindow`.
 - (UIImage*)snapshotWithOverlays:(NSArray<UIView*>*)overlays
                        baseImage:(UIImage*)baseImage
                    frameInWindow:(CGRect)frameInWindow {
@@ -280,7 +280,7 @@
   return snapshot;
 }
 
-// Updates the snapshot cache with |snapshot|.
+// Updates the snapshot cache with `snapshot`.
 - (void)updateSnapshotCacheWithImage:(UIImage*)snapshot {
   if (snapshot) {
     [self.snapshotCache setImage:snapshot withSnapshotID:self.tabID];
@@ -290,7 +290,7 @@
   }
 }
 
-// Draws |overlays| onto |context| at offsets relative to the window.
+// Draws `overlays` onto `context` at offsets relative to the window.
 - (void)drawOverlays:(NSArray<UIView*>*)overlays context:(CGContext*)context {
   for (UIView* overlay in overlays) {
     CGContextSaveGState(context);
diff --git a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
index bc10e900..d982ec3 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
+++ b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
@@ -16,26 +16,26 @@
 // Protocol for the SnapshotGenerator's delegate.
 @protocol SnapshotGeneratorDelegate
 
-// Returns whether it is possible to capture a snapshot for |webState|.
+// Returns whether it is possible to capture a snapshot for `webState`.
 - (BOOL)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator
     canTakeSnapshotForWebState:(web::WebState*)webState;
 
-// Returns the edge insets to use to crop the snapshot for |webState| during
+// Returns the edge insets to use to crop the snapshot for `webState` during
 // generation. If the snapshot should not be cropped, then UIEdgeInsetsZero
 // can be returned.  The returned insets should be in the coordinate system of
-// the view returned by |-baseViewForWebState:|.
+// the view returned by `-baseViewForWebState:`.
 - (UIEdgeInsets)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator
     snapshotEdgeInsetsForWebState:(web::WebState*)webState;
 
 // Returns the list of overlay views that should be rendered over the
-// page when generating the snapshot for |webState|. If no overlays should
+// page when generating the snapshot for `webState`. If no overlays should
 // be rendered, the list may be nil or empty. The order of views in the array
 // will be the z order of their image in the composed snapshot. A view at the
 // end of the array will appear in front of a view at the beginning.
 - (NSArray<UIView*>*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator
            snapshotOverlaysForWebState:(web::WebState*)webState;
 
-// Invoked before capturing a snapshot for |webState|. The delegate can remove
+// Invoked before capturing a snapshot for `webState`. The delegate can remove
 // subviews from the hierarchy or take other actions to ensure the snapshot
 // is correclty captured.
 - (void)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator
@@ -45,7 +45,7 @@
 - (UIView*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator
          baseViewForWebState:(web::WebState*)webState;
 
-// Returns the default tintAdjustmentMode for the base view in |webState|.
+// Returns the default tintAdjustmentMode for the base view in `webState`.
 - (UIViewTintAdjustmentMode)snapshotGenerator:
                                 (SnapshotGenerator*)snapshotGenerator
          defaultTintAdjustmentModeForWebState:(web::WebState*)webState;
diff --git a/ios/chrome/browser/snapshots/snapshot_lru_cache.h b/ios/chrome/browser/snapshots/snapshot_lru_cache.h
index adf4f35..bc3b761 100644
--- a/ios/chrome/browser/snapshots/snapshot_lru_cache.h
+++ b/ios/chrome/browser/snapshots/snapshot_lru_cache.h
@@ -21,22 +21,22 @@
 // default value for the cache size.
 - (instancetype)init NS_UNAVAILABLE;
 
-// |maxCacheSize| value is used to specify the maximum amount of items that the
+// `maxCacheSize` value is used to specify the maximum amount of items that the
 // cache can hold before starting to evict items.
 - (instancetype)initWithCacheSize:(NSUInteger)maxCacheSize
     NS_DESIGNATED_INITIALIZER;
 
-// Query the cache for an item corresponding to the |key|. Returns nil if there
+// Query the cache for an item corresponding to the `key`. Returns nil if there
 // is no item corresponding to that key.
 - (id)objectForKey:(id<NSObject>)key;
 
-// Adds the pair |key|, |obj| to the cache. If the value of the maxCacheSize
+// Adds the pair `key`, `obj` to the cache. If the value of the maxCacheSize
 // property is non zero, the cache may evict an elements if the maximum cache
-// size is reached. If the |key| is already present in the cache, the value for
-// that key is replaced by |object|.
+// size is reached. If the `key` is already present in the cache, the value for
+// that key is replaced by `object`.
 - (void)setObject:(id<NSObject>)object forKey:(NSObject*)key;
 
-// Remove the key, value pair corresponding to the given |key|.
+// Remove the key, value pair corresponding to the given `key`.
 - (void)removeObjectForKey:(id<NSObject>)key;
 
 // Remove all objects from the cache.
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.h b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
index 507508384..66e7a1e 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.h
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
@@ -29,8 +29,8 @@
 
   ~SnapshotTabHelper() override;
 
-  // Creates the tab helper for |web_state| if it does not exists. The
-  // unique identifier |tab_id| is used when interacting with the
+  // Creates the tab helper for `web_state` if it does not exists. The
+  // unique identifier `tab_id` is used when interacting with the
   // cache to save or fetch snapshots.
   static void CreateForWebState(web::WebState* web_state, NSString* tab_id);
 
@@ -42,22 +42,22 @@
   // not owned by the tab helper.
   void SetSnapshotCache(SnapshotCache* snapshot_cache);
 
-  // Retrieves a color snapshot for the current page, invoking |callback|
+  // Retrieves a color snapshot for the current page, invoking `callback`
   // with the image. The callback may be called synchronously is there is
   // a cached snapshot available in memory, otherwise it will be invoked
-  // asynchronously after retrieved from disk. Invokes |callback| with nil if a
+  // asynchronously after retrieved from disk. Invokes `callback` with nil if a
   // snapshot does not exist.
   void RetrieveColorSnapshot(void (^callback)(UIImage*));
 
-  // Retrieves a grey snapshot for the current page, invoking |callback|
+  // Retrieves a grey snapshot for the current page, invoking `callback`
   // with the image. The callback may be called synchronously is there is
   // a cached snapshot available in memory, otherwise it will be invoked
   // asynchronously after retrieved from disk or re-generated. Invokes
-  // |callback| with nil if a snapshot does not exist.
+  // `callback` with nil if a snapshot does not exist.
   void RetrieveGreySnapshot(void (^callback)(UIImage*));
 
   // Asynchronously generates a new snapshot, updates the snapshot cache, and
-  // invokes |callback| with the new snapshot image. Invokes |callback| with nil
+  // invokes `callback` with the new snapshot image. Invokes `callback` with nil
   // if snapshot generation fails.
   void UpdateSnapshotWithCallback(void (^callback)(UIImage*));
 
@@ -96,18 +96,18 @@
   NSString* tab_id_ = nil;
   SnapshotGenerator* snapshot_generator_ = nil;
 
-  // Manages this object as an observer of |web_state_|.
+  // Manages this object as an observer of `web_state_`.
   base::ScopedObservation<web::WebState, web::WebStateObserver>
       web_state_observation_{this};
 
   bool ignore_next_load_ = false;
 
-  // True if |web_state_| was loading at the time of the last call to
+  // True if `web_state_` was loading at the time of the last call to
   // UpdateSnapshotWithCallback(). If true, the last snapshot is expected to
   // become stale once the new page is loaded and rendered.
   bool was_loading_during_last_snapshot_ = false;
 
-  // Used to ensure |UpdateSnapshotWithCallback()| is not run when this object
+  // Used to ensure `UpdateSnapshotWithCallback()` is not run when this object
   // is destroyed.
   base::WeakPtrFactory<SnapshotTabHelper> weak_ptr_factory_;
 
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
index 87e0a0b..991d3bd 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -125,7 +125,7 @@
   // Snapshots taken while page is loading will eventually be stale. It
   // is important that another snapshot is taken after the new
   // page has loaded to replace the stale snapshot. The
-  // |IOS.PageLoadedSnapshotResult| histogram shows the outcome of
+  // `IOS.PageLoadedSnapshotResult` histogram shows the outcome of
   // snapshot attempts when the page is loaded after having taken
   // a stale snapshot.
   switch (load_completion_status) {
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
index 4178ce55..7ffc207da 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
@@ -63,7 +63,7 @@
 
 namespace {
 
-// Returns whether the |image| dominant color is |color|.
+// Returns whether the `image` dominant color is `color`.
 bool IsDominantColorForImage(UIImage* image, UIColor* color) {
   UIColor* dominant_color =
       DominantColorForImage(gfx::Image(image), /*opacity=*/1.0);
diff --git a/ios/chrome/browser/snapshots/snapshots_util.h b/ios/chrome/browser/snapshots/snapshots_util.h
index 6b56bc5..d2dc808 100644
--- a/ios/chrome/browser/snapshots/snapshots_util.h
+++ b/ios/chrome/browser/snapshots/snapshots_util.h
@@ -10,11 +10,11 @@
 #include "base/callback.h"
 #include "base/files/file_path.h"
 
-// Clears the application snapshots taken by iOS and invoke |callback| when
+// Clears the application snapshots taken by iOS and invoke `callback` when
 // the deletion has completed (asynchronously).
 void ClearIOSSnapshots(base::OnceClosure callback);
 
-// Adds to |snapshotsPaths| all the possible paths to the application's
+// Adds to `snapshotsPaths` all the possible paths to the application's
 // snapshots taken by iOS.
 void GetSnapshotsPaths(std::vector<base::FilePath>* snapshotsPaths);
 
diff --git a/ios/chrome/browser/snapshots/snapshots_util.mm b/ios/chrome/browser/snapshots/snapshots_util.mm
index a6db552e..275351b2 100644
--- a/ios/chrome/browser/snapshots/snapshots_util.mm
+++ b/ios/chrome/browser/snapshots/snapshots_util.mm
@@ -26,7 +26,7 @@
     "PortraitUpsideDown",
 };
 
-// Delete all files in |paths|.
+// Delete all files in `paths`.
 void DeleteAllFiles(std::vector<base::FilePath> paths) {
   for (const auto& path : paths) {
     base::DeleteFile(path);
diff --git a/ios/chrome/browser/store_kit/store_kit_coordinator.mm b/ios/chrome/browser/store_kit/store_kit_coordinator.mm
index 0ecd8f1..80cb897 100644
--- a/ios/chrome/browser/store_kit/store_kit_coordinator.mm
+++ b/ios/chrome/browser/store_kit/store_kit_coordinator.mm
@@ -48,14 +48,14 @@
 
 - (void)stop {
   // Do not call -dismissViewControllerAnimated:completion: on
-  // |self.baseViewController|, since the receiver of the method can be
+  // `self.baseViewController`, since the receiver of the method can be
   // dismissed if there is no presented view controller. On iOS 12
   // SKStoreProductViewControllerDelegate is responsible for dismissing
   // SKStoreProductViewController. On iOS 13.0 OS dismisses
   // SKStoreProductViewController after calling -productViewControllerDidFinish:
   // On iOS 13.2 OS dismisses SKStoreProductViewController before calling
   // -productViewControllerDidFinish: Calling
-  // -dismissViewControllerAnimated:completion: on |self.baseViewController| on
+  // -dismissViewControllerAnimated:completion: on `self.baseViewController` on
   // iOS 13.2 will dismiss base view controller and break the application UI.
   // According to SKStoreProductViewController documentation the delegate is
   // responsible for calling deprecated dismissModalViewControllerAnimated: so
diff --git a/ios/chrome/browser/store_kit/store_kit_launcher.h b/ios/chrome/browser/store_kit/store_kit_launcher.h
index e8e1e44c..5630835 100644
--- a/ios/chrome/browser/store_kit/store_kit_launcher.h
+++ b/ios/chrome/browser/store_kit/store_kit_launcher.h
@@ -12,12 +12,12 @@
 // store with StoreKit.
 @protocol StoreKitLauncher
 
-// Opens StoreKit modal to present a product identified with |productID|.
+// Opens StoreKit modal to present a product identified with `productID`.
 - (void)openAppStore:(NSString*)productID;
 
-// Opens StoreKit modal to present a product using |productParameters|.
+// Opens StoreKit modal to present a product using `productParameters`.
 // SKStoreProductParameterITunesItemIdentifier key must be set in
-// |productParameters|.
+// `productParameters`.
 - (void)openAppStoreWithParameters:(NSDictionary*)productParameters;
 
 @end
diff --git a/ios/chrome/browser/store_kit/store_kit_tab_helper.h b/ios/chrome/browser/store_kit/store_kit_tab_helper.h
index 724a5ca..3d1e0fb 100644
--- a/ios/chrome/browser/store_kit/store_kit_tab_helper.h
+++ b/ios/chrome/browser/store_kit/store_kit_tab_helper.h
@@ -22,11 +22,11 @@
   void SetLauncher(id<StoreKitLauncher> launcher);
   id<StoreKitLauncher> GetLauncher();
 
-  // Use StoreKitLauncher to launch storekit with |app_id| application
+  // Use StoreKitLauncher to launch storekit with `app_id` application
   // identifier.
   void OpenAppStore(NSString* app_id);
 
-  // Use StoreKitLauncher to launch storekit using |product_params| as product
+  // Use StoreKitLauncher to launch storekit using `product_params` as product
   // parameters, application id must be set for key:
   // SKStoreProductParameterITunesItemIdentifier. Additional key/value pairs can
   // be set in the dictionary to represent analytic/marketing parameters.
diff --git a/ios/chrome/browser/ui/activity_services/BUILD.gn b/ios/chrome/browser/ui/activity_services/BUILD.gn
index fcda223e..a04bce3 100644
--- a/ios/chrome/browser/ui/activity_services/BUILD.gn
+++ b/ios/chrome/browser/ui/activity_services/BUILD.gn
@@ -108,8 +108,6 @@
   deps = [
     "//components/strings",
     "//ios/chrome/app/strings:ios_strings_grit",
-    "//ios/chrome/browser/ui/popup_menu:constants",
-    "//ios/chrome/browser/ui/popup_menu/overflow_menu:feature_flags",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//ios/third_party/earl_grey2:test_lib",
diff --git a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm
index cd36b457..b36d202a 100644
--- a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm
+++ b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm
@@ -8,14 +8,11 @@
 
 #include "base/ios/ios_util.h"
 #include "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h"
-#import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
-#import "ios/testing/earl_grey/app_launch_configuration.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #include "ios/web/public/test/http_server/error_page_response_provider.h"
 #import "ios/web/public/test/http_server/http_server.h"
@@ -57,12 +54,6 @@
 
 @implementation ActivityServiceControllerTestCase
 
-- (AppLaunchConfiguration)appConfigurationForTestCase {
-  AppLaunchConfiguration config;
-  config.features_enabled.push_back(kNewOverflowMenuShareChromeAction);
-  return config;
-}
-
 - (void)testOpenActivityServiceControllerAndCopy {
   // Set up mock http server.
   std::map<GURL, std::string> responses;
@@ -84,12 +75,4 @@
   AssertActivityServiceNotVisible();
 }
 
-// Verifies that Tools Menu > Share Chrome brings up the "share sheet".
-- (void)testShareChromeApp {
-  [ChromeEarlGreyUI openToolsMenu];
-  [ChromeEarlGreyUI
-      tapToolsMenuAction:grey_accessibilityID(kToolsMenuShareChromeId)];
-  AssertActivityServiceVisible();
-}
-
 @end
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn
index fe9e838..d37ddfd 100644
--- a/ios/chrome/browser/ui/autofill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -63,8 +63,16 @@
   frameworks = [ "UIKit.framework" ]
 }
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("bridges") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   sources = [
     "card_expiration_date_fix_flow_view_bridge.h",
     "card_expiration_date_fix_flow_view_bridge.mm",
diff --git a/ios/chrome/browser/ui/autofill/cells/BUILD.gn b/ios/chrome/browser/ui/autofill/cells/BUILD.gn
index 18c7a3b..9d2a613 100644
--- a/ios/chrome/browser/ui/autofill/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/cells/BUILD.gn
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("cells") {
   sources = [
     "autofill_edit_item.h",
@@ -46,7 +51,10 @@
     "//ui/base",
   ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("unit_tests") {
@@ -71,5 +79,8 @@
     "//third_party/ocmock",
   ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 007d70b..81636f8 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -133,7 +133,6 @@
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h"
 #import "ios/chrome/browser/ui/ui_feature_flags.h"
-#import "ios/chrome/browser/ui/util/named_guide.h"
 #import "ios/chrome/browser/ui/util/page_animation_util.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h"
@@ -299,9 +298,6 @@
 // Coordinator for the QR scanner.
 @property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
 
-// Coordinator that manages Lens features.
-@property(nonatomic, strong) LensCoordinator* lensCoordinator;
-
 // Coordinator for displaying the Reading List.
 @property(nonatomic, strong) ReadingListCoordinator* readingListCoordinator;
 
@@ -370,6 +366,7 @@
   BubblePresenter* _bubblePresenter;
   ToolbarAccessoryPresenter* _toolbarAccessoryPresenter;
   NewTabPageCoordinator* _ntpCoordinator;
+  LensCoordinator* _lensCoordinator;
   ToolbarCoordinatorAdaptor* _toolbarCoordinatorAdaptor;
   PrimaryToolbarCoordinator* _primaryToolbarCoordinator;
   SecondaryToolbarCoordinator* _secondaryToolbarCoordinator;
@@ -695,6 +692,8 @@
   _ntpCoordinator.toolbarDelegate = _toolbarCoordinatorAdaptor;
   _ntpCoordinator.bubblePresenter = _bubblePresenter;
 
+  _lensCoordinator = [[LensCoordinator alloc] initWithBrowser:self.browser];
+
   _textZoomHandler = HandlerForProtocol(_dispatcher, TextZoomCommands);
   _helpHandler = HandlerForProtocol(_dispatcher, HelpCommands);
   _popupMenuCommandsHandler =
@@ -712,6 +711,7 @@
   _viewControllerDependencies.downloadManagerCoordinator =
       self.downloadManagerCoordinator;
   _viewControllerDependencies.ntpCoordinator = _ntpCoordinator;
+  _viewControllerDependencies.lensCoordinator = _lensCoordinator;
   _viewControllerDependencies.primaryToolbarCoordinator =
       _primaryToolbarCoordinator;
   _viewControllerDependencies.secondaryToolbarCoordinator =
@@ -752,6 +752,9 @@
 
   _ntpCoordinator.baseViewController = self.viewController;
 
+  _lensCoordinator.baseViewController = self.viewController;
+  [_lensCoordinator start];
+
   [_dispatcher startDispatchingToTarget:self.viewController
                             forProtocol:@protocol(BrowserCommands)];
 }
@@ -764,6 +767,7 @@
   _viewControllerDependencies.popupMenuCoordinator = nil;
   _viewControllerDependencies.downloadManagerCoordinator = nil;
   _viewControllerDependencies.ntpCoordinator = nil;
+  _viewControllerDependencies.lensCoordinator = nil;
   _viewControllerDependencies.primaryToolbarCoordinator = nil;
   _viewControllerDependencies.secondaryToolbarCoordinator = nil;
   _viewControllerDependencies.tabStripCoordinator = nil;
@@ -799,6 +803,9 @@
   [self.qrScannerCoordinator stop];
   self.qrScannerCoordinator = nil;
 
+  [_lensCoordinator stop];
+  _lensCoordinator = nil;
+
   [self.downloadManagerCoordinator stop];
   self.downloadManagerCoordinator = nil;
 
@@ -847,11 +854,6 @@
   self.printController =
       [[PrintController alloc] initWithBaseViewController:self.viewController];
 
-  self.lensCoordinator =
-      [[LensCoordinator alloc] initWithBaseViewController:self.viewController
-                                                  browser:self.browser];
-  [self.lensCoordinator start];
-
   /* NetExportCoordinator is created and started by a delegate method */
 
   /* passwordBreachCoordinator is created and started by a BrowserCommand */
@@ -965,9 +967,6 @@
 
   self.printController = nil;
 
-  [self.lensCoordinator stop];
-  self.lensCoordinator = nil;
-
   [self.readingListCoordinator stop];
   self.readingListCoordinator = nil;
 
@@ -1112,13 +1111,11 @@
   // Exit fullscreen if needed to make sure that share button is visible.
   FullscreenController::FromBrowser(self.browser)->ExitFullscreen();
 
-  NamedGuide* guide = [NamedGuide guideWithName:kToolsMenuGuide
-                                           view:self.viewController.view];
   self.sharingCoordinator = [[SharingCoordinator alloc]
       initWithBaseViewController:self.viewController
                          browser:self.browser
                           params:params
-                      originView:guide.constrainedView];
+                      originView:self.viewController.view];
   [self.sharingCoordinator start];
 }
 
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
index 7e7bc64e4..72cb78b5 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -38,6 +38,7 @@
 @protocol HelpCommands;
 @class KeyCommandsProvider;
 @class NewTabPageCoordinator;
+@class LensCoordinator;
 @protocol PopupMenuCommands;
 @class PopupMenuCoordinator;
 // TODO(crbug.com/1328039): Remove all use of the prerender service from BVC
@@ -63,6 +64,7 @@
   PopupMenuCoordinator* popupMenuCoordinator;
   DownloadManagerCoordinator* downloadManagerCoordinator;
   NewTabPageCoordinator* ntpCoordinator;
+  LensCoordinator* lensCoordinator;
   PrimaryToolbarCoordinator* primaryToolbarCoordinator;
   SecondaryToolbarCoordinator* secondaryToolbarCoordinator;
   TabStripCoordinator* tabStripCoordinator;
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 0c62478..fc7a7750 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -74,6 +74,7 @@
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_view.h"
+#import "ios/chrome/browser/ui/lens/lens_coordinator.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
 #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
 #import "ios/chrome/browser/ui/main_content/main_content_ui.h"
@@ -235,6 +236,7 @@
 
 // Note other delegates defined in the Delegates category header.
 @interface BrowserViewController () <FindBarPresentationDelegate,
+                                     LensPresentationDelegate,
                                      FullscreenUIElement,
                                      MainContentUI,
                                      SideSwipeControllerDelegate,
@@ -498,6 +500,8 @@
     self.popupMenuCommandsHandler = dependencies.popupMenuCommandsHandler;
     self.snackbarCommandsHandler = dependencies.snackbarCommandsHandler;
 
+    dependencies.lensCoordinator.delegate = self;
+
     _inNewTabAnimation = NO;
     self.fullscreenController = dependencies.fullscreenController;
     _footerFullscreenProgress = 1.0;
@@ -3631,6 +3635,22 @@
                    atOffset:[self currentHeaderOffset]];
 }
 
+#pragma mark - LensPresentationDelegate:
+
+- (CGRect)webContentAreaForLensCoordinator:(LensCoordinator*)lensCoordinator {
+  DCHECK(lensCoordinator);
+
+  // The LensCoordinator needs the content area of the webView with the
+  // header and footer toolbars visible.
+  UIEdgeInsets viewportInsets = UIEdgeInsetsZero;
+  if (!IsRegularXRegularSizeClass(self)) {
+    viewportInsets.bottom = [self secondaryToolbarHeightWithInset];
+  }
+
+  viewportInsets.top = [self expandedTopToolbarHeight];
+  return UIEdgeInsetsInsetRect(self.contentArea.bounds, viewportInsets);
+}
+
 #pragma mark - NewTabPageTabHelperDelegate
 
 - (void)newTabPageHelperDidChangeVisibility:(NewTabPageTabHelper*)NTPHelper
diff --git a/ios/chrome/browser/ui/collection_view/BUILD.gn b/ios/chrome/browser/ui/collection_view/BUILD.gn
index 31a807b..4859a96 100644
--- a/ios/chrome/browser/ui/collection_view/BUILD.gn
+++ b/ios/chrome/browser/ui/collection_view/BUILD.gn
@@ -2,8 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("collection_view") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   sources = [
     "collection_view_controller.h",
     "collection_view_controller.mm",
@@ -22,7 +30,10 @@
 }
 
 source_set("test_support") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   testonly = true
   sources = [
     "collection_view_controller_test.h",
@@ -40,7 +51,10 @@
 }
 
 source_set("unit_tests") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   testonly = true
   sources = [ "collection_view_controller_unittest.mm" ]
   deps = [
diff --git a/ios/chrome/browser/ui/collection_view/cells/BUILD.gn b/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
index 2846030..53008802 100644
--- a/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/collection_view/cells/BUILD.gn
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("cells") {
   sources = [
     "MDCCollectionViewCell+Chrome.h",
@@ -32,7 +37,10 @@
   ]
   public_deps = [ "//ios/third_party/material_components_ios" ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("test_support") {
@@ -61,5 +69,8 @@
     "//testing/gtest",
   ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
diff --git a/ios/chrome/browser/ui/commands/lens_commands.h b/ios/chrome/browser/ui/commands/lens_commands.h
index 131ea13c..c5fc7a8 100644
--- a/ios/chrome/browser/ui/commands/lens_commands.h
+++ b/ios/chrome/browser/ui/commands/lens_commands.h
@@ -6,6 +6,7 @@
 #define IOS_CHROME_BROWSER_UI_COMMANDS_LENS_COMMANDS_H_
 
 @class SearchImageWithLensCommand;
+enum class LensEntrypoint;
 
 // Commands related to Lens.
 @protocol LensCommands
@@ -13,6 +14,9 @@
 // Search for an image with Lens, using `command` parameters.
 - (void)searchImageWithLens:(SearchImageWithLensCommand*)command;
 
+// Opens the input selection UI for the given entrypoint.
+- (void)openInputSelectionForEntrypoint:(LensEntrypoint)entrypoint;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_COMMANDS_LENS_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index a199b3f..75d15d93 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("start_suggest") {
   sources = [
     "start_suggest_service_factory.h",
@@ -118,7 +123,10 @@
     "//ui/base",
     "//ui/strings",
   ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   public_deps = [ "//ios/third_party/material_components_ios" ]
 }
 
@@ -182,6 +190,7 @@
     "//components/strings",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
+    "//ios/chrome/browser/drag_and_drop",
     "//ios/chrome/browser/ntp",
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/collection_view",
@@ -200,6 +209,8 @@
     "//ios/chrome/browser/ui/toolbar/buttons",
     "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/ui/util:util",
+    "//ios/chrome/browser/url_loading",
+    "//ios/chrome/browser/url_loading:url_loading_params_header",
     "//ios/chrome/common:timing",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/elements",
@@ -210,7 +221,10 @@
     "//ui/base",
   ]
   public_deps = [ ":content_suggestions_ui_util" ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("content_suggestions_constant") {
@@ -316,7 +330,10 @@
     "//third_party/ocmock",
     "//third_party/ocmock",
   ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("eg2_tests") {
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
index e319ae4..f18f92e2 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("cells") {
   sources = [
     "content_suggestions_gesture_commands.h",
@@ -68,7 +73,10 @@
     "//ui/base",
     "//url",
   ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("constants") {
@@ -102,5 +110,8 @@
     "//ui/base",
     "//url",
   ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm
index 33015c0..fba59d6b 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.mm
@@ -144,8 +144,12 @@
             constraintEqualToAnchor:contentContainer.topAnchor],
       ]];
     }
+    // Height constraint must be flexible since on launch before the Feed
+    // CollectionView is used a native UICollectionView is the parent, and it
+    // can attempt to apply a large height constraint to the
+    // ContentSuggestionsViewController.
     self.heightConstraint = [self.heightAnchor
-        constraintEqualToConstant:[self calculateIntrinsicHeight]];
+        constraintGreaterThanOrEqualToConstant:[self calculateIntrinsicHeight]];
     self.heightConstraint.active = YES;
   }
   return self;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
index a1ff415..59f8d67b 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -17,7 +17,6 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
-#import "ios/chrome/browser/drag_and_drop/url_drag_drop_handler.h"
 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_cache_factory.h"
 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
 #include "ios/chrome/browser/favicon/large_icon_cache.h"
@@ -66,7 +65,6 @@
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
-#import "ios/chrome/browser/url_loading/url_loading_params.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/web_state.h"
@@ -79,8 +77,7 @@
 @interface ContentSuggestionsCoordinator () <
     ContentSuggestionsHeaderCommands,
     ContentSuggestionsMenuProvider,
-    ContentSuggestionsViewControllerAudience,
-    URLDropDelegate> {
+    ContentSuggestionsViewControllerAudience> {
   // Observer bridge for mediator to listen to
   // StartSurfaceRecentTabObserverBridge.
   std::unique_ptr<StartSurfaceRecentTabObserverBridge> _startSurfaceObserver;
@@ -91,7 +88,6 @@
     ContentSuggestionsMediator* contentSuggestionsMediator;
 @property(nonatomic, strong)
     ContentSuggestionsHeaderSynchronizer* headerCollectionInteractionHandler;
-@property(nonatomic, strong) URLDragDropHandler* dragDropHandler;
 @property(nonatomic, strong) ActionSheetCoordinator* alertCoordinator;
 @property(nonatomic, assign) BOOL contentSuggestionsEnabled;
 // Authentication Service for the user's signed-in state.
@@ -171,18 +167,14 @@
         self.contentSuggestionsMediator;
     self.contentSuggestionsViewController.audience = self;
     self.contentSuggestionsViewController.menuProvider = self;
+    self.contentSuggestionsViewController.urlLoadingBrowserAgent =
+        UrlLoadingBrowserAgent::FromBrowser(self.browser);
 
     self.contentSuggestionsMediator.consumer =
         self.contentSuggestionsViewController;
 
     self.ntpMediator.suggestionsMediator = self.contentSuggestionsMediator;
     [self.ntpMediator setUp];
-
-    self.dragDropHandler = [[URLDragDropHandler alloc] init];
-    self.dragDropHandler.dropDelegate = self;
-    [self.contentSuggestionsViewController.view
-        addInteraction:[[UIDropInteraction alloc]
-                           initWithDelegate:self.dragDropHandler]];
 }
 
 - (void)stop {
@@ -248,17 +240,6 @@
               .window.rootViewController.view safeAreaInsets];
 }
 
-#pragma mark - URLDropDelegate
-
-- (BOOL)canHandleURLDropInView:(UIView*)view {
-  return YES;
-}
-
-- (void)view:(UIView*)view didDropURL:(const GURL&)URL atPoint:(CGPoint)point {
-  UrlLoadingBrowserAgent::FromBrowser(self.browser)
-      ->Load(UrlLoadParams::InCurrentTab(URL));
-}
-
 #pragma mark - ContentSuggestionsHeaderCommands
 
 - (void)updateForHeaderSizeChange {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
index 5e685be..3e4983d8 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -12,6 +12,7 @@
 @protocol ContentSuggestionsCommands;
 @protocol ContentSuggestionsMenuProvider;
 @protocol ContentSuggestionsViewControllerAudience;
+class UrlLoadingBrowserAgent;
 
 // CollectionViewController to display the suggestions items.
 @interface ContentSuggestionsViewController
@@ -34,6 +35,7 @@
     audience;
 // Provider of menu configurations for the contentSuggestions component.
 @property(nonatomic, weak) id<ContentSuggestionsMenuProvider> menuProvider;
+@property(nonatomic, assign) UrlLoadingBrowserAgent* urlLoadingBrowserAgent;
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 669bc98..9827a1b 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -8,6 +8,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/drag_and_drop/url_drag_drop_handler.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_module_container.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h"
@@ -32,6 +33,8 @@
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h"
 #import "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
+#import "ios/chrome/browser/url_loading/url_loading_params.h"
 #import "ios/chrome/common/material_timing.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/favicon/favicon_view.h"
@@ -48,9 +51,6 @@
 const int kModuleWidthCompact = 343;
 const int kModuleWidthRegular = 432;
 
-// The height of the modules;
-const int kModuleHeight = 139;
-
 // The spacing between the modules.
 const float kModuleVerticalSpacing = 16.0f;
 
@@ -68,7 +68,10 @@
 
 @interface ContentSuggestionsViewController () <
     UIGestureRecognizerDelegate,
-    ContentSuggestionsSelectionActions>
+    ContentSuggestionsSelectionActions,
+    URLDropDelegate>
+
+@property(nonatomic, strong) URLDragDropHandler* dragDropHandler;
 
 // Whether an item of type ItemTypePromo has already been added to the model.
 @property(nonatomic, assign) BOOL promoAdded;
@@ -141,6 +144,11 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
 
+  self.dragDropHandler = [[URLDragDropHandler alloc] init];
+  self.dragDropHandler.dropDelegate = self;
+  [self.view addInteraction:[[UIDropInteraction alloc]
+                                initWithDelegate:self.dragDropHandler]];
+
   if (IsContentSuggestionsUIModuleRefreshEnabled()) {
     self.view.backgroundColor = [UIColor clearColor];
   } else {
@@ -197,11 +205,9 @@
     }
     CGFloat cardWidth = content_suggestions::searchFieldWidth(
         self.view.bounds.size.width, self.traitCollection);
-    [NSLayoutConstraint activateConstraints:@[
-      [parentView.widthAnchor constraintEqualToConstant:cardWidth],
-      [parentView.heightAnchor
-          constraintEqualToConstant:kReturnToRecentTabSize.height]
-    ]];
+    [NSLayoutConstraint
+        activateConstraints:@[ [parentView.widthAnchor
+                                constraintEqualToConstant:cardWidth] ]];
   }
   if (self.whatsNewView) {
     [self addUIElement:self.whatsNewView withCustomBottomSpacing:0];
@@ -221,7 +227,6 @@
     self.mostVisitedStackView.distribution = UIStackViewDistributionFillEqually;
     self.mostVisitedStackView.spacing = horizontalSpacing;
 
-    UIView* parentView = self.mostVisitedStackView;
     if (IsContentSuggestionsUIModuleRefreshEnabled()) {
       self.mostVisitedStackView.backgroundColor =
           ntp_home::kNTPBackgroundColor();
@@ -241,30 +246,30 @@
           [self.mostVisitedViews addObject:view];
         }
       }
-      parentView = self.mostVisitedModuleContainer;
       [self.verticalStackView
           addArrangedSubview:self.mostVisitedModuleContainer];
+      CGFloat width =
+          GetModuleWidthForHorizontalTraitCollection(self.traitCollection);
+      self.mostVisitedContainerWidthAnchor =
+          [self.mostVisitedModuleContainer.widthAnchor
+              constraintEqualToConstant:width];
+      [NSLayoutConstraint
+          activateConstraints:@[ self.mostVisitedContainerWidthAnchor ]];
     } else {
       self.mostVisitedStackView.alignment = UIStackViewAlignmentTop;
       [self addUIElement:self.mostVisitedStackView
           withCustomBottomSpacing:kMostVisitedBottomMargin];
+      CGFloat width =
+          MostVisitedTilesContentHorizontalSpace(self.traitCollection);
+      CGFloat height =
+          MostVisitedCellSize(self.traitCollection.preferredContentSizeCategory)
+              .height;
+      [NSLayoutConstraint activateConstraints:@[
+        [self.mostVisitedStackView.widthAnchor constraintEqualToConstant:width],
+        [self.mostVisitedStackView.heightAnchor
+            constraintGreaterThanOrEqualToConstant:height]
+      ]];
     }
-    CGFloat width =
-        IsContentSuggestionsUIModuleRefreshEnabled()
-            ? GetModuleWidthForHorizontalTraitCollection(self.traitCollection)
-            : MostVisitedTilesContentHorizontalSpace(self.traitCollection);
-    CGFloat height =
-        IsContentSuggestionsUIModuleRefreshEnabled()
-            ? kModuleHeight
-            : MostVisitedCellSize(
-                  self.traitCollection.preferredContentSizeCategory)
-                  .height;
-    self.mostVisitedContainerWidthAnchor =
-        [parentView.widthAnchor constraintEqualToConstant:width];
-    [NSLayoutConstraint activateConstraints:@[
-      self.mostVisitedContainerWidthAnchor,
-      [parentView.heightAnchor constraintGreaterThanOrEqualToConstant:height]
-    ]];
     [self populateMostVisitedModule];
   }
   BOOL noTrendingQueriesToShow =
@@ -293,12 +298,8 @@
             constraintEqualToConstant:
                 GetModuleWidthForHorizontalTraitCollection(
                     self.traitCollection)];
-    [NSLayoutConstraint activateConstraints:@[
-      self.trendingQueriesContainerWidthAnchor,
-      [self.trendingQueriesModuleContainer.heightAnchor
-          constraintEqualToConstant:[self.trendingQueriesModuleContainer
-                                            calculateIntrinsicHeight]]
-    ]];
+    [NSLayoutConstraint
+        activateConstraints:@[ self.trendingQueriesContainerWidthAnchor ]];
     [self populateTrendingQueriesModule];
   }
   if (self.shortcutsViews) {
@@ -327,33 +328,32 @@
       index++;
     }
 
-    UIView* parentView = self.shortcutsStackView;
     if (IsContentSuggestionsUIModuleRefreshEnabled()) {
       self.shortcutsModuleContainer = [[ContentSuggestionsModuleContainer alloc]
           initWithContentView:self.shortcutsStackView
                    moduleType:ContentSuggestionsModuleTypeShortcuts];
-      parentView = self.shortcutsModuleContainer;
       [self.verticalStackView addArrangedSubview:self.shortcutsModuleContainer];
+      CGFloat width =
+          GetModuleWidthForHorizontalTraitCollection(self.traitCollection);
+      self.shortcutsContainerWidthAnchor =
+          [self.shortcutsModuleContainer.widthAnchor
+              constraintEqualToConstant:width];
+      [NSLayoutConstraint
+          activateConstraints:@[ self.shortcutsContainerWidthAnchor ]];
     } else {
       [self addUIElement:self.shortcutsStackView
           withCustomBottomSpacing:kMostVisitedBottomMargin];
+      CGFloat width =
+          MostVisitedTilesContentHorizontalSpace(self.traitCollection);
+      CGFloat height =
+          MostVisitedCellSize(self.traitCollection.preferredContentSizeCategory)
+              .height;
+      [NSLayoutConstraint activateConstraints:@[
+        [self.shortcutsStackView.widthAnchor constraintEqualToConstant:width],
+        [self.shortcutsStackView.heightAnchor
+            constraintGreaterThanOrEqualToConstant:height]
+      ]];
     }
-    CGFloat width =
-        IsContentSuggestionsUIModuleRefreshEnabled()
-            ? GetModuleWidthForHorizontalTraitCollection(self.traitCollection)
-            : MostVisitedTilesContentHorizontalSpace(self.traitCollection);
-    CGFloat height =
-        IsContentSuggestionsUIModuleRefreshEnabled()
-            ? kModuleHeight
-            : MostVisitedCellSize(
-                  self.traitCollection.preferredContentSizeCategory)
-                  .height;
-    self.shortcutsContainerWidthAnchor =
-        [parentView.widthAnchor constraintEqualToConstant:width];
-    [NSLayoutConstraint activateConstraints:@[
-      self.shortcutsContainerWidthAnchor,
-      [parentView.heightAnchor constraintGreaterThanOrEqualToConstant:height]
-    ]];
   }
 }
 
@@ -374,6 +374,16 @@
              ntp_home::FakeOmniboxAccessibilityID();
 }
 
+#pragma mark - URLDropDelegate
+
+- (BOOL)canHandleURLDropInView:(UIView*)view {
+  return YES;
+}
+
+- (void)view:(UIView*)view didDropURL:(const GURL&)URL atPoint:(CGPoint)point {
+  self.urlLoadingBrowserAgent->Load(UrlLoadParams::InCurrentTab(URL));
+}
+
 #pragma mark - UITraitEnvironment
 
 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index a594497..1d3a480 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -171,24 +171,12 @@
 
 // Tests that all items are accessible on the home page.
 // This is currently needed to prevent this test case from being ignored.
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testAccessibility DISABLED_testAccessibility
-#else
-#define MAYBE_testAccessibility testAccessibility
-#endif
-- (void)MAYBE_testAccessibility {
+- (void)testAccessibility {
   [ChromeEarlGrey verifyAccessibilityForCurrentScreen];
 }
 
 // Tests that the collections shortcut are displayed and working.
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testCollectionShortcuts DISABLED_testCollectionShortcuts
-#else
-#define MAYBE_testCollectionShortcuts testCollectionShortcuts
-#endif
-- (void)MAYBE_testCollectionShortcuts {
+- (void)testCollectionShortcuts {
   // Check the Bookmarks.
   [[EarlGrey
       selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
@@ -244,13 +232,7 @@
 
 // Tests that when loading an invalid URL, the NTP is still displayed.
 // Prevents regressions from https://crbug.com/1063154 .
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testInvalidURL DISABLED_testInvalidURL
-#else
-#define MAYBE_testInvalidURL testInvalidURL
-#endif
-- (void)MAYBE_testInvalidURL {
+- (void)testInvalidURL {
 #if !TARGET_IPHONE_SIMULATOR
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Disabled for iPad, because key '-' could not be "
@@ -645,13 +627,7 @@
 }
 
 // Tests that tapping the fake omnibox moves the collection.
-// TODO(crbug.com/1326523): enable once fixed on ios15-sdk-sim
-- (void)DISABLED_testTapFakeOmniboxScroll {
-  // Disable the test on iOS 15.3 due to build failure.
-  // TODO(crbug.com/1306515): enable the test with fix.
-  if (@available(iOS 15.3, *)) {
-    EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3.");
-  }
+- (void)testTapFakeOmniboxScroll {
   // Get the collection and its layout.
   UICollectionView* collectionView = [NewTabPageAppInterface collectionView];
 
@@ -684,13 +660,7 @@
 
 // Tests that tapping the fake omnibox then unfocusing it moves the collection
 // back to where it was.
-// TODO(crbug.com/1326523): enable once fixed on ios15-sdk-sim
-- (void)DISABLED_testTapFakeOmniboxScrollScrolled {
-  // Disable the test on iOS 15.3 due to build failure.
-  // TODO(crbug.com/1306515): enable the test with fix.
-  if (@available(iOS 15.3, *)) {
-    EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3.");
-  }
+- (void)testTapFakeOmniboxScrollScrolled {
   // Get the collection and its layout.
   UICollectionView* collectionView = [NewTabPageAppInterface collectionView];
 
@@ -740,13 +710,7 @@
                             [NSString stringWithFormat:@"%i", 3])];
 }
 
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testFavicons DISABLED_testFavicons
-#else
-#define MAYBE_testFavicons testFavicons
-#endif
-- (void)MAYBE_testFavicons {
+- (void)testFavicons {
   for (NSInteger index = 0; index < 4; index++) {
     [[EarlGrey
         selectElementWithMatcher:
@@ -888,15 +852,7 @@
 
 // Test to ensure that initial position and content are maintained when rotating
 // the device back and forth.
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testInitialPositionAndOrientationChange \
-  DISABLED_testInitialPositionAndOrientationChange
-#else
-#define MAYBE_testInitialPositionAndOrientationChange \
-  testInitialPositionAndOrientationChange
-#endif
-- (void)MAYBE_testInitialPositionAndOrientationChange {
+- (void)testInitialPositionAndOrientationChange {
   UICollectionView* collectionView = [NewTabPageAppInterface collectionView];
 
   [self testNTPInitialPositionAndContent:collectionView];
@@ -982,13 +938,7 @@
 }
 
 // Test to ensure that NTP for incognito mode works properly.
-// TODO(crbug.com/1339419): Test fails on device.
-#if !TARGET_IPHONE_SIMULATOR
-#define MAYBE_testIncognitoMode DISABLED_testIncognitoMode
-#else
-#define MAYBE_testIncognitoMode testIncognitoMode
-#endif
-- (void)MAYBE_testIncognitoMode {
+- (void)testIncognitoMode {
   // Checks that default NTP is not incognito.
   [self
       testNTPInitialPositionAndContent:[NewTabPageAppInterface collectionView]];
diff --git a/ios/chrome/browser/ui/fancy_ui/BUILD.gn b/ios/chrome/browser/ui/fancy_ui/BUILD.gn
index 9249ab6..a07611e 100644
--- a/ios/chrome/browser/ui/fancy_ui/BUILD.gn
+++ b/ios/chrome/browser/ui/fancy_ui/BUILD.gn
@@ -2,8 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("fancy_ui") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   sources = [
     "primary_action_button.h",
     "primary_action_button.mm",
diff --git a/ios/chrome/browser/ui/lens/BUILD.gn b/ios/chrome/browser/ui/lens/BUILD.gn
index d5b8125..c5458b4 100644
--- a/ios/chrome/browser/ui/lens/BUILD.gn
+++ b/ios/chrome/browser/ui/lens/BUILD.gn
@@ -10,8 +10,10 @@
   ]
   deps = [
     ":lens_entrypoint",
+    "//ios/chrome/browser/application_context",
     "//ios/chrome/browser/browser_state:browser_state",
     "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/signin:signin",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/url_loading",
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.h b/ios/chrome/browser/ui/lens/lens_coordinator.h
index 9218b93..bd33cca 100644
--- a/ios/chrome/browser/ui/lens/lens_coordinator.h
+++ b/ios/chrome/browser/ui/lens/lens_coordinator.h
@@ -7,9 +7,33 @@
 
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
+@class LensCoordinator;
+
+// A protocol for view controllers that wish to present a Lens experience.
+@protocol LensPresentationDelegate
+
+// Returns the web content frame for the Lens Coordinator to use for
+// animations.
+- (CGRect)webContentAreaForLensCoordinator:(LensCoordinator*)lensCoordinator;
+
+@end
+
 // LensCoordinator presents the public interface for Lens related features.
 @interface LensCoordinator : ChromeCoordinator
 
+// Initializes this Coordinator with its `browser` and a nil base view
+// controller.
+- (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+                                   browser:(Browser*)browser NS_UNAVAILABLE;
+
+// The base view controller for this coordinator.
+@property(weak, nonatomic, readwrite) UIViewController* baseViewController;
+
+// The presentation delegate for this coordinator.
+@property(weak, nonatomic, readwrite) id<LensPresentationDelegate> delegate;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_LENS_LENS_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm
index 334a14f..6f8664d2 100644
--- a/ios/chrome/browser/ui/lens/lens_coordinator.mm
+++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -4,10 +4,15 @@
 
 #import "ios/chrome/browser/ui/lens/lens_coordinator.h"
 
+#import "ios/chrome/browser/application_context/application_context.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/main/browser.h"
+#import "ios/chrome/browser/signin/authentication_service.h"
+#import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
+#import "ios/chrome/browser/ui/commands/lens_commands.h"
+#import "ios/chrome/browser/ui/commands/omnibox_commands.h"
 #import "ios/chrome/browser/ui/commands/search_image_with_lens_command.h"
 #import "ios/chrome/browser/ui/lens/lens_entrypoint.h"
 #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h"
@@ -21,7 +26,7 @@
 #error "This file requires ARC support."
 #endif
 
-@interface LensCoordinator () <ChromeLensControllerDelegate>
+@interface LensCoordinator () <ChromeLensControllerDelegate, LensCommands>
 
 // A controller that can provide an entrypoint into Lens features.
 @property(nonatomic, strong) id<ChromeLensController> lensController;
@@ -32,15 +37,20 @@
 @end
 
 @implementation LensCoordinator
-@synthesize viewController = _viewController;
+@synthesize baseViewController = _baseViewController;
 
 #pragma mark - ChromeCoordinator
 
+- (instancetype)initWithBrowser:(Browser*)browser {
+  DCHECK(browser);
+  return [super initWithBaseViewController:nil browser:browser];
+}
+
 - (void)start {
   DCHECK(self.browser);
   [self.browser->GetCommandDispatcher()
       startDispatchingToTarget:self
-                   forSelector:@selector(searchImageWithLens:)];
+                   forProtocol:@protocol(LensCommands)];
 
   [super start];
 }
@@ -63,6 +73,71 @@
                               isIncognito)];
 }
 
+- (void)openInputSelectionForEntrypoint:(LensEntrypoint)entrypoint {
+  // Cancel any omnibox editing.
+  Browser* browser = self.browser;
+  CommandDispatcher* dispatcher = browser->GetCommandDispatcher();
+  id<OmniboxCommands> omniboxCommandsHandler =
+      HandlerForProtocol(dispatcher, OmniboxCommands);
+  [omniboxCommandsHandler cancelOmniboxEdit];
+
+  // Early return if Lens is not available.
+  if (!ios::provider::IsLensSupported()) {
+    return;
+  }
+
+  // Create a Lens configuration for this request.
+  ChromeBrowserState* browserState = browser->GetBrowserState();
+  const bool isIncognito = browserState->IsOffTheRecord();
+  LensConfiguration* configuration = [[LensConfiguration alloc] init];
+  configuration.isIncognito = isIncognito;
+  configuration.ssoService = GetApplicationContext()->GetSSOService();
+  configuration.entrypoint = entrypoint;
+
+  if (!isIncognito) {
+    AuthenticationService* authenticationService =
+        AuthenticationServiceFactory::GetForBrowserState(browserState);
+    ChromeIdentity* chromeIdentity = authenticationService->GetPrimaryIdentity(
+        ::signin::ConsentLevel::kSignin);
+    configuration.identity = chromeIdentity;
+  }
+
+  // Set the controller.
+  id<ChromeLensController> lensController =
+      ios::provider::NewChromeLensController(configuration);
+  DCHECK(lensController);
+
+  self.lensController = lensController;
+  lensController.delegate = self;
+
+  // Create an input selection UIViewController and present it modally.
+  CGRect contentArea = [UIScreen mainScreen].bounds;
+
+  id<LensPresentationDelegate> delegate = self.delegate;
+  if (delegate) {
+    contentArea = [delegate webContentAreaForLensCoordinator:self];
+  }
+
+  UIViewController* viewController = [lensController
+      inputSelectionViewControllerWithWebContentFrame:contentArea];
+
+  // TODO(crbug.com/1353430): the returned UIViewController
+  // must not be nil, remove this check once the internal
+  // implementation of the method is complete.
+  if (!viewController) {
+    return;
+  }
+
+  self.viewController = viewController;
+
+  [viewController
+      setModalPresentationStyle:UIModalPresentationOverCurrentContext];
+
+  [self.baseViewController presentViewController:viewController
+                                        animated:YES
+                                      completion:nil];
+}
+
 #pragma mark - ChromeLensControllerDelegate
 
 - (void)lensControllerDidTapDismissButton {
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index 2c4ed8b..a27082d 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("ntp") {
   sources = [
     "discover_feed_preview_delegate.h",
@@ -117,7 +122,10 @@
 }
 
 source_set("ntp_internal") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   sources = [
     "feed_header_view_controller.h",
     "feed_header_view_controller.mm",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h b/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h
index ff1ecf56..9f35d0a8 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h
@@ -22,10 +22,6 @@
 // Feature to enable smart sorting the new overflow menu.
 extern const base::Feature kSmartSortingNewOverflowMenu;
 
-// Feature to enable smart sorting new destinations added to the new overflow
-// menu.
-extern const base::Feature kSmartSortingNewDestinations;
-
 // Feature to add a "Share Chrome App" action to the overflow menu
 extern const base::Feature kNewOverflowMenuShareChromeAction;
 
@@ -47,9 +43,6 @@
 // Whether the new Google Password Manager branding is enabled.
 bool IsPasswordManagerBrandingUpdateEnabled();
 
-// Whether smart sorting for new destinations is enabled.
-bool IsSmartSortingNewDestinationsEnabled();
-
 // Whether smart sorting the new overflow menu is enabled.
 bool IsSmartSortingNewOverflowMenuEnabled();
 
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.mm
index 52885b1..493cfc15 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.mm
@@ -25,9 +25,6 @@
 const base::Feature kSmartSortingNewOverflowMenu{
     "kSmartSortingNewOverflowMenu", base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kSmartSortingNewDestinations{
-    "SmartSortingNewDestinations", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kNewOverflowMenuShareChromeAction{
     "kNewOverflowMenuShareChromeAction", base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -64,11 +61,6 @@
   return false;
 }
 
-bool IsSmartSortingNewDestinationsEnabled() {
-  return IsSmartSortingNewOverflowMenuEnabled() &&
-         base::FeatureList::IsEnabled(kSmartSortingNewDestinations);
-}
-
 bool IsSmartSortingNewOverflowMenuEnabled() {
   return IsNewOverflowMenuEnabled() &&
          base::FeatureList::IsEnabled(kSmartSortingNewOverflowMenu);
diff --git a/ios/chrome/browser/ui/sad_tab/BUILD.gn b/ios/chrome/browser/ui/sad_tab/BUILD.gn
index c6fa4d6..c44c0c8 100644
--- a/ios/chrome/browser/ui/sad_tab/BUILD.gn
+++ b/ios/chrome/browser/ui/sad_tab/BUILD.gn
@@ -2,8 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 source_set("sad_tab") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   sources = [
     "sad_tab_view.h",
     "sad_tab_view.mm",
@@ -57,7 +65,10 @@
 }
 
 source_set("unit_tests") {
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
   testonly = true
   sources = [
     "sad_tab_coordinator_unittest.mm",
diff --git a/ios/components/security_interstitials/safe_browsing/pending_unsafe_resource_storage.h b/ios/components/security_interstitials/safe_browsing/pending_unsafe_resource_storage.h
index 20cb7bd..71bdb7d 100644
--- a/ios/components/security_interstitials/safe_browsing/pending_unsafe_resource_storage.h
+++ b/ios/components/security_interstitials/safe_browsing/pending_unsafe_resource_storage.h
@@ -7,6 +7,7 @@
 
 #include "base/scoped_observation.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #import "components/safe_browsing/ios/browser/safe_browsing_url_allow_list.h"
 #include "components/security_interstitials/core/unsafe_resource.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -30,7 +31,7 @@
   // Returns the pending UnsafeResource, or null if the pending decision is
   // finished.
   const security_interstitials::UnsafeResource* resource() const {
-    return base::OptionalOrNullptr(resource_);
+    return base::OptionalToPtr(resource_);
   }
 
  private:
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 fc703e7..19b7981 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 @@
-d15e58b7125814197bca7ca116ff27cfc6a1bd87
\ No newline at end of file
+25c9ddd6fbde30d2971fc1e747db22e8751cd04f
\ 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 7e68c37..0a92044 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 @@
-8940de4a000216438913f7c29e43d3d0044d4c63
\ No newline at end of file
+c69c117c072dab01bbdc1c604550368967bfb6a5
\ 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 21e8df0..dd800865 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 @@
-5277e9314dadff364500c94a88ca2147455cb0b8
\ No newline at end of file
+384c054dbde43fc05854468bbe71d20b5a6798d8
\ 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 10f149d6..316a7fe 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 @@
-4593a1b62d32dd0aa1eb3ab7e37ca48452efd87d
\ No newline at end of file
+a6bf27140541c18e349c23974b80c9b83a5b90a0
\ 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 3c3fac9..57cf9040 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 @@
-113b288a2848b1d87066acebac38f1de8d526a7b
\ No newline at end of file
+fc75661cc9ee381643ae7202c1f8a1c86d2adfea
\ 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 602cb3e2..04a721b 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 @@
-983d20d70fb951c39512548999d9d8fe34e4e657
\ No newline at end of file
+e134333de4b8cc237728948fcdafed6416ba5aed
\ 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 0542ba3..9024d0e 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 @@
-b52ee2598283029e72ca3e63ea43e196d507040c
\ No newline at end of file
+8a976d739116e7e4d3f819bc1517ac3cbe5fbaca
\ 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 6f64d691..bb18446 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 @@
-2040dcda344e477d90b2d4c03d38247fef77d9a7
\ No newline at end of file
+560e245300e902cb279cc280533849e07f8c0796
\ 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 b0ad61fb..1d1925b 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 @@
-85b19e38d91f8b13d3ea4f96a3fb47cf170955ef
\ No newline at end of file
+c81ce63ed30ac2305d9be171bd3696f7f5f1a117
\ 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 db3629f..2f802a5 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 @@
-afae03ba6404e5720bd21b76b6d6e02b6e95816d
\ No newline at end of file
+769c3be8445dbc42af82c34773726b83faff289a
\ No newline at end of file
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn
index 93d51146..ee075dce 100644
--- a/ios/third_party/material_components_ios/BUILD.gn
+++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -1582,10 +1582,7 @@
 
 config("disable_deprecated") {
   cflags = [ "-Wno-deprecated" ]
-}
-
-config("disable_deprecated_declarations") {
-  cflags = [ "-Wno-deprecated-declarations" ]
+  cflags += [ "-Wno-deprecated-declarations" ]
 }
 
 # TODO(crbug.com/1153275): MDCTabBarViewItemView.h has incomplete nullability
@@ -1650,14 +1647,6 @@
     # is fixed in MDC. Remove this once fixed.
     ":disable_availability",
   ]
-
-  public_configs = [
-    # TODO(crbug.com/1344830): A number of components used by Chrome are
-    # marked deprecated in material_components_ios. Disable deprecation
-    # warnings as a temporary measure, until we remove all existing use in
-    # Chrome.
-    ":disable_deprecated_declarations",
-  ]
 }
 
 # Template to declare a bundle_data target to pack localized strings bundle.
diff --git a/ios/web/public/test/earl_grey/js_test_util.h b/ios/web/public/test/earl_grey/js_test_util.h
index fef053b..9232657 100644
--- a/ios/web/public/test/earl_grey/js_test_util.h
+++ b/ios/web/public/test/earl_grey/js_test_util.h
@@ -5,8 +5,6 @@
 #ifndef IOS_WEB_PUBLIC_TEST_EARL_GREY_JS_TEST_UTIL_H_
 #define IOS_WEB_PUBLIC_TEST_EARL_GREY_JS_TEST_UTIL_H_
 
-#import <Foundation/Foundation.h>
-
 namespace web {
 
 class WebState;
@@ -16,10 +14,6 @@
 // unrecoverable error (such as no web view) occurs.
 [[nodiscard]] bool WaitUntilWindowIdInjected(WebState* web_state);
 
-// Synchronously returns the result of executed JavaScript on interstitial page
-// displayed for |web_state|.
-id ExecuteScriptOnInterstitial(WebState* web_state, NSString* script);
-
 }  // namespace web
 
 #endif  // IOS_WEB_PUBLIC_TEST_EARL_GREY_JS_TEST_UTIL_H_
diff --git a/ios/web/public/test/earl_grey/js_test_util.mm b/ios/web/public/test/earl_grey/js_test_util.mm
index cf1c802..97421e5 100644
--- a/ios/web/public/test/earl_grey/js_test_util.mm
+++ b/ios/web/public/test/earl_grey/js_test_util.mm
@@ -7,9 +7,7 @@
 #import <WebKit/WebKit.h>
 
 #import "base/test/ios/wait_util.h"
-#include "base/timer/elapsed_timer.h"
-#import "ios/testing/earl_grey/earl_grey_app.h"
-#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+#import "base/values.h"
 #import "ios/web/public/web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -25,51 +23,34 @@
 // completed. If |out_error| is not nil, it is set to the error resulting from
 // the execution, if one occurs. The return value is the result of the
 // JavaScript execution, or nil if script execution timed out.
-id ExecuteJavaScript(WebState* web_state,
-                     NSString* javascript,
-                     NSError* __autoreleasing* out_error) {
+absl::optional<base::Value> ExecuteJavaScript(
+    WebState* web_state,
+    const std::u16string& javascript) {
   __block bool did_complete = false;
-  __block id result = nil;
-  CRWJSInjectionReceiver* receiver = web_state->GetJSInjectionReceiver();
-  [receiver executeJavaScript:javascript
-            completionHandler:^(id value, NSError* error) {
-              did_complete = true;
-              result = [value copy];
-              if (out_error)
-                *out_error = [error copy];
-            }];
+  __block absl::optional<base::Value> result;
+
+  web_state->ExecuteJavaScript(
+      javascript, base::BindOnce(^(const base::Value* completion_result) {
+        result = completion_result->Clone();
+        did_complete = true;
+      }));
 
   // Wait for completion.
   BOOL succeeded = WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{
     return did_complete;
   });
 
-  return succeeded ? result : nil;
+  return succeeded ? std::move(result) : absl::nullopt;
 }
 
 bool WaitUntilWindowIdInjected(WebState* web_state) {
-  bool is_window_id_injected = false;
-  bool is_timeout = false;
-  bool is_unrecoverable_error = false;
-
-  base::ElapsedTimer timer;
-  base::TimeDelta timeout = base::Seconds(kWaitForJSCompletionTimeout);
-
   // Keep polling until either the JavaScript execution returns with expected
   // value (indicating that Window ID is set), the timeout occurs, or an
   // unrecoverable error occurs.
-  while (!is_window_id_injected && !is_timeout && !is_unrecoverable_error) {
-    NSError* error = nil;
-    id result = ExecuteJavaScript(web_state, @"0", &error);
-    if (error) {
-      is_unrecoverable_error = ![error.domain isEqual:WKErrorDomain] ||
-                               error.code != WKErrorJavaScriptExceptionOccurred;
-    } else {
-      is_window_id_injected = [result isEqual:@0];
-    }
-    is_timeout = timeout < timer.Elapsed();
-  }
-  return !is_timeout && !is_unrecoverable_error;
+  return WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{
+    absl::optional<base::Value> result = ExecuteJavaScript(web_state, u"0");
+    return result && result->is_double() && result->GetDouble() == 0.0;
+  });
 }
 
 }  // namespace web
diff --git a/media/BUILD.gn b/media/BUILD.gn
index d6a29c4..1e33238 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -231,6 +231,10 @@
       "//build/config/fuchsia/test/platform_video_codecs.shard.test-cml",
       "//third_party/fuchsia-sdk/sdk/pkg/vulkan/client.shard.cml",
     ]
+
+    if (enable_library_cdms) {
+      excluded_files = [ "lib.unstripped/libclearkeycdm.so" ]
+    }
   }
 
   if (enable_media_remoting) {
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
index ed5fa39f..9298aeb 100644
--- a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
+++ b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
@@ -143,29 +143,38 @@
     }
 
     /**
-     * Get a name of default android codec.
+     * Get the name of the first codec matching the provided parameters.
+     *
      * @param mime MIME type of the media.
      * @param direction Whether this is encoder or decoder.
      * @param requireSoftwareCodec Whether we require a software codec.
-     * @return name of the codec.
+     * @param requireHardwareCodec Whether we require a hardware codec.
+     * @return name of the codec or empty string if none exists.
      */
     @CalledByNative
-    private static String getDefaultCodecName(
-            String mime, int direction, boolean requireSoftwareCodec) {
+    private static String getDefaultCodecName(String mime, int direction,
+            boolean requireSoftwareCodec, boolean requireHardwareCodec) {
+        assert !(requireSoftwareCodec && requireHardwareCodec);
         MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
         for (MediaCodecInfo info : codecListHelper) {
             int codecDirection =
                     info.isEncoder() ? MediaCodecDirection.ENCODER : MediaCodecDirection.DECODER;
             if (codecDirection != direction) continue;
 
-            if (requireSoftwareCodec && !isSoftwareCodec(info)) continue;
+            boolean isSoftware = isSoftwareCodec(info);
+            if (requireSoftwareCodec && !isSoftware) continue;
+            if (requireHardwareCodec && isSoftware) continue;
 
             for (String supportedType : info.getSupportedTypes()) {
                 if (supportedType.equalsIgnoreCase(mime)) return info.getName();
             }
         }
 
-        Log.e(TAG, "Decoder for type %s is not supported on this device", mime);
+        Log.e(TAG,
+                "%s for type %s is not supported on this device [requireSoftware=%b, "
+                        + "requireHardware=%b].",
+                direction == MediaCodecDirection.ENCODER ? "Encoder" : "Decoder", mime,
+                requireSoftwareCodec, requireHardwareCodec);
         return "";
     }
 
@@ -361,7 +370,8 @@
                 // codec name and append ".secure" to get the secure codec name.
                 // TODO(xhwang): Now b/15587335 is fixed, we should have better
                 // API support.
-                String decoderName = getDefaultCodecName(mime, MediaCodecDirection.DECODER, false);
+                String decoderName =
+                        getDefaultCodecName(mime, MediaCodecDirection.DECODER, false, false);
                 if (decoderName.equals("")) return result;
 
                 // To work around an issue that we cannot get the codec info
@@ -378,7 +388,7 @@
             } else {
                 if (codecType == CodecType.SOFTWARE) {
                     String decoderName =
-                            getDefaultCodecName(mime, MediaCodecDirection.DECODER, true);
+                            getDefaultCodecName(mime, MediaCodecDirection.DECODER, true, false);
                     result.mediaCodec = MediaCodec.createByCodecName(decoderName);
                 } else if (mime.equals(MediaFormat.MIMETYPE_AUDIO_RAW)) {
                     result.mediaCodec = MediaCodec.createByCodecName("OMX.google.raw.decoder");
diff --git a/media/base/android/media_codec_util.cc b/media/base/android/media_codec_util.cc
index fe96d28..06589b3 100644
--- a/media/base/android/media_codec_util.cc
+++ b/media/base/android/media_codec_util.cc
@@ -72,17 +72,6 @@
          supported.end();
 }
 
-static std::string GetDefaultCodecName(const std::string& mime_type,
-                                       MediaCodecDirection direction,
-                                       bool requires_software_codec) {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
-  ScopedJavaLocalRef<jstring> j_codec_name =
-      Java_MediaCodecUtil_getDefaultCodecName(
-          env, j_mime, static_cast<int>(direction), requires_software_codec);
-  return ConvertJavaStringToUTF8(env, j_codec_name.obj());
-}
-
 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) {
   DCHECK(IsSupportedAndroidMimeType(android_mime_type));
   JNIEnv* env = AttachCurrentThread();
@@ -330,33 +319,28 @@
 // static
 bool MediaCodecUtil::IsKnownUnaccelerated(VideoCodec codec,
                                           MediaCodecDirection direction) {
-  std::string codec_name =
-      GetDefaultCodecName(CodecToAndroidMimeType(codec), direction, false);
-  DVLOG(1) << __func__ << "Default codec for " << GetCodecName(codec) << " : "
-           << codec_name << ", direction: " << static_cast<int>(direction);
+  auto* env = AttachCurrentThread();
+  auto j_mime = ConvertUTF8ToJavaString(env, CodecToAndroidMimeType(codec));
+  auto j_codec_name = Java_MediaCodecUtil_getDefaultCodecName(
+      env, j_mime, static_cast<int>(direction), /*requireSoftwareCodec=*/false,
+      /*requireHardwareCodec=*/true);
+
+  auto codec_name = ConvertJavaStringToUTF8(env, j_codec_name.obj());
+  DVLOG(1) << __func__ << "Default hardware codec for " << GetCodecName(codec)
+           << " : " << codec_name
+           << ", direction: " << static_cast<int>(direction);
   if (codec_name.empty())
     return true;
 
   // MediaTek hardware vp8 is known slower than the software implementation.
-  if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) {
-    if (codec == VideoCodec::kVP8) {
-      // We may still reject VP8 hardware decoding later on certain chipsets,
-      // see isDecoderSupportedForDevice(). We don't have the the chipset ID
-      // here to check now though.
-      return base::android::BuildInfo::GetInstance()->sdk_int() < SDK_VERSION_P;
-    }
-
-    return false;
+  if (base::StartsWith(codec_name, "OMX.MTK.") && codec == VideoCodec::kVP8) {
+    // We may still reject VP8 hardware decoding later on certain chipsets,
+    // see isDecoderSupportedForDevice(). We don't have the the chipset ID
+    // here to check now though.
+    return base::android::BuildInfo::GetInstance()->sdk_int() < SDK_VERSION_P;
   }
 
-  // It would be nice if MediaCodecInfo externalized some notion of
-  // HW-acceleration but it doesn't. Android Media guidance is that the
-  // "OMX.google" prefix is always used for SW decoders, so that's what we
-  // use. "OMX.SEC.*" codec is Samsung software implementation - report it
-  // as unaccelerated as well.
-  return base::StartsWith(codec_name, "OMX.google.",
-                          base::CompareCase::SENSITIVE) ||
-         base::StartsWith(codec_name, "OMX.SEC.", base::CompareCase::SENSITIVE);
+  return false;
 }
 
 }  // namespace media
diff --git a/media/base/video_codecs.cc b/media/base/video_codecs.cc
index 4af7ed4..21743dd 100644
--- a/media/base/video_codecs.cc
+++ b/media/base/video_codecs.cc
@@ -16,6 +16,8 @@
 namespace media {
 
 // The names come from src/third_party/ffmpeg/libavcodec/codec_desc.c
+// TODO(crbug.com/1357080): The returned strings are used by ChunkDemuxer in
+// the code logic as well in tests. Merge with GetCodecNameForUMA() if possible.
 std::string GetCodecName(VideoCodec codec) {
   switch (codec) {
     case VideoCodec::kUnknown:
@@ -45,6 +47,36 @@
   return "";
 }
 
+// Reported as part of some UMA names. NEVER change existing strings!
+std::string GetCodecNameForUMA(VideoCodec codec) {
+  switch (codec) {
+    case VideoCodec::kUnknown:
+      return "Unknown";
+    case VideoCodec::kH264:
+      return "H264";
+    case VideoCodec::kHEVC:
+      return "HEVC";
+    case VideoCodec::kDolbyVision:
+      return "DolbyVision";
+    case VideoCodec::kVC1:
+      return "VC1";
+    case VideoCodec::kMPEG2:
+      return "MPEG2Video";
+    case VideoCodec::kMPEG4:
+      return "MPEG4";
+    case VideoCodec::kTheora:
+      return "Theora";
+    case VideoCodec::kVP8:
+      return "VP8";
+    case VideoCodec::kVP9:
+      return "VP9";
+    case VideoCodec::kAV1:
+      return "AV1";
+  }
+  NOTREACHED();
+  return "";
+}
+
 std::string GetProfileName(VideoCodecProfile profile) {
   switch (profile) {
     case VIDEO_CODEC_PROFILE_UNKNOWN:
diff --git a/media/base/video_codecs.h b/media/base/video_codecs.h
index c522256..c928efd9 100644
--- a/media/base/video_codecs.h
+++ b/media/base/video_codecs.h
@@ -114,7 +114,12 @@
   VideoCodecLevel level;
 };
 
+// Returns a name for `codec` for logging and display purposes.
 std::string MEDIA_EXPORT GetCodecName(VideoCodec codec);
+
+// Returns a name for `codec` to be used for UMA reporting.
+std::string MEDIA_EXPORT GetCodecNameForUMA(VideoCodec codec);
+
 std::string MEDIA_EXPORT GetProfileName(VideoCodecProfile profile);
 std::string MEDIA_EXPORT BuildH264MimeSuffix(VideoCodecProfile profile,
                                              uint8_t level);
diff --git a/media/capture/video/win/video_capture_device_mf_win.cc b/media/capture/video/win/video_capture_device_mf_win.cc
index 526d3c1..10911005 100644
--- a/media/capture/video/win/video_capture_device_mf_win.cc
+++ b/media/capture/video/win/video_capture_device_mf_win.cc
@@ -1408,7 +1408,7 @@
     // support optional shallow focus capability (according to
     // https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/ksproperty-cameracontrol-extended-backgroundsegmentation)
     // but that support is not needed here.
-    HRESULT hr = extended_camera_controller_->GetExtendedCameraControl(
+    hr = extended_camera_controller_->GetExtendedCameraControl(
         MF_CAPTURE_ENGINE_MEDIASOURCE,
         KSPROPERTY_CAMERACONTROL_EXTENDED_BACKGROUNDSEGMENTATION,
         &extended_camera_control);
@@ -1604,7 +1604,7 @@
   if (extended_camera_controller_) {
     ComPtr<IMFExtendedCameraControl> extended_camera_control;
     if (settings->has_background_blur_mode) {
-      HRESULT hr = extended_camera_controller_->GetExtendedCameraControl(
+      hr = extended_camera_controller_->GetExtendedCameraControl(
           MF_CAPTURE_ENGINE_MEDIASOURCE,
           KSPROPERTY_CAMERACONTROL_EXTENDED_BACKGROUNDSEGMENTATION,
           &extended_camera_control);
diff --git a/media/cdm/cdm_paths.cc b/media/cdm/cdm_paths.cc
index 1aae2c8..f4c0396 100644
--- a/media/cdm/cdm_paths.cc
+++ b/media/cdm/cdm_paths.cc
@@ -15,7 +15,12 @@
 // Name of the ClearKey CDM library.
 const char kClearKeyCdmLibraryName[] = "clearkeycdm";
 
-const char kClearKeyCdmBaseDirectory[] = "ClearKeyCdm";
+const char kClearKeyCdmBaseDirectory[] =
+#if BUILDFLAG(IS_FUCHSIA)
+    "lib/"
+#endif
+    "ClearKeyCdm";
+
 const char kClearKeyCdmDisplayName[] = "Clear Key CDM";
 
 const CdmType kClearKeyCdmType{0x3a2e0fadde4bd1b7ull, 0xcb90df3e240d1694ull};
diff --git a/media/cdm/cdm_paths_unittest.cc b/media/cdm/cdm_paths_unittest.cc
index 1a569ef5..507ca1d 100644
--- a/media/cdm/cdm_paths_unittest.cc
+++ b/media/cdm/cdm_paths_unittest.cc
@@ -29,6 +29,8 @@
     "cros";
 #elif BUILDFLAG(IS_LINUX)
     "linux";
+#elif BUILDFLAG(IS_FUCHSIA)
+    "fuchsia";
 #else
 #error unsupported platform
 #endif
diff --git a/media/cdm/external_clear_key_test_helper.cc b/media/cdm/external_clear_key_test_helper.cc
index febd0d4..beef6bec 100644
--- a/media/cdm/external_clear_key_test_helper.cc
+++ b/media/cdm/external_clear_key_test_helper.cc
@@ -31,20 +31,15 @@
 }
 
 void ExternalClearKeyTestHelper::LoadLibrary() {
-#if BUILDFLAG(IS_FUCHSIA)
-  library_path_ =
-      base::FilePath(base::GetLoadableModuleName(kClearKeyCdmLibraryName));
-#else   // BUILDFLAG(IS_FUCHSIA)
   // Determine the location of the CDM. It is expected to be in the same
   // directory as the current module.
   base::FilePath cdm_base_path;
-  ASSERT_TRUE(base::PathService::Get(base::DIR_MODULE, &cdm_base_path));
+  ASSERT_TRUE(base::PathService::Get(base::DIR_ASSETS, &cdm_base_path));
   cdm_base_path = cdm_base_path.Append(
       GetPlatformSpecificDirectory(kClearKeyCdmBaseDirectory));
   library_path_ = cdm_base_path.AppendASCII(
       base::GetLoadableModuleName(kClearKeyCdmLibraryName));
   ASSERT_TRUE(base::PathExists(library_path_)) << library_path_.value();
-#endif  // BUILDFLAG(IS_FUCHSIA)
 
   // Now load the CDM library.
   library_ = base::ScopedNativeLibrary(library_path_);
diff --git a/media/cdm/library_cdm/cdm_paths.gni b/media/cdm/library_cdm/cdm_paths.gni
index d18f179f..d85a2ea3 100644
--- a/media/cdm/library_cdm/cdm_paths.gni
+++ b/media/cdm/library_cdm/cdm_paths.gni
@@ -21,6 +21,8 @@
   component_os = "win"
 } else if (is_mac) {
   component_os = "mac"
+} else if (is_fuchsia) {
+  component_os = "fuchsia"
 } else {
   assert(false, "unsupported_platform")
 }
@@ -31,15 +33,16 @@
 # components, but is optional for other platforms.
 # Note:
 # - |cdm_platform_specific_path| is exported as a BUILDFLAG to cdm_paths.cc.
-if (is_fuchsia) {
-  cdm_platform_specific_path = ""
-  clearkey_cdm_path = "lib"
-  widevine_cdm_path = "lib"
-} else {
-  cdm_platform_specific_path =
-      "_platform_specific/$component_os" + "_" + "$component_arch"
+cdm_platform_specific_path =
+    "_platform_specific/$component_os" + "_" + "$component_arch"
 
-  # Path of Clear Key and Widevine CDMs relative to the output dir.
-  clearkey_cdm_path = "ClearKeyCdm/$cdm_platform_specific_path"
-  widevine_cdm_path = "WidevineCdm/$cdm_platform_specific_path"
+# Path of Clear Key and Widevine CDMs relative to the output dir.
+clearkey_cdm_path = "ClearKeyCdm/$cdm_platform_specific_path"
+widevine_cdm_path = "WidevineCdm/$cdm_platform_specific_path"
+
+# Shared libraries must be within lib/ on Fuchsia.
+# TODO(fxbug.dev/105910): Remove when the GN SDK drops this limitation.
+if (is_fuchsia) {
+  clearkey_cdm_path = "lib/" + clearkey_cdm_path
+  widevine_cdm_path = "lib/" + clearkey_cdm_path
 }
diff --git a/media/cdm/library_cdm/clear_key_cdm/BUILD.gn b/media/cdm/library_cdm/clear_key_cdm/BUILD.gn
index 94deeb5..4b47070 100644
--- a/media/cdm/library_cdm/clear_key_cdm/BUILD.gn
+++ b/media/cdm/library_cdm/clear_key_cdm/BUILD.gn
@@ -8,7 +8,7 @@
 
 assert(enable_library_cdms)
 
-loadable_module("clear_key_cdm") {
+loadable_module("clear_key_cdm_bin") {
   testonly = true
   output_dir = "$root_out_dir/$clearkey_cdm_path"
   output_name = "clearkeycdm"
@@ -48,3 +48,17 @@
     deps += [ "//third_party/ffmpeg" ]
   }
 }
+
+group("clear_key_cdm") {
+  testonly = true
+  deps = [ ":clear_key_cdm_bin" ]
+  if (is_fuchsia) {
+    # Tests that need the CDM binary must include this target in their
+    # `data_deps`. Due to the unique path of CDMs, the Fuchsia SDK will include
+    # the unstripped binary (see fxbug.dev/105910). Therefore, targets that
+    # depend on this one must add the unstripped library path to
+    # `excluded_files` when `is_fuchsia` to prevent the unstripped binary from
+    # being added to the package.
+    data = [ "$root_out_dir/$clearkey_cdm_path/libclearkeycdm.so" ]
+  }
+}
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index 9677fa2..288d36aa 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -99,6 +99,13 @@
       "h264_to_annex_b_bitstream_converter.cc",
       "h264_to_annex_b_bitstream_converter.h",
     ]
+
+    if (enable_platform_hevc) {
+      sources += [
+        "h265_to_annex_b_bitstream_converter.cc",
+        "h265_to_annex_b_bitstream_converter.h",
+      ]
+    }
   }
 
   if (media_use_ffmpeg) {
@@ -379,6 +386,10 @@
   if (proprietary_codecs) {
     sources += [ "h264_to_annex_b_bitstream_converter_unittest.cc" ]
 
+    if (enable_platform_hevc) {
+      sources += [ "h265_to_annex_b_bitstream_converter_unittest.cc" ]
+    }
+
     if (media_use_ffmpeg) {
       sources += [
         "ffmpeg_aac_bitstream_converter_unittest.cc",
diff --git a/media/filters/h265_to_annex_b_bitstream_converter.cc b/media/filters/h265_to_annex_b_bitstream_converter.cc
new file mode 100644
index 0000000..dbf3c16
--- /dev/null
+++ b/media/filters/h265_to_annex_b_bitstream_converter.cc
@@ -0,0 +1,295 @@
+// 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 "media/filters/h265_to_annex_b_bitstream_converter.h"
+
+#include <stddef.h>
+
+#include "base/logging.h"
+#include "media/formats/mp4/box_definitions.h"
+#include "media/formats/mp4/hevc.h"
+#include "media/video/h265_nalu_parser.h"
+
+namespace media {
+namespace {
+
+static const uint8_t kStartCodePrefix[3] = {0, 0, 1};
+static const uint32_t kParamSetStartCodeSize = 1 + sizeof(kStartCodePrefix);
+
+// Helper function which determines whether NAL unit of given type marks
+// access unit boundary.
+static bool IsAccessUnitBoundaryNal(int nal_unit_type) {
+  // Spec 7.4.2.4.4
+  // Check if this packet marks access unit boundary by checking the
+  // packet type.
+  if (nal_unit_type == media::H265NALU::VPS_NUT ||
+      nal_unit_type == media::H265NALU::SPS_NUT ||
+      nal_unit_type == media::H265NALU::PPS_NUT ||
+      nal_unit_type == media::H265NALU::AUD_NUT ||
+      nal_unit_type == media::H265NALU::PREFIX_SEI_NUT ||
+      (nal_unit_type >= media::H265NALU::RSV_NVCL41 &&
+       nal_unit_type <= media::H265NALU::RSV_NVCL44) ||
+      (nal_unit_type >= media::H265NALU::UNSPEC48 &&
+       nal_unit_type <= media::H265NALU::UNSPEC55)) {
+    return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+H265ToAnnexBBitstreamConverter::H265ToAnnexBBitstreamConverter() = default;
+
+H265ToAnnexBBitstreamConverter::~H265ToAnnexBBitstreamConverter() = default;
+
+bool H265ToAnnexBBitstreamConverter::ParseConfiguration(
+    const uint8_t* configuration_record,
+    int configuration_record_size,
+    mp4::HEVCDecoderConfigurationRecord* hevc_config) {
+  DCHECK(configuration_record);
+  DCHECK_GT(configuration_record_size, 0);
+  DCHECK(hevc_config);
+
+  if (!hevc_config->Parse(configuration_record, configuration_record_size))
+    return false;
+
+  configuration_processed_ = true;
+  return true;
+}
+
+uint32_t H265ToAnnexBBitstreamConverter::GetConfigSize(
+    const mp4::HEVCDecoderConfigurationRecord& hevc_config) const {
+  uint32_t config_size = 0;
+
+  for (auto& nalu_array : hevc_config.arrays) {
+    for (auto& nalu : nalu_array.units) {
+      config_size += kParamSetStartCodeSize + nalu.size();
+    }
+  }
+  return config_size;
+}
+
+uint32_t H265ToAnnexBBitstreamConverter::CalculateNeededOutputBufferSize(
+    const uint8_t* input,
+    uint32_t input_size,
+    const mp4::HEVCDecoderConfigurationRecord* hevc_config) const {
+  uint32_t output_size = 0;
+  uint32_t data_left = input_size;
+  bool first_nal_in_this_access_unit = first_nal_unit_in_access_unit_;
+
+  if (input_size == 0)
+    return 0;  // Error: invalid input data
+
+  if (!configuration_processed_) {
+    return 0;  // Error: configuration not handled, we don't know nal unit width
+  }
+
+  if (hevc_config)
+    output_size += GetConfigSize(*hevc_config);
+
+  uint8_t nal_unit_length_field_width = hevc_config->lengthSizeMinusOne + 1;
+  CHECK(nal_unit_length_field_width == 1 || nal_unit_length_field_width == 2 ||
+        nal_unit_length_field_width == 4);
+
+  // Then add the needed size for the actual packet
+  while (data_left > 0) {
+    if (data_left < nal_unit_length_field_width) {
+      return 0;  // Error: not enough data for correct conversion.
+    }
+
+    // Read the next NAL unit length from the input buffer
+    uint8_t size_of_len_field;
+    uint32_t nal_unit_length;
+    for (nal_unit_length = 0, size_of_len_field = nal_unit_length_field_width;
+         size_of_len_field > 0; input++, size_of_len_field--, data_left--) {
+      nal_unit_length <<= 8;
+      nal_unit_length |= *input;
+    }
+
+    if (nal_unit_length == 0) {
+      break;  // Signifies that no more data left in the buffer
+    } else if (nal_unit_length > data_left) {
+      return 0;  // Error: Not enough data for correct conversion
+    }
+    data_left -= nal_unit_length;
+
+    // Six bits after forbidden_zero_bit of first NAL unit byte signify
+    // nal_unit_type.
+    int nal_unit_type = (*input >> 1) & 0x3F;
+    if (first_nal_in_this_access_unit ||
+        IsAccessUnitBoundaryNal(nal_unit_type)) {
+      output_size += 1;  // Extra zero_byte for these nal units
+      first_nal_in_this_access_unit = false;
+    }
+    // Start code prefix
+    output_size += sizeof(kStartCodePrefix);
+    // Actual NAL unit size
+    output_size += nal_unit_length;
+    input += nal_unit_length;
+    // No need for trailing zero bits
+  }
+  return output_size;
+}
+
+bool H265ToAnnexBBitstreamConverter::ConvertHEVCDecoderConfigToByteStream(
+    const mp4::HEVCDecoderConfigurationRecord& hevc_config,
+    uint8_t* output,
+    uint32_t* output_size) {
+  uint8_t* out = output;
+  uint32_t out_size = *output_size;
+  *output_size = 0;
+
+  for (auto& nalu_array : hevc_config.arrays) {
+    for (auto& nalu : nalu_array.units) {
+      if (!WriteParamSet(nalu, &out, &out_size)) {
+        return false;
+      }
+    }
+  }
+
+  configuration_processed_ = true;
+  *output_size = out - output;
+  return true;
+}
+
+bool H265ToAnnexBBitstreamConverter::ConvertNalUnitStreamToByteStream(
+    const uint8_t* input,
+    uint32_t input_size,
+    const mp4::HEVCDecoderConfigurationRecord* hevc_config,
+    uint8_t* output,
+    uint32_t* output_size) {
+  const uint8_t* inscan = input;  // We read the input from here progressively
+  uint8_t* outscan = output;      // We write the output to here progressively
+  uint32_t data_left = input_size;
+
+  if (input_size == 0 || *output_size == 0) {
+    *output_size = 0;
+    return false;  // Error: invalid input
+  }
+
+  uint8_t nal_unit_length_field_width = hevc_config->lengthSizeMinusOne + 1;
+  CHECK(nal_unit_length_field_width == 1 || nal_unit_length_field_width == 2 ||
+        nal_unit_length_field_width == 4);
+
+  // Do the actual conversion for the actual input packet
+  int nal_unit_count = 0;
+  while (data_left > 0) {
+    uint8_t i;
+    uint32_t nal_unit_length;
+
+    // Read the next NAL unit length from the input buffer by scanning
+    // the input stream with the specific length field width
+    for (nal_unit_length = 0, i = nal_unit_length_field_width;
+         i > 0 && data_left > 0; inscan++, i--, data_left--) {
+      nal_unit_length <<= 8;
+      nal_unit_length |= *inscan;
+    }
+
+    if (nal_unit_length == 0) {
+      break;  // Successful conversion, end of buffer
+    } else if (nal_unit_length > data_left) {
+      *output_size = 0;
+      return false;  // Error: not enough data for correct conversion
+    }
+
+    // Six bits after forbidden_zero_bit of first NAL unit byte signify
+    // nal_unit_type.
+    int nal_unit_type = (*inscan >> 1) & 0x3F;
+    nal_unit_count++;
+
+    // Insert the config after the AUD if an AUD is the first NAL unit or
+    // before all NAL units if the first one isn't an AUD.
+    if (hevc_config &&
+        (nal_unit_type != H265NALU::AUD_NUT || nal_unit_count > 1)) {
+      uint32_t output_bytes_used = outscan - output;
+
+      DCHECK_GE(*output_size, output_bytes_used);
+
+      uint32_t config_size = *output_size - output_bytes_used;
+      if (!ConvertHEVCDecoderConfigToByteStream(*hevc_config, outscan,
+                                                &config_size)) {
+        DVLOG(1) << "Failed to insert parameter sets.";
+        *output_size = 0;
+        return false;  // Failed to convert the buffer.
+      }
+      outscan += config_size;
+      hevc_config = nullptr;
+    }
+    uint32_t start_code_len;
+    first_nal_unit_in_access_unit_
+        ? start_code_len = sizeof(kStartCodePrefix) + 1
+        : start_code_len = sizeof(kStartCodePrefix);
+    if (static_cast<uint32_t>(outscan - output) + start_code_len +
+            nal_unit_length >
+        *output_size) {
+      *output_size = 0;
+      return false;  // Error: too small output buffer
+    }
+
+    // Check if this packet marks access unit boundary by checking the
+    // packet type.
+    if (IsAccessUnitBoundaryNal(nal_unit_type)) {
+      first_nal_unit_in_access_unit_ = true;
+    }
+
+    // Write extra zero-byte before start code prefix if this packet
+    // signals next access unit.
+    if (first_nal_unit_in_access_unit_) {
+      *outscan = 0;
+      outscan++;
+      first_nal_unit_in_access_unit_ = false;
+    }
+
+    // No need to write leading zero bits.
+    // Write start-code prefix.
+    memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix));
+    outscan += sizeof(kStartCodePrefix);
+    // Then write the actual NAL unit from the input buffer.
+    memcpy(outscan, inscan, nal_unit_length);
+    inscan += nal_unit_length;
+    data_left -= nal_unit_length;
+    outscan += nal_unit_length;
+    // No need for trailing zero bits.
+  }
+  // Successful conversion, output the freshly allocated bitstream buffer.
+  *output_size = static_cast<uint32_t>(outscan - output);
+  return true;
+}
+
+bool H265ToAnnexBBitstreamConverter::WriteParamSet(
+    const std::vector<uint8_t>& param_set,
+    uint8_t** out,
+    uint32_t* out_size) const {
+  // Strip trailing null bytes.
+  size_t size = param_set.size();
+  while (size && param_set[size - 1] == 0)
+    size--;
+  if (!size)
+    return false;
+
+  // Verify space.
+  uint32_t bytes_left = *out_size;
+  if (bytes_left < kParamSetStartCodeSize ||
+      bytes_left - kParamSetStartCodeSize < size) {
+    return false;
+  }
+
+  uint8_t* start = *out;
+  uint8_t* buf = start;
+
+  // Write the 4 byte Annex B start code.
+  *buf++ = 0;  // zero byte
+  memcpy(buf, kStartCodePrefix, sizeof(kStartCodePrefix));
+  buf += sizeof(kStartCodePrefix);
+
+  // Copy the data.
+  memcpy(buf, &param_set[0], size);
+  buf += size;
+
+  *out = buf;
+  *out_size -= buf - start;
+  return true;
+}
+
+}  // namespace media
diff --git a/media/filters/h265_to_annex_b_bitstream_converter.h b/media/filters/h265_to_annex_b_bitstream_converter.h
new file mode 100644
index 0000000..55fc75317
--- /dev/null
+++ b/media/filters/h265_to_annex_b_bitstream_converter.h
@@ -0,0 +1,156 @@
+// 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 MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
+#define MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "media/base/media_export.h"
+
+namespace media {
+
+namespace mp4 {
+struct HEVCDecoderConfigurationRecord;
+}
+
+// H265ToAnnexBBitstreamConverter is a class to convert H.265 bitstream from
+// MP4 format (as specified in ISO/IEC 14496-15) into H.265 bytestream
+// (as specified in ISO/IEC 14496-10 Annex B).
+class MEDIA_EXPORT H265ToAnnexBBitstreamConverter {
+ public:
+  H265ToAnnexBBitstreamConverter();
+
+  H265ToAnnexBBitstreamConverter(const H265ToAnnexBBitstreamConverter&) =
+      delete;
+  H265ToAnnexBBitstreamConverter& operator=(
+      const H265ToAnnexBBitstreamConverter&) = delete;
+
+  ~H265ToAnnexBBitstreamConverter();
+
+  // Parses the global HEVCDecoderConfigurationRecord from the file format's
+  // headers. Converter will remember the field length from the configuration
+  // headers after this.
+  //
+  // Parameters
+  //   configuration_record
+  //     Pointer to buffer containing HEVCDecoderConfigurationRecord.
+  //   configuration_record_size
+  //     Size of the buffer in bytes.
+  //   hevc_config
+  //     Pointer to place the parsed HEVCDecoderConfigurationRecord data into.
+  //
+  // Returns
+  //   Returns true if |configuration_record| was successfully parsed. False
+  //   is returned if a parsing error occurred.
+  //   |hevc_config| only contains valid data when true is returned.
+  bool ParseConfiguration(const uint8_t* configuration_record,
+                          int configuration_record_size,
+                          mp4::HEVCDecoderConfigurationRecord* hevc_config);
+
+  // Returns the buffer size needed to store the parameter sets in |hevc_config|
+  // in Annex B form.
+  uint32_t GetConfigSize(
+      const mp4::HEVCDecoderConfigurationRecord& hevc_config) const;
+
+  // Calculates needed buffer size for the bitstream converted into bytestream.
+  // Lightweight implementation that does not do the actual conversion.
+  //
+  // Parameters
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
+  //   input_size
+  //     Size of the buffer in bytes.
+  //   hevc_config
+  //     The HEVCDecoderConfigurationRecord that contains the parameter sets
+  //     that will be inserted into the output. nullptr if no parameter sets
+  //     need to be inserted.
+  //
+  // Returns
+  //   Required buffer size for the output NAL unit buffer when converted
+  //   to bytestream format, or 0 if could not determine the size of
+  //   the output buffer from the data in |input| and |hevc_config|.
+  uint32_t CalculateNeededOutputBufferSize(
+      const uint8_t* input,
+      uint32_t input_size,
+      const mp4::HEVCDecoderConfigurationRecord* hevc_config) const;
+
+  // ConvertHEVCDecoderConfigToByteStream converts the
+  // HEVCDecoderConfigurationRecord from the MP4 headers to bytestream format.
+  // Client is responsible for making sure the output buffer is large enough
+  // to hold the output data. Client can precalculate the needed output buffer
+  // size by using GetConfigSize().
+  //
+  // Parameters
+  //   hevc_config
+  //     The HEVCDecoderConfigurationRecord that contains the parameter sets
+  //     that will be written to |output|.
+  //   output
+  //     Pointer to buffer where the output should be written to.
+  //   output_size (i/o)
+  //     Pointer to the size of the output buffer. Will contain the number of
+  //     bytes written to output after successful call.
+  //
+  // Returns
+  //    true  if successful conversion|
+  //    false if conversion not successful (|output_size| will hold the amount
+  //          of converted data)
+  bool ConvertHEVCDecoderConfigToByteStream(
+      const mp4::HEVCDecoderConfigurationRecord& hevc_config,
+      uint8_t* output,
+      uint32_t* output_size);
+
+  // ConvertNalUnitStreamToByteStream converts the NAL unit from MP4 format
+  // to bytestream format. Client is responsible for making sure the output
+  // buffer is large enough to hold the output data. Client can precalculate the
+  // needed output buffer size by using CalculateNeededOutputBufferSize.
+  //
+  // Parameters
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
+  //   input_size
+  //     Size of the buffer in bytes.
+  //   hevc_config
+  //     The HEVCDecoderConfigurationRecord that contains the parameter sets to
+  //     insert into the output. NULL if no parameter sets need to be inserted.
+  //   output
+  //     Pointer to buffer where the output should be written to.
+  //   output_size (i/o)
+  //     Pointer to the size of the output buffer. Will contain the number of
+  //     bytes written to output after successful call.
+  //
+  // Returns
+  //    true  if successful conversion
+  //    false if conversion not successful (output_size will hold the amount
+  //          of converted data)
+  bool ConvertNalUnitStreamToByteStream(
+      const uint8_t* input,
+      uint32_t input_size,
+      const mp4::HEVCDecoderConfigurationRecord* hevc_config,
+      uint8_t* output,
+      uint32_t* output_size);
+
+ private:
+  // Writes Annex B start code and |param_set| to |*out|.
+  //  |*out| - Is the memory location to write the parameter set.
+  //  |*out_size| - Number of bytes available for the parameter set.
+  // Returns true if the start code and param set were successfully
+  // written. On a successful write, |*out| is updated to point to the first
+  // byte after the data that was written. |*out_size| is updated to reflect
+  // the new number of bytes left in |*out|.
+  bool WriteParamSet(const std::vector<uint8_t>& param_set,
+                     uint8_t** out,
+                     uint32_t* out_size) const;
+
+  // Flag for indicating whether global parameter sets have been processed.
+  bool configuration_processed_ = false;
+  // Flag for indicating whether next NAL unit starts new access unit.
+  bool first_nal_unit_in_access_unit_ = false;
+};
+
+}  // namespace media
+
+#endif  // MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
diff --git a/media/filters/h265_to_annex_b_bitstream_converter_unittest.cc b/media/filters/h265_to_annex_b_bitstream_converter_unittest.cc
new file mode 100644
index 0000000..325e0d3
--- /dev/null
+++ b/media/filters/h265_to_annex_b_bitstream_converter_unittest.cc
@@ -0,0 +1,238 @@
+// 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 "media/filters/h265_to_annex_b_bitstream_converter.h"
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "media/formats/mp4/box_definitions.h"
+#include "media/formats/mp4/hevc.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+class H265ToAnnexBBitstreamConverterTest : public testing::Test {
+ public:
+  H265ToAnnexBBitstreamConverterTest(
+      const H265ToAnnexBBitstreamConverterTest&) = delete;
+  H265ToAnnexBBitstreamConverterTest& operator=(
+      const H265ToAnnexBBitstreamConverterTest&) = delete;
+
+ protected:
+  H265ToAnnexBBitstreamConverterTest() = default;
+
+  ~H265ToAnnexBBitstreamConverterTest() override = default;
+
+ protected:
+  mp4::HEVCDecoderConfigurationRecord hevc_config_;
+};
+
+static const uint8_t kHeaderDataOkWithFieldLen4[] = {
+    0x01, 0x01, 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x96, 0xf0, 0x00, 0xfc, 0xfd, 0xf8, 0xf8, 0x00, 0x00, 0x0f,
+    0x03, 0xa0, 0x00, 0x01, 0x00, 0x18, 0x40, 0x01, 0x0c, 0x01, 0xff,
+    0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x03, 0x00, 0x96, 0x9d, 0xc0, 0x90, 0xa1, 0x00, 0x01,
+    0x00, 0x29, 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00,
+    0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03,
+    0xc0, 0x80, 0x10, 0xe5, 0x96, 0x77, 0x92, 0x46, 0xda, 0xf0, 0x10,
+    0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x06, 0x1a, 0x80, 0x80, 0xa2,
+    0x00, 0x01, 0x00, 0x06, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89};
+
+static const uint8_t kPacketDataOkWithFieldLen4[] = {
+    0x00, 0x00, 0x00, 0x2d, 0x00, 0x01, 0xe0, 0xa6, 0xf5, 0xd7,
+    0xd2, 0x24, 0x0a, 0x19, 0x1a, 0xa0, 0xdc, 0x8c, 0x68, 0x5e,
+    0x35, 0x20, 0x40, 0x64, 0x1c, 0x86, 0x81, 0x8a, 0x25, 0x5d,
+    0x65, 0x6c, 0xfe, 0x80, 0x7a, 0xe3, 0xf4, 0x63, 0xe1, 0xcf,
+    0xf2, 0x6e, 0x92, 0x1e, 0xff, 0xd3, 0x65, 0xd9, 0x60};
+
+TEST_F(H265ToAnnexBBitstreamConverterTest, Success) {
+  // Initialize converter.
+  std::unique_ptr<uint8_t[]> output;
+  H265ToAnnexBBitstreamConverter converter;
+
+  // Parse the headers.
+  EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
+                                           sizeof(kHeaderDataOkWithFieldLen4),
+                                           &hevc_config_));
+  uint32_t config_size = converter.GetConfigSize(hevc_config_);
+  EXPECT_GT(config_size, 0U);
+
+  // Go on with converting the headers.
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+  EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+
+  // Calculate buffer size for actual NAL unit.
+  uint32_t output_size = converter.CalculateNeededOutputBufferSize(
+      kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
+      &hevc_config_);
+  EXPECT_GT(output_size, 0U);
+  output.reset(new uint8_t[output_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+
+  uint32_t output_size_left_for_nal_unit = output_size;
+  // Do the conversion for actual NAL unit.
+  EXPECT_TRUE(converter.ConvertNalUnitStreamToByteStream(
+      kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
+      &hevc_config_, output.get(), &output_size_left_for_nal_unit));
+}
+
+TEST_F(H265ToAnnexBBitstreamConverterTest, FailureHeaderBufferOverflow) {
+  // Initialize converter
+  H265ToAnnexBBitstreamConverter converter;
+
+  // Simulate 10 nalu_array HEVCDecoderConfigurationRecord,
+  // which would extend beyond the buffer.
+  uint8_t corrupted_header[sizeof(kHeaderDataOkWithFieldLen4)];
+  memcpy(corrupted_header, kHeaderDataOkWithFieldLen4,
+         sizeof(kHeaderDataOkWithFieldLen4));
+  // 23th byte contain the number of nalu arrays
+  corrupted_header[22] = corrupted_header[22] | 0xA;
+
+  // Parse the headers
+  EXPECT_FALSE(converter.ParseConfiguration(
+      corrupted_header, sizeof(corrupted_header), &hevc_config_));
+}
+
+TEST_F(H265ToAnnexBBitstreamConverterTest, FailureNalUnitBreakage) {
+  // Initialize converter.
+  std::unique_ptr<uint8_t[]> output;
+  H265ToAnnexBBitstreamConverter converter;
+
+  // Parse the headers.
+  EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
+                                           sizeof(kHeaderDataOkWithFieldLen4),
+                                           &hevc_config_));
+  uint32_t config_size = converter.GetConfigSize(hevc_config_);
+  EXPECT_GT(config_size, 0U);
+
+  // Go on with converting the headers.
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+  EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+
+  // Simulate NAL unit broken in middle by writing only some of the data.
+  uint8_t corrupted_nal_unit[sizeof(kPacketDataOkWithFieldLen4) - 30];
+  memcpy(corrupted_nal_unit, kPacketDataOkWithFieldLen4,
+         sizeof(kPacketDataOkWithFieldLen4) - 30);
+
+  // Calculate buffer size for actual NAL unit, should return 0 because of
+  // incomplete input buffer.
+  uint32_t output_size = converter.CalculateNeededOutputBufferSize(
+      corrupted_nal_unit, sizeof(corrupted_nal_unit), &hevc_config_);
+  EXPECT_EQ(output_size, 0U);
+
+  // Ignore the error and try to go on with conversion simulating wrong usage.
+  output_size = sizeof(kPacketDataOkWithFieldLen4);
+  output.reset(new uint8_t[output_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+
+  uint32_t output_size_left_for_nal_unit = output_size;
+  // Do the conversion for actual NAL unit, expecting failure.
+  EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
+      corrupted_nal_unit, sizeof(corrupted_nal_unit), &hevc_config_,
+      output.get(), &output_size_left_for_nal_unit));
+  EXPECT_EQ(output_size_left_for_nal_unit, 0U);
+}
+
+TEST_F(H265ToAnnexBBitstreamConverterTest, FailureTooSmallOutputBuffer) {
+  // Initialize converter.
+  std::unique_ptr<uint8_t[]> output;
+  H265ToAnnexBBitstreamConverter converter;
+
+  // Parse the headers.
+  EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
+                                           sizeof(kHeaderDataOkWithFieldLen4),
+                                           &hevc_config_));
+  uint32_t config_size = converter.GetConfigSize(hevc_config_);
+  EXPECT_GT(config_size, 0U);
+  uint32_t real_config_size = config_size;
+
+  // Go on with converting the headers with too small buffer.
+  config_size -= 10;
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+  EXPECT_FALSE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+  EXPECT_EQ(config_size, 0U);
+
+  // Still too small (but only 1 byte short).
+  config_size = real_config_size - 1;
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+  EXPECT_FALSE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+  EXPECT_EQ(config_size, 0U);
+
+  // Finally, retry with valid buffer.
+  config_size = real_config_size;
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+  EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+
+  // Calculate buffer size for actual NAL unit.
+  uint32_t output_size = converter.CalculateNeededOutputBufferSize(
+      kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
+      &hevc_config_);
+  EXPECT_GT(output_size, 0U);
+  // Simulate too small output buffer.
+  output_size -= 1;
+  output.reset(new uint8_t[output_size]);
+  EXPECT_TRUE(output.get() != nullptr);
+
+  uint32_t output_size_left_for_nal_unit = output_size;
+  // Do the conversion for actual NAL unit (expect failure).
+  EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
+      kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
+      &hevc_config_, output.get(), &output_size_left_for_nal_unit));
+  EXPECT_EQ(output_size_left_for_nal_unit, 0U);
+}
+
+static const uint8_t kCorruptedPacketConfiguration[] = {
+    0x01, 0x01, 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x96, 0xf0, 0x00, 0xfc, 0xfd, 0xf8, 0xf8, 0x00, 0x00, 0x0f,
+    0x03, 0xa0, 0x00, 0x01, 0x00, 0x18, 0x40, 0x01, 0x0c, 0x01, 0xff,
+    0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x03, 0x00, 0x96, 0x9d, 0xc0, 0x90, 0xa1, 0x00, 0x01,
+    0x00, 0x29, 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00,
+    0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03,
+    0xc0, 0x80, 0x10, 0xe5, 0x96, 0x77, 0x92, 0x46, 0xda, 0xf0, 0x10,
+    0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x06, 0x1a, 0x80, 0x80, 0xa2,
+    0x00, 0x01, 0x00, 0x06, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89};
+
+static const uint8_t kCorruptedPacketData[] = {
+    0x00, 0x00, 0x00, 0x15, 0x01, 0x9f, 0x6e, 0xbc, 0x85, 0x3f,
+    0x0f, 0x87, 0x47, 0xa8, 0xd7, 0x5b, 0xfc, 0xb8, 0xfd, 0x3f,
+    0x57, 0x0e, 0xac, 0xf5, 0x4c, 0x01, 0x2e, 0x57};
+
+TEST_F(H265ToAnnexBBitstreamConverterTest, CorruptedPacket) {
+  // Initialize converter.
+  std::unique_ptr<uint8_t[]> output;
+  H265ToAnnexBBitstreamConverter converter;
+
+  // Parse the headers.
+  EXPECT_TRUE(converter.ParseConfiguration(
+      kCorruptedPacketConfiguration, sizeof(kCorruptedPacketConfiguration),
+      &hevc_config_));
+  uint32_t config_size = converter.GetConfigSize(hevc_config_);
+  EXPECT_GT(config_size, 0U);
+
+  // Go on with converting the headers.
+  output.reset(new uint8_t[config_size]);
+  EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
+      hevc_config_, output.get(), &config_size));
+
+  // Expect an error here.
+  uint32_t output_size = converter.CalculateNeededOutputBufferSize(
+      kCorruptedPacketData, sizeof(kCorruptedPacketData), &hevc_config_);
+  EXPECT_EQ(output_size, 0U);
+}
+
+}  // namespace media
diff --git a/media/formats/mp4/hevc.cc b/media/formats/mp4/hevc.cc
index 20fbb8c5..2c94d23 100644
--- a/media/formats/mp4/hevc.cc
+++ b/media/formats/mp4/hevc.cc
@@ -236,7 +236,7 @@
   if (subsamples && !subsamples->empty()) {
     int subsample_index = AVC::FindSubsampleIndex(*buffer, subsamples,
                                                   &(*config_insert_point));
-    // Update the size of the subsample where SPS/PPS is to be inserted.
+    // Update the size of the subsample where VPS/SPS/PPS is to be inserted.
     (*subsamples)[subsample_index].clear_bytes += param_sets.size();
   }
 
diff --git a/media/gpu/OWNERS b/media/gpu/OWNERS
index 07a34f0d..2530348a 100644
--- a/media/gpu/OWNERS
+++ b/media/gpu/OWNERS
@@ -10,4 +10,3 @@
 jcliang@chromium.org
 jkardatzke@chromium.org
 mcasas@chromium.org
-posciak@chromium.org
diff --git a/media/gpu/android/codec_image.cc b/media/gpu/android/codec_image.cc
index 7bb06e0..13f4baa4 100644
--- a/media/gpu/android/codec_image.cc
+++ b/media/gpu/android/codec_image.cc
@@ -259,10 +259,6 @@
   return output_buffer_renderer_->texture_owner()->GetAHardwareBuffer();
 }
 
-bool CodecImage::HasMutableState() const {
-  return false;
-}
-
 CodecImageHolder::CodecImageHolder(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     scoped_refptr<CodecImage> codec_image,
diff --git a/media/gpu/android/codec_image.h b/media/gpu/android/codec_image.h
index e8a70fc51..e627cb9 100644
--- a/media/gpu/android/codec_image.h
+++ b/media/gpu/android/codec_image.h
@@ -86,12 +86,6 @@
   std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
   GetAHardwareBuffer() override;
 
-  // If we re-use one CodecImage with different output buffers, then we must
-  // not claim to have mutable state.  Otherwise, CopyTexImage is only called
-  // once.  For pooled shared images, this must return false.  For single-use
-  // images, it works either way.
-  bool HasMutableState() const override;
-
   // Notify us that we're no longer in-use for display, and may be pointed at
   // another output buffer via a call to Initialize.
   void NotifyUnused();
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc
index 94215b3..1b2dab0 100644
--- a/media/gpu/android/media_codec_video_decoder.cc
+++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -141,17 +141,25 @@
   }
 
   if (device_info->IsAv1DecoderAvailable()) {
-    // Technically we should check which profiles are supported, but since we
-    // don't have an AV1 SW decoder, just allow them all. See notes below for
-    // H264 profiles on the reasons why.
-    supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
-                                   gfx::Size(0, 0), gfx::Size(3840, 2160),
-                                   true,    // allow_encrypted
-                                   false);  // require_encrypted
-    supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
-                                   gfx::Size(0, 0), gfx::Size(2160, 3840),
-                                   true,    // allow_encrypted
-                                   false);  // require_encrypted
+    if (device_info->IsDecoderKnownUnaccelerated(VideoCodec::kAV1)) {
+      supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
+                                     gfx::Size(0, 0), gfx::Size(3840, 2160),
+                                     true,   // allow_encrypted
+                                     true);  // require_encrypted
+      supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
+                                     gfx::Size(0, 0), gfx::Size(2160, 3840),
+                                     true,   // allow_encrypted
+                                     true);  // require_encrypted
+    } else {
+      supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
+                                     gfx::Size(0, 0), gfx::Size(3840, 2160),
+                                     true,    // allow_encrypted
+                                     false);  // require_encrypted
+      supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX,
+                                     gfx::Size(0, 0), gfx::Size(2160, 3840),
+                                     true,    // allow_encrypted
+                                     false);  // require_encrypted
+    }
   }
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/media/gpu/v4l2/test/av1_decoder.cc b/media/gpu/v4l2/test/av1_decoder.cc
index dbb107d7..9799e07 100644
--- a/media/gpu/v4l2/test/av1_decoder.cc
+++ b/media/gpu/v4l2/test/av1_decoder.cc
@@ -154,9 +154,10 @@
                                const libgav1::Delta& delta_lf) {
   conditionally_set_flags(&v4l2_lf->flags, delta_lf.present,
                           V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_PRESENT);
+  conditionally_set_flags(&v4l2_lf->flags, delta_lf.multi,
+                          V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_MULTI);
 
   v4l2_lf->delta_lf_res = delta_lf.scale;
-  v4l2_lf->delta_lf_multi = delta_lf.multi;
 }
 
 // Section 5.9.12. Quantization params syntax
@@ -439,7 +440,6 @@
 
 // Section 5.11. Tile Group OBU syntax
 void FillTileGroupParams(
-    v4l2_ctrl_av1_tile_group* tile_group_params,
     std::vector<struct v4l2_ctrl_av1_tile_group_entry>*
         tile_group_entry_vectors,
     const base::span<const uint8_t> frame_obu_data,
@@ -454,14 +454,6 @@
   CHECK_GT(tile_columns, 0u);
   const uint16_t num_tiles = base::checked_cast<uint16_t>(tile_buffers.size());
 
-  conditionally_set_flags(&tile_group_params->flags, num_tiles > 1,
-                          V4L2_AV1_TILE_GROUP_FLAG_START_AND_END_PRESENT);
-
-  if (num_tiles >= 1) {
-    tile_group_params->tg_start = 0;
-    tile_group_params->tg_end = num_tiles - 1;
-  }
-
   for (uint16_t tile_index = 0; tile_index < num_tiles; ++tile_index) {
     struct v4l2_ctrl_av1_tile_group_entry tile_group_entry_params = {};
 
@@ -613,7 +605,7 @@
 
 // 5.9.2. Uncompressed header syntax
 void Av1Decoder::SetupFrameParams(
-    struct v4l2_ctrl_av1_frame_header* v4l2_frame_params,
+    struct v4l2_ctrl_av1_frame* v4l2_frame_params,
     const absl::optional<libgav1::ObuSequenceHeader>& seq_header,
     const libgav1::ObuFrameHeader& frm_header) {
   FillLoopFilterParams(&v4l2_frame_params->loop_filter, frm_header.loop_filter);
@@ -643,70 +635,70 @@
                          frm_header.global_motion);
 
   conditionally_set_u32_flags(&v4l2_frame_params->flags, frm_header.show_frame,
-                              V4L2_AV1_FRAME_HEADER_FLAG_SHOW_FRAME);
+                              V4L2_AV1_FRAME_FLAG_SHOW_FRAME);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.showable_frame,
-                              V4L2_AV1_FRAME_HEADER_FLAG_SHOWABLE_FRAME);
+                              V4L2_AV1_FRAME_FLAG_SHOWABLE_FRAME);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.error_resilient_mode,
-                              V4L2_AV1_FRAME_HEADER_FLAG_ERROR_RESILIENT_MODE);
+                              V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE);
   // libgav1 header has |enable_cdf_update| instead of |disable_cdf_update|.
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               !frm_header.enable_cdf_update,
-                              V4L2_AV1_FRAME_HEADER_FLAG_DISABLE_CDF_UPDATE);
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, frm_header.allow_screen_content_tools,
-      V4L2_AV1_FRAME_HEADER_FLAG_ALLOW_SCREEN_CONTENT_TOOLS);
+                              V4L2_AV1_FRAME_FLAG_DISABLE_CDF_UPDATE);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              frm_header.allow_screen_content_tools,
+                              V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.force_integer_mv,
-                              V4L2_AV1_FRAME_HEADER_FLAG_FORCE_INTEGER_MV);
+                              V4L2_AV1_FRAME_FLAG_FORCE_INTEGER_MV);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.allow_intrabc,
-                              V4L2_AV1_FRAME_HEADER_FLAG_ALLOW_INTRABC);
+                              V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.use_superres,
-                              V4L2_AV1_FRAME_HEADER_FLAG_USE_SUPERRES);
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, frm_header.allow_high_precision_mv,
-      V4L2_AV1_FRAME_HEADER_FLAG_ALLOW_HIGH_PRECISION_MV);
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, frm_header.is_motion_mode_switchable,
-      V4L2_AV1_FRAME_HEADER_FLAG_IS_MOTION_MODE_SWITCHABLE);
+                              V4L2_AV1_FRAME_FLAG_USE_SUPERRES);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              frm_header.allow_high_precision_mv,
+                              V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              frm_header.is_motion_mode_switchable,
+                              V4L2_AV1_FRAME_FLAG_IS_MOTION_MODE_SWITCHABLE);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.use_ref_frame_mvs,
-                              V4L2_AV1_FRAME_HEADER_FLAG_USE_REF_FRAME_MVS);
+                              V4L2_AV1_FRAME_FLAG_USE_REF_FRAME_MVS);
   // libgav1 header has |enable_frame_end_update_cdf| instead.
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, !frm_header.enable_frame_end_update_cdf,
-      V4L2_AV1_FRAME_HEADER_FLAG_DISABLE_FRAME_END_UPDATE_CDF);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              !frm_header.enable_frame_end_update_cdf,
+                              V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.tile_info.uniform_spacing,
-                              V4L2_AV1_FRAME_HEADER_FLAG_UNIFORM_TILE_SPACING);
+                              V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.allow_warped_motion,
-                              V4L2_AV1_FRAME_HEADER_FLAG_ALLOW_WARPED_MOTION);
+                              V4L2_AV1_FRAME_FLAG_ALLOW_WARPED_MOTION);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.reference_mode_select,
-                              V4L2_AV1_FRAME_HEADER_FLAG_REFERENCE_SELECT);
+                              V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.reduced_tx_set,
-                              V4L2_AV1_FRAME_HEADER_FLAG_REDUCED_TX_SET);
+                              V4L2_AV1_FRAME_FLAG_REDUCED_TX_SET);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.skip_mode_frame[0] > 0,
-                              V4L2_AV1_FRAME_HEADER_FLAG_SKIP_MODE_ALLOWED);
+                              V4L2_AV1_FRAME_FLAG_SKIP_MODE_ALLOWED);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.skip_mode_present,
-                              V4L2_AV1_FRAME_HEADER_FLAG_SKIP_MODE_PRESENT);
+                              V4L2_AV1_FRAME_FLAG_SKIP_MODE_PRESENT);
   conditionally_set_u32_flags(&v4l2_frame_params->flags,
                               frm_header.frame_size_override_flag,
-                              V4L2_AV1_FRAME_HEADER_FLAG_FRAME_SIZE_OVERRIDE);
+                              V4L2_AV1_FRAME_FLAG_FRAME_SIZE_OVERRIDE);
   // libgav1 header doesn't have |buffer_removal_time_present_flag|.
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, frm_header.buffer_removal_time[0] > 0,
-      V4L2_AV1_FRAME_HEADER_FLAG_BUFFER_REMOVAL_TIME_PRESENT);
-  conditionally_set_u32_flags(
-      &v4l2_frame_params->flags, frm_header.frame_refs_short_signaling,
-      V4L2_AV1_FRAME_HEADER_FLAG_FRAME_REFS_SHORT_SIGNALING);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              frm_header.buffer_removal_time[0] > 0,
+                              V4L2_AV1_FRAME_FLAG_BUFFER_REMOVAL_TIME_PRESENT);
+  conditionally_set_u32_flags(&v4l2_frame_params->flags,
+                              frm_header.frame_refs_short_signaling,
+                              V4L2_AV1_FRAME_FLAG_FRAME_REFS_SHORT_SIGNALING);
 
   switch (frm_header.frame_type) {
     case libgav1::kFrameKey:
@@ -954,35 +946,22 @@
                               .size = sizeof(v4l2_seq_params),
                               .ptr = &v4l2_seq_params});
 
-  struct v4l2_ctrl_av1_frame_header v4l2_frame_params = {};
+  struct v4l2_ctrl_av1_frame v4l2_frame_params = {};
 
   SetupFrameParams(&v4l2_frame_params, current_sequence_header_,
                    current_frame_header);
 
-  // TODO(stevecho): V4L2_CID_STATELESS_AV1_FRAME_HEADER is trending to be
-  // changed to V4L2_CID_STATELESS_AV1_FRAME
-  ext_ctrl_vectors.push_back({.id = V4L2_CID_STATELESS_AV1_FRAME_HEADER,
+  ext_ctrl_vectors.push_back({.id = V4L2_CID_STATELESS_AV1_FRAME,
                               .size = sizeof(v4l2_frame_params),
                               .ptr = &v4l2_frame_params});
 
-  struct v4l2_ctrl_av1_tile_group tile_group_params = {};
   std::vector<struct v4l2_ctrl_av1_tile_group_entry> tile_group_entry_vectors;
 
   FillTileGroupParams(
-      &tile_group_params, &tile_group_entry_vectors,
+      &tile_group_entry_vectors,
       base::make_span(ivf_frame_data_, ivf_frame_header_.frame_size),
       current_frame_header.tile_info, obu_parser_->tile_buffers());
 
-  // TODO(b/240736764): We are discussing to remove tile group control.
-  // But current MTK driver expects this control with error check, so we need
-  // this setup for the time being. Also, current libgav1 parser doesn't have
-  // information about start & end index of each tile group. Thus, we are
-  // setting up this control only for the 1st tile group. In fact, current tests
-  // don't have cases when 2+ tile groups exist within a frame.
-  ext_ctrl_vectors.push_back({.id = V4L2_CID_STATELESS_AV1_TILE_GROUP,
-                              .size = sizeof(tile_group_params),
-                              .ptr = &tile_group_params});
-
   ext_ctrl_vectors.push_back({.id = V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY,
                               .size = base::checked_cast<__u32>(
                                   tile_group_entry_vectors.size() *
diff --git a/media/gpu/v4l2/test/av1_decoder.h b/media/gpu/v4l2/test/av1_decoder.h
index 781ea37..63d9375a 100644
--- a/media/gpu/v4l2/test/av1_decoder.h
+++ b/media/gpu/v4l2/test/av1_decoder.h
@@ -11,6 +11,43 @@
 // once the bug is fixed.
 #include <linux/media/av1-ctrls.h>
 
+// XXX(wenst): Revert to old API definitions while the headers are being
+// landed to avoid build break. Remove after updated header has landed
+#ifdef V4L2_CID_STATELESS_AV1_FRAME_HEADER
+
+// Name changes
+#define V4L2_CID_STATELESS_AV1_FRAME V4L2_CID_STATELESS_AV1_FRAME_HEADER
+#define v4l2_ctrl_av1_frame v4l2_ctrl_av1_frame_header
+
+// Copied from new header file. New macros simply strip out the "_HEADER"
+// from the name, and replace BIT() macro usage with hex values.
+#define V4L2_AV1_FRAME_FLAG_SHOW_FRAME 0x00000001
+#define V4L2_AV1_FRAME_FLAG_SHOWABLE_FRAME 0x00000002
+#define V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE 0x00000004
+#define V4L2_AV1_FRAME_FLAG_DISABLE_CDF_UPDATE 0x00000008
+#define V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS 0x00000010
+#define V4L2_AV1_FRAME_FLAG_FORCE_INTEGER_MV 0x00000020
+#define V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC 0x00000040
+#define V4L2_AV1_FRAME_FLAG_USE_SUPERRES 0x00000080
+#define V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV 0x00000100
+#define V4L2_AV1_FRAME_FLAG_IS_MOTION_MODE_SWITCHABLE 0x00000200
+#define V4L2_AV1_FRAME_FLAG_USE_REF_FRAME_MVS 0x00000400
+#define V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF 0x00000800
+#define V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING 0x00001000
+#define V4L2_AV1_FRAME_FLAG_ALLOW_WARPED_MOTION 0x00002000
+#define V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT 0x00004000
+#define V4L2_AV1_FRAME_FLAG_REDUCED_TX_SET 0x00008000
+#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_ALLOWED 0x00010000
+#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_PRESENT 0x00020000
+#define V4L2_AV1_FRAME_FLAG_FRAME_SIZE_OVERRIDE 0x00040000
+#define V4L2_AV1_FRAME_FLAG_BUFFER_REMOVAL_TIME_PRESENT 0x00080000
+#define V4L2_AV1_FRAME_FLAG_FRAME_REFS_SHORT_SIGNALING 0x00100000
+
+// Does not exist in old header file as this was originally
+// v4l2_av1_loop_filter::delta_lf_multi
+#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_MULTI 0x8
+#endif
+
 #include <set>
 
 #include "base/files/memory_mapped_file.h"
@@ -86,7 +123,7 @@
   // Sets up per frame parameters |v4l2_frame_params| needed for AV1 decoding
   // with VIDIOC_S_EXT_CTRLS ioctl call.
   void SetupFrameParams(
-      struct v4l2_ctrl_av1_frame_header* v4l2_frame_params,
+      struct v4l2_ctrl_av1_frame* v4l2_frame_params,
       const absl::optional<libgav1::ObuSequenceHeader>& seq_header,
       const libgav1::ObuFrameHeader& frm_header);
 
diff --git a/media/gpu/vaapi/test/decode.cc b/media/gpu/vaapi/test/decode.cc
index 713d495..f7642ad 100644
--- a/media/gpu/vaapi/test/decode.cc
+++ b/media/gpu/vaapi/test/decode.cc
@@ -5,6 +5,7 @@
 #include <va/va.h>
 
 #include <iostream>
+#include <fstream>
 #include <sstream>
 #include <string>
 
@@ -57,7 +58,7 @@
     "           [--frames=<number of frames to decode>]\n"
     "           [--fetch=<derive|get>]\n"
     "           [--out-prefix=<path prefix of decoded frame PNGs>]\n"
-    "           [--md5]\n"
+    "           [--md5[=<checksum path>]]\n"
     "           [--visible]\n"
     "           [--loop]\n"
     "           [--v=<log verbosity>]\n"
@@ -102,12 +103,13 @@
     "        If specified along with --loop (see below), only saves the first\n"
     "        iteration of decoded frames.\n"
     "        If omitted, the output of this binary is error or lack thereof.\n"
-    "    --md5\n"
-    "        Optional. If specified, prints the md5 of each decoded (and\n"
-    "        visible, if --visible is specified) frame in I420 format to\n"
-    "        stdout.\n"
-    "        Only supported when vaDeriveImage() produces I420 and NV12 data\n"
-    "        for all frames in the video.\n"
+    "    --md5[=<checksum path>]\n"
+    "        Optional. If specified without a value, prints the md5 of each\n"
+    "        decoded (and visible, if --visible is specified) frame in I420\n"
+    "        format to stdout. If specified with a value, prints the md5 to\n"
+    "        the specified value instead of stdout. Only supported when\n"
+    "        vaDeriveImage() produces I420 and NV12 data for all frames\n"
+    "        in the video.\n"
     "    --visible\n"
     "        Optional. If specified, applies post-decode processing (PNG\n"
     "        output, md5 hash) only to visible frames.\n"
@@ -228,6 +230,16 @@
     return EXIT_FAILURE;
   }
 
+  std::ofstream md5_checksum_log;
+  const std::string md5_checksum_log_path = cmd->GetSwitchValueASCII("md5");
+  if (!md5_checksum_log_path.empty()) {
+    md5_checksum_log.open(md5_checksum_log_path);
+    if (!md5_checksum_log.is_open()) {
+      LOG(ERROR) << "Could not open " << md5_checksum_log_path << " for writing";
+      return EXIT_FAILURE;
+    }
+  }
+
   // Initialize VA stubs.
   StubPathMap paths;
   const std::string va_suffix(base::NumberToString(VA_MAJOR_VERSION + 1));
@@ -283,7 +295,10 @@
             base::StringPrintf("%s_%d.png", output_prefix.c_str(), i));
       }
       if (cmd->HasSwitch("md5")) {
-        std::cout << dec->LastDecodedFrameMD5Sum() << std::endl;
+        if (md5_checksum_log.is_open())
+          md5_checksum_log << dec->LastDecodedFrameMD5Sum() << std::endl;
+        else
+          std::cout << dec->LastDecodedFrameMD5Sum() << std::endl;
       }
     }
 
@@ -292,5 +307,9 @@
 
   LOG(INFO) << "Done reading.";
 
+  // Closes log file if opened.
+  if (md5_checksum_log.is_open())
+    md5_checksum_log.close();
+
   return EXIT_SUCCESS;
 }
diff --git a/media/mojo/BUILD.gn b/media/mojo/BUILD.gn
index 636a734..3eaccd7b 100644
--- a/media/mojo/BUILD.gn
+++ b/media/mojo/BUILD.gn
@@ -22,7 +22,11 @@
     if (service == "renderer") {
       enable_mojo_renderer = true
     } else if (service == "cdm") {
-      enable_mojo_cdm = true
+      # Fuchsia communicates directly with the platform CDM via FIDL instead of
+      # the mojo service.
+      if (!is_fuchsia) {
+        enable_mojo_cdm = true
+      }
     } else if (service == "audio_decoder") {
       enable_mojo_audio_decoder = true
     } else if (service == "audio_encoder") {
diff --git a/media/mojo/clients/mojo_video_encode_accelerator.cc b/media/mojo/clients/mojo_video_encode_accelerator.cc
index 6a3fd9ba..93720d6 100644
--- a/media/mojo/clients/mojo_video_encode_accelerator.cc
+++ b/media/mojo/clients/mojo_video_encode_accelerator.cc
@@ -177,7 +177,6 @@
       mojo_frame = frame;
       break;
     case VideoFrame::STORAGE_SHMEM: {
-      size_t num_planes = VideoFrame::NumPlanes(frame->format());
       std::vector<uint32_t> offsets(num_planes);
       std::vector<int32_t> strides(num_planes);
       for (size_t i = 0; i < num_planes; ++i) {
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc
index e98ae88..9aab88b 100644
--- a/media/mojo/services/media_metrics_provider.cc
+++ b/media/mojo/services/media_metrics_provider.cc
@@ -13,6 +13,7 @@
 #include "build/build_config.h"
 #include "build/chromecast_buildflags.h"
 #include "media/base/key_systems.h"
+#include "media/base/video_codecs.h"
 #include "media/learning/mojo/mojo_learning_task_controller_service.h"
 #include "media/mojo/services/video_decode_stats_recorder.h"
 #include "media/mojo/services/watch_time_recorder.h"
@@ -103,22 +104,8 @@
 std::string MediaMetricsProvider::GetUMANameForAVStream(
     const PipelineInfo& player_info) {
   constexpr char kPipelineUmaPrefix[] = "Media.PipelineStatus.AudioVideo.";
-  std::string uma_name = kPipelineUmaPrefix;
-  // TODO(xhwang): Use a helper function to simply the codec name mapping.
-  if (player_info.video_codec == VideoCodec::kVP8)
-    uma_name += "VP8.";
-  else if (player_info.video_codec == VideoCodec::kVP9)
-    uma_name += "VP9.";
-  else if (player_info.video_codec == VideoCodec::kH264)
-    uma_name += "H264.";
-  else if (player_info.video_codec == VideoCodec::kAV1)
-    uma_name += "AV1.";
-  else if (player_info.video_codec == VideoCodec::kHEVC)
-    uma_name += "HEVC.";
-  else if (player_info.video_codec == VideoCodec::kDolbyVision)
-    uma_name += "DolbyVision.";
-  else
-    return uma_name + "Other";
+  std::string uma_name =
+      kPipelineUmaPrefix + GetCodecNameForUMA(player_info.video_codec) + ".";
 
   // Add Renderer name when not using the default RendererImpl.
   if (renderer_type_ == RendererType::kMediaFoundation) {
diff --git a/media/remoting/courier_renderer.cc b/media/remoting/courier_renderer.cc
index dfe3541..b4de287 100644
--- a/media/remoting/courier_renderer.cc
+++ b/media/remoting/courier_renderer.cc
@@ -57,6 +57,25 @@
 // data flow rates for metrics.
 constexpr base::TimeDelta kDataFlowPollPeriod = base::Seconds(10);
 
+// base::Bind* doesn't understand openscreen::WeakPtr, so we must manually
+// check the RpcMessenger pointer before calling into it.
+void RegisterForRpcTask(
+    openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
+    int rpc_handle,
+    openscreen::cast::RpcMessenger::ReceiveMessageCallback message_cb) {
+  if (rpc_messenger) {
+    rpc_messenger->RegisterMessageReceiverCallback(rpc_handle,
+                                                   std::move(message_cb));
+  }
+}
+void DeregisterFromRpcTask(
+    openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
+    int rpc_handle) {
+  if (rpc_messenger) {
+    rpc_messenger->UnregisterMessageReceiverCallback(rpc_handle);
+  }
+}
+
 }  // namespace
 
 CourierRenderer::CourierRenderer(
@@ -77,23 +96,15 @@
   // Note: The constructor is running on the main thread, but will be destroyed
   // on the media thread. Therefore, all weak pointers must be dereferenced on
   // the media thread.
-  rpc_messenger_->RegisterMessageReceiverCallback(
-      rpc_handle_,
-      [runner = media_task_runner_, ptr = weak_factory_.GetWeakPtr()](
-          std::unique_ptr<openscreen::cast::RpcMessage> message) {
-        CourierRenderer::OnMessageReceivedOnMainThread(runner, ptr,
-                                                       std::move(message));
-      });
+  media_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&CourierRenderer::RegisterForRpcMessaging,
+                                weak_factory_.GetWeakPtr()));
 }
 
 CourierRenderer::~CourierRenderer() {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
 
-  // Post task on main thread to unregister message receiver.
-  main_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&CourierRenderer::DeregisterFromRpcMessaging,
-                                weak_factory_.GetWeakPtr()));
-
+  DeregisterFromRpcMessaging();
   if (video_renderer_sink_) {
     video_renderer_sink_->PaintSingleFrame(
         VideoFrame::CreateBlackFrame(gfx::Size(1280, 720)));
@@ -808,10 +819,28 @@
            !audio_demuxer_stream_adapter_->is_data_pending()));
 }
 
+void CourierRenderer::RegisterForRpcMessaging() {
+  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  auto receive_callback = BindToCurrentLoop(base::BindRepeating(
+      &CourierRenderer::OnReceivedRpc, weak_factory_.GetWeakPtr()));
+
+  main_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &RegisterForRpcTask, rpc_messenger_, rpc_handle_,
+          [cb = std::move(receive_callback)](
+
+              std::unique_ptr<openscreen::cast::RpcMessage> message) {
+            cb.Run(std::move(message));
+          }));
+}
+
 void CourierRenderer::DeregisterFromRpcMessaging() {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
   if (rpc_messenger_) {
-    rpc_messenger_->UnregisterMessageReceiverCallback(rpc_handle_);
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&DeregisterFromRpcTask, rpc_messenger_, rpc_handle_));
   }
 }
 
diff --git a/media/remoting/courier_renderer.h b/media/remoting/courier_renderer.h
index 9fdf9c9..61664d33 100644
--- a/media/remoting/courier_renderer.h
+++ b/media/remoting/courier_renderer.h
@@ -161,7 +161,11 @@
   // though the playback might be delayed or paused.
   bool IsWaitingForDataFromDemuxers() const;
 
-  // Helper to deregister the renderer from the RPC messenger.
+  // Helpers to register/deregister the renderer with the RPC messenger. These
+  // must be called on the media thread to dereference the weak pointer to
+  // this, which if contains a valid RPC messenger pointer will result in a
+  // jump to the main thread.
+  void RegisterForRpcMessaging();
   void DeregisterFromRpcMessaging();
 
   State state_;
diff --git a/media/remoting/demuxer_stream_adapter.cc b/media/remoting/demuxer_stream_adapter.cc
index b1b3026a..08add23 100644
--- a/media/remoting/demuxer_stream_adapter.cc
+++ b/media/remoting/demuxer_stream_adapter.cc
@@ -24,6 +24,27 @@
 namespace media {
 namespace remoting {
 
+namespace {
+// base::Bind* doesn't understand openscreen::WeakPtr, so we must manually
+// check the RpcMessenger pointer before calling into it.
+void RegisterForRpcTask(
+    openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
+    int rpc_handle,
+    openscreen::cast::RpcMessenger::ReceiveMessageCallback message_cb) {
+  if (rpc_messenger) {
+    rpc_messenger->RegisterMessageReceiverCallback(rpc_handle,
+                                                   std::move(message_cb));
+  }
+}
+void DeregisterFromRpcTask(
+    openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
+    int rpc_handle) {
+  if (rpc_messenger) {
+    rpc_messenger->UnregisterMessageReceiverCallback(rpc_handle);
+  }
+}
+}  // namespace
+
 DemuxerStreamAdapter::DemuxerStreamAdapter(
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
@@ -56,17 +77,8 @@
   DCHECK(media_task_runner_->BelongsToCurrentThread());
   DCHECK(demuxer_stream);
   DCHECK(!error_callback_.is_null());
-  auto receive_callback = BindToCurrentLoop(base::BindRepeating(
-      &DemuxerStreamAdapter::OnReceivedRpc, weak_factory_.GetWeakPtr()));
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &RpcMessenger::RegisterMessageReceiverCallback, rpc_messenger_,
-          rpc_handle_,
-          [cb = std::move(receive_callback)](
-              std::unique_ptr<openscreen::cast::RpcMessage> message) {
-            cb.Run(std::move(message));
-          }));
+
+  RegisterForRpcMessaging();
 
   stream_sender_.Bind(std::move(stream_sender_remote));
   stream_sender_.set_disconnect_handler(
@@ -76,10 +88,7 @@
 
 DemuxerStreamAdapter::~DemuxerStreamAdapter() {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&DemuxerStreamAdapter::DeregisterFromRpcMessaging,
-                     weak_factory_.GetWeakPtr()));
+  DeregisterFromRpcMessaging();
 }
 
 int64_t DemuxerStreamAdapter::GetBytesWrittenAndReset() {
@@ -429,10 +438,26 @@
   std::move(error_callback_).Run(stop_trigger);
 }
 
+void DemuxerStreamAdapter::RegisterForRpcMessaging() {
+  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  auto receive_callback = BindToCurrentLoop(base::BindRepeating(
+      &DemuxerStreamAdapter::OnReceivedRpc, weak_factory_.GetWeakPtr()));
+  main_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &RegisterForRpcTask, rpc_messenger_, rpc_handle_,
+          [cb = std::move(receive_callback)](
+              std::unique_ptr<openscreen::cast::RpcMessage> message) {
+            cb.Run(std::move(message));
+          }));
+}
+
 void DemuxerStreamAdapter::DeregisterFromRpcMessaging() {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
   if (rpc_messenger_) {
-    rpc_messenger_->UnregisterMessageReceiverCallback(rpc_handle_);
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&DeregisterFromRpcTask, rpc_messenger_, rpc_handle_));
   }
 }
 
diff --git a/media/remoting/demuxer_stream_adapter.h b/media/remoting/demuxer_stream_adapter.h
index 7574a92a..ec68c87 100644
--- a/media/remoting/demuxer_stream_adapter.h
+++ b/media/remoting/demuxer_stream_adapter.h
@@ -131,7 +131,11 @@
   // Callback function when a fatal runtime error occurs.
   void OnFatalError(StopTrigger stop_trigger);
 
-  // Helper to deregister the renderer from the RPC messenger.
+  // Helpers to register/deregister the adapter with the RPC messenger. These
+  // must be called on the media thread to dereference the weak pointer to
+  // this, which if contains a valid RPC messenger pointer will result in a
+  // jump to the main thread.
+  void RegisterForRpcMessaging();
   void DeregisterFromRpcMessaging();
 
   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
diff --git a/media/video/video_encode_accelerator_adapter.cc b/media/video/video_encode_accelerator_adapter.cc
index 6889a87..6043c8ca 100644
--- a/media/video/video_encode_accelerator_adapter.cc
+++ b/media/video/video_encode_accelerator_adapter.cc
@@ -148,12 +148,11 @@
     : public base::RefCountedThreadSafe<ReadOnlyRegionPool> {
  public:
   struct Handle {
-    Handle() = default;
     ~Handle() {
       if (recycle_cb)
         std::move(recycle_cb).Run();
     }
-    bool IsValid() { return region && mapping; }
+    bool IsValid() const { return region && mapping; }
     base::ReadOnlySharedMemoryRegion* region = nullptr;
     base::WritableSharedMemoryMapping* mapping = nullptr;
     base::OnceClosure recycle_cb;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 52f286f..b31c639d 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1198,6 +1198,10 @@
     ]
   }
 
+  if (is_chromeos_ash) {
+    deps += [ "//third_party/xdg_shared_mime_info" ]
+  }
+
   if (is_mac) {
     sources += [
       "base/network_notification_thread_mac.cc",
diff --git a/net/base/DEPS b/net/base/DEPS
index fac79a6..54ab40c 100644
--- a/net/base/DEPS
+++ b/net/base/DEPS
@@ -1,3 +1,9 @@
 include_rules = [
   "+grit",  # For generated headers
 ]
+
+specific_include_rules = {
+  "platform_mime_util_linux\.cc": [
+    "+third_party/xdg_shared_mime_info",
+  ]
+}
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 6c7a0ec..252c869 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -83,11 +83,19 @@
     {FILE_PATH_LITERAL("avif"), {"image/avif"}},
     {FILE_PATH_LITERAL("jxl"), {"image/jxl"}},
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-    // These are test cases for testing platform mime types on Chrome OS.
+    // These are test cases for testing platform mime types on ChromeOS.
     {FILE_PATH_LITERAL("epub"), {"application/epub+zip"}},
     {FILE_PATH_LITERAL("apk"), {"application/vnd.android.package-archive"}},
-    {FILE_PATH_LITERAL("cer"), {"application/x-x509-ca-cert"}},
-    {FILE_PATH_LITERAL("crt"), {"application/x-x509-ca-cert"}},
+    {FILE_PATH_LITERAL("cer"),
+     {
+         "application/x-x509-ca-cert",
+         "application/pkix-cert",  // System override for ChromeOS.
+     }},
+    {FILE_PATH_LITERAL("crt"),
+     {
+         "application/x-x509-ca-cert",
+         "application/pkix-cert",  // System override for ChromeOS.
+     }},
     {FILE_PATH_LITERAL("zip"), {"application/zip"}},
     {FILE_PATH_LITERAL("ics"), {"text/calendar"}},
 #endif
@@ -96,7 +104,8 @@
          "application/x-mpegurl",  // Chrome's secondary mapping.
          "audio/x-mpegurl",  // https://crbug.com/1273061, system override for
                              // android-arm[64]-test and Linux. Possibly more.
-         "audio/mpegurl",    // System override for mac.
+         "application/vnd.apple.mpegurl",  // System override for ChromeOS.
+         "audio/mpegurl",                  // System override for mac.
      }},
     {FILE_PATH_LITERAL("csv"), {"text/csv"}},
     {FILE_PATH_LITERAL("not an extension / for sure"), {}},
diff --git a/net/base/platform_mime_util_linux.cc b/net/base/platform_mime_util_linux.cc
index 6c079a4..ed2cfd29 100644
--- a/net/base/platform_mime_util_linux.cc
+++ b/net/base/platform_mime_util_linux.cc
@@ -11,6 +11,8 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "net/android/network_library.h"
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
+#include "third_party/xdg_shared_mime_info/mime_cache.h"
 #else
 #include "base/nix/mime_util_xdg.h"
 #endif
@@ -27,7 +29,7 @@
 bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
     const base::FilePath::StringType& ext,
     std::string* result) const {
-  return false;
+  return xdg_shared_mime_info::GetMimeCacheTypeFromExtension(ext, result);
 }
 #else
 bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
diff --git a/net/cert/internal/trust_store_win.cc b/net/cert/internal/trust_store_win.cc
index 85159c87..36f62c5 100644
--- a/net/cert/internal/trust_store_win.cc
+++ b/net/cert/internal/trust_store_win.cc
@@ -68,8 +68,9 @@
     }
   }
   for (DWORD i = 0; i < usage->cUsageIdentifier; i++) {
-    if (base::StringPiece(usage->rgpszUsageIdentifier[i]) ==
-        szOID_PKIX_KP_SERVER_AUTH) {
+    base::StringPiece eku = base::StringPiece(usage->rgpszUsageIdentifier[i]);
+    if ((eku == szOID_PKIX_KP_SERVER_AUTH) ||
+        (eku == szOID_ANY_ENHANCED_KEY_USAGE)) {
       return true;
     }
   }
@@ -290,8 +291,9 @@
               CERT_FIND_SHA1_HASH, &cert_hash_blob, cert_from_store))) {
     base::span<const uint8_t> cert_from_store_span = base::make_span(
         cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
-    if (base::ranges::equal(cert_span, cert_from_store_span) &&
-        IsCertTrustedForServerAuth(cert_from_store)) {
+    // If a cert is in the windows distruted store, it is considered
+    // distrusted for all purporses. EKU isn't checked. See crbug.com/1355961.
+    if (base::ranges::equal(cert_span, cert_from_store_span)) {
       return CertificateTrust::ForDistrusted();
     }
   }
@@ -317,40 +319,18 @@
     return CertificateTrust::ForTrustAnchorEnforcingExpiration();
   }
 
-  cert_from_store = nullptr;
-  bool intermediate_found = false;
-  bool intermediate_is_trusted = true;
-  while ((cert_from_store = CertFindCertificateInStore(
-              intermediate_cert_store_.get(), X509_ASN_ENCODING, 0,
-              CERT_FIND_SHA1_HASH, &cert_hash_blob, cert_from_store))) {
-    base::span<const uint8_t> cert_from_store_span = base::make_span(
-        cert_from_store->pbCertEncoded, cert_from_store->cbCertEncoded);
-
-    if (base::ranges::equal(cert_span, cert_from_store_span)) {
-      // Found cert, yay!
-      intermediate_found = true;
-      intermediate_is_trusted &= IsCertTrustedForServerAuth(cert_from_store);
-    }
-  }
-
-  // Found at least one instance of the cert in the intermediate store, and all
-  // instances found are trusted for TLS server auth.
-  if (intermediate_found && intermediate_is_trusted) {
-    return CertificateTrust::ForUnspecified();
-  }
-
   // If we fall through here, we've either
   //
-  // (a) found the cert in root or intermediates (or both) but neither is
-  //     usable for server auth (in which case treat as distrusted for path
-  //     building)
+  // (a) found the cert but it is not usable for server auth. Treat this as
+  //     Unspecified trust. Originally this was treated as Distrusted, but this
+  //     is inconsistent with how the Windows verifier works, which is to union
+  //     all of the EKU usages for all instances of the cert, whereas sending
+  //     back Distrusted would not do that.
   //
   // or
   //
   // (b) Haven't found the cert. Tell everyone Unspecified.
-  return (root_found || intermediate_found)
-             ? CertificateTrust::ForDistrusted()
-             : CertificateTrust::ForUnspecified();
+  return CertificateTrust::ForUnspecified();
 }
 
 }  // namespace net
diff --git a/net/cert/internal/trust_store_win_unittest.cc b/net/cert/internal/trust_store_win_unittest.cc
index b1b73c4a..f38c44db 100644
--- a/net/cert/internal/trust_store_win_unittest.cc
+++ b/net/cert/internal/trust_store_win_unittest.cc
@@ -151,11 +151,6 @@
 // - kMultiRootDByD: only has szOID_PKIX_KP_SERVER_AUTH EKU set
 // - kMultiRootEByE: only has szOID_PKIX_KP_CLIENT_AUTH set
 // - kMultiRootCByD: no EKU usages set
-//
-// And the intermediate store as follows:
-//
-// - kMultiRootCByE: only has szOID_PKIX_KP_CLIENT_AUTH set
-// - kMultiRootCByD: only has szOID_PKIX_KP_SERVER_AUTH EKU set
 TEST(TrustStoreWin, GetTrustRestrictedEKU) {
   crypto::ScopedHCERTSTORE root_store(CertOpenStore(
       CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
@@ -170,10 +165,6 @@
                                            szOID_PKIX_KP_CLIENT_AUTH));
   ASSERT_TRUE(
       AddToStoreWithEKURestriction(root_store.get(), kMultiRootCByD, nullptr));
-  ASSERT_TRUE(AddToStoreWithEKURestriction(
-      intermediate_store.get(), kMultiRootCByE, szOID_PKIX_KP_CLIENT_AUTH));
-  ASSERT_TRUE(AddToStoreWithEKURestriction(
-      intermediate_store.get(), kMultiRootCByD, szOID_PKIX_KP_SERVER_AUTH));
   std::unique_ptr<TrustStoreWin> trust_store_win =
       TrustStoreWin::CreateForTesting(std::move(root_store),
                                       std::move(intermediate_store),
@@ -187,14 +178,56 @@
       // trusted.
       {kMultiRootDByD, CertificateTrustType::TRUSTED_ANCHOR_WITH_EXPIRATION},
       // Root cert with EKU szOID_PKIX_KP_CLIENT_AUTH does not allow usage of
-      // cert for server auth.
-      {kMultiRootEByE, CertificateTrustType::DISTRUSTED},
-      // Root cert with no EKU usages but is also an intermediate cert that is
-      // allowed for server auth, so we let it be used for path building.
+      // cert for server auth, return UNSPECIFIED.
+      {kMultiRootEByE, CertificateTrustType::UNSPECIFIED},
+      // Root cert with no EKU usages, return UNSPECIFIED.
       {kMultiRootCByD, CertificateTrustType::UNSPECIFIED},
-      // Intermediate cert with EKU szOID_PKIX_KP_CLIENT_AUTH does not allow
-      // usage of cert for server auth.
-      {kMultiRootCByE, CertificateTrustType::DISTRUSTED},
+      // Unknown cert has unspecified trust.
+      {kMultiRootFByE, CertificateTrustType::UNSPECIFIED},
+  };
+  for (const auto& test_data : kTestData) {
+    SCOPED_TRACE(test_data.file_name);
+    auto parsed_cert = ParseCertFromFile(test_data.file_name);
+    ASSERT_TRUE(parsed_cert);
+    CertificateTrust trust =
+        trust_store_win->GetTrust(parsed_cert.get(), nullptr);
+    EXPECT_EQ(test_data.expected_result, trust.type);
+  }
+}
+
+// Repeat the GetTrustRestrictedEKU test but use szOID_ANY_ENHANCED_KEY_USAGE
+// instead of szOID_PKIX_KP_SERVER_AUTH
+TEST(TrustStoreWin, GetTrustRestrictedEKUAnyUsage) {
+  crypto::ScopedHCERTSTORE root_store(CertOpenStore(
+      CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
+  crypto::ScopedHCERTSTORE intermediate_store(CertOpenStore(
+      CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
+  crypto::ScopedHCERTSTORE disallowed_store(CertOpenStore(
+      CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
+
+  ASSERT_TRUE(AddToStoreWithEKURestriction(root_store.get(), kMultiRootDByD,
+                                           szOID_ANY_ENHANCED_KEY_USAGE));
+  ASSERT_TRUE(AddToStoreWithEKURestriction(root_store.get(), kMultiRootEByE,
+                                           szOID_PKIX_KP_CLIENT_AUTH));
+  ASSERT_TRUE(
+      AddToStoreWithEKURestriction(root_store.get(), kMultiRootCByD, nullptr));
+  std::unique_ptr<TrustStoreWin> trust_store_win =
+      TrustStoreWin::CreateForTesting(std::move(root_store),
+                                      std::move(intermediate_store),
+                                      std::move(disallowed_store));
+
+  constexpr struct TestData {
+    base::StringPiece file_name;
+    CertificateTrustType expected_result;
+  } kTestData[] = {
+      // Root cert with EKU szOID_ANY_ENHANCED_KEY_USAGE usage set should be
+      // trusted.
+      {kMultiRootDByD, CertificateTrustType::TRUSTED_ANCHOR_WITH_EXPIRATION},
+      // Root cert with EKU szOID_PKIX_KP_CLIENT_AUTH does not allow usage of
+      // cert for server auth, return UNSPECIFIED.
+      {kMultiRootEByE, CertificateTrustType::UNSPECIFIED},
+      // Root cert with no EKU usages, return UNSPECIFIED.
+      {kMultiRootCByD, CertificateTrustType::UNSPECIFIED},
       // Unknown cert has unspecified trust.
       {kMultiRootFByE, CertificateTrustType::UNSPECIFIED},
   };
@@ -224,10 +257,6 @@
                                            szOID_PKIX_KP_SERVER_AUTH));
   ASSERT_TRUE(
       AddToStoreWithEKURestriction(root_store.get(), kMultiRootDByD, nullptr));
-  ASSERT_TRUE(AddToStoreWithEKURestriction(
-      intermediate_store.get(), kMultiRootCByD, szOID_PKIX_KP_SERVER_AUTH));
-  ASSERT_TRUE(AddToStoreWithEKURestriction(
-      intermediate_store.get(), kMultiRootCByD, szOID_PKIX_KP_SERVER_AUTH));
   std::unique_ptr<TrustStoreWin> trust_store_win =
       TrustStoreWin::CreateForTesting(std::move(root_store),
                                       std::move(intermediate_store),
@@ -237,10 +266,7 @@
     base::StringPiece file_name;
     CertificateTrustType expected_result;
   } kTestData[] = {
-      {kMultiRootDByD, CertificateTrustType::DISTRUSTED},
-      // Root cert with no EKU usages but is also an intermediate cert that is
-      // allowed for server auth, so we let it be used for path building.
-      {kMultiRootCByD, CertificateTrustType::UNSPECIFIED},
+      {kMultiRootDByD, CertificateTrustType::UNSPECIFIED},
   };
   for (const auto& test_data : kTestData) {
     SCOPED_TRACE(test_data.file_name);
@@ -252,8 +278,7 @@
   }
 }
 
-// Test that disallowed certs with the right EKU settings will be
-// distrusted.
+// Test that disallowed certs will be distrusted regardless of EKU settings.
 TEST(TrustStoreWin, GetTrustDisallowedCerts) {
   crypto::ScopedHCERTSTORE root_store(CertOpenStore(
       CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
@@ -277,9 +302,8 @@
     base::StringPiece file_name;
     CertificateTrustType expected_result;
   } kTestData[] = {
-      // dByD in root, also in distrusted but without szOID_PKIX_KP_SERVER_AUTH
-      // set.
-      {kMultiRootDByD, CertificateTrustType::TRUSTED_ANCHOR_WITH_EXPIRATION},
+      // dByD in root, distrusted but without szOID_PKIX_KP_SERVER_AUTH set.
+      {kMultiRootDByD, CertificateTrustType::DISTRUSTED},
       // dByD in root, also in distrusted with szOID_PKIX_KP_SERVER_AUTH set.
       {kMultiRootEByE, CertificateTrustType::DISTRUSTED},
   };
diff --git a/net/cert/pki/path_builder_unittest.cc b/net/cert/pki/path_builder_unittest.cc
index 80c5baa..6497d92 100644
--- a/net/cert/pki/path_builder_unittest.cc
+++ b/net/cert/pki/path_builder_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
+#include "base/ranges/algorithm.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
@@ -917,7 +918,7 @@
 }
 
 // Test to ensure that path building stops when an intermediate cert is
-// encountered that is not usable for TLS because of EKU restrictions.
+// encountered that is not usable for TLS because it is explicitly distrusted.
 TEST_F(PathBuilderMultiRootTest, TrustStoreWinOnlyFindTrustedTLSPath) {
   crypto::ScopedHCERTSTORE root_store(CertOpenStore(
       CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL, 0, nullptr));
@@ -932,7 +933,7 @@
                                szOID_PKIX_KP_SERVER_AUTH);
   AddToStoreWithEKURestriction(intermediate_store.get(), c_by_e_,
                                szOID_PKIX_KP_SERVER_AUTH);
-  AddToStoreWithEKURestriction(intermediate_store.get(), c_by_d_, nullptr);
+  AddToStoreWithEKURestriction(disallowed_store.get(), c_by_d_, nullptr);
 
   std::unique_ptr<TrustStoreWin> trust_store = TrustStoreWin::CreateForTesting(
       std::move(root_store), std::move(intermediate_store),
@@ -948,7 +949,7 @@
 
   auto result = path_builder.Run();
   ASSERT_TRUE(result.HasValidPath());
-  ASSERT_EQ(2U, result.paths.size());
+  ASSERT_EQ(1U, result.paths.size());
   const auto& path = *result.GetBestValidPath();
   ASSERT_EQ(3U, path.certs.size());
   EXPECT_TRUE(AreCertsEq(b_by_c_, path.certs[0]));
@@ -956,14 +957,12 @@
   EXPECT_TRUE(AreCertsEq(e_by_e_, path.certs[2]));
 
   // Should only be one valid path, the one above.
-  int valid_paths = 0;
-  for (auto&& path : result.paths) {
-    valid_paths += path->IsValid() ? 1 : 0;
-  }
+  int valid_paths =
+      base::ranges::count_if(result.paths, &CertPathBuilderResultPath::IsValid);
   ASSERT_EQ(1, valid_paths);
 }
 
-// Test that if an intermediate is disabled for TLS, and it is the only
+// Test that if an intermediate is untrusted, and it is the only
 // path, then path building should fail, even if the root is enabled for
 // TLS.
 TEST_F(PathBuilderMultiRootTest, TrustStoreWinNoPathEKURestrictions) {
@@ -976,7 +975,7 @@
 
   AddToStoreWithEKURestriction(root_store.get(), d_by_d_,
                                szOID_PKIX_KP_SERVER_AUTH);
-  AddToStoreWithEKURestriction(intermediate_store.get(), c_by_d_, nullptr);
+  AddToStoreWithEKURestriction(disallowed_store.get(), c_by_d_, nullptr);
   std::unique_ptr<TrustStoreWin> trust_store = TrustStoreWin::CreateForTesting(
       std::move(root_store), std::move(intermediate_store),
       std::move(disallowed_store));
diff --git a/net/cookies/cookie_partition_key.cc b/net/cookies/cookie_partition_key.cc
index ec9872e7..52664b3e 100644
--- a/net/cookies/cookie_partition_key.cc
+++ b/net/cookies/cookie_partition_key.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "net/base/features.h"
 #include "net/cookies/cookie_constants.h"
 
@@ -111,7 +112,7 @@
   const SchemefulSite* partition_key_site =
       first_party_set_owner_site
           ? first_party_set_owner_site
-          : base::OptionalOrNullptr(network_isolation_key.GetTopFrameSite());
+          : base::OptionalToPtr(network_isolation_key.GetTopFrameSite());
   if (!partition_key_site)
     return absl::nullopt;
 
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc
index 13c70c26..f3d214cf 100644
--- a/net/cookies/cookie_util.cc
+++ b/net/cookies/cookie_util.cc
@@ -20,6 +20,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_tokenizer.h"
 #include "base/strings/string_util.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "net/base/features.h"
 #include "net/base/isolation_info.h"
@@ -817,7 +818,7 @@
         request_site,
         force_ignore_top_frame_party
             ? nullptr
-            : base::OptionalOrNullptr(
+            : base::OptionalToPtr(
                   isolation_info.network_isolation_key().GetTopFrameSite()),
         isolation_info.party_context().value(), std::move(callback));
   }
diff --git a/net/cookies/first_party_set_metadata.cc b/net/cookies/first_party_set_metadata.cc
index 0937d89..e4cb25bc 100644
--- a/net/cookies/first_party_set_metadata.cc
+++ b/net/cookies/first_party_set_metadata.cc
@@ -7,6 +7,7 @@
 #include <tuple>
 
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "net/cookies/first_party_set_entry.h"
 
 namespace net {
@@ -35,8 +36,8 @@
 std::ostream& operator<<(std::ostream& os,
                          const FirstPartySetMetadata& metadata) {
   os << "{" << metadata.context() << ", "
-     << base::OptionalOrNullptr(metadata.frame_entry()) << ", "
-     << base::OptionalOrNullptr(metadata.top_frame_entry()) << "}";
+     << base::OptionalToPtr(metadata.frame_entry()) << ", "
+     << base::OptionalToPtr(metadata.top_frame_entry()) << "}";
   return os;
 }
 
diff --git a/net/cookies/test_cookie_access_delegate.cc b/net/cookies/test_cookie_access_delegate.cc
index 3145188..bef2322 100644
--- a/net/cookies/test_cookie_access_delegate.cc
+++ b/net/cookies/test_cookie_access_delegate.cc
@@ -16,6 +16,7 @@
 #include "base/stl_util.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/types/optional_util.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/cookie_constants.h"
 #include "net/cookies/cookie_util.h"
@@ -61,8 +62,8 @@
   return RunMaybeAsync(
       FirstPartySetMetadata(
           SamePartyContext(),
-          base::OptionalOrNullptr(FindFirstPartySetOwnerSync(site)),
-          base::OptionalOrNullptr(top_frame_owner)),
+          base::OptionalToPtr(FindFirstPartySetOwnerSync(site)),
+          base::OptionalToPtr(top_frame_owner)),
       std::move(callback));
 }
 
diff --git a/net/disk_cache/blockfile/block_files_unittest.cc b/net/disk_cache/blockfile/block_files_unittest.cc
index a2168ea9..6d53ef15 100644
--- a/net/disk_cache/blockfile/block_files_unittest.cc
+++ b/net/disk_cache/blockfile/block_files_unittest.cc
@@ -30,8 +30,11 @@
 
 namespace disk_cache {
 
-// Flaky on ChromeOS: https://crbug.com/1156795
 #if BUILDFLAG(IS_CHROMEOS_ASH)
+// Flaky on ChromeOS: https://crbug.com/1156795
+#define MAYBE_BlockFiles_Grow DISABLED_BlockFiles_Grow
+#elif BUILDFLAG(IS_FUCHSIA)
+// Too slow on Fuchsia: https://crbug.com/1354793
 #define MAYBE_BlockFiles_Grow DISABLED_BlockFiles_Grow
 #else
 #define MAYBE_BlockFiles_Grow BlockFiles_Grow
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
index fd2e535..a5d8e57c 100644
--- a/net/dns/dns_test_util.cc
+++ b/net/dns/dns_test_util.cc
@@ -20,6 +20,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "base/types/optional_util.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
@@ -543,15 +544,14 @@
       case MockDnsClientRule::ResultType::kFail: {
         int error = result_.net_error.value_or(ERR_NAME_NOT_RESOLVED);
         DCHECK_NE(error, OK);
-        std::move(callback_).Run(error,
-                                 base::OptionalOrNullptr(result_.response));
+        std::move(callback_).Run(error, base::OptionalToPtr(result_.response));
         break;
       }
       case MockDnsClientRule::ResultType::kEmpty:
       case MockDnsClientRule::ResultType::kOk:
       case MockDnsClientRule::ResultType::kMalformed:
         DCHECK(!result_.net_error.has_value());
-        std::move(callback_).Run(OK, base::OptionalOrNullptr(result_.response));
+        std::move(callback_).Run(OK, base::OptionalToPtr(result_.response));
         break;
       case MockDnsClientRule::ResultType::kTimeout:
         DCHECK(!result_.net_error.has_value());
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h
index eb91546..a112651 100644
--- a/net/dns/host_cache.h
+++ b/net/dns/host_cache.h
@@ -24,6 +24,7 @@
 #include "base/stl_util.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "net/base/address_family.h"
 #include "net/base/connection_endpoint_metadata.h"
@@ -188,7 +189,7 @@
     absl::optional<std::vector<HostResolverEndpointResult>> GetEndpoints()
         const;
     const std::vector<IPEndPoint>* ip_endpoints() const {
-      return base::OptionalOrNullptr(ip_endpoints_);
+      return base::OptionalToPtr(ip_endpoints_);
     }
     void set_ip_endpoints(
         absl::optional<std::vector<IPEndPoint>> ip_endpoints) {
@@ -198,7 +199,7 @@
         const;
     void ClearMetadatas() { endpoint_metadatas_.reset(); }
     const std::set<std::string>* aliases() const {
-      return base::OptionalOrNullptr(aliases_);
+      return base::OptionalToPtr(aliases_);
     }
     void set_aliases(std::set<std::string> aliases) {
       aliases_ = std::move(aliases);
@@ -217,7 +218,7 @@
       hostnames_ = std::move(hostnames);
     }
     const std::vector<bool>* https_record_compatibility() const {
-      return base::OptionalOrNullptr(https_record_compatibility_);
+      return base::OptionalToPtr(https_record_compatibility_);
     }
     void set_https_record_compatibility(
         absl::optional<std::vector<bool>> https_record_compatibility) {
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index 095269c..471f922 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -59,6 +59,7 @@
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "net/base/address_family.h"
@@ -668,13 +669,13 @@
 
   const AddressList* GetAddressResults() const override {
     DCHECK(complete_);
-    return base::OptionalOrNullptr(legacy_address_results_);
+    return base::OptionalToPtr(legacy_address_results_);
   }
 
   const std::vector<HostResolverEndpointResult>* GetEndpointResults()
       const override {
     DCHECK(complete_);
-    return base::OptionalOrNullptr(endpoint_results_);
+    return base::OptionalToPtr(endpoint_results_);
   }
 
   const absl::optional<std::vector<std::string>>& GetTextResults()
@@ -710,7 +711,7 @@
     }
 #endif  // DCHECK_IS_ON()
 
-    return base::OptionalOrNullptr(fixed_up_dns_alias_results_);
+    return base::OptionalToPtr(fixed_up_dns_alias_results_);
   }
 
   const std::vector<bool>* GetExperimentalResultsForTesting() const override {
@@ -1865,7 +1866,7 @@
 
     net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_MANAGER_DNS_TASK, [&] {
       return NetLogDnsTaskFailedParams(net_error, failed_transaction_type, ttl,
-                                       base::OptionalOrNullptr(saved_results_));
+                                       base::OptionalToPtr(saved_results_));
     });
 
     // Expect this to result in destroying `this` and thus cancelling any
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index cef2e2f..f97a118 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -15522,7 +15522,6 @@
   void SetUp() override {
     // The request host scheme and port are only preserved if the SVCB feature
     // is enabled.
-    base::test::ScopedFeatureList features;
     features.InitAndEnableFeatureWithParameters(
         features::kUseDnsHttpsSvcb,
         {// Disable timeouts.
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index 3f662a4c..bd116f8 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -32,6 +32,7 @@
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "net/base/address_family.h"
 #include "net/base/address_list.h"
@@ -218,13 +219,13 @@
 
   const AddressList* GetAddressResults() const override {
     DCHECK(complete_);
-    return base::OptionalOrNullptr(address_results_);
+    return base::OptionalToPtr(address_results_);
   }
 
   const std::vector<HostResolverEndpointResult>* GetEndpointResults()
       const override {
     DCHECK(complete_);
-    return base::OptionalOrNullptr(endpoint_results_);
+    return base::OptionalToPtr(endpoint_results_);
   }
 
   const absl::optional<std::vector<std::string>>& GetTextResults()
@@ -245,7 +246,7 @@
 
   const std::set<std::string>* GetDnsAliasResults() const override {
     DCHECK(complete_);
-    return base::OptionalOrNullptr(fixed_up_dns_alias_results_);
+    return base::OptionalToPtr(fixed_up_dns_alias_results_);
   }
 
   net::ResolveErrorInfo GetResolveErrorInfo() const override {
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 481d9891..1ce77f3 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -373,8 +373,8 @@
         aliases_.erase(alias_it);
 
         // Remap pooled session keys.
-        const auto& aliases = available_session->pooled_aliases();
-        for (auto it = aliases.begin(); it != aliases.end();) {
+        const auto& pooled_aliases = available_session->pooled_aliases();
+        for (auto it = pooled_aliases.begin(); it != pooled_aliases.end();) {
           // Ignore aliases this loop is inserting.
           if (it->socket_tag() == key.socket_tag()) {
             ++it;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index bd33636..2a39aed 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -32,6 +32,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "base/types/optional_util.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "net/base/features.h"
@@ -335,7 +336,7 @@
 
     cookie_partition_key_ = CookiePartitionKey::FromNetworkIsolationKey(
         request_->isolation_info().network_isolation_key(),
-        base::OptionalOrNullptr(
+        base::OptionalToPtr(
             first_party_set_metadata_.top_frame_entry().has_value()
                 ? absl::make_optional(
                       first_party_set_metadata_.top_frame_entry()->primary())
diff --git a/remoting/ios/app/BUILD.gn b/remoting/ios/app/BUILD.gn
index 8b911c5..a686a38 100644
--- a/remoting/ios/app/BUILD.gn
+++ b/remoting/ios/app/BUILD.gn
@@ -11,6 +11,11 @@
   deps = [ ":ios_remoting_app" ]
 }
 
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
+}
+
 # source set to be used by both external and internal app.
 source_set("common_source_set") {
   sources = [
@@ -125,7 +130,10 @@
     "//remoting/ios/facade",
   ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 source_set("app_source_set") {
@@ -149,7 +157,10 @@
 
   # TODO(crbug.com/875022) fix for OpenGLES deprecation.
   defines = [ "GLES_SILENCE_DEPRECATION" ]
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
 }
 
 ios_remoting_app_tmpl("ios_remoting_app") {
diff --git a/remoting/ios/mdc/BUILD.gn b/remoting/ios/mdc/BUILD.gn
index ba4cbac..ad4d67f 100644
--- a/remoting/ios/mdc/BUILD.gn
+++ b/remoting/ios/mdc/BUILD.gn
@@ -16,5 +16,13 @@
 
   deps = [ "//ios/third_party/material_components_ios" ]
 
-  configs += [ "//build/config/compiler:enable_arc" ]
+  configs += [
+    ":disable_deprecated_declarations",
+    "//build/config/compiler:enable_arc",
+  ]
+}
+
+# TODO(crbug.com/1344830): Migrate away from deprecated MDC APIs.
+config("disable_deprecated_declarations") {
+  cflags = [ "-Wno-deprecated-declarations" ]
 }
diff --git a/remoting/protocol/webrtc_frame_scheduler.h b/remoting/protocol/webrtc_frame_scheduler.h
index 7d3a8f3..052737d 100644
--- a/remoting/protocol/webrtc_frame_scheduler.h
+++ b/remoting/protocol/webrtc_frame_scheduler.h
@@ -6,7 +6,6 @@
 #define REMOTING_PROTOCOL_WEBRTC_FRAME_SCHEDULER_H_
 
 #include "base/callback_forward.h"
-#include "remoting/protocol/video_channel_state_observer.h"
 
 namespace webrtc {
 class DesktopFrame;
@@ -17,10 +16,10 @@
 // An abstract interface for frame schedulers, which are responsible for
 // scheduling when video frames are captured and for defining encoding
 // parameters for each frame.
-class WebrtcFrameScheduler : public VideoChannelStateObserver {
+class WebrtcFrameScheduler {
  public:
   WebrtcFrameScheduler() = default;
-  ~WebrtcFrameScheduler() override = default;
+  virtual ~WebrtcFrameScheduler() = default;
 
   // Starts the scheduler. |capture_callback| will be called whenever a new
   // frame should be captured.
diff --git a/remoting/protocol/webrtc_frame_scheduler_constant_rate.cc b/remoting/protocol/webrtc_frame_scheduler_constant_rate.cc
index 28054465..ab89985b 100644
--- a/remoting/protocol/webrtc_frame_scheduler_constant_rate.cc
+++ b/remoting/protocol/webrtc_frame_scheduler_constant_rate.cc
@@ -19,33 +19,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-void WebrtcFrameSchedulerConstantRate::OnKeyFrameRequested() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void WebrtcFrameSchedulerConstantRate::OnTargetBitrateChanged(
-    int bitrate_kbps) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void WebrtcFrameSchedulerConstantRate::OnFrameEncoded(
-    WebrtcVideoEncoder::EncodeResult encode_result,
-    const WebrtcVideoEncoder::EncodedFrame* encoded_frame) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (encoded_frame && encoded_frame->stats) {
-    // This scheduler cannot estimate this delay. Set it to 0 so the client can
-    // still calculate the derived stats.
-    encoded_frame->stats->send_pending_delay = base::TimeDelta();
-  }
-}
-
-void WebrtcFrameSchedulerConstantRate::OnEncodedFrameSent(
-    webrtc::EncodedImageCallback::Result result,
-    const WebrtcVideoEncoder::EncodedFrame& frame) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
 void WebrtcFrameSchedulerConstantRate::Start(
     const base::RepeatingClosure& capture_callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/remoting/protocol/webrtc_frame_scheduler_constant_rate.h b/remoting/protocol/webrtc_frame_scheduler_constant_rate.h
index b36d5a4f..1b4e6a4 100644
--- a/remoting/protocol/webrtc_frame_scheduler_constant_rate.h
+++ b/remoting/protocol/webrtc_frame_scheduler_constant_rate.h
@@ -27,16 +27,6 @@
 
   ~WebrtcFrameSchedulerConstantRate() override;
 
-  // VideoChannelStateObserver implementation.
-  void OnKeyFrameRequested() override;
-  void OnTargetBitrateChanged(int bitrate_kbps) override;
-  void OnFrameEncoded(
-      WebrtcVideoEncoder::EncodeResult encode_result,
-      const WebrtcVideoEncoder::EncodedFrame* encoded_frame) override;
-  void OnEncodedFrameSent(
-      webrtc::EncodedImageCallback::Result result,
-      const WebrtcVideoEncoder::EncodedFrame& frame) override;
-
   // WebrtcFrameScheduler implementation.
   void Start(const base::RepeatingClosure& capture_callback) override;
   void Pause(bool pause) override;
diff --git a/remoting/protocol/webrtc_frame_scheduler_unittest.cc b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
index 2fc3666..4419361 100644
--- a/remoting/protocol/webrtc_frame_scheduler_unittest.cc
+++ b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
@@ -22,9 +22,7 @@
 
 class WebrtcFrameSchedulerTest : public ::testing::Test {
  public:
-  WebrtcFrameSchedulerTest()
-      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-        frame_(DesktopSize(1, 1)) {}
+  WebrtcFrameSchedulerTest() = default;
   ~WebrtcFrameSchedulerTest() override = default;
 
   void InitConstantRateScheduler() {
@@ -37,24 +35,19 @@
     capture_callback_count_++;
 
     if (simulate_capture_) {
-      // Simulate a completed capture and encode.
       scheduler_->OnFrameCaptured(&frame_);
-      WebrtcVideoEncoder::EncodedFrame encoded_frame;
-      encoded_frame.key_frame = false;
-      encoded_frame.data = webrtc::EncodedImageBuffer::Create(1);
-      scheduler_->OnFrameEncoded(WebrtcVideoEncoder::EncodeResult::SUCCEEDED,
-                                 &encoded_frame);
     }
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
   std::unique_ptr<WebrtcFrameScheduler> scheduler_;
 
   int capture_callback_count_ = 0;
   bool simulate_capture_ = true;
-  BasicDesktopFrame frame_;
+  BasicDesktopFrame frame_{DesktopSize(1, 1)};
 };
 
 TEST_F(WebrtcFrameSchedulerTest, NoCapturesIfZeroFps) {
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc
index d464ce8..609de4fa 100644
--- a/remoting/protocol/webrtc_video_stream.cc
+++ b/remoting/protocol/webrtc_video_stream.cc
@@ -68,11 +68,6 @@
   void Pause(bool pause);
   void SelectSource(webrtc::ScreenId id);
 
-  // Mimics the remoting::VideoChannelStateObserver interface but only
-  // implements the methods the outer class needs to call.
-  void OnKeyFrameRequested();
-  void OnTargetBitrateChanged(int bitrate_kbps);
-
   // Called by the video track source to set the max frame rate for the stream.
   void SetMaxFramerateFps(int max_framerate_fps);
 
@@ -182,16 +177,6 @@
   capturer_->SelectSource(id);
 }
 
-void WebrtcVideoStream::Core::OnKeyFrameRequested() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  scheduler_.OnKeyFrameRequested();
-}
-
-void WebrtcVideoStream::Core::OnTargetBitrateChanged(int bitrate_kbps) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  scheduler_.OnTargetBitrateChanged(bitrate_kbps);
-}
-
 void WebrtcVideoStream::Core::SetMaxFramerateFps(int max_framerate_fps) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   scheduler_.SetMaxFramerateFps(max_framerate_fps);
@@ -320,23 +305,10 @@
 
 void WebrtcVideoStream::OnKeyFrameRequested() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  // Unretained is sound as |core_| is owned by |this| and destroyed on
-  // |core_task_runner_|.
-  core_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&WebrtcVideoStream::Core::OnKeyFrameRequested,
-                                base::Unretained(core_.get())));
 }
 
 void WebrtcVideoStream::OnTargetBitrateChanged(int bitrate_kbps) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  // Unretained is sound as |core_| is owned by |this| and destroyed on
-  // |core_task_runner_|.
-  core_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&WebrtcVideoStream::Core::OnTargetBitrateChanged,
-                     base::Unretained(core_.get()), bitrate_kbps));
 }
 
 void WebrtcVideoStream::OnFrameEncoded(
diff --git a/services/cert_verifier/cert_verifier_service_factory.cc b/services/cert_verifier/cert_verifier_service_factory.cc
index 7cd1c5b..cfdb935 100644
--- a/services/cert_verifier/cert_verifier_service_factory.cc
+++ b/services/cert_verifier/cert_verifier_service_factory.cc
@@ -11,6 +11,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -107,7 +108,7 @@
     mojom::CertVerifierCreationParamsPtr creation_params) {
   net::ChromeRootStoreData* root_store_data = nullptr;
 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
-  root_store_data = base::OptionalOrNullptr(root_store_data_);
+  root_store_data = base::OptionalToPtr(root_store_data_);
 #endif
 
   internal::CertVerifierServiceImpl* service_impl = GetNewCertVerifierImpl(
diff --git a/services/device/compute_pressure/pressure_manager_impl_unittest.cc b/services/device/compute_pressure/pressure_manager_impl_unittest.cc
index f9fe69b..c569bf55 100644
--- a/services/device/compute_pressure/pressure_manager_impl_unittest.cc
+++ b/services/device/compute_pressure/pressure_manager_impl_unittest.cc
@@ -140,10 +140,9 @@
   std::unique_ptr<PressureManagerImplSync> manager_impl_sync_;
 };
 
-// Disabled on Fuchsia arm64 debug builds: https://crbug.com/1250654
-#if BUILDFLAG(IS_FUCHSIA) && defined(_DEBUG) && defined(ARCH_CPU_ARM64)
-#define MAYBE_OneClient DISABLED_OneClient
-#elif BUILDFLAG(IS_LINUX) && defined(USE_OZONE)  // https://crbug.com/1226086
+// TODO(crbug.com/1226086): Fix test flakiness.
+#if (BUILDFLAG(IS_FUCHSIA) && defined(_DEBUG) && defined(ARCH_CPU_ARM64)) || \
+    (BUILDFLAG(IS_LINUX) && defined(USE_OZONE))
 #define MAYBE_OneClient DISABLED_OneClient
 #else
 #define MAYBE_OneClient OneClient
@@ -157,10 +156,9 @@
   EXPECT_EQ(client.updates()[0].first, mojom::PressureState{0.42});
 }
 
-// Disabled on Fuchsia arm64 debug builds: https://crbug.com/1250654
-#if BUILDFLAG(IS_FUCHSIA) && defined(_DEBUG) && defined(ARCH_CPU_ARM64)
-#define MAYBE_ThreeClients DISABLED_ThreeClients
-#elif BUILDFLAG(IS_LINUX) && defined(USE_OZONE)  // https://crbug.com/1226086
+// TODO(crbug.com/1226086): Fix test flakiness.
+#if (BUILDFLAG(IS_FUCHSIA) && defined(_DEBUG) && defined(ARCH_CPU_ARM64)) || \
+    (BUILDFLAG(IS_LINUX) && defined(USE_OZONE))
 #define MAYBE_ThreeClients DISABLED_ThreeClients
 #else
 #define MAYBE_ThreeClients ThreeClients
diff --git a/services/device/fingerprint/OWNERS b/services/device/fingerprint/OWNERS
index e0389dd..81ca4478 100644
--- a/services/device/fingerprint/OWNERS
+++ b/services/device/fingerprint/OWNERS
@@ -1 +1 @@
-rsorokin@chromium.org
\ No newline at end of file
+rsorokin@google.com
\ No newline at end of file
diff --git a/services/network/cookie_settings.cc b/services/network/cookie_settings.cc
index bc8267d..53c2e73 100644
--- a/services/network/cookie_settings.cc
+++ b/services/network/cookie_settings.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/ranges/algorithm.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/cookie_settings_base.h"
 #include "net/base/features.h"
@@ -124,7 +125,7 @@
       GetCookieSettingWithMetadata(
           url,
           GetFirstPartyURL(site_for_cookies,
-                           base::OptionalOrNullptr(top_frame_origin)),
+                           base::OptionalToPtr(top_frame_origin)),
           IsThirdPartyRequest(url, site_for_cookies), QueryReason::kCookies),
       cookie.IsSameParty(), cookie.IsPartitioned(), /*record_metrics=*/true);
 }
@@ -164,7 +165,7 @@
   //
   // We don't record metrics here, since this isn't actually accessing a cookie.
   CookieSettingWithMetadata metadata = GetCookieSettingWithMetadata(
-      url, site_for_cookies, base::OptionalOrNullptr(top_frame_origin),
+      url, site_for_cookies, base::OptionalToPtr(top_frame_origin),
       QueryReason::kCookies);
   if (IsHypotheticalCookieAllowed(metadata,
                                   same_party_cookie_context_type ==
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc
index 02664f1..409cc05 100644
--- a/services/network/cors/cors_url_loader.cc
+++ b/services/network/cors/cors_url_loader.cc
@@ -484,8 +484,10 @@
     forwarding_client_->OnReceiveEarlyHints(std::move(early_hints));
 }
 
-void CorsURLLoader::OnReceiveResponse(mojom::URLResponseHeadPtr response_head,
-                                      mojo::ScopedDataPipeConsumerHandle body) {
+void CorsURLLoader::OnReceiveResponse(
+    mojom::URLResponseHeadPtr response_head,
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK(network_loader_);
   DCHECK(forwarding_client_);
   DCHECK(!deferred_redirect_url_);
@@ -516,8 +518,8 @@
   response_head->timing_allow_passed = !timing_allow_failed_flag_;
   response_head->has_authorization_covered_by_wildcard_on_preflight =
       has_authorization_covered_by_wildcard_;
-  forwarding_client_->OnReceiveResponse(std::move(response_head),
-                                        std::move(body));
+  forwarding_client_->OnReceiveResponse(
+      std::move(response_head), std::move(body), std::move(cached_metadata));
 }
 
 void CorsURLLoader::OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -638,13 +640,6 @@
                                        std::move(ack_callback));
 }
 
-void CorsURLLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  DCHECK(network_loader_);
-  DCHECK(forwarding_client_);
-  DCHECK(!deferred_redirect_url_);
-  forwarding_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void CorsURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   DCHECK(network_loader_);
   DCHECK(forwarding_client_);
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h
index 469a5c1..43b8df8 100644
--- a/services/network/cors/cors_url_loader.h
+++ b/services/network/cors/cors_url_loader.h
@@ -98,14 +98,15 @@
 
   // mojom::URLLoaderClient overrides:
   void OnReceiveEarlyHints(mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         base::OnceCallback<void()> callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const URLLoaderCompletionStatus& status) override;
 
diff --git a/services/network/cors/cors_url_loader_test_util.cc b/services/network/cors/cors_url_loader_test_util.cc
index 5289cb1..63a186a 100644
--- a/services/network/cors/cors_url_loader_test_util.cc
+++ b/services/network/cors/cors_url_loader_test_util.cc
@@ -72,8 +72,8 @@
   for (const auto& header : extra_headers)
     response->headers->SetHeader(header.first, header.second);
 
-  client_remote_->OnReceiveResponse(std::move(response),
-                                    mojo::ScopedDataPipeConsumerHandle());
+  client_remote_->OnReceiveResponse(
+      std::move(response), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
 }
 
 void TestURLLoaderFactory::NotifyClientOnComplete(int error_code) {
diff --git a/services/network/first_party_sets/first_party_sets_access_delegate.cc b/services/network/first_party_sets/first_party_sets_access_delegate.cc
index b14c5bf..5550a2d 100644
--- a/services/network/first_party_sets/first_party_sets_access_delegate.cc
+++ b/services/network/first_party_sets/first_party_sets_access_delegate.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/stl_util.h"
 #include "base/time/time.h"
+#include "base/types/optional_util.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/first_party_set_metadata.h"
 
@@ -107,7 +108,7 @@
       callbacks = base::SplitOnceCallback(std::move(callback));
 
   absl::optional<net::FirstPartySetMetadata> sync_result =
-      manager_->ComputeMetadata(site, base::OptionalOrNullptr(top_frame_site),
+      manager_->ComputeMetadata(site, base::OptionalToPtr(top_frame_site),
                                 party_context, context_config_,
                                 std::move(callbacks.first));
 
@@ -173,4 +174,4 @@
   pending_queries_->push_back(std::move(run_query));
 }
 
-}  // namespace network
\ No newline at end of file
+}  // namespace network
diff --git a/services/network/first_party_sets/first_party_sets_manager.cc b/services/network/first_party_sets/first_party_sets_manager.cc
index c3ddd45..36e9211 100644
--- a/services/network/first_party_sets/first_party_sets_manager.cc
+++ b/services/network/first_party_sets/first_party_sets_manager.cc
@@ -20,6 +20,7 @@
 #include "base/stl_util.h"
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
+#include "base/types/optional_util.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/first_party_set_entry.h"
 #include "net/cookies/first_party_set_metadata.h"
@@ -113,7 +114,7 @@
                       timer.Elapsed());
 
   std::move(callback).Run(
-      ComputeMetadataInternal(site, base::OptionalOrNullptr(top_frame_site),
+      ComputeMetadataInternal(site, base::OptionalToPtr(top_frame_site),
                               party_context, fps_context_config));
 }
 
@@ -143,8 +144,8 @@
                      : absl::nullopt;
 
   return net::FirstPartySetMetadata(
-      context, base::OptionalOrNullptr(FindEntry(site, fps_context_config)),
-      base::OptionalOrNullptr(top_frame_owner));
+      context, base::OptionalToPtr(FindEntry(site, fps_context_config)),
+      base::OptionalToPtr(top_frame_owner));
 }
 
 absl::optional<net::FirstPartySetEntry> FirstPartySetsManager::FindEntry(
diff --git a/services/network/host_resolver.cc b/services/network/host_resolver.cc
index 9986bce..0070fec 100644
--- a/services/network/host_resolver.cc
+++ b/services/network/host_resolver.cc
@@ -98,7 +98,7 @@
 }
 
 void HostResolver::ResolveHost(
-    const net::HostPortPair& host,
+    mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     mojom::ResolveHostParametersPtr optional_parameters,
     mojo::PendingRemote<mojom::ResolveHostClient> response_client) {
@@ -110,10 +110,12 @@
 #endif  // !BUILDFLAG(ENABLE_MDNS)
 
   if (resolve_host_callback.Get())
-    resolve_host_callback.Get().Run(host.host());
+    resolve_host_callback.Get().Run(host->is_host_port_pair()
+                                        ? host->get_host_port_pair().host()
+                                        : host->get_scheme_host_port().host());
 
   auto request = std::make_unique<ResolveHostRequest>(
-      internal_resolver_, host, network_isolation_key,
+      internal_resolver_, std::move(host), network_isolation_key,
       ConvertOptionalParameters(optional_parameters), net_log_);
 
   mojo::PendingReceiver<mojom::ResolveHostHandle> control_handle_receiver;
diff --git a/services/network/host_resolver.h b/services/network/host_resolver.h
index 7d8540c..6de8888 100644
--- a/services/network/host_resolver.h
+++ b/services/network/host_resolver.h
@@ -56,7 +56,7 @@
   ~HostResolver() override;
 
   void ResolveHost(
-      const net::HostPortPair& host,
+      mojom::HostResolverHostPtr host,
       const net::NetworkIsolationKey& network_isolation_key,
       mojom::ResolveHostParametersPtr optional_parameters,
       mojo::PendingRemote<mojom::ResolveHostClient> response_client) override;
diff --git a/services/network/host_resolver_unittest.cc b/services/network/host_resolver_unittest.cc
index 00ee616b..d1bcaaf 100644
--- a/services/network/host_resolver_unittest.cc
+++ b/services/network/host_resolver_unittest.cc
@@ -228,9 +228,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.test", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.test", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.top_level_result_error());
@@ -259,9 +261,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.test", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.test", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
 
   bool control_handle_closed = false;
   auto connection_error_callback =
@@ -293,9 +297,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -317,9 +323,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("priority.test", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("priority.test", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -366,7 +374,8 @@
   mojom::ResolveHostParametersPtr any_parameters =
       mojom::ResolveHostParameters::New();
   any_parameters->source = net::HostResolverSource::ANY;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(any_parameters),
                        std::move(pending_any_client));
 
@@ -376,7 +385,8 @@
   mojom::ResolveHostParametersPtr system_parameters =
       mojom::ResolveHostParameters::New();
   system_parameters->source = net::HostResolverSource::SYSTEM;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(system_parameters),
                        std::move(pending_system_client));
 
@@ -386,7 +396,8 @@
   mojom::ResolveHostParametersPtr dns_parameters =
       mojom::ResolveHostParameters::New();
   dns_parameters->source = net::HostResolverSource::DNS;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(dns_parameters),
                        std::move(pending_dns_client));
 
@@ -411,7 +422,8 @@
   mojom::ResolveHostParametersPtr mdns_parameters =
       mojom::ResolveHostParameters::New();
   mdns_parameters->source = net::HostResolverSource::MULTICAST_DNS;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(mdns_parameters),
                        std::move(pending_mdns_client));
 
@@ -448,7 +460,8 @@
   mojom::ResolveHostParametersPtr system_parameters =
       mojom::ResolveHostParameters::New();
   system_parameters->source = net::HostResolverSource::SYSTEM;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(system_parameters),
                        std::move(pending_system_client_ptr));
   system_run_loop.Run();
@@ -471,7 +484,8 @@
   mojom::ResolveHostParametersPtr cached_parameters =
       mojom::ResolveHostParameters::New();
   cached_parameters->source = net::HostResolverSource::SYSTEM;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(cached_parameters),
                        std::move(pending_cached_client));
 
@@ -482,9 +496,11 @@
   mojom::ResolveHostParametersPtr uncached_parameters =
       mojom::ResolveHostParameters::New();
   uncached_parameters->source = net::HostResolverSource::ANY;
-  resolver.ResolveHost(
-      net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
-      std::move(uncached_parameters), std::move(pending_uncached_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(uncached_parameters),
+                       std::move(pending_uncached_client));
 
   cached_run_loop.Run();
   uncached_run_loop.Run();
@@ -511,7 +527,8 @@
   base::RunLoop run_loop;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
   TestResolveHostClient client(&pending_client, &run_loop);
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_client));
   run_loop.Run();
@@ -533,7 +550,8 @@
       mojom::ResolveHostParameters::New();
   cached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(cached_parameters),
                        std::move(pending_cached_client));
   cached_run_loop.Run();
@@ -551,9 +569,11 @@
       mojom::ResolveHostParameters::New();
   uncached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
-  resolver.ResolveHost(
-      net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
-      std::move(uncached_parameters), std::move(pending_uncached_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(uncached_parameters),
+                       std::move(pending_uncached_client));
   uncached_run_loop.Run();
 
   EXPECT_EQ(net::OK, uncached_client.result_error());
@@ -573,7 +593,8 @@
   base::RunLoop run_loop;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
   TestResolveHostClient client(&pending_client, &run_loop);
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_client));
   run_loop.Run();
@@ -601,7 +622,8 @@
       mojom::ResolveHostParameters::New();
   cached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(cached_parameters),
                        std::move(pending_cached_client));
   cached_run_loop.Run();
@@ -621,9 +643,11 @@
       mojom::ResolveHostParameters::New();
   uncached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
-  resolver.ResolveHost(
-      net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
-      std::move(uncached_parameters), std::move(pending_uncached_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(uncached_parameters),
+                       std::move(pending_uncached_client));
   uncached_run_loop.Run();
 
   EXPECT_EQ(net::OK, uncached_client.result_error());
@@ -645,7 +669,8 @@
   base::RunLoop run_loop;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
   TestResolveHostClient client(&pending_client, &run_loop);
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_client));
   run_loop.Run();
@@ -664,7 +689,8 @@
       mojom::ResolveHostParameters::New();
   cached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
-  resolver.ResolveHost(net::HostPortPair(kDomain, 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
                        net::NetworkIsolationKey(), std::move(cached_parameters),
                        std::move(pending_cached_client));
   cached_run_loop.Run();
@@ -678,9 +704,11 @@
       mojom::ResolveHostParameters::New();
   uncached_parameters->cache_usage =
       mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
-  resolver.ResolveHost(
-      net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
-      std::move(uncached_parameters), std::move(pending_uncached_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair(kDomain, 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(uncached_parameters),
+                       std::move(pending_uncached_client));
   uncached_run_loop.Run();
   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, uncached_client.result_error());
 }
@@ -701,9 +729,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -728,9 +758,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -753,9 +785,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("secure.test", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("secure.test", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -781,9 +815,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED,
@@ -809,9 +845,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
 
   bool control_handle_closed = false;
   auto connection_error_callback =
@@ -843,8 +881,9 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(net::HostPortPair("nik.test", 160), kNetworkIsolationKey,
-                       std::move(optional_parameters),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("nik.test", 160)),
+                       kNetworkIsolationKey, std::move(optional_parameters),
                        std::move(pending_response_client));
   run_loop.Run();
 
@@ -868,7 +907,8 @@
 
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_response_client));
   run_loop.Run();
@@ -895,9 +935,11 @@
 
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -925,9 +967,11 @@
 
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   control_handle.reset();
   run_loop.Run();
 
@@ -957,9 +1001,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -992,9 +1038,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, nullptr);
 
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
 
   control_handle->Cancel(net::ERR_ABORTED);
   run_loop.RunUntilIdle();
@@ -1009,7 +1057,8 @@
   base::RunLoop run_loop2;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_response_client2));
   run_loop2.Run();
@@ -1041,9 +1090,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                            net::HostPortPair("localhost", 80)),
+                        net::NetworkIsolationKey(),
+                        std::move(optional_parameters),
+                        std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -1078,9 +1129,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -1107,7 +1160,8 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, nullptr);
 
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_response_client));
 
@@ -1124,7 +1178,8 @@
   base::RunLoop run_loop2;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_response_client2));
   run_loop2.Run();
@@ -1163,8 +1218,10 @@
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
   resolver_remote->ResolveHost(
-      net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -1202,8 +1259,10 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
   resolver_remote->ResolveHost(
-      net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -1240,9 +1299,10 @@
   base::RunLoop run_loop;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, nullptr);
-  resolver_remote->ResolveHost(net::HostPortPair("localhost", 160),
-                               net::NetworkIsolationKey(), nullptr,
-                               std::move(pending_response_client));
+  resolver_remote->ResolveHost(
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 160)),
+      net::NetworkIsolationKey(), nullptr, std::move(pending_response_client));
 
   resolver_remote.reset();
   run_loop.RunUntilIdle();
@@ -1260,7 +1320,8 @@
   base::RunLoop run_loop2;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), nullptr,
                        std::move(pending_response_client2));
   run_loop2.Run();
@@ -1288,7 +1349,8 @@
 
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
-  resolver.ResolveHost(net::HostPortPair("localhost", 80),
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("localhost", 80)),
                        net::NetworkIsolationKey(), std::move(parameters),
                        std::move(pending_response_client));
   run_loop.Run();
@@ -1337,9 +1399,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -1378,9 +1442,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -1416,9 +1482,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
   run_loop.Run();
 
   // No queries made, so result is `ERR_DNS_CACHE_MISS`.
@@ -1613,9 +1681,11 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver.ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver.ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                           net::HostPortPair("example.com", 160)),
+                       net::NetworkIsolationKey(),
+                       std::move(optional_parameters),
+                       std::move(pending_response_client));
 
   run_loop.Run();
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index f42edc9..d73a375 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1735,7 +1735,7 @@
 }
 
 void NetworkContext::ResolveHost(
-    const net::HostPortPair& host,
+    mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     mojom::ResolveHostParametersPtr optional_parameters,
     mojo::PendingRemote<mojom::ResolveHostClient> response_client) {
@@ -1743,8 +1743,7 @@
     internal_host_resolver_ = std::make_unique<HostResolver>(
         url_request_context_->host_resolver(), url_request_context_->net_log());
   }
-
-  internal_host_resolver_->ResolveHost(host, network_isolation_key,
+  internal_host_resolver_->ResolveHost(std::move(host), network_isolation_key,
                                        std::move(optional_parameters),
                                        std::move(response_client));
 }
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 0d6063bd..212fc5f 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -386,7 +386,7 @@
   void CreateNetLogExporter(
       mojo::PendingReceiver<mojom::NetLogExporter> receiver) override;
   void ResolveHost(
-      const net::HostPortPair& host,
+      mojom::HostResolverHostPtr host,
       const net::NetworkIsolationKey& network_isolation_key,
       mojom::ResolveHostParametersPtr optional_parameters,
       mojo::PendingRemote<mojom::ResolveHostClient> response_client) override;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index 99cf666f..1e16036 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -3483,8 +3483,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("sync.test", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("sync.test", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.top_level_result_error());
@@ -3515,8 +3517,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("async.test", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("async.test", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
 
   bool control_handle_closed = false;
   auto connection_error_callback =
@@ -3553,8 +3557,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("example.com", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED,
@@ -3584,8 +3590,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("example.com", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
 
   bool control_handle_closed = false;
   auto connection_error_callback =
@@ -3624,8 +3632,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("nik.test", 160), kNetworkIsolationKey,
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("nik.test", 160)),
+      kNetworkIsolationKey, std::move(optional_parameters),
+      std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -3648,9 +3658,10 @@
 
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
-  network_context->ResolveHost(net::HostPortPair("localhost", 80),
-                               net::NetworkIsolationKey(), nullptr,
-                               std::move(pending_response_client));
+  network_context->ResolveHost(
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), nullptr, std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
@@ -3678,8 +3689,10 @@
   // Resolve "localhost" because it should always resolve fast and locally, even
   // when using a real HostResolver.
   network_context->ResolveHost(
-      net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 160)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   control_handle.reset();
   run_loop.Run();
 
@@ -3715,8 +3728,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -3758,8 +3773,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -3799,8 +3816,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   network_context->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -3888,7 +3907,8 @@
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
-  resolver->ResolveHost(net::HostPortPair("localhost", 80),
+  resolver->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                            net::HostPortPair("localhost", 80)),
                         net::NetworkIsolationKey(), nullptr,
                         std::move(pending_response_client));
   run_loop.Run();
@@ -3929,8 +3949,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   resolver_remote->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   bool control_handle_closed = false;
   auto connection_error_callback =
       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
@@ -3974,8 +3996,10 @@
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
 
   resolver_remote->ResolveHost(
-      net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+      network::mojom::HostResolverHost::NewHostPortPair(
+          net::HostPortPair("localhost", 80)),
+      net::NetworkIsolationKey(), std::move(optional_parameters),
+      std::move(pending_response_client));
   // Run a bit to ensure the resolve request makes it to the resolver. Otherwise
   // the resolver will be destroyed and close its pipe before it even knows
   // about the request to send a failure.
@@ -4071,9 +4095,11 @@
   optional_parameters->source = net::HostResolverSource::DNS;
   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
   TestResolveHostClient response_client(&pending_response_client, &run_loop);
-  resolver->ResolveHost(
-      net::HostPortPair(kQueryHostname, 80), net::NetworkIsolationKey(),
-      std::move(optional_parameters), std::move(pending_response_client));
+  resolver->ResolveHost(network::mojom::HostResolverHost::NewHostPortPair(
+                            net::HostPortPair(kQueryHostname, 80)),
+                        net::NetworkIsolationKey(),
+                        std::move(optional_parameters),
+                        std::move(pending_response_client));
   run_loop.Run();
 
   EXPECT_EQ(net::OK, response_client.result_error());
diff --git a/services/network/network_service_memory_cache_unittest.cc b/services/network/network_service_memory_cache_unittest.cc
index 5687a5d..5040f01 100644
--- a/services/network/network_service_memory_cache_unittest.cc
+++ b/services/network/network_service_memory_cache_unittest.cc
@@ -167,7 +167,8 @@
 
     mojo::Remote<mojom::URLLoaderClient> client(std::move(pending_client));
     mojom::URLResponseHeadPtr response_head = CreateCacheableURLResponseHead();
-    client->OnReceiveResponse(std::move(response_head), /*body=*/{});
+    client->OnReceiveResponse(std::move(response_head), /*body=*/{},
+                              absl::nullopt);
     client->OnComplete(URLLoaderCompletionStatus(net::OK));
   }
   void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override {
@@ -826,9 +827,10 @@
   request.trusted_params = ResourceRequest::TrustedParams();
   request.trusted_params->devtools_observer = devtools_observer.Bind();
 
-  LoaderPair pair = CreateLoaderAndStart(request);
-  pair.client->RunUntilComplete();
-  const URLLoaderCompletionStatus& status = pair.client->completion_status();
+  LoaderPair loader_pair = CreateLoaderAndStart(request);
+  loader_pair.client->RunUntilComplete();
+  const URLLoaderCompletionStatus& status =
+      loader_pair.client->completion_status();
   ASSERT_EQ(status.error_code, net::OK);
   ASSERT_TRUE(status.exists_in_memory_cache);
 
@@ -838,9 +840,9 @@
   // Check whether the cached response has `Cache-Control: max-age=120` as the
   // original response had.
   bool has_expected_header = false;
-  for (const auto& pair : devtools_observer.response_headers()) {
-    if (base::EqualsCaseInsensitiveASCII(pair->key, "cache-control") &&
-        pair->value == "max-age=120") {
+  for (const auto& header_pair : devtools_observer.response_headers()) {
+    if (base::EqualsCaseInsensitiveASCII(header_pair->key, "cache-control") &&
+        header_pair->value == "max-age=120") {
       has_expected_header = true;
       break;
     }
diff --git a/services/network/network_service_memory_cache_url_loader.cc b/services/network/network_service_memory_cache_url_loader.cc
index 409f284..670d768 100644
--- a/services/network/network_service_memory_cache_url_loader.cc
+++ b/services/network/network_service_memory_cache_url_loader.cc
@@ -86,7 +86,7 @@
 
   // Start sending the response.
   client_->OnReceiveResponse(std::move(response_head),
-                             std::move(consumer_handle));
+                             std::move(consumer_handle), absl::nullopt);
 
   // Set up data pipe producer.
   producer_handle_watcher_ = std::make_unique<mojo::SimpleWatcher>(
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc
index b807b5c..6c28e9d 100644
--- a/services/network/network_service_network_delegate.cc
+++ b/services/network/network_service_network_delegate.cc
@@ -10,6 +10,7 @@
 #include "base/debug/dump_without_crashing.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/types/optional_util.h"
 #include "build/build_config.h"
 #include "components/domain_reliability/monitor.h"
 #include "net/base/features.h"
@@ -192,8 +193,7 @@
            ->cookie_settings()
            .AnnotateAndMoveUserBlockedCookies(
                request.url(), request.site_for_cookies(),
-               base::OptionalOrNullptr(
-                   request.isolation_info().top_frame_origin()),
+               base::OptionalToPtr(request.isolation_info().top_frame_origin()),
                maybe_included_cookies, excluded_cookies)) {
     // CookieSettings has already moved and annotated the cookies.
     return false;
diff --git a/services/network/public/cpp/empty_url_loader_client.cc b/services/network/public/cpp/empty_url_loader_client.cc
index e4f6801..b60ca529 100644
--- a/services/network/public/cpp/empty_url_loader_client.cc
+++ b/services/network/public/cpp/empty_url_loader_client.cc
@@ -65,7 +65,8 @@
 
 void EmptyURLLoaderClient::OnReceiveResponse(
     const mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   if (!body)
     return;
 
@@ -86,8 +87,6 @@
   std::move(callback).Run();
 }
 
-void EmptyURLLoaderClient::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {}
-
 void EmptyURLLoaderClient::OnTransferSizeUpdated(int32_t transfer_size_diff) {}
 
 void EmptyURLLoaderClient::OnComplete(const URLLoaderCompletionStatus& status) {
diff --git a/services/network/public/cpp/empty_url_loader_client.h b/services/network/public/cpp/empty_url_loader_client.h
index eaea259f..4efc4a8 100644
--- a/services/network/public/cpp/empty_url_loader_client.h
+++ b/services/network/public/cpp/empty_url_loader_client.h
@@ -38,14 +38,15 @@
 
   // mojom::URLLoaderClient overrides:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const URLLoaderCompletionStatus& status) override;
 
diff --git a/services/network/public/cpp/empty_url_loader_client_unittest.cc b/services/network/public/cpp/empty_url_loader_client_unittest.cc
index 3d4475b..6fa898e 100644
--- a/services/network/public/cpp/empty_url_loader_client_unittest.cc
+++ b/services/network/public/cpp/empty_url_loader_client_unittest.cc
@@ -39,7 +39,7 @@
 
   // Upcasting to mojom::URLLoaderClient to access mojom methods.
   mojom::URLLoaderClient* client = empty_client.get();
-  client->OnReceiveResponse(nullptr, std::move(consumer_handle));
+  client->OnReceiveResponse(nullptr, std::move(consumer_handle), absl::nullopt);
   client->OnComplete(URLLoaderCompletionStatus(net::OK));
 
   EXPECT_TRUE(mojo::BlockingCopyFromString(body, producer_handle));
diff --git a/services/network/public/cpp/first_party_sets_mojom_traits.cc b/services/network/public/cpp/first_party_sets_mojom_traits.cc
index cbc0fe1..9840e915 100644
--- a/services/network/public/cpp/first_party_sets_mojom_traits.cc
+++ b/services/network/public/cpp/first_party_sets_mojom_traits.cc
@@ -5,6 +5,7 @@
 #include "services/network/public/cpp/first_party_sets_mojom_traits.h"
 
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "mojo/public/cpp/bindings/enum_traits.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/first_party_set_entry.h"
@@ -128,8 +129,8 @@
     return false;
 
   *out_metadata =
-      net::FirstPartySetMetadata(context, base::OptionalOrNullptr(frame_entry),
-                                 base::OptionalOrNullptr(top_frame_entry));
+      net::FirstPartySetMetadata(context, base::OptionalToPtr(frame_entry),
+                                 base::OptionalToPtr(top_frame_entry));
 
   return true;
 }
diff --git a/services/network/public/cpp/initiator_lock_compatibility.cc b/services/network/public/cpp/initiator_lock_compatibility.cc
index 920efec..146798a 100644
--- a/services/network/public/cpp/initiator_lock_compatibility.cc
+++ b/services/network/public/cpp/initiator_lock_compatibility.cc
@@ -8,6 +8,7 @@
 
 #include "base/containers/flat_set.h"
 #include "base/stl_util.h"
+#include "base/types/optional_util.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -59,9 +60,9 @@
 ScopedRequestInitiatorOriginLockCrashKey::
     ScopedRequestInitiatorOriginLockCrashKey(
         const absl::optional<url::Origin>& request_initiator_origin_lock)
-    : ScopedOriginCrashKey(
-          GetRequestInitiatorOriginLockCrashKey(),
-          base::OptionalOrNullptr(request_initiator_origin_lock)) {}
+    : ScopedOriginCrashKey(GetRequestInitiatorOriginLockCrashKey(),
+                           base::OptionalToPtr(request_initiator_origin_lock)) {
+}
 
 ScopedRequestInitiatorOriginLockCrashKey::
     ~ScopedRequestInitiatorOriginLockCrashKey() = default;
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index 3d34279..cda43d3 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -6,6 +6,7 @@
 
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/types/optional_util.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "net/base/load_flags.h"
 #include "net/log/net_log_source.h"
@@ -304,7 +305,7 @@
     const network::ResourceRequest& request)
     : url_(GetRequestUrlCrashKey(), request.url.possibly_invalid_spec()),
       request_initiator_(GetRequestInitiatorCrashKey(),
-                         base::OptionalOrNullptr(request.request_initiator)),
+                         base::OptionalToPtr(request.request_initiator)),
       resource_type_(GetRequestResourceTypeCrashKey(),
                      base::NumberToString(request.resource_type)) {}
 
diff --git a/services/network/public/cpp/simple_url_loader.cc b/services/network/public/cpp/simple_url_loader.cc
index 6911946..9718cfc 100644
--- a/services/network/public/cpp/simple_url_loader.cc
+++ b/services/network/public/cpp/simple_url_loader.cc
@@ -342,11 +342,12 @@
 
   // mojom::URLLoaderClient implementation;
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          mojom::URLResponseHeadPtr response_head) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
@@ -1720,7 +1721,8 @@
 
 void SimpleURLLoaderImpl::OnReceiveResponse(
     mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (request_state_->response_info) {
     // The final headers have already been received, so the URLLoader is
@@ -1801,10 +1803,6 @@
                               {} /* new_url */);
 }
 
-void SimpleURLLoaderImpl::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  // Ignored.
-}
-
 void SimpleURLLoaderImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {}
 
 void SimpleURLLoaderImpl::OnUploadProgress(
diff --git a/services/network/public/cpp/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc
index becf296..394c8d1e 100644
--- a/services/network/public/cpp/simple_url_loader_unittest.cc
+++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -2103,7 +2103,7 @@
           ASSERT_EQ(mojo::CreateDataPipe(1024, body_stream_, consumer_handle),
                     MOJO_RESULT_OK);
           client_->OnReceiveResponse(std::move(response_info),
-                                     std::move(consumer_handle));
+                                     std::move(consumer_handle), absl::nullopt);
           break;
         }
         case TestLoaderEvent::kReceived401Response: {
@@ -2116,7 +2116,7 @@
           ASSERT_EQ(mojo::CreateDataPipe(1024, body_stream_, consumer_handle),
                     MOJO_RESULT_OK);
           client_->OnReceiveResponse(std::move(response_info),
-                                     std::move(consumer_handle));
+                                     std::move(consumer_handle), absl::nullopt);
           break;
         }
         case TestLoaderEvent::kReceived501Response: {
@@ -2129,7 +2129,7 @@
           ASSERT_EQ(mojo::CreateDataPipe(1024, body_stream_, consumer_handle),
                     MOJO_RESULT_OK);
           client_->OnReceiveResponse(std::move(response_info),
-                                     std::move(consumer_handle));
+                                     std::move(consumer_handle), absl::nullopt);
           break;
         }
         case TestLoaderEvent::kReceivedResponseNoData: {
@@ -2139,7 +2139,8 @@
               base::MakeRefCounted<net::HttpResponseHeaders>(
                   net::HttpUtil::AssembleRawHeaders(headers));
           client_->OnReceiveResponse(std::move(response_info),
-                                     mojo::ScopedDataPipeConsumerHandle());
+                                     mojo::ScopedDataPipeConsumerHandle(),
+                                     absl::nullopt);
           break;
         }
         case TestLoaderEvent::kBodyDataRead: {
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
index ce31778..e343ba74 100644
--- a/services/network/public/mojom/BUILD.gn
+++ b/services/network/public/mojom/BUILD.gn
@@ -988,6 +988,7 @@
     "//services/proxy_resolver/public/mojom",
     "//url/mojom:url_mojom_gurl",
     "//url/mojom:url_mojom_origin",
+    "//url/mojom:url_mojom_scheme_host_port",
   ]
 
   if (is_win) {
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom
index 7ca8f82..675bcc1 100644
--- a/services/network/public/mojom/host_resolver.mojom
+++ b/services/network/public/mojom/host_resolver.mojom
@@ -11,6 +11,7 @@
 import "services/network/public/mojom/network_isolation_key.mojom";
 import "services/network/public/mojom/network_param.mojom";
 import "services/network/public/mojom/request_priority.mojom";
+import "url/mojom/scheme_host_port.mojom";
 
 struct DnsOverHttpsServerConfig {
   string server_template;
@@ -48,6 +49,12 @@
   // not exposed via Mojo.
 };
 
+// The target host of ResolveHost method.
+union HostResolverHost {
+  url.mojom.SchemeHostPort scheme_host_port;
+  HostPortPair host_port_pair;
+};
+
 // Overridable DNS configuration values for host resolution. All fields default
 // to a non-overriding state where the relevant value will be used from system
 // DNS configuration.
@@ -286,15 +293,15 @@
 interface HostResolver {
   // Resolves the given hostname (or IP address literal). Results are a network
   // error code, and on success (network error code OK), an AddressList. All
-  // results are sent via the passed |response_client|.
+  // results are sent via the passed `response_client`.
   //
-  // |network_isolation_key| specifies what NetworkIsolationKey to use as an
+  // `network_isolation_key` specifies what NetworkIsolationKey to use as an
   // index into the host cache. This both allows a URLLoader created with the
   // same NetworkIsolationKey to access the host cache entry populated by a
   // call to the HostResolver, and prevents the result from being leaked to
   // URLLoaders made using a different NetworkIsolationKey.
   //
-  // Additional optional parameters may be set using |optional_parameters|. If
+  // Additional optional parameters may be set using `optional_parameters`. If
   // unset, reasonable defaults will be used, equivalent to using a
   // ResolveHostParameters struct without changing any fields from their default
   // values.
@@ -304,8 +311,17 @@
   //
   // All outstanding requests are cancelled if the HostResolver or parent
   // NetworkContext are destroyed. Such requests will receive ERR_FAILED via
-  // |response_client|.
-  ResolveHost(HostPortPair host,
+  // `response_client`.
+  //
+  // When `host` is a SchemeHostPort, behaves under the assumption that the
+  // resolution is being done for the purpose of making a connection with the
+  // specified scheme to the specified host and port. This could result in
+  // scheme-specific DNS queries, e.g. for HTTPS resource records, and special
+  // errors if DNS indicates a connection should not be made using the
+  // specified scheme, e.g. ERR_DNS_NAME_HTTPS_ONLY indicates that a connection
+  // should not be made without first redirecting an http or ws request to an
+  // https or wss request.
+  ResolveHost(HostResolverHost host,
               NetworkIsolationKey network_isolation_key,
               ResolveHostParameters? optional_parameters,
               pending_remote<ResolveHostClient> response_client);
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index d911012..42086b641 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -1319,8 +1319,17 @@
   // HostResolver::ResolveHost.
   //
   // All outstanding requests are cancelled if the NetworkContext is destroyed.
-  // Such requests will receive ERR_FAILED via |response_client|.
-  ResolveHost(HostPortPair host,
+  // Such requests will receive ERR_FAILED via `response_client`.
+  //
+  // When `host` is a SchemeHostPort, behaves under the assumption that the
+  // resolution is being done for the purpose of making a connection with the
+  // specified scheme to the specified host and port. This could result in
+  // scheme-specific DNS queries, e.g. for HTTPS resource records, and special
+  // errors if DNS indicates a connection should not be made using the
+  // specified scheme, e.g. ERR_DNS_NAME_HTTPS_ONLY indicates that a connection
+  // should not be made without first redirecting an http or ws request to an
+  // https or wss request.
+  ResolveHost(HostResolverHost host,
               NetworkIsolationKey network_isolation_key,
               ResolveHostParameters? optional_parameters,
               pending_remote<ResolveHostClient> response_client);
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom
index f8281611..8632424 100644
--- a/services/network/public/mojom/url_loader.mojom
+++ b/services/network/public/mojom/url_loader.mojom
@@ -99,8 +99,11 @@
   // Called when the response head is received.
   // The loader is expected to close its end of the pipe after finishing
   // writing the body, so that the client knows when it is done reading.
+  // Optionally, the response can contain cached metadata, such as a V8 code
+  // cache.
   OnReceiveResponse(URLResponseHead head,
-                    handle<data_pipe_consumer>? body);
+                    handle<data_pipe_consumer>? body,
+                    mojo_base.mojom.BigBuffer? cached_metadata);
 
   // Called when the request has been redirected. The receiver is expected to
   // call FollowRedirect or cancel the request.
@@ -112,9 +115,6 @@
   // ready to receive the next upload progress.
   OnUploadProgress(int64 current_position, int64 total_size) => ();
 
-  // Called when cached metadata from a resource request is ready.
-  OnReceiveCachedMetadata(mojo_base.mojom.BigBuffer data);
-
   // Called when the transfer size is updated. This is only called if
   // |report_raw_headers| is set or the renderer has permission to read the
   // request. The transfer size is the length of the response (including both
diff --git a/services/network/resolve_host_request.cc b/services/network/resolve_host_request.cc
index eac0d59cb..e6afb41d1 100644
--- a/services/network/resolve_host_request.cc
+++ b/services/network/resolve_host_request.cc
@@ -18,7 +18,7 @@
 
 ResolveHostRequest::ResolveHostRequest(
     net::HostResolver* resolver,
-    const net::HostPortPair& host,
+    mojom::HostResolverHostPtr host,
     const net::NetworkIsolationKey& network_isolation_key,
     const absl::optional<net::HostResolver::ResolveHostParameters>&
         optional_parameters,
@@ -26,11 +26,19 @@
   DCHECK(resolver);
   DCHECK(net_log);
 
-  internal_request_ = resolver->CreateRequest(
-      host, network_isolation_key,
-      net::NetLogWithSource::Make(
-          net_log, net::NetLogSourceType::NETWORK_SERVICE_HOST_RESOLVER),
-      optional_parameters);
+  if (host->is_host_port_pair()) {
+    internal_request_ = resolver->CreateRequest(
+        host->get_host_port_pair(), network_isolation_key,
+        net::NetLogWithSource::Make(
+            net_log, net::NetLogSourceType::NETWORK_SERVICE_HOST_RESOLVER),
+        optional_parameters);
+  } else {
+    internal_request_ = resolver->CreateRequest(
+        host->get_scheme_host_port(), network_isolation_key,
+        net::NetLogWithSource::Make(
+            net_log, net::NetLogSourceType::NETWORK_SERVICE_HOST_RESOLVER),
+        optional_parameters);
+  }
 }
 
 ResolveHostRequest::~ResolveHostRequest() {
diff --git a/services/network/resolve_host_request.h b/services/network/resolve_host_request.h
index eb7bb04..44c7eda 100644
--- a/services/network/resolve_host_request.h
+++ b/services/network/resolve_host_request.h
@@ -18,7 +18,6 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
-class HostPortPair;
 class NetLog;
 class NetworkIsolationKey;
 }  // namespace net
@@ -32,7 +31,7 @@
  public:
   ResolveHostRequest(
       net::HostResolver* resolver,
-      const net::HostPortPair& host,
+      mojom::HostResolverHostPtr host,
       const net::NetworkIsolationKey& network_isolation_key,
       const absl::optional<net::HostResolver::ResolveHostParameters>&
           optional_parameters,
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc
index b98d114..eb22528 100644
--- a/services/network/restricted_cookie_manager.cc
+++ b/services/network/restricted_cookie_manager.cc
@@ -19,6 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/types/optional_util.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/features.h"
@@ -342,7 +343,7 @@
       first_party_set_metadata_(std::move(first_party_set_metadata)),
       cookie_partition_key_(net::CookiePartitionKey::FromNetworkIsolationKey(
           isolation_info.network_isolation_key(),
-          base::OptionalOrNullptr(
+          base::OptionalToPtr(
               first_party_set_metadata_.top_frame_entry().has_value()
                   ? absl::make_optional(
                         first_party_set_metadata_.top_frame_entry()->primary())
@@ -385,7 +386,7 @@
   first_party_set_metadata_ = std::move(first_party_set_metadata);
   cookie_partition_key_ = net::CookiePartitionKey::FromNetworkIsolationKey(
       isolation_info_.network_isolation_key(),
-      base::OptionalOrNullptr(
+      base::OptionalToPtr(
           first_party_set_metadata_.top_frame_entry().has_value()
               ? absl::make_optional(
                     first_party_set_metadata_.top_frame_entry()->primary())
diff --git a/services/network/test/test_dns_util.cc b/services/network/test/test_dns_util.cc
index ae819fd..6b11781 100644
--- a/services/network/test/test_dns_util.cc
+++ b/services/network/test/test_dns_util.cc
@@ -78,8 +78,11 @@
     const net::NetworkIsolationKey& network_isolation_key) {
   mojo::PendingRemote<network::mojom::ResolveHostClient> client;
   DnsLookupClient dns_lookup_client(client.InitWithNewPipeAndPassReceiver());
-  network_context->ResolveHost(host_port_pair, network_isolation_key,
-                               std::move(params), std::move(client));
+  // TODO(crbug.com/1355169): Consider passing a SchemeHostPort to trigger HTTPS
+  // DNS resource record query.
+  network_context->ResolveHost(
+      network::mojom::HostResolverHost::NewHostPortPair(host_port_pair),
+      network_isolation_key, std::move(params), std::move(client));
   return dns_lookup_client.WaitForResult();
 }
 
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
index 538e9787..1c56db57 100644
--- a/services/network/test/test_network_context.h
+++ b/services/network/test/test_network_context.h
@@ -213,7 +213,7 @@
   void CreateNetLogExporter(
       mojo::PendingReceiver<mojom::NetLogExporter> receiver) override {}
   void ResolveHost(
-      const net::HostPortPair& host,
+      mojom::HostResolverHostPtr host,
       const net::NetworkIsolationKey& network_isolation_key,
       mojom::ResolveHostParametersPtr optional_parameters,
       mojo::PendingRemote<mojom::ResolveHostClient> response_client) override {}
diff --git a/services/network/test/test_url_loader_client.cc b/services/network/test/test_url_loader_client.cc
index fe980a8..e6c4e7f 100644
--- a/services/network/test/test_url_loader_client.cc
+++ b/services/network/test/test_url_loader_client.cc
@@ -19,7 +19,6 @@
 void TestURLLoaderClient::OnReceiveEarlyHints(
     network::mojom::EarlyHintsPtr early_hints) {
   EXPECT_FALSE(has_received_response_);
-  EXPECT_FALSE(has_received_cached_metadata_);
   EXPECT_FALSE(has_received_completion_);
   has_received_early_hints_ = true;
   early_hints_.push_back(std::move(early_hints));
@@ -27,11 +26,17 @@
 
 void TestURLLoaderClient::OnReceiveResponse(
     mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   EXPECT_FALSE(has_received_response_);
   EXPECT_FALSE(has_received_completion_);
   has_received_response_ = true;
   response_head_ = std::move(response_head);
+  if (cached_metadata) {
+    cached_metadata_ =
+        std::string(reinterpret_cast<const char*>(cached_metadata->data()),
+                    cached_metadata->size());
+  }
   if (quit_closure_for_on_receive_response_)
     std::move(quit_closure_for_on_receive_response_).Run();
 
@@ -43,7 +48,6 @@
 void TestURLLoaderClient::OnReceiveRedirect(
     const net::RedirectInfo& redirect_info,
     mojom::URLResponseHeadPtr response_head) {
-  EXPECT_FALSE(has_received_cached_metadata_);
   EXPECT_FALSE(response_body_.is_valid());
   EXPECT_FALSE(has_received_response_);
   // Use ClearHasReceivedRedirect to accept more redirects.
@@ -56,16 +60,6 @@
     std::move(quit_closure_for_on_receive_redirect_).Run();
 }
 
-void TestURLLoaderClient::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  EXPECT_FALSE(has_received_cached_metadata_);
-  EXPECT_FALSE(has_received_completion_);
-  has_received_cached_metadata_ = true;
-  cached_metadata_ =
-      std::string(reinterpret_cast<const char*>(data.data()), data.size());
-  if (quit_closure_for_on_receive_cached_metadata_)
-    std::move(quit_closure_for_on_receive_cached_metadata_).Run();
-}
-
 void TestURLLoaderClient::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   EXPECT_FALSE(has_received_completion_);
   EXPECT_GT(transfer_size_diff, 0);
@@ -132,14 +126,6 @@
   run_loop.Run();
 }
 
-void TestURLLoaderClient::RunUntilCachedMetadataReceived() {
-  if (has_received_cached_metadata_)
-    return;
-  base::RunLoop run_loop;
-  quit_closure_for_on_receive_cached_metadata_ = run_loop.QuitClosure();
-  run_loop.Run();
-}
-
 void TestURLLoaderClient::RunUntilResponseBodyArrived() {
   if (response_body_.is_valid())
     return;
diff --git a/services/network/test/test_url_loader_client.h b/services/network/test/test_url_loader_client.h
index daf98496..395f22e 100644
--- a/services/network/test/test_url_loader_client.h
+++ b/services/network/test/test_url_loader_client.h
@@ -38,11 +38,12 @@
   ~TestURLLoaderClient() override;
 
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          mojom::URLResponseHeadPtr response_head) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
@@ -55,9 +56,6 @@
   bool has_received_upload_progress() const {
     return has_received_upload_progress_;
   }
-  bool has_received_cached_metadata() const {
-    return has_received_cached_metadata_;
-  }
   bool has_received_completion() const { return has_received_completion_; }
   bool has_received_disconnect() const { return has_received_disconnect_; }
   const mojom::URLResponseHeadPtr& response_head() const {
@@ -68,7 +66,9 @@
     return response_head_->ssl_info;
   }
   const net::RedirectInfo& redirect_info() const { return redirect_info_; }
-  const std::string& cached_metadata() const { return cached_metadata_; }
+  const absl::optional<std::string>& cached_metadata() const {
+    return cached_metadata_;
+  }
   mojo::DataPipeConsumerHandle response_body() { return response_body_.get(); }
   mojo::ScopedDataPipeConsumerHandle response_body_release() {
     return std::move(response_body_);
@@ -95,7 +95,6 @@
 
   void RunUntilResponseReceived();
   void RunUntilRedirectReceived();
-  void RunUntilCachedMetadataReceived();
   void RunUntilResponseBodyArrived();
   void RunUntilComplete();
   void RunUntilDisconnect();
@@ -107,20 +106,18 @@
   mojo::Receiver<mojom::URLLoaderClient> receiver_{this};
   mojom::URLResponseHeadPtr response_head_;
   net::RedirectInfo redirect_info_;
-  std::string cached_metadata_;
+  absl::optional<std::string> cached_metadata_;
   mojo::ScopedDataPipeConsumerHandle response_body_;
   URLLoaderCompletionStatus completion_status_;
   bool has_received_early_hints_ = false;
   bool has_received_response_ = false;
   bool has_received_redirect_ = false;
   bool has_received_upload_progress_ = false;
-  bool has_received_cached_metadata_ = false;
   bool has_received_completion_ = false;
   bool has_received_disconnect_ = false;
 
   base::OnceClosure quit_closure_for_on_receive_response_;
   base::OnceClosure quit_closure_for_on_receive_redirect_;
-  base::OnceClosure quit_closure_for_on_receive_cached_metadata_;
   base::OnceClosure quit_closure_for_on_start_loading_response_body_;
   base::OnceClosure quit_closure_for_on_complete_;
   base::OnceClosure quit_closure_for_disconnect_;
diff --git a/services/network/test/test_url_loader_factory.cc b/services/network/test/test_url_loader_factory.cc
index 0ed3d025..6926d45 100644
--- a/services/network/test/test_url_loader_factory.cc
+++ b/services/network/test/test_url_loader_factory.cc
@@ -278,7 +278,7 @@
 
   if ((response_flags & kSendHeadersOnNetworkError) ||
       status.error_code == net::OK) {
-    client->OnReceiveResponse(std::move(head), std::move(body));
+    client->OnReceiveResponse(std::move(head), std::move(body), absl::nullopt);
   }
 
   client->OnComplete(status);
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 2e8a874..292ef6b 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -2159,8 +2159,8 @@
   DCHECK_EQ(emitted_devtools_raw_request_, emitted_devtools_raw_response_);
   response_->emitted_extra_info = emitted_devtools_raw_request_;
 
-  url_loader_client_.Get()->OnReceiveResponse(response_->Clone(),
-                                              std::move(consumer_handle_));
+  url_loader_client_.Get()->OnReceiveResponse(
+      response_->Clone(), std::move(consumer_handle_), absl::nullopt);
 }
 
 void URLLoader::CompletePendingWrite(bool success) {
@@ -2451,8 +2451,8 @@
   }
   producer_handle.reset();
 
-  url_loader_client_.Get()->OnReceiveResponse(response_->Clone(),
-                                              std::move(consumer_handle));
+  url_loader_client_.Get()->OnReceiveResponse(
+      response_->Clone(), std::move(consumer_handle), absl::nullopt);
 
   // Tell the real URLLoaderClient that the response has been completed.
   if (corb_detachable_) {
diff --git a/storage/browser/blob/blob_url_loader.cc b/storage/browser/blob/blob_url_loader.cc
index c69e62bfd..22ec286 100644
--- a/storage/browser/blob/blob_url_loader.cc
+++ b/storage/browser/blob/blob_url_loader.cc
@@ -232,11 +232,9 @@
   // services/network/url_loader.h
 
   client_->OnReceiveResponse(std::move(response),
-                             std::move(response_body_consumer_handle_));
+                             std::move(response_body_consumer_handle_),
+                             std::move(metadata));
   sent_headers_ = true;
-
-  if (metadata.has_value())
-    client_->OnReceiveCachedMetadata(std::move(metadata.value()));
 }
 
 }  // namespace storage
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index dc257bc..0cdc2084 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1462,7 +1462,7 @@
           "--board=jacuzzi",
           "--flash"
         ],
-        "experiment_percentage": 5,
+        "experiment_percentage": 50,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -3541,6 +3541,33 @@
       },
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter",
+          "--lacros-chrome-path=lacros_clang_x64",
+          "--test-launcher-jobs=3"
+        ],
+        "ci_only": true,
+        "experiment_percentage": 1,
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "browser_tests_require_lacros experiment",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
+        "args": [
           "--gtest_filter=-*UsingRealWebcam*"
         ],
         "isolate_profile_data": true,
@@ -5677,21 +5704,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -5704,7 +5731,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -5741,21 +5768,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -5768,26 +5795,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -5800,7 +5827,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
@@ -5845,21 +5872,21 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -5871,7 +5898,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -5907,21 +5934,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -5933,26 +5960,26 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -5964,7 +5991,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "args": [
@@ -5991,21 +6018,21 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -6017,7 +6044,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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -6053,21 +6080,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -6079,26 +6106,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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -6110,7 +6137,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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9fe0b42..07e06e2 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -99314,21 +99314,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -99336,7 +99336,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -99368,21 +99368,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -99390,26 +99390,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -99417,7 +99417,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
@@ -99452,28 +99452,28 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -99504,54 +99504,54 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "args": [
@@ -99573,28 +99573,28 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -99625,54 +99625,54 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
@@ -100908,20 +100908,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -100935,7 +100935,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -100972,20 +100972,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -100999,25 +100999,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -101031,7 +101031,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "merge": {
@@ -101076,20 +101076,20 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -101102,7 +101102,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -101138,20 +101138,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -101164,25 +101164,25 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5263.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -101195,7 +101195,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "args": [
@@ -101222,20 +101222,20 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -101248,7 +101248,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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -101284,20 +101284,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -101310,25 +101310,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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -101341,7 +101341,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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "merge": {
@@ -102752,20 +102752,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -102779,7 +102779,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -102816,20 +102816,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -102843,25 +102843,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -102875,7 +102875,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "merge": {
@@ -102920,20 +102920,20 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -102946,7 +102946,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -102982,20 +102982,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -103008,25 +103008,25 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5263.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -103039,7 +103039,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "args": [
@@ -103066,20 +103066,20 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -103092,7 +103092,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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -103128,20 +103128,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -103154,25 +103154,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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -103185,7 +103185,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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "merge": {
@@ -103901,20 +103901,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -103927,7 +103927,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -103963,20 +103963,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -103989,25 +103989,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -104020,7 +104020,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 878880a..986bb247 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -20767,21 +20767,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_v104.0.5112.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -20794,7 +20794,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -20831,21 +20831,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_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -20858,26 +20858,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -20890,7 +20890,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
@@ -20935,21 +20935,21 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -20961,7 +20961,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -20997,21 +20997,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -21023,26 +21023,26 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -21054,7 +21054,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "args": [
@@ -21081,21 +21081,21 @@
       {
         "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.105/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/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.105",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.110",
         "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.105",
-              "revision": "version:104.0.5112.105"
+              "location": "lacros_version_skew_tests_v104.0.5112.110",
+              "revision": "version:104.0.5112.110"
             }
           ],
           "dimension_sets": [
@@ -21107,7 +21107,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.105"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.110"
       },
       {
         "args": [
@@ -21143,21 +21143,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/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 106.0.5249.7",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.12",
         "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_v106.0.5249.7",
-              "revision": "version:106.0.5249.7"
+              "location": "lacros_version_skew_tests_v106.0.5249.12",
+              "revision": "version:106.0.5249.12"
             }
           ],
           "dimension_sets": [
@@ -21169,26 +21169,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 106.0.5249.7"
+        "variant_id": "Lacros version skew testing ash 106.0.5249.12"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.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 107.0.5263.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5270.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_v107.0.5263.0",
-              "revision": "version:107.0.5263.0"
+              "location": "lacros_version_skew_tests_v107.0.5270.0",
+              "revision": "version:107.0.5270.0"
             }
           ],
           "dimension_sets": [
@@ -21200,7 +21200,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 107.0.5263.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5270.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py
index 89f3060..ffb6a2d 100755
--- a/testing/buildbot/generate_buildbot_json.py
+++ b/testing/buildbot/generate_buildbot_json.py
@@ -1215,10 +1215,10 @@
                                    cloned_variant.get('mixins', []) + mixins)
 
         description = []
-        if piece := cloned_config.get('description'):
-          description.append(piece)
-        if piece := cloned_variant.get('description'):
-          description.append(piece)
+        if cloned_config.get('description'):
+          description.append(cloned_config.get('description'))
+        if cloned_variant.get('description'):
+          description.append(cloned_variant.get('description'))
         if description:
           cloned_config['description'] = '\n'.join(description)
         basic_swarming_def = cloned_config.get('swarming', {})
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 0a5aa6a00..baf121ab1 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2497,7 +2497,7 @@
   'lacros_all_tast_tests jacuzzi': {
     'modifications': {
       'lacros-arm-generic-rel': {
-        'experiment_percentage': 5,
+        'experiment_percentage': 50,
       },
     },
   },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 849e473..27c7b844 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3753,6 +3753,21 @@
           'shards': 4,
         },
       },
+      # TODO(crbug.com/1357218): Experiment whether lowering the parallel jobs can improve the success rate.
+      'browser_tests_require_lacros experiment': {
+        'name': 'browser_tests_require_lacros experiment',
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter',
+          '--lacros-chrome-path=lacros_clang_x64',
+          '--test-launcher-jobs=3',
+        ],
+        'test': 'browser_tests',
+        'swarming': {
+          'shards': 4,
+        },
+        'ci_only': True,
+        'experiment_percentage': 1,
+      },
     },
 
     'linux_chromeos_lacros_gtests': {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index e445894..7ff14f7 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,30 +22,30 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5263.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5270.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 107.0.5263.0',
+    'identifier': 'Lacros version skew testing ash 107.0.5270.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v107.0.5263.0',
-          'revision': 'version:107.0.5263.0',
+          'location': 'lacros_version_skew_tests_v107.0.5270.0',
+          'revision': 'version:107.0.5270.0',
         },
       ],
     },
   },
   'LACROS_VERSION_SKEW_DEV': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.12/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 106.0.5249.7',
+    'identifier': 'Lacros version skew testing ash 106.0.5249.12',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v106.0.5249.7',
-          'revision': 'version:106.0.5249.7',
+          'location': 'lacros_version_skew_tests_v106.0.5249.12',
+          'revision': 'version:106.0.5249.12',
         },
       ],
     },
@@ -67,15 +67,15 @@
   },
   'LACROS_VERSION_SKEW_STABLE': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.105/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.110/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 104.0.5112.105',
+    'identifier': 'Lacros version skew testing ash 104.0.5112.110',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v104.0.5112.105',
-          'revision': 'version:104.0.5112.105',
+          'location': 'lacros_version_skew_tests_v104.0.5112.110',
+          'revision': 'version:104.0.5112.110',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 3b2262f..6b19667 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2455,7 +2455,8 @@
                 "windows",
                 "mac",
                 "chromeos",
-                "chromeos_lacros"
+                "chromeos_lacros",
+                "linux"
             ],
             "experiments": [
                 {
@@ -2582,6 +2583,27 @@
             ]
         }
     ],
+    "ChromeAppsDeprecation": [
+        {
+            "platforms": [
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20220824",
+                    "params": {
+                        "allow_list": "alhngdkjgnedakdlnamimgfihgkmenbh"
+                    },
+                    "enable_features": [
+                        "ChromeAppsDeprecation",
+                        "KeepForceInstalledPreinstalledApps"
+                    ]
+                }
+            ]
+        }
+    ],
     "ChromeLabs": [
         {
             "platforms": [
@@ -3161,21 +3183,6 @@
             ]
         }
     ],
-    "ContentSuggestionsUIModuleRefresh": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "ContentSuggestionsUIModuleRefresh"
-                    ]
-                }
-            ]
-        }
-    ],
     "ContextMenuGoogleLensChip": [
         {
             "platforms": [
@@ -4071,21 +4078,6 @@
             ]
         }
     ],
-    "DriveFsBidirectionalNativeMessaging": [
-        {
-            "platforms": [
-                "chromeos"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "DriveFsBidirectionalNativeMessaging"
-                    ]
-                }
-            ]
-        }
-    ],
     "EarlyExitOnNoopClassOrStyleChange": [
         {
             "platforms": [
@@ -6831,9 +6823,9 @@
             ],
             "experiments": [
                 {
-                    "name": "32KB_input_stream_20220815",
+                    "name": "4KB_input_stream_20220829",
                     "params": {
-                        "max_input_stream_bytes_available_unknown": "32768"
+                        "max_input_stream_bytes_available_unknown": "4096"
                     },
                     "enable_features": [
                         "OptimizeNetworkBuffers2"
@@ -7443,7 +7435,6 @@
         {
             "platforms": [
                 "android",
-                "android_weblayer",
                 "android_webview",
                 "chromeos",
                 "chromeos_lacros",
@@ -7453,9 +7444,10 @@
             ],
             "experiments": [
                 {
-                    "name": "FirstScriptLazy_20220609",
+                    "name": "FirstScriptLazy_20220829",
                     "params": {
-                        "compile-strategy": "first-script-lazy"
+                        "compile-strategy": "first-script-lazy",
+                        "inline-script-timeout": "5ms"
                     },
                     "enable_features": [
                         "PrecompileInlineScripts"
@@ -9153,6 +9145,24 @@
                     "enable_features": [
                         "StartSurface"
                     ]
+                },
+                {
+                    "name": "Start+ModuleRefresh",
+                    "params": {
+                        "ReturnToStartSurfaceInactiveDurationInSeconds": "21600",
+                        "show_return_to_recent_tab": "true",
+                        "shrink_logo": "true"
+                    },
+                    "enable_features": [
+                        "ContentSuggestionsUIModuleRefresh",
+                        "StartSurface"
+                    ]
+                },
+                {
+                    "name": "ModuleRefresh",
+                    "enable_features": [
+                        "ContentSuggestionsUIModuleRefresh"
+                    ]
                 }
             ]
         }
diff --git a/third_party/androidx/bisect_androidx_pinpoint.sh b/third_party/androidx/bisect_androidx_pinpoint.sh
index bac1d60f..5e6f709 100755
--- a/third_party/androidx/bisect_androidx_pinpoint.sh
+++ b/third_party/androidx/bisect_androidx_pinpoint.sh
@@ -18,7 +18,7 @@
 PERF_BENCHMARK="startup.mobile" \
 PERF_BOT="android-pixel4-perf" \
 PERF_STORY="cct_coldish_bbc" \
-PERF_METRIC="messageloop_start_time" '$0 "$@"
+PERF_METRIC="messageloop_start_time" $0 "$@"
 fi
 
 # Determine Chromium src path based on script location.
diff --git a/third_party/blink/common/loader/mime_sniffing_throttle_unittest.cc b/third_party/blink/common/loader/mime_sniffing_throttle_unittest.cc
index f5ab67b7..3e493ef 100644
--- a/third_party/blink/common/loader/mime_sniffing_throttle_unittest.cc
+++ b/third_party/blink/common/loader/mime_sniffing_throttle_unittest.cc
@@ -88,7 +88,7 @@
     is_resumed_ = true;
     // Resume from OnReceiveResponse() with a customized response header.
     destination_loader_client()->OnReceiveResponse(
-        std::move(updated_response_head_), std::move(body_));
+        std::move(updated_response_head_), std::move(body_), absl::nullopt);
   }
 
   void SetPriority(net::RequestPriority priority) override { NOTIMPLEMENTED(); }
diff --git a/third_party/blink/common/loader/mime_sniffing_url_loader.cc b/third_party/blink/common/loader/mime_sniffing_url_loader.cc
index 085d819f..6be5ce5d 100644
--- a/third_party/blink/common/loader/mime_sniffing_url_loader.cc
+++ b/third_party/blink/common/loader/mime_sniffing_url_loader.cc
@@ -94,7 +94,8 @@
 
 void MimeSniffingURLLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // OnReceiveResponse() shouldn't be called because MimeSniffingURLLoader is
   // created by MimeSniffingThrottle::WillProcessResponse(), which is equivalent
   // to OnReceiveResponse().
@@ -118,10 +119,6 @@
                                                    std::move(ack_callback));
 }
 
-void MimeSniffingURLLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  destination_url_loader_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void MimeSniffingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   destination_url_loader_client_->OnTransferSizeUpdated(transfer_size_diff);
 }
diff --git a/third_party/blink/common/loader/throttling_url_loader.cc b/third_party/blink/common/loader/throttling_url_loader.cc
index d636c50b..1b23e75 100644
--- a/third_party/blink/common/loader/throttling_url_loader.cc
+++ b/third_party/blink/common/loader/throttling_url_loader.cc
@@ -366,6 +366,7 @@
   start_info_->url_loader_factory = std::move(factory);
   start_info_->options = url_loader_options;
   body_.reset();
+  cached_metadata_.reset();
   StartNow();
 }
 
@@ -658,7 +659,8 @@
 
 void ThrottlingURLLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
   DCHECK(!loader_completed_);
   DCHECK(deferring_throttles_.empty());
@@ -666,6 +668,7 @@
                response_url_.possibly_invalid_spec());
   did_receive_response_ = true;
   body_ = std::move(body);
+  cached_metadata_ = std::move(cached_metadata);
 
   // Dispatch BeforeWillProcessResponse().
   if (!throttles_.empty()) {
@@ -719,8 +722,8 @@
     }
   }
 
-  forwarding_client_->OnReceiveResponse(std::move(response_head),
-                                        std::move(body_));
+  forwarding_client_->OnReceiveResponse(
+      std::move(response_head), std::move(body_), std::move(cached_metadata_));
 }
 
 void ThrottlingURLLoader::OnReceiveRedirect(
@@ -836,13 +839,6 @@
                                        std::move(ack_callback));
 }
 
-void ThrottlingURLLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
-  DCHECK(!loader_completed_);
-
-  forwarding_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
 void ThrottlingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
   DCHECK(!loader_completed_);
@@ -950,7 +946,8 @@
     case DEFERRED_RESPONSE: {
       client_receiver_.Resume();
       forwarding_client_->OnReceiveResponse(
-          std::move(response_info_->response_head), std::move(body_));
+          std::move(response_info_->response_head), std::move(body_),
+          std::move(cached_metadata_));
       // Note: |this| may be deleted here.
       break;
     }
diff --git a/third_party/blink/common/loader/throttling_url_loader_unittest.cc b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
index e807d3e..ead5c10 100644
--- a/third_party/blink/common/loader/throttling_url_loader_unittest.cc
+++ b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
@@ -79,7 +79,8 @@
 
   void NotifyClientOnReceiveResponse() {
     client_remote_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                      mojo::ScopedDataPipeConsumerHandle());
+                                      mojo::ScopedDataPipeConsumerHandle(),
+                                      absl::nullopt);
   }
 
   void NotifyClientOnReceiveRedirect() {
@@ -202,8 +203,10 @@
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
     on_received_response_called_++;
     if (on_received_response_callback_)
       std::move(on_received_response_callback_).Run();
@@ -218,7 +221,6 @@
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override {}
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
   void OnComplete(const network::URLLoaderCompletionStatus& status) override {
     on_complete_called_++;
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index dca977f..cbe0941 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -137,6 +137,7 @@
     "platform/modules/mediastream/web_media_stream_track.h",
     "platform/modules/mediastream/web_media_stream_video_renderer.h",
     "platform/modules/mediastream/web_platform_media_stream_source.h",
+    "platform/modules/remoteplayback/remote_playback_source.h",
     "platform/modules/remoteplayback/web_remote_playback_client.h",
     "platform/modules/service_worker/web_service_worker_error.h",
     "platform/modules/service_worker/web_service_worker_fetch_context.h",
diff --git a/third_party/blink/public/common/loader/mime_sniffing_url_loader.h b/third_party/blink/public/common/loader/mime_sniffing_url_loader.h
index ab9b6279..b2360a54 100644
--- a/third_party/blink/public/common/loader/mime_sniffing_url_loader.h
+++ b/third_party/blink/public/common/loader/mime_sniffing_url_loader.h
@@ -88,15 +88,16 @@
   // network::mojom::URLLoaderClient implementation (called from the source of
   // the response):
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/third_party/blink/public/common/loader/throttling_url_loader.h b/third_party/blink/public/common/loader/throttling_url_loader.h
index 2c40612..60c2346 100644
--- a/third_party/blink/public/common/loader/throttling_url_loader.h
+++ b/third_party/blink/public/common/loader/throttling_url_loader.h
@@ -159,15 +159,16 @@
 
   // network::mojom::URLLoaderClient implementation:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
@@ -267,6 +268,7 @@
   // Set if response is deferred.
   std::unique_ptr<ResponseInfo> response_info_;
   mojo::ScopedDataPipeConsumerHandle body_;
+  absl::optional<mojo_base::BigBuffer> cached_metadata_;
 
   struct RedirectInfo {
     RedirectInfo(const net::RedirectInfo& in_redirect_info,
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 2d89311..b210510 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3664,6 +3664,7 @@
   kDeferredShaping2ReshapedByPrinting = 4343,
   kDeferredShaping2ReshapedByScrolling = 4344,
   kLCPCandidateImageFromOriginDirtyStyle = 4345,
+  kV8TurboFanOsrCompileStarted = 4346,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/mojom/webauthn/authenticator.mojom b/third_party/blink/public/mojom/webauthn/authenticator.mojom
index abd8644c..b3673f87 100644
--- a/third_party/blink/public/mojom/webauthn/authenticator.mojom
+++ b/third_party/blink/public/mojom/webauthn/authenticator.mojom
@@ -44,6 +44,7 @@
   INVALID_ALLOW_CREDENTIALS_FOR_LARGE_BLOB,
   FAILED_TO_SAVE_CREDENTIAL_ID_FOR_PAYMENT_EXTENSION,
   REMOTE_DESKTOP_CLIENT_OVERRIDE_NOT_AUTHORIZED,
+  DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED,
 
   // ERROR_WITH_DOM_EXCEPTION_DETAILS indicates that the error will be
   // described in a `WebAuthnDOMExceptionDetails` structure.
@@ -90,6 +91,12 @@
   uint16 matcher_protection_type;
 };
 
+// The output for the `devicePubKey` extension.
+struct DevicePublicKeyResponse {
+  array<uint8> authenticator_output;
+  array<uint8> signature;
+};
+
 // The public key and attestation returned by Authenticator::MakeCredential.
 struct MakeCredentialAuthenticatorResponse {
   CommonCredentialInfo info;
@@ -144,6 +151,8 @@
   // extension output should be.
   bool echo_large_blob;
   bool supports_large_blob;
+
+  DevicePublicKeyResponse? device_public_key;
 };
 
 struct GetAssertionAuthenticatorResponse {
@@ -201,6 +210,8 @@
   // The value of the `getCredBlob` extension output, which maybe empty, or
   // null if none.
   array<uint8>? get_cred_blob;
+
+  DevicePublicKeyResponse? device_public_key;
 };
 
 // Information about the relying party. These fields take arbitrary input.
@@ -327,6 +338,11 @@
   bool same_origin_with_ancestors;
 };
 
+struct DevicePublicKeyRequest {
+  AttestationConveyancePreference attestation;
+  array<string> attestation_formats;
+};
+
 // Parameters passed into calls to GetAssertion.
 struct PublicKeyCredentialRequestOptions {
   // If true, indicates that this request should prioritize showing a UI only if
@@ -395,16 +411,10 @@
   // Indicates that a remote desktop client is making a forwarded request on
   // behalf of another origin.
   RemoteDesktopClientOverride? remote_desktop_client_override;
-};
 
-// See https://w3c.github.io/webauthn/#enumdef-attestationconveyancepreference
-enum AttestationConveyancePreference {
-  NONE,
-  INDIRECT,
-  DIRECT,
-  // A non-standard addition that we hope will become standard. This indicates
-  // that the RP desires individual attestaion from the device.
-  ENTERPRISE,
+  // If present, reflects the contents of the "devicePubKey" extension.
+  // https://github.com/w3c/webauthn/pull/1663
+  DevicePublicKeyRequest? device_public_key;
 };
 
 // https://w3c.github.io/webauthn/#enum-residentKeyRequirement
@@ -534,6 +544,20 @@
   // Indicates that a remote desktop client is making a forwarded request on
   // behalf of another origin.
   RemoteDesktopClientOverride? remote_desktop_client_override;
+
+  // If present, reflects the contents of the "devicePubKey" extension.
+  // https://github.com/w3c/webauthn/pull/1663
+  DevicePublicKeyRequest? device_public_key;
+};
+
+// See https://w3c.github.io/webauthn/#enumdef-attestationconveyancepreference
+enum AttestationConveyancePreference {
+  NONE,
+  INDIRECT,
+  DIRECT,
+  // A non-standard addition that we hope will become standard. This indicates
+  // that the RP desires individual attestation from the device.
+  ENTERPRISE,
 };
 
 enum PublicKeyCredentialType {
diff --git a/third_party/blink/public/platform/modules/remoteplayback/remote_playback_source.h b/third_party/blink/public/platform/modules/remoteplayback/remote_playback_source.h
new file mode 100644
index 0000000..afec5975
--- /dev/null
+++ b/third_party/blink/public/platform/modules/remoteplayback/remote_playback_source.h
@@ -0,0 +1,18 @@
+// 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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_REMOTEPLAYBACK_REMOTE_PLAYBACK_SOURCE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_REMOTEPLAYBACK_REMOTE_PLAYBACK_SOURCE_H_
+
+namespace blink {
+// TODO(crbug.com/1353987): Convert Url format for Android to use
+// `remote-playback:media-element?...`.
+// The scheme for RemotePlayback Urls on both Android and Desktop.
+constexpr char kRemotePlaybackPresentationUrlScheme[] = "remote-playback";
+// The format for RemotePlayback Urls on desktop.
+constexpr char kRemotePlaybackDesktopUrlFormat[] =
+    "remote-playback:media-session?tab_id=%d&video_codec=%s&audio_codec=%s";
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_REMOTEPLAYBACK_REMOTE_PLAYBACK_SOURCE_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
index 878ba4e..6aca107 100644
--- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
+++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -383,6 +383,9 @@
     case v8::Isolate::kFunctionPrototypeCaller:
       blink_feature = WebFeature::kV8FunctionPrototypeCaller;
       break;
+    case v8::Isolate::kTurboFanOsrCompileStarted:
+      blink_feature = WebFeature::kV8TurboFanOsrCompileStarted;
+      break;
 
     default:
       // This can happen if V8 has added counters that this version of Blink
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 05df7e22..0e51452 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -165,6 +165,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_inputs.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_outputs.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_outputs.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_inputs.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_inputs.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_outputs.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_outputs.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_payment_inputs.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_payment_inputs.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index bf50224..ca89d4b 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -143,6 +143,8 @@
           "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_large_blob_inputs.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_large_blob_outputs.idl",
+          "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_inputs.idl",
+          "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_outputs.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_payment_inputs.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authenticator_assertion_response.idl",
           "//third_party/blink/renderer/modules/credentialmanagement/authenticator_attestation_response.idl",
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc
index ab0763348..7cb114e0 100644
--- a/third_party/blink/renderer/core/css/css_selector.cc
+++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -329,7 +329,7 @@
     case kPseudoPlaceholder:
     case kPseudoPlaceholderShown:
     case kPseudoPlaying:
-    case kPseudoPopupHidden:
+    case kPseudoPopupOpeningOrOpen:
     case kPseudoReadOnly:
     case kPseudoReadWrite:
     case kPseudoRelativeAnchor:
@@ -383,7 +383,7 @@
     {"-internal-media-controls-overlay-cast-button",
      CSSSelector::kPseudoWebKitCustomElement},
     {"-internal-multi-select-focus", CSSSelector::kPseudoMultiSelectFocus},
-    {"-internal-popup-hidden", CSSSelector::kPseudoPopupHidden},
+    {"-internal-popup-opening-or-open", CSSSelector::kPseudoPopupOpeningOrOpen},
     {"-internal-relative-anchor", CSSSelector::kPseudoRelativeAnchor},
     {"-internal-selector-fragment-anchor",
      CSSSelector::kPseudoSelectorFragmentAnchor},
@@ -576,7 +576,7 @@
   if (match->type == CSSSelector::kPseudoOpen && !popup_attribute_enabled)
     return CSSSelector::kPseudoUnknown;
 
-  if (match->type == CSSSelector::kPseudoPopupHidden &&
+  if (match->type == CSSSelector::kPseudoPopupOpeningOrOpen &&
       !popup_attribute_enabled)
     return CSSSelector::kPseudoUnknown;
 
@@ -779,7 +779,7 @@
     case kPseudoPictureInPicture:
     case kPseudoPlaceholderShown:
     case kPseudoPlaying:
-    case kPseudoPopupHidden:
+    case kPseudoPopupOpeningOrOpen:
     case kPseudoReadOnly:
     case kPseudoReadWrite:
     case kPseudoRelativeAnchor:
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h
index 66bdd87..c98aeb33 100644
--- a/third_party/blink/renderer/core/css/css_selector.h
+++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -285,7 +285,7 @@
     kPseudoMultiSelectFocus,
     kPseudoHostHasAppearance,
     kPseudoOpen,
-    kPseudoPopupHidden,
+    kPseudoPopupOpeningOrOpen,
     kPseudoSlotted,
     kPseudoVideoPersistent,
     kPseudoVideoPersistentAncestor,
diff --git a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
index b289249..08e10bc6 100644
--- a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
+++ b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
@@ -43,7 +43,7 @@
     "-internal-list-box",
     "-internal-media-controls-overlay-cast-button",
     "-internal-multi-select-focus",
-    "-internal-popup-hidden",
+    "-internal-popup-opening-or-open",
     "-internal-shadow-host-has-appearance",
     "-internal-spatial-navigation-focus",
     "-internal-video-persistent",
diff --git a/third_party/blink/renderer/core/css/popup.css b/third_party/blink/renderer/core/css/popup.css
index 1f0ecd1..26e0bea3 100644
--- a/third_party/blink/renderer/core/css/popup.css
+++ b/third_party/blink/renderer/core/css/popup.css
@@ -9,8 +9,8 @@
 
 @namespace "http://www.w3.org/1999/xhtml";
 
-[popup]:-internal-popup-hidden {
-  display: none;
+[popup]:not(:-internal-popup-opening-or-open,dialog[open]) {
+  display:none;
 }
 
 [popup] {
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 4145579..de6ff38 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -5428,10 +5428,7 @@
           state_list->Append(*state_name);
         }
 
-        // TODO(https://github.com/tabatkins/css-toggle/issues/19): The
-        // spec currently allows an empty list of states, but this
-        // doesn't make sense, so we do not.
-        if (state_list->length() == 0 || !block.AtEnd()) {
+        if (state_list->length() < 2u || !block.AtEnd()) {
           return nullptr;
         }
         list->Append(*state_list);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index cd50498..e07365ee 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -2420,7 +2420,7 @@
       if (const auto* states_list = DynamicTo<CSSValueList>(state_value)) {
         ++index;
         found_states = true;
-        DCHECK_LE(1u, states_list->length());
+        DCHECK_LE(2u, states_list->length());
         ToggleRoot::States::NamesType states_vec;
         states_vec.ReserveInitialCapacity(states_list->length());
         for (const auto& state : *states_list) {
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc
index fdc37e6..6ee32ec 100644
--- a/third_party/blink/renderer/core/css/rule_feature_set.cc
+++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -177,7 +177,7 @@
     case CSSSelector::kPseudoMultiSelectFocus:
     case CSSSelector::kPseudoHostHasAppearance:
     case CSSSelector::kPseudoOpen:
-    case CSSSelector::kPseudoPopupHidden:
+    case CSSSelector::kPseudoPopupOpeningOrOpen:
     case CSSSelector::kPseudoSlotted:
     case CSSSelector::kPseudoVideoPersistent:
     case CSSSelector::kPseudoVideoPersistentAncestor:
@@ -653,7 +653,7 @@
       case CSSSelector::kPseudoOutOfRange:
       case CSSSelector::kPseudoDefined:
       case CSSSelector::kPseudoOpen:
-      case CSSSelector::kPseudoPopupHidden:
+      case CSSSelector::kPseudoPopupOpeningOrOpen:
       case CSSSelector::kPseudoVideoPersistent:
       case CSSSelector::kPseudoVideoPersistentAncestor:
       case CSSSelector::kPseudoXrOverlay:
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc
index a4074fa..685df68 100644
--- a/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1504,18 +1504,19 @@
         return element.popupOpen();
       }
       return false;
-    case CSSSelector::kPseudoPopupHidden:
+    case CSSSelector::kPseudoPopupOpeningOrOpen:
       if (!RuntimeEnabledFeatures::HTMLPopupAttributeEnabled(
               element.GetDocument().GetExecutionContext())) {
+        // The html.css UA stylesheet contains a rule for <dialog> elements
+        // that uses this pseudo, with `dialog:not(this_pseudo)`, so it's
+        // important to *not* match when the feature is *disabled*.
         return false;
       }
       if (element.HasPopupAttribute()) {
-        return element.GetPopupData()->visibilityState() ==
+        return element.GetPopupData()->visibilityState() !=
                PopupVisibilityState::kHidden;
       }
-      // Invalid values of the `popup` attribute should match the
-      // :-internal-popup-hidden pseudo selector.
-      return element.FastHasAttribute(html_names::kPopupAttr);
+      return false;
     case CSSSelector::kPseudoFullscreen:
     // fall through
     case CSSSelector::kPseudoFullScreen:
diff --git a/third_party/blink/renderer/core/dom/css_toggle.cc b/third_party/blink/renderer/core/dom/css_toggle.cc
index 44906fc3f..1faa8556 100644
--- a/third_party/blink/renderer/core/dom/css_toggle.cc
+++ b/third_party/blink/renderer/core/dom/css_toggle.cc
@@ -148,8 +148,17 @@
 void CSSToggle::setStatesInternal(const States& states,
                                   ExceptionState& exception_state) {
   if (states.IsNames()) {
+    const auto& states_vec = states.AsNames();
+
+    if (states_vec.size() < 2u) {
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kSyntaxError,
+          "The value provided contains fewer than 2 states.");
+      return;
+    }
+
     HashSet<AtomicString> states_present;
-    for (const AtomicString& state : states.AsNames()) {
+    for (const AtomicString& state : states_vec) {
       auto add_result = states_present.insert(state);
       if (!add_result.is_new_entry) {
         exception_state.ThrowDOMException(
@@ -277,10 +286,21 @@
 }
 
 void CSSToggle::SetValueAndCheckGroup(const State& value) {
+  // The specification says that we should go through the whole ChangeToggle
+  // algorithm (with a "set" value), but this implements a more direct way of
+  // doing the same thing.
   SetValue(value);
 
-  if (is_group_ && OwnerElement() && !ValueMatches(State(0u)))
-    MakeRestOfToggleGroupZero();
+  if (is_group_ && OwnerElement()) {
+    const ToggleRoot* specifier = FindToggleSpecifier();
+    const States* states = nullptr;
+    if (specifier)
+      states = &specifier->StateSet();
+
+    if (!ValueMatches(State(0u), states)) {
+      MakeRestOfToggleGroupZero();
+    }
+  }
 }
 
 void CSSToggle::SetValue(const State& value) {
@@ -335,12 +355,33 @@
   }
 }
 
+const ToggleRoot* CSSToggle::FindToggleSpecifier() const {
+  Element* owner_element = OwnerElement();
+  if (!owner_element)
+    return nullptr;
+
+  const ToggleRoot* toggle_specifier = nullptr;
+  if (const ComputedStyle* style = owner_element->GetComputedStyle()) {
+    if (const ToggleRootList* toggle_root = style->ToggleRoot()) {
+      for (const auto& item : toggle_root->Roots()) {
+        if (item.Name() == name_) {
+          toggle_specifier = &item;
+        }
+      }
+    }
+  }
+  return toggle_specifier;
+}
+
 // https://tabatkins.github.io/css-toggle/#toggle-match-value
-bool CSSToggle::ValueMatches(const State& other) const {
+bool CSSToggle::ValueMatches(const State& other,
+                             const States* states_override) const {
   if (value_ == other)
     return true;
 
-  if (value_.IsInteger() == other.IsInteger() || !states_.IsNames())
+  const States& states = states_override ? *states_override : states_;
+
+  if (value_.IsInteger() == other.IsInteger() || !states.IsNames())
     return false;
 
   State::IntegerType integer;
@@ -353,7 +394,7 @@
     ident = &value_.AsName();
   }
 
-  auto ident_index = states_.AsNames().Find(*ident);
+  auto ident_index = states.AsNames().Find(*ident);
   return ident_index != kNotFound && integer == ident_index;
 }
 
diff --git a/third_party/blink/renderer/core/dom/css_toggle.h b/third_party/blink/renderer/core/dom/css_toggle.h
index 34e505e..d2fba6b2 100644
--- a/third_party/blink/renderer/core/dom/css_toggle.h
+++ b/third_party/blink/renderer/core/dom/css_toggle.h
@@ -73,7 +73,7 @@
 
   void SetValue(const State& value);
   void MakeRestOfToggleGroupZero();
-
+  const ToggleRoot* FindToggleSpecifier() const;
   void FireToggleChangeEvent();
 
   enum class PostRecalcAt : uint8_t {
@@ -82,7 +82,8 @@
   };
   void SetNeedsStyleRecalc(Element* toggle_element, PostRecalcAt when);
 
-  bool ValueMatches(const State& other) const;
+  bool ValueMatches(const State& other,
+                    const States* states_override = nullptr) const;
 
  private:
   void setStatesInternal(const States& states, ExceptionState& exception_state);
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 2a034094..f23e1716 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6109,6 +6109,15 @@
 
 ScriptPromise Document::requestStorageAccessForSite(ScriptState* script_state,
                                                     const AtomicString& site) {
+  if (!GetFrame()) {
+    // Note that in detached frames, resolvers are not able to return a promise.
+    return ScriptPromise::RejectWithDOMException(
+        script_state, MakeGarbageCollected<DOMException>(
+                          DOMExceptionCode::kSecurityError,
+                          "requestStorageAccessForSite: Cannot be used unless "
+                          "the document is fully active."));
+  }
+
   ScriptPromiseResolver* resolver =
       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
 
@@ -6116,17 +6125,6 @@
   // can be changed when it is resolved or rejected.
   ScriptPromise promise = resolver->Promise();
 
-  if (!GetFrame()) {
-    AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-        mojom::blink::ConsoleMessageSource::kSecurity,
-        mojom::blink::ConsoleMessageLevel::kError,
-        "requestStorageAccessForSite: Must not be called from a detached "
-        "frame."));
-
-    resolver->Reject();
-    return promise;
-  }
-
   const bool has_user_gesture =
       LocalFrame::HasTransientUserActivation(GetFrame());
   if (!has_user_gesture) {
@@ -7042,9 +7040,6 @@
       }
     }
 
-    if (frame->GetFrameScheduler())
-      frame->GetFrameScheduler()->OnDomContentLoaded();
-
     if (ShouldMarkFontPerformance())
       FontPerformance::MarkDomContentLoaded();
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 4348bfeb..fdc6bc1 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1211,8 +1211,8 @@
 }
 
 void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions* options) {
-  DeferredShapingController::From(GetDocument())
-      ->ReshapeAllDeferred(ReshapeReason::kScrollingApi);
+  if (auto* ds_controller = DeferredShapingController::From(GetDocument()))
+    ds_controller->ReshapeAllDeferred(ReshapeReason::kScrollingApi);
   ActivateDisplayLockIfNeeded(DisplayLockActivationReason::kScrollIntoView);
   GetDocument().EnsurePaintLocationDataValidForNode(
       this, DocumentUpdateReason::kJavaScript);
@@ -2588,7 +2588,7 @@
   document.AddToTopLayer(this);
   // Remove display:none styling:
   GetPopupData()->setVisibilityState(PopupVisibilityState::kTransitioning);
-  PseudoStateChanged(CSSSelector::kPseudoPopupHidden);
+  PseudoStateChanged(CSSSelector::kPseudoPopupOpeningOrOpen);
 
   // Force a style update. This ensures that base property values are set prior
   // to `:open` matching, so that transitions can start on the change to
@@ -2816,7 +2816,7 @@
   if (GetPopupData()) {
     GetPopupData()->setVisibilityState(PopupVisibilityState::kHidden);
     GetPopupData()->setAnimationFinishedListener(nullptr);
-    PseudoStateChanged(CSSSelector::kPseudoPopupHidden);
+    PseudoStateChanged(CSSSelector::kPseudoPopupOpeningOrOpen);
   }
 }
 
@@ -8992,19 +8992,12 @@
 
   DCHECK_EQ(toggle->OwnerElement(), element);
 
-  const ToggleRoot* toggle_specifier = nullptr;
-  if (const ComputedStyle* style = element->GetComputedStyle()) {
-    if (const ToggleRootList* toggle_root = style->ToggleRoot()) {
-      for (const auto& item : toggle_root->Roots()) {
-        if (item.Name() == name) {
-          toggle_specifier = &item;
-        }
-      }
-    }
-  }
+  CSSToggle::State old_value = toggle->Value();
+  ChangeToggle(toggle, activation, toggle->FindToggleSpecifier());
+  CSSToggle::State new_value = toggle->Value();
 
-  ChangeToggle(toggle, activation, toggle_specifier);
-  toggle->FireToggleChangeEvent();
+  if (old_value != new_value)
+    toggle->FireToggleChangeEvent();
 }
 
 // Implement https://tabatkins.github.io/css-toggle/#change-a-toggle
@@ -9102,8 +9095,8 @@
       }
     }
 
-    if (t->StateSet().IsNames()) {
-      const auto& names = t->StateSet().AsNames();
+    if (states.IsNames()) {
+      const auto& names = states.AsNames();
       if (index < names.size()) {
         t->SetValue(State(names[index]));
       } else {
@@ -9116,7 +9109,7 @@
 
   // If t’s value does not match 0, and group is true, then set the value of
   // all other toggles in the same toggle group as t to 0.
-  if (is_group && !t->ValueMatches(State(0u)))
+  if (is_group && !t->ValueMatches(State(0u), &states))
     t->MakeRestOfToggleGroupZero();
 }
 
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc
index af75276b..69534465 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.cc
+++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -419,10 +419,16 @@
   if (options->hasSignal() && options->signal()->aborted())
     return false;
 
+  // It doesn't make sense to add an event listener without an ExecutionContext
+  // and some code below here assumes we have one.
+  auto* execution_context = GetExecutionContext();
+  if (!execution_context)
+    return false;
+
   // Consider `Permissions-Policy: unload`.
   if (event_type == event_type_names::kUnload &&
       RuntimeEnabledFeatures::PermissionsPolicyUnloadEnabled() &&
-      !GetExecutionContext()->IsFeatureEnabled(
+      !execution_context->IsFeatureEnabled(
           mojom::blink::PermissionsPolicyFeature::kUnload,
           ReportOptions::kReportOnFailure)) {
     return false;
diff --git a/third_party/blink/renderer/core/dom/events/event_target_test.cc b/third_party/blink/renderer/core/dom/events/event_target_test.cc
index 3d53326..347041c 100644
--- a/third_party/blink/renderer/core/dom/events/event_target_test.cc
+++ b/third_party/blink/renderer/core/dom/events/event_target_test.cc
@@ -85,4 +85,16 @@
       GetDocument().IsUseCounted(WebFeature::kAddEventListenerWithAbortSignal));
 }
 
+// See https://crbug.com/1357453.
+// Tests that we don't crash when adding a unload event handler to a target
+// that has no ExecutionContext.
+TEST_F(EventTargetTest, UnloadWithoutExecutionContext) {
+  GetDocument().GetSettings()->SetScriptEnabled(true);
+  ClassicScript::CreateUnspecifiedScript(R"JS(
+      document.createElement("track").track.addEventListener(
+          "unload",() => {});
+                      )JS")
+      ->RunScript(GetDocument().domWindow());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 2470dd3..10768acc 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1741,6 +1741,9 @@
     return;
   }
 
+  if (IsPictureInPictureWindow())
+    return;
+
   LocalFrame* frame = GetFrame();
   Page* page = frame->GetPage();
   if (!page)
@@ -1759,6 +1762,9 @@
     return;
   }
 
+  if (IsPictureInPictureWindow())
+    return;
+
   LocalFrame* frame = GetFrame();
   Page* page = frame->GetPage();
   if (!page)
@@ -1777,6 +1783,9 @@
     return;
   }
 
+  if (IsPictureInPictureWindow())
+    return;
+
   LocalFrame* frame = GetFrame();
   Page* page = frame->GetPage();
   if (!page)
@@ -1794,6 +1803,9 @@
     return;
   }
 
+  if (IsPictureInPictureWindow())
+    return;
+
   LocalFrame* frame = GetFrame();
   Page* page = frame->GetPage();
   if (!page)
@@ -2213,8 +2225,11 @@
   DCHECK(result.new_window);
 
   result.frame->Navigate(frame_request, WebFrameLoadType::kStandard);
+  LocalDOMWindow* pip_dom_window =
+      To<LocalDOMWindow>(result.frame->DomWindow());
+  pip_dom_window->SetIsPictureInPictureWindow();
 
-  return result.frame->DomWindow();
+  return pip_dom_window;
 }
 
 void LocalDOMWindow::Trace(Visitor* visitor) const {
@@ -2337,4 +2352,12 @@
   return fence_.Get();
 }
 
+bool LocalDOMWindow::IsPictureInPictureWindow() const {
+  return is_picture_in_picture_window_;
+}
+
+void LocalDOMWindow::SetIsPictureInPictureWindow() {
+  is_picture_in_picture_window_ = true;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 7091b97..f739d3b 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -503,6 +503,10 @@
 
   void DispatchLoadEvent();
 
+  // Is this a Document Picture in Picture window?
+  bool IsPictureInPictureWindow() const;
+  void SetIsPictureInPictureWindow();
+
   // Return the viewport size including scrollbars.
   gfx::Size GetViewportSize() const;
 
@@ -603,6 +607,10 @@
   Member<Fence> fence_;
 
   Member<CloseWatcher::WatcherStack> closewatcher_stack_;
+
+  // If set, this window is a Document Picture in Picture window.
+  // https://github.com/steimelchrome/document-pip-explainer/blob/main/explainer.md
+  bool is_picture_in_picture_window_ = false;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
index 43883e393..e61f1a13 100644
--- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
+++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -314,10 +314,6 @@
   // Inform the aggregator that we have reached First Contentful Paint.
   // The UKM event for the pre-FCP period will be recorded and UMA for
   // aggregated contributions to FCP are reported.
-  // TODO(crbug.com/1330675): This is called for the main frame or local frame
-  // roots only, depending on features::kLocalFrameRootPrePostFCPMetrics. When
-  // the experiment finishes, we should let only local frame roots use this
-  // class.
   void DidReachFirstContentfulPaint();
 
   bool InMainFrameUpdate() { return in_main_frame_update_; }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index 2cc95e2f..c348448 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -739,8 +739,7 @@
   }
   void DidChangeMobileFriendliness(const MobileFriendliness& mf);
 
-  // Returns the UKM aggregator for this frame, or this frame's local root if
-  // features::kLocalFrameRootPrePostFCPMetrics is enabled, creating it if
+  // Returns the UKM aggregator for this frame's local root, creating it if
   // necessary.
   LocalFrameUkmAggregator& EnsureUkmAggregator();
   void ResetUkmAggregatorForTesting();
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index d3c0acc..50499a2b 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -450,7 +450,7 @@
   // Friend class for testing.
   friend class ContextMenuControllerTest;
   friend class HTMLMediaElementTest;
-  friend class PictureInPictureControllerTest;
+  friend class PictureInPictureControllerVideoTest;
   friend class VideoWakeLockTest;
 
   class SourceMetadata {
diff --git a/third_party/blink/renderer/core/html/media/video_wake_lock.cc b/third_party/blink/renderer/core/html/media/video_wake_lock.cc
index 1acb0dd..1a7f4a5 100644
--- a/third_party/blink/renderer/core/html/media/video_wake_lock.cc
+++ b/third_party/blink/renderer/core/html/media/video_wake_lock.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -18,8 +19,24 @@
 
 namespace blink {
 
+namespace {
+
+Page* GetContainingPage(HTMLVideoElement& video) {
+  LocalDOMWindow* window = video.DomWindow();
+  if (!window)
+    return nullptr;
+
+  LocalFrame* frame = window->GetFrame();
+  if (!frame)
+    return nullptr;
+
+  return frame->GetPage();
+}
+
+}  // namespace
+
 VideoWakeLock::VideoWakeLock(HTMLVideoElement& video)
-    : PageVisibilityObserver(video.GetDocument().GetPage()),
+    : PageVisibilityObserver(GetContainingPage(video)),
       ExecutionContextLifecycleStateObserver(video.GetExecutionContext()),
       video_element_(video) {
   VideoElement().addEventListener(event_type_names::kPlaying, this, true);
@@ -46,6 +63,7 @@
 
 void VideoWakeLock::ElementDidMoveToNewDocument() {
   SetExecutionContext(VideoElement().GetExecutionContext());
+  SetPage(GetContainingPage(VideoElement()));
 
   if (RuntimeEnabledFeatures::VideoWakeLockOptimisationHiddenMutedEnabled()) {
     intersection_observer_->disconnect();
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css
index c4e1ae81..e216fe7 100644
--- a/third_party/blink/renderer/core/html/resources/html.css
+++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -1367,7 +1367,9 @@
     unicode-bidi: plaintext;
 }
 
-dialog:not([open]) {
+/* The `,[popup]:-internal-popup-opening-or-open` is to support the pop-up API, and
+   has no effect if the HTMLPopupAttribute feature is disabled. */
+dialog:not([open],[popup]:-internal-popup-opening-or-open) {
     /* https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3 */
     display: none;
 }
diff --git a/third_party/blink/renderer/core/inspector/inspector_contrast.cc b/third_party/blink/renderer/core/inspector/inspector_contrast.cc
index 2e24f46..e7a9931 100644
--- a/third_party/blink/renderer/core/inspector/inspector_contrast.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_contrast.cc
@@ -276,8 +276,8 @@
   }
 
   if (RuntimeEnabledFeatures::DeferredShapingEnabled()) {
-    DeferredShapingController::From(*document_)
-        ->ReshapeAllDeferred(ReshapeReason::kInspector);
+    if (auto* ds_controller = DeferredShapingController::From(*document_))
+      ds_controller->ReshapeAllDeferred(ReshapeReason::kInspector);
     document_->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
   }
   PhysicalRect content_bounds = GetNodeRect(text_node);
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index 934d02c..46dccdc 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -382,7 +382,7 @@
     DEFINE_STRING_MAPPING(PseudoListBox)
     DEFINE_STRING_MAPPING(PseudoMultiSelectFocus)
     DEFINE_STRING_MAPPING(PseudoOpen)
-    DEFINE_STRING_MAPPING(PseudoPopupHidden)
+    DEFINE_STRING_MAPPING(PseudoPopupOpeningOrOpen)
     DEFINE_STRING_MAPPING(PseudoHostHasAppearance)
     DEFINE_STRING_MAPPING(PseudoVideoPersistent)
     DEFINE_STRING_MAPPING(PseudoVideoPersistentAncestor)
diff --git a/third_party/blink/renderer/core/layout/deferred_shaping_controller.h b/third_party/blink/renderer/core/layout/deferred_shaping_controller.h
index ff8edcc0..1f8e1a67 100644
--- a/third_party/blink/renderer/core/layout/deferred_shaping_controller.h
+++ b/third_party/blink/renderer/core/layout/deferred_shaping_controller.h
@@ -20,7 +20,7 @@
 class LocalFrame;
 class Node;
 
-enum ReshapeReason {
+enum class ReshapeReason {
   kComputedStyle,
   kDomContentLoaded,  // DOMCntentLoaded after FCP
   kFcp,               // FCP after DOMContentLoaded
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 747c093a..8d7341a 100644
--- a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
+++ b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/dom/range.h"
 #include "third_party/blink/renderer/core/editing/position_with_affinity.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect.h"
+#include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/layout/deferred_shaping_controller.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
 #include "third_party/blink/renderer/core/page/print_context.h"
@@ -551,4 +552,11 @@
   // Pass if no DCHECK failures.
 }
 
+TEST_F(DeferredShapingTest, ScrollIntoViewInInactiveDocument) {
+  Document* doc = Document::CreateForTest();
+  Node* root = doc->appendChild(doc->CreateRawElement(html_names::kHTMLTag));
+  To<Element>(root)->scrollIntoView();
+  // PASS if no crash.
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc
index e8a6dd8..65f388a 100644
--- a/third_party/blink/renderer/core/script/classic_pending_script.cc
+++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -61,7 +61,9 @@
   if (element.IsPotentiallyRenderBlocking())
     return false;
 
-  if (features::kDelayAsyncScriptExecutionCrossSiteOnlyParam.Get()) {
+  static const bool delay_async_script_execution_cross_site_only =
+      features::kDelayAsyncScriptExecutionCrossSiteOnlyParam.Get();
+  if (delay_async_script_execution_cross_site_only) {
     ExecutionContext* context = element_document.GetExecutionContext();
     scoped_refptr<const SecurityOrigin> src_security_origin =
         SecurityOrigin::Create(url);
diff --git a/third_party/blink/renderer/core/script/script_runner.cc b/third_party/blink/renderer/core/script/script_runner.cc
index c047855b4..0d44c44 100644
--- a/third_party/blink/renderer/core/script/script_runner.cc
+++ b/third_party/blink/renderer/core/script/script_runner.cc
@@ -183,10 +183,13 @@
       // execution aren't removed, we eventually want to trigger
       // script-execution anyway for compatibility reasons, since waiting too
       // long for the milestones can cause compatibility issues.
+      // |pending_script| has to be wrapped by WrapWeakPersistent because the
+      // following delayed task should not persist a PendingScript.
       task_runner_->PostDelayedTask(
           FROM_HERE,
           WTF::Bind(&ScriptRunner::RemoveDelayReasonFromScript,
-                    WrapWeakPersistent(this), WrapPersistent(pending_script),
+                    WrapWeakPersistent(this),
+                    WrapWeakPersistent(pending_script),
                     DelayReason::kMilestone),
           features::kDelayAsyncScriptExecutionLimitParam.Get());
     }
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 980747d..6f551d1 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -273,6 +273,17 @@
   return false;
 }
 
+// The transition to/from nullptr style can affect subsequent siblings
+// if they reference a named timeline which appeared/disappeared.
+static bool AffectsScrollAnimations(const ComputedStyle* old_style,
+                                    const ComputedStyle* new_style) {
+  if (old_style && !old_style->ScrollTimelineName().IsEmpty())
+    return true;
+  if (new_style && !new_style->ScrollTimelineName().IsEmpty())
+    return true;
+  return false;
+}
+
 bool ComputedStyle::NeedsReattachLayoutTree(const Element& element,
                                             const ComputedStyle* old_style,
                                             const ComputedStyle* new_style) {
@@ -343,8 +354,11 @@
     const ComputedStyle* new_style) {
   if (old_style == new_style)
     return Difference::kEqual;
-  if (!old_style || !new_style)
+  if (!old_style || !new_style) {
+    if (AffectsScrollAnimations(old_style, new_style))
+      return Difference::kSiblingDescendantAffecting;
     return Difference::kInherited;
+  }
 
   // For inline elements, the new computed first line style will be |new_style|
   // inheriting from the parent's first line style. If |new_style| is different
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
index 6a8daf2..582c4d3 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl
@@ -45,4 +45,8 @@
   // Allows a remote desktop client to override the `origin` and
   // `sameOriginWithAncestors` internal arguments for a request.
   [RuntimeEnabled=WebAuthenticationRemoteDesktopSupport] RemoteDesktopClientOverride remoteDesktopClientOverride;
+
+  // Device-bound public-key support.
+  // https://github.com/w3c/webauthn/pull/1663
+  [RuntimeEnabled=WebAuthenticationDevicePublicKey] AuthenticationExtensionsDevicePublicKeyInputs devicePubKey;
 };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl
index cff4b08..57d447d6 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl
@@ -23,4 +23,8 @@
   // https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension
   boolean credBlob;
   ArrayBuffer getCredBlob;
+
+  // Device-bound public-key support.
+  // https://github.com/w3c/webauthn/pull/1663
+  [RuntimeEnabled=WebAuthenticationDevicePublicKey] AuthenticationExtensionsDevicePublicKeyOutputs devicePubKey;
 };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_inputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_inputs.idl
new file mode 100644
index 0000000..6f0b71b5
--- /dev/null
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_inputs.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://github.com/w3c/webauthn/pull/1663
+dictionary AuthenticationExtensionsDevicePublicKeyInputs {
+  DOMString attestation = "none";
+  sequence<DOMString> attestationFormats = [];
+};
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_outputs.idl b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_outputs.idl
new file mode 100644
index 0000000..bfa9453
--- /dev/null
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_device_public_key_outputs.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://github.com/w3c/webauthn/pull/1663
+dictionary AuthenticationExtensionsDevicePublicKeyOutputs {
+  ArrayBuffer authenticatorOutput;
+  ArrayBuffer signature;
+};
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
index 2ef0d658..702c5ff 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_client_inputs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_inputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_inputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_payment_inputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.h"
@@ -50,6 +51,8 @@
 using blink::mojom::blink::CredentialInfo;
 using blink::mojom::blink::CredentialInfoPtr;
 using blink::mojom::blink::CredentialType;
+using blink::mojom::blink::DevicePublicKeyRequest;
+using blink::mojom::blink::DevicePublicKeyRequestPtr;
 using blink::mojom::blink::IdentityProvider;
 using blink::mojom::blink::IdentityProviderPtr;
 using blink::mojom::blink::LargeBlobSupport;
@@ -548,6 +551,10 @@
           RemoteDesktopClientOverride::From(
               *extensions->remoteDesktopClientOverride());
     }
+    if (extensions->hasDevicePubKey()) {
+      mojo_options->device_public_key =
+          DevicePublicKeyRequest::From(*extensions->devicePubKey());
+    }
   }
 
   return mojo_options;
@@ -680,6 +687,10 @@
           RemoteDesktopClientOverride::From(
               *extensions->remoteDesktopClientOverride());
     }
+    if (extensions->hasDevicePubKey()) {
+      mojo_options->device_public_key =
+          DevicePublicKeyRequest::From(*extensions->devicePubKey());
+    }
   }
 
   return mojo_options;
@@ -707,4 +718,18 @@
   return mojo_provider;
 }
 
+// static
+DevicePublicKeyRequestPtr
+TypeConverter<DevicePublicKeyRequestPtr,
+              blink::AuthenticationExtensionsDevicePublicKeyInputs>::
+    Convert(const blink::AuthenticationExtensionsDevicePublicKeyInputs&
+                device_public_key) {
+  auto ret = DevicePublicKeyRequest::New();
+  ret->attestation = ConvertTo<absl::optional<AttestationConveyancePreference>>(
+                         device_public_key.attestation())
+                         .value_or(AttestationConveyancePreference::NONE);
+  ret->attestation_formats = device_public_key.attestationFormats();
+  return ret;
+}
+
 }  // namespace mojo
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
index 6b320da1ca..dd5681e 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
+++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.h
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
+class AuthenticationExtensionsDevicePublicKeyInputs;
 class AuthenticatorSelectionCriteria;
 class CableAuthenticationData;
 class CableRegistrationData;
@@ -198,6 +199,13 @@
       const blink::IdentityProvider&);
 };
 
+template <>
+struct TypeConverter<blink::mojom::blink::DevicePublicKeyRequestPtr,
+                     blink::AuthenticationExtensionsDevicePublicKeyInputs> {
+  static blink::mojom::blink::DevicePublicKeyRequestPtr Convert(
+      const blink::AuthenticationExtensionsDevicePublicKeyInputs&);
+};
+
 }  // namespace mojo
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGEMENT_CREDENTIAL_MANAGER_TYPE_CONVERTERS_H_
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
index b42d85a..a74b2ea 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -19,6 +19,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_client_inputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_client_outputs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_inputs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_device_public_key_outputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_inputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_large_blob_outputs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_payment_inputs.h"
@@ -500,6 +502,10 @@
       return DOMException::Create(
           /*message=*/dom_exception_details->message,
           /*name=*/dom_exception_details->name);
+    case AuthenticatorStatus::DEVICE_PUBLIC_KEY_ATTESTATION_REJECTED:
+      return MakeGarbageCollected<DOMException>(
+          DOMExceptionCode::kNotAllowedError,
+          "The authenticator responded with an invalid message");
     case AuthenticatorStatus::UNKNOWN_ERROR:
       return MakeGarbageCollected<DOMException>(
           DOMExceptionCode::kNotReadableError,
@@ -509,6 +515,26 @@
   return nullptr;
 }
 
+// Abort an ongoing PublicKeyCredential create() or get() operation.
+void AbortPublicKeyRequest(ScriptState* script_state) {
+  if (!script_state->ContextIsValid())
+    return;
+
+  auto* authenticator =
+      CredentialManagerProxy::From(script_state)->Authenticator();
+  authenticator->Cancel();
+}
+
+// Abort an ongoing OtpCredential get() operation.
+void AbortOtpRequest(ScriptState* script_state) {
+  if (!script_state->ContextIsValid())
+    return;
+
+  auto* webotp_service =
+      CredentialManagerProxy::From(script_state)->WebOTPService();
+  webotp_service->Abort();
+}
+
 // Abort an ongoing FederatedCredential login() operation.
 void AbortIdentityCredentialRequest(ScriptState* script_state) {
   if (!script_state->ContextIsValid())
@@ -607,7 +633,6 @@
 
 void OnMakePublicKeyCredentialComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
-    AbortSignal* signal,
     RequiredOriginType required_origin_type,
     AuthenticatorStatus status,
     MakeCredentialAuthenticatorResponsePtr credential,
@@ -616,14 +641,8 @@
   AssertSecurityRequirementsBeforeResponse(resolver, required_origin_type);
   if (status != AuthenticatorStatus::SUCCESS) {
     DCHECK(!credential);
-    if (signal && signal->aborted()) {
-      auto* script_state = resolver->GetScriptState();
-      ScriptState::Scope script_state_scope(script_state);
-      resolver->Reject(signal->reason(script_state));
-    } else {
-      resolver->Reject(
-          AuthenticatorStatusToDOMException(status, dom_exception_details));
-    }
+    resolver->Reject(
+        AuthenticatorStatusToDOMException(status, dom_exception_details));
     return;
   }
   DCHECK(credential);
@@ -674,6 +693,15 @@
     large_blob_outputs->setSupported(credential->supports_large_blob);
     extension_outputs->setLargeBlob(large_blob_outputs);
   }
+  if (credential->device_public_key) {
+    AuthenticationExtensionsDevicePublicKeyOutputs* device_public_key_outputs =
+        AuthenticationExtensionsDevicePublicKeyOutputs::Create();
+    device_public_key_outputs->setAuthenticatorOutput(VectorToDOMArrayBuffer(
+        std::move(credential->device_public_key->authenticator_output)));
+    device_public_key_outputs->setSignature(VectorToDOMArrayBuffer(
+        std::move(credential->device_public_key->signature)));
+    extension_outputs->setDevicePubKey(device_public_key_outputs);
+  }
   resolver->Resolve(MakeGarbageCollected<PublicKeyCredential>(
       credential->info->id, raw_id, authenticator_response,
       credential->authenticator_attachment, extension_outputs));
@@ -690,7 +718,6 @@
 
 void OnSaveCredentialIdForPaymentExtension(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
-    AbortSignal* signal,
     MakeCredentialAuthenticatorResponsePtr credential,
     PaymentCredentialStorageStatus storage_status) {
   auto status = AuthenticatorStatus::SUCCESS;
@@ -700,14 +727,13 @@
     credential = nullptr;
   }
   OnMakePublicKeyCredentialComplete(
-      std::move(scoped_resolver), signal,
+      std::move(scoped_resolver),
       RequiredOriginType::kSecureWithPaymentPermissionPolicy, status,
       std::move(credential), /*dom_exception_details=*/nullptr);
 }
 
 void OnMakePublicKeyCredentialWithPaymentExtensionComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
-    AbortSignal* signal,
     const String& rp_id_for_payment_extension,
     const WTF::Vector<uint8_t>& user_id_for_payment_extension,
     AuthenticatorStatus status,
@@ -720,14 +746,8 @@
   AssertSecurityRequirementsBeforeResponse(resolver, required_origin_type);
   if (status != AuthenticatorStatus::SUCCESS) {
     DCHECK(!credential);
-    if (signal && signal->aborted()) {
-      auto* script_state = resolver->GetScriptState();
-      ScriptState::Scope script_state_scope(script_state);
-      resolver->Reject(signal->reason(script_state));
-    } else {
-      resolver->Reject(
-          AuthenticatorStatusToDOMException(status, dom_exception_details));
-    }
+    resolver->Reject(
+        AuthenticatorStatusToDOMException(status, dom_exception_details));
     return;
   }
 
@@ -740,12 +760,11 @@
       std::move(user_id_for_payment_extension),
       WTF::Bind(&OnSaveCredentialIdForPaymentExtension,
                 std::make_unique<ScopedPromiseResolver>(resolver),
-                WrapPersistent(signal), std::move(credential)));
+                std::move(credential)));
 }
 
 void OnGetAssertionComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
-    AbortSignal* signal,
     AuthenticatorStatus status,
     GetAssertionAuthenticatorResponsePtr credential,
     WebAuthnDOMExceptionDetailsPtr dom_exception_details) {
@@ -797,6 +816,16 @@
       extension_outputs->setGetCredBlob(
           VectorToDOMArrayBuffer(std::move(*credential->get_cred_blob)));
     }
+    if (credential->device_public_key) {
+      AuthenticationExtensionsDevicePublicKeyOutputs*
+          device_public_key_outputs =
+              AuthenticationExtensionsDevicePublicKeyOutputs::Create();
+      device_public_key_outputs->setAuthenticatorOutput(VectorToDOMArrayBuffer(
+          std::move(credential->device_public_key->authenticator_output)));
+      device_public_key_outputs->setSignature(VectorToDOMArrayBuffer(
+          std::move(credential->device_public_key->signature)));
+      extension_outputs->setDevicePubKey(device_public_key_outputs);
+    }
     resolver->Resolve(MakeGarbageCollected<PublicKeyCredential>(
         credential->info->id,
         VectorToDOMArrayBuffer(std::move(credential->info->raw_id)),
@@ -805,18 +834,11 @@
     return;
   }
   DCHECK(!credential);
-  if (signal && signal->aborted()) {
-    auto* script_state = resolver->GetScriptState();
-    ScriptState::Scope script_state_scope(script_state);
-    resolver->Reject(signal->reason(script_state));
-  } else {
-    resolver->Reject(
-        AuthenticatorStatusToDOMException(status, dom_exception_details));
-  }
+  resolver->Reject(
+      AuthenticatorStatusToDOMException(status, dom_exception_details));
 }
 
 void OnSmsReceive(ScriptPromiseResolver* resolver,
-                  AbortSignal* signal,
                   base::TimeTicks start_time,
                   mojom::blink::SmsStatus status,
                   const String& otp) {
@@ -833,14 +855,8 @@
     return;
   }
   if (status == mojom::blink::SmsStatus::kAborted) {
-    if (signal && signal->aborted()) {
-      auto* script_state = resolver->GetScriptState();
-      ScriptState::Scope script_state_scope(script_state);
-      resolver->Reject(signal->reason(script_state));
-    } else {
-      resolver->Reject(MakeGarbageCollected<DOMException>(
-          DOMExceptionCode::kAbortError, "OTP retrieval was aborted."));
-    }
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kAbortError, "OTP retrieval was aborted."));
     return;
   }
   if (status == mojom::blink::SmsStatus::kCancelled) {
@@ -934,58 +950,6 @@
 
 const char CredentialsContainer::kSupplementName[] = "CredentialsContainer";
 
-class CredentialsContainer::OtpRequestAbortAlgorithm final
-    : public AbortSignal::Algorithm {
- public:
-  explicit OtpRequestAbortAlgorithm(ScriptState* script_state)
-      : script_state_(script_state) {}
-  ~OtpRequestAbortAlgorithm() override = default;
-
-  // Abort an ongoing OtpCredential get() operation.
-  void Run() override {
-    if (!script_state_->ContextIsValid())
-      return;
-
-    auto* webotp_service =
-        CredentialManagerProxy::From(script_state_)->WebOTPService();
-    webotp_service->Abort();
-  }
-
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(script_state_);
-    Algorithm::Trace(visitor);
-  }
-
- private:
-  Member<ScriptState> script_state_;
-};
-
-class CredentialsContainer::PublicKeyRequestAbortAlgorithm final
-    : public AbortSignal::Algorithm {
- public:
-  explicit PublicKeyRequestAbortAlgorithm(ScriptState* script_state)
-      : script_state_(script_state) {}
-  ~PublicKeyRequestAbortAlgorithm() override = default;
-
-  // Abort an ongoing PublicKeyCredential create() or get() operation.
-  void Run() override {
-    if (!script_state_->ContextIsValid())
-      return;
-
-    auto* authenticator =
-        CredentialManagerProxy::From(script_state_)->Authenticator();
-    authenticator->Cancel();
-  }
-
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(script_state_);
-    Algorithm::Trace(visitor);
-  }
-
- private:
-  Member<ScriptState> script_state_;
-};
-
 CredentialsContainer* CredentialsContainer::credentials(Navigator& navigator) {
   CredentialsContainer* credentials =
       Supplement<Navigator>::From<CredentialsContainer>(navigator);
@@ -1151,14 +1115,14 @@
               "Ignoring unknown publicKey.userVerification value"));
     }
 
-    auto* signal = options->getSignalOr(nullptr);
-    if (signal) {
-      if (signal->aborted()) {
-        resolver->Reject(signal->reason(script_state));
+    if (options->hasSignal()) {
+      if (options->signal()->aborted()) {
+        resolver->Reject(MakeGarbageCollected<DOMException>(
+            DOMExceptionCode::kAbortError, "Request has been aborted."));
         return promise;
       }
-      signal->AddAlgorithm(
-          MakeGarbageCollected<PublicKeyRequestAbortAlgorithm>(script_state));
+      options->signal()->AddAlgorithm(
+          WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
     }
 
     bool is_conditional_ui_request =
@@ -1185,8 +1149,7 @@
       authenticator->GetAssertion(
           std::move(mojo_options),
           WTF::Bind(&OnGetAssertionComplete,
-                    std::make_unique<ScopedPromiseResolver>(resolver),
-                    WrapPersistent(signal)));
+                    std::make_unique<ScopedPromiseResolver>(resolver)));
     } else {
       resolver->Reject(MakeGarbageCollected<DOMException>(
           DOMExceptionCode::kNotSupportedError,
@@ -1203,20 +1166,19 @@
       return promise;
     }
 
-    auto* signal = options->getSignalOr(nullptr);
-    if (signal) {
-      if (signal->aborted()) {
-        resolver->Reject(signal->reason(script_state));
+    if (options->hasSignal()) {
+      if (options->signal()->aborted()) {
+        resolver->Reject(MakeGarbageCollected<DOMException>(
+            DOMExceptionCode::kAbortError, "Request has been aborted."));
         return promise;
       }
-      signal->AddAlgorithm(
-          MakeGarbageCollected<OtpRequestAbortAlgorithm>(script_state));
+      options->signal()->AddAlgorithm(
+          WTF::Bind(&AbortOtpRequest, WrapPersistent(script_state)));
     }
 
     auto* webotp_service =
         CredentialManagerProxy::From(script_state)->WebOTPService();
     webotp_service->Receive(WTF::Bind(&OnSmsReceive, WrapPersistent(resolver),
-                                      WrapPersistent(signal),
                                       base::TimeTicks::Now()));
 
     UseCounter::Count(context, WebFeature::kWebOTP);
@@ -1557,14 +1519,14 @@
     }
   }
 
-  auto* signal = options->getSignalOr(nullptr);
-  if (signal) {
-    if (signal->aborted()) {
-      resolver->Reject(signal->reason(script_state));
+  if (options->hasSignal()) {
+    if (options->signal()->aborted()) {
+      resolver->Reject(MakeGarbageCollected<DOMException>(
+          DOMExceptionCode::kAbortError, "Request has been aborted."));
       return promise;
     }
-    signal->AddAlgorithm(
-        MakeGarbageCollected<PublicKeyRequestAbortAlgorithm>(script_state));
+    options->signal()->AddAlgorithm(
+        WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
   }
 
   if (options->publicKey()->hasAttestation() &&
@@ -1701,14 +1663,14 @@
           std::move(mojo_options),
           WTF::Bind(&OnMakePublicKeyCredentialWithPaymentExtensionComplete,
                     std::make_unique<ScopedPromiseResolver>(resolver),
-                    WrapPersistent(signal), rp_id_for_payment_extension,
+                    rp_id_for_payment_extension,
                     std::move(user_id_for_payment_extension)));
     } else {
       authenticator->MakeCredential(
           std::move(mojo_options),
           WTF::Bind(&OnMakePublicKeyCredentialComplete,
                     std::make_unique<ScopedPromiseResolver>(resolver),
-                    WrapPersistent(signal), required_origin_type));
+                    required_origin_type));
     }
   }
 
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
index 395c6736..86ee9e87 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
@@ -40,10 +40,6 @@
   ScriptPromise preventSilentAccess(ScriptState*);
 
   void Trace(Visitor*) const override;
-
- private:
-  class OtpRequestAbortAlgorithm;
-  class PublicKeyRequestAbortAlgorithm;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc
index 756e357..9234895 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -56,11 +56,6 @@
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-#include "media/filters/h264_to_annex_b_bitstream_converter.h"
-#include "media/formats/mp4/box_definitions.h"
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
 using blink::WebMediaSource;
 using blink::WebSourceBuffer;
 
@@ -281,19 +276,6 @@
   std::unique_ptr<media::VideoDecoderConfig> video_config;
   String console_message;
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  // TODO(crbug.com/1144908): The SourceBuffer needs these for converting h264
-  // EncodedVideoChunks. Probably best if these details are put into a new
-  // WebCodecs VideoDecoderHelper abstraction (or similar), since this top-level
-  // MediaSource impl shouldn't need to worry about the details of specific
-  // codec bitstream conversions (nor should the underlying implementation be
-  // depended upon to redo work done already in WebCodecs decoder configuration
-  // validation.) In initial prototype, we do not support h264 buffering, so
-  // will fail if these become populated by MakeMediaVideoDecoderConfig, below.
-  std::unique_ptr<media::H264ToAnnexBBitstreamConverter> h264_converter;
-  std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord> h264_avcc;
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
   if (config->hasAudioConfig()) {
     if (!AudioDecoder::IsValidAudioDecoderConfig(*(config->audioConfig()),
                                                  &console_message /* out */)) {
@@ -322,21 +304,19 @@
       return nullptr;
     }
 
+    bool converter_needed = false;
     absl::optional<media::VideoDecoderConfig> out_video_config =
         VideoDecoder::MakeMediaVideoDecoderConfig(*(config->videoConfig()),
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-                                                  h264_converter /* out */,
-                                                  h264_avcc /* out */,
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-                                                  &console_message /* out */);
+                                                  &console_message /* out */,
+                                                  &converter_needed /* out */);
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
     // TODO(crbug.com/1144908): Initial prototype does not support h264
     // buffering. See above.
-    if (out_video_config && (h264_converter || h264_avcc)) {
+    if (out_video_config && converter_needed) {
       out_video_config = absl::nullopt;
       console_message =
-          "H.264 EncodedVideoChunk buffering is not yet supported in MSE. See "
-          "https://crbug.com/1144908.";
+          "H.264/H.265 EncodedVideoChunk buffering is not yet supported in "
+          "MSE.See https://crbug.com/1144908.";
     }
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
index 141e92f6..eb21156 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/html/media/html_media_test_helper.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
 #include "third_party/blink/renderer/core/layout/layout_image.h"
+#include "third_party/blink/renderer/core/loader/empty_clients.h"
 #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/core/testing/wait_for_event.h"
@@ -208,7 +209,9 @@
   std::unique_ptr<WebMediaPlayer> web_media_player_;
 };
 
-class PictureInPictureControllerTest : public RenderingTest {
+// These tests should be for video Picture in Picture.  See below if you'd like
+// to test document Picture in Picture.
+class PictureInPictureControllerVideoTest : public RenderingTest {
  public:
   void SetUp() override {
     client_ = std::make_unique<PictureInPictureTestWebFrameClient>(
@@ -244,6 +247,7 @@
   void TearDown() override {
     GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
         mojom::blink::PictureInPictureService::Name_, {});
+    RenderingTest::TearDown();
   }
 
   HTMLVideoElement* Video() const { return video_.Get(); }
@@ -270,7 +274,7 @@
   frame_test_helpers::WebViewHelper helper_;
 };
 
-TEST_F(PictureInPictureControllerTest, EnterPictureInPictureFiresEvent) {
+TEST_F(PictureInPictureControllerVideoTest, EnterPictureInPictureFiresEvent) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .PictureInPictureElement());
 
@@ -289,7 +293,7 @@
                          .PictureInPictureElement());
 }
 
-TEST_F(PictureInPictureControllerTest,
+TEST_F(PictureInPictureControllerVideoTest,
        FrameThrottlingIsSetProperlyWithoutSetup) {
   // This test assumes that it throttling is allowed by default.
   ASSERT_TRUE(GetWidget()->GetMayThrottleIfUndrawnFramesForTesting());
@@ -309,7 +313,7 @@
   EXPECT_TRUE(GetWidget()->GetMayThrottleIfUndrawnFramesForTesting());
 }
 
-TEST_F(PictureInPictureControllerTest, ExitPictureInPictureFiresEvent) {
+TEST_F(PictureInPictureControllerVideoTest, ExitPictureInPictureFiresEvent) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .PictureInPictureElement());
 
@@ -336,7 +340,7 @@
                          .PictureInPictureElement());
 }
 
-TEST_F(PictureInPictureControllerTest, StartObserving) {
+TEST_F(PictureInPictureControllerVideoTest, StartObserving) {
   EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument())
                    .IsSessionObserverReceiverBoundForTesting());
 
@@ -355,7 +359,7 @@
                   .IsSessionObserverReceiverBoundForTesting());
 }
 
-TEST_F(PictureInPictureControllerTest, StopObserving) {
+TEST_F(PictureInPictureControllerVideoTest, StopObserving) {
   EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument())
                    .IsSessionObserverReceiverBoundForTesting());
 
@@ -381,7 +385,7 @@
                    .IsSessionObserverReceiverBoundForTesting());
 }
 
-TEST_F(PictureInPictureControllerTest, PlayPauseButton_InfiniteDuration) {
+TEST_F(PictureInPictureControllerVideoTest, PlayPauseButton_InfiniteDuration) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .PictureInPictureElement());
 
@@ -399,7 +403,7 @@
                                      event_type_names::kEnterpictureinpicture);
 }
 
-TEST_F(PictureInPictureControllerTest, PlayPauseButton_MediaSource) {
+TEST_F(PictureInPictureControllerVideoTest, PlayPauseButton_MediaSource) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .PictureInPictureElement());
 
@@ -418,7 +422,7 @@
                                      event_type_names::kEnterpictureinpicture);
 }
 
-TEST_F(PictureInPictureControllerTest, PerformMediaPlayerAction) {
+TEST_F(PictureInPictureControllerVideoTest, PerformMediaPlayerAction) {
   frame_test_helpers::WebViewHelper helper;
   helper.Initialize();
 
@@ -437,7 +441,8 @@
       bounds, blink::mojom::MediaPlayerActionType::kPictureInPicture, true);
 }
 
-TEST_F(PictureInPictureControllerTest, EnterPictureInPictureAfterResettingWMP) {
+TEST_F(PictureInPictureControllerVideoTest,
+       EnterPictureInPictureAfterResettingWMP) {
   V8TestingScope scope;
 
   EXPECT_NE(nullptr, Video()->GetWebMediaPlayer());
@@ -461,7 +466,7 @@
             dom_exception->code());
 }
 
-TEST_F(PictureInPictureControllerTest,
+TEST_F(PictureInPictureControllerVideoTest,
        EnterPictureInPictureProvideSourceBoundsSetToBoundsInWidget) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .PictureInPictureElement());
@@ -483,7 +488,7 @@
   EXPECT_EQ(Service().source_bounds(), Video()->BoundsInWidget());
 }
 
-TEST_F(PictureInPictureControllerTest,
+TEST_F(PictureInPictureControllerVideoTest,
        EnterPictureInPictureProvideSourceBoundsSetToReplacedContentRect) {
   // Create one image with a size of 10x10px
   SkImageInfo raster_image_info =
@@ -537,7 +542,7 @@
   EXPECT_EQ(Service().source_bounds(), gfx::Rect(173, 173, 20, 20));
 }
 
-TEST_F(PictureInPictureControllerTest, VideoIsNotAllowedIfAutoPip) {
+TEST_F(PictureInPictureControllerVideoTest, VideoIsNotAllowedIfAutoPip) {
   EXPECT_EQ(PictureInPictureControllerImpl::Status::kEnabled,
             PictureInPictureControllerImpl::From(GetDocument())
                 .IsElementAllowed(*Video(), /*report_failure=*/false));
@@ -550,7 +555,64 @@
                 .IsElementAllowed(*Video(), /*report_failure=*/false));
 }
 
-TEST_F(PictureInPictureControllerTest, CreateDocumentPictureInPictureWindow) {
+class PictureInPictureControllerChromeClient
+    : public RenderingTestChromeClient {
+ public:
+  explicit PictureInPictureControllerChromeClient(
+      DummyPageHolder* dummy_page_holder)
+      : dummy_page_holder_(dummy_page_holder) {}
+
+  Page* CreateWindowDelegate(LocalFrame*,
+                             const FrameLoadRequest&,
+                             const AtomicString&,
+                             const WebWindowFeatures&,
+                             network::mojom::blink::WebSandboxFlags,
+                             const SessionStorageNamespaceId&,
+                             bool& consumed_user_gesture) override {
+    return &dummy_page_holder_->GetPage();
+  }
+  MOCK_METHOD(void, SetWindowRect, (const gfx::Rect&, LocalFrame&));
+
+ private:
+  DummyPageHolder* dummy_page_holder_;
+};
+
+// Tests for Document Picture in Picture.
+// Unlike the video tests above, these don't have a widget.  However, that makes
+// it much easier to use RenderingTest more properly to set the ChromeClient.
+// Having the ChromeClient lets us mock SetWindowRect.
+class PictureInPictureControllerDocumentTest : public RenderingTest {
+ public:
+  void SetUp() override {
+    chrome_client_ =
+        MakeGarbageCollected<PictureInPictureControllerChromeClient>(
+            &dummy_page_holder_);
+    RenderingTest::SetUp();
+  }
+
+  Document& GetDocument() const { return *GetFrame().GetDocument(); }
+
+  // Used by RenderingTest.
+  RenderingTestChromeClient& GetChromeClient() const override {
+    return *chrome_client_;
+  }
+
+  // Convenience function to set expectations on the mock.
+  PictureInPictureControllerChromeClient& GetPipChromeClient() const {
+    return *chrome_client_;
+  }
+
+ private:
+  Persistent<PictureInPictureControllerChromeClient> chrome_client_;
+  // This is used by our chrome client to create the PiP window.  We keep
+  // ownership of it here so that it outlives the GC'd objects.  The client
+  // cannot own it because it also has a GC root to the client; everything would
+  // leak if we did so.
+  DummyPageHolder dummy_page_holder_;
+};
+
+TEST_F(PictureInPictureControllerDocumentTest,
+       CreateDocumentPictureInPictureWindow) {
   EXPECT_EQ(nullptr, PictureInPictureControllerImpl::From(GetDocument())
                          .pictureInPictureWindow());
 
@@ -603,6 +665,13 @@
   EXPECT_NE(nullptr, pictureInPictureWindow);
   EXPECT_EQ(url.GetString(),
             pictureInPictureWindow->document()->BaseURL().GetString());
+
+  // Verify that move* and resize* don't call through to the chrome client.
+  EXPECT_CALL(GetPipChromeClient(), SetWindowRect(_, _)).Times(0);
+  pictureInPictureWindow->document()->domWindow()->moveTo(10, 10);
+  pictureInPictureWindow->document()->domWindow()->moveBy(10, 10);
+  pictureInPictureWindow->document()->domWindow()->resizeTo(10, 10);
+  pictureInPictureWindow->document()->domWindow()->resizeBy(10, 10);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
index e951e6f..c7b8135 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -8,6 +8,8 @@
 #include <utility>
 
 #include "base/numerics/safe_conversions.h"
+#include "base/strings/strcat.h"
+#include "third_party/blink/public/platform/modules/remoteplayback/remote_playback_source.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
@@ -76,7 +78,9 @@
       source_string.data(),
       base::checked_cast<unsigned>(source_string.length()));
 
-  return KURL("remote-playback://" + encoded_source);
+  return KURL(
+      base::StrCat({kRemotePlaybackPresentationUrlScheme, "://"}).c_str() +
+      encoded_source);
 }
 
 bool IsBackgroundAvailabilityMonitoringDisabled() {
diff --git a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
index 0355a8b8..836754a3 100644
--- a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
+++ b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
@@ -46,7 +46,8 @@
 
 void NavigationPreloadRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   DCHECK(!response_);
   response_ = std::make_unique<WebURLResponse>();
   // TODO(horo): Set report_security_info to true when DevTools is attached.
@@ -84,9 +85,6 @@
   NOTREACHED();
 }
 
-void NavigationPreloadRequest::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {}
-
 void NavigationPreloadRequest::OnTransferSizeUpdated(
     int32_t transfer_size_diff) {}
 
diff --git a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.h b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.h
index e68efb5..6fc38c1 100644
--- a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.h
+++ b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.h
@@ -41,15 +41,16 @@
 
   // network::mojom::URLLoaderClient:
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
index f07cb5c..2fbc25c 100644
--- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -69,6 +69,8 @@
     "video_decoder.h",
     "video_decoder_broker.cc",
     "video_decoder_broker.h",
+    "video_decoder_helper.cc",
+    "video_decoder_helper.h",
     "video_encoder.cc",
     "video_encoder.h",
     "video_frame.cc",
diff --git a/third_party/blink/renderer/modules/webcodecs/DEPS b/third_party/blink/renderer/modules/webcodecs/DEPS
index 51ef2f1..f5d9772 100644
--- a/third_party/blink/renderer/modules/webcodecs/DEPS
+++ b/third_party/blink/renderer/modules/webcodecs/DEPS
@@ -18,6 +18,7 @@
     "+media/base",
     "+media/filters",
     "+media/formats/mp4/box_definitions.h",
+    "+media/formats/mp4/hevc.h",
     "+media/media_buildflags.h",
     "+media/mojo",
     "+media/renderers",
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
index 36bc6967..bccaa735 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -60,6 +60,10 @@
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
 #include "media/filters/h264_to_annex_b_bitstream_converter.h"  // nogncheck
 #include "media/formats/mp4/box_definitions.h"                  // nogncheck
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#include "media/filters/h265_to_annex_b_bitstream_converter.h"  // nogncheck
+#include "media/formats/mp4/hevc.h"                             // nogncheck
+#endif
 #endif
 
 namespace blink {
@@ -185,6 +189,16 @@
 #endif
 }
 
+void ParseH265KeyFrame(const media::DecoderBuffer& buffer, bool* is_key_frame) {
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  auto result = media::mp4::HEVC::AnalyzeAnnexB(
+      buffer.data(), buffer.data_size(), std::vector<media::SubsampleEntry>());
+  *is_key_frame = result.is_keyframe.value_or(false);
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+}
+
 }  // namespace
 
 // static
@@ -291,14 +305,7 @@
   // Check that we can make a media::VideoDecoderConfig. The |js_error_message|
   // is ignored, we report only via |support.supported|.
   absl::optional<MediaConfigType> media_config;
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  std::unique_ptr<media::H264ToAnnexBBitstreamConverter> h264_converter;
-  std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord> h264_avcc;
-  media_config = MakeMediaVideoDecoderConfig(*config_copy, h264_converter,
-                                             h264_avcc, &js_error_message);
-#else
   media_config = MakeMediaVideoDecoderConfig(*config_copy, &js_error_message);
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
   if (!media_config) {
     support->setSupported(false);
     return ScriptPromise::Cast(
@@ -407,14 +414,21 @@
 
 // static
 absl::optional<media::VideoDecoderConfig>
-VideoDecoder::MakeMediaVideoDecoderConfig(
-    const ConfigType& config,
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-    std::unique_ptr<media::H264ToAnnexBBitstreamConverter>& out_h264_converter,
-    std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord>& out_h264_avcc,
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-    String* js_error_message) {
+VideoDecoder::MakeMediaVideoDecoderConfig(const ConfigType& config,
+                                          String* js_error_message,
+                                          bool* needs_converter_out) {
+  std::unique_ptr<VideoDecoderHelper> decoder_helper;
+  return MakeMediaVideoDecoderConfigInternal(
+      config, decoder_helper, js_error_message, needs_converter_out);
+}
 
+// static
+absl::optional<media::VideoDecoderConfig>
+VideoDecoder::MakeMediaVideoDecoderConfigInternal(
+    const ConfigType& config,
+    std::unique_ptr<VideoDecoderHelper>& decoder_helper,
+    String* js_error_message,
+    bool* needs_converter_out) {
   media::VideoType video_type;
   if (!ParseCodecString(config.codec(), video_type, *js_error_message)) {
     // Checked by IsValidVideoDecoderConfig().
@@ -436,29 +450,34 @@
       extra_data.assign(start, start + size);
     }
   }
+  if (needs_converter_out) {
+    *needs_converter_out = (extra_data.size() > 0);
+  }
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  if (video_type.codec == media::VideoCodec::kH264 && !extra_data.empty()) {
-    out_h264_avcc =
-        std::make_unique<media::mp4::AVCDecoderConfigurationRecord>();
-    out_h264_converter =
-        std::make_unique<media::H264ToAnnexBBitstreamConverter>();
-    if (!out_h264_converter->ParseConfiguration(
-            extra_data.data(), static_cast<uint32_t>(extra_data.size()),
-            out_h264_avcc.get())) {
-      *js_error_message = "Failed to parse avcC.";
+  if ((extra_data.size() > 0) &&
+      (video_type.codec == media::VideoCodec::kH264 ||
+       video_type.codec == media::VideoCodec::kHEVC)) {
+    VideoDecoderHelper::Status status;
+    decoder_helper = VideoDecoderHelper::Create(
+        video_type, extra_data.data(), static_cast<int>(extra_data.size()),
+        &status);
+    if (status != VideoDecoderHelper::Status::kSucceed) {
+      if (video_type.codec == media::VideoCodec::kH264) {
+        if (status == VideoDecoderHelper::Status::kDescriptionParseFailed) {
+          *js_error_message = "Failed to parse avcC.";
+        } else if (status == VideoDecoderHelper::Status::kUnsupportedCodec) {
+          *js_error_message = "H.264 decoding is not supported.";
+        }
+      } else if (video_type.codec == media::VideoCodec::kHEVC) {
+        if (status == VideoDecoderHelper::Status::kDescriptionParseFailed) {
+          *js_error_message = "Failed to parse hvcC.";
+        } else if (status == VideoDecoderHelper::Status::kUnsupportedCodec) {
+          *js_error_message = "HEVC decoding is not supported.";
+        }
+      }
       return absl::nullopt;
     }
-  } else {
-    out_h264_avcc.reset();
-    out_h264_converter.reset();
   }
-#else
-  if (video_type.codec == media::VideoCodec::kH264) {
-    *js_error_message = "H.264 decoding is not supported.";
-    return absl::nullopt;
-  }
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
   // Guess 720p if no coded size hint is provided. This choice should result in
   // a preference for hardware decode.
@@ -522,12 +541,8 @@
     String* js_error_message) {
   DCHECK(js_error_message);
   absl::optional<media::VideoDecoderConfig> media_config =
-      MakeMediaVideoDecoderConfig(config,
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-                                  h264_converter_ /* out */,
-                                  h264_avcc_ /* out */,
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-                                  js_error_message /* out */);
+      MakeMediaVideoDecoderConfigInternal(config, decoder_helper_ /* out */,
+                                          js_error_message /* out */);
   if (media_config)
     current_codec_ = media_config->codec();
   return media_config;
@@ -536,14 +551,13 @@
 media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>>
 VideoDecoder::MakeDecoderBuffer(const InputType& chunk, bool verify_key_frame) {
   scoped_refptr<media::DecoderBuffer> decoder_buffer = chunk.buffer();
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  if (h264_converter_) {
+  if (decoder_helper_) {
     const uint8_t* src = chunk.buffer()->data();
     size_t src_size = chunk.buffer()->data_size();
 
     // Note: this may not be safe if support for SharedArrayBuffers is added.
-    uint32_t output_size = h264_converter_->CalculateNeededOutputBufferSize(
-        src, static_cast<uint32_t>(src_size), h264_avcc_.get());
+    uint32_t output_size = decoder_helper_->CalculateNeededOutputBufferSize(
+        src, static_cast<uint32_t>(src_size));
     if (!output_size) {
       return media::DecoderStatus(
           media::DecoderStatus::Codes::kMalformedBitstream,
@@ -551,9 +565,9 @@
     }
 
     std::vector<uint8_t> buf(output_size);
-    if (!h264_converter_->ConvertNalUnitStreamToByteStream(
-            src, static_cast<uint32_t>(src_size), h264_avcc_.get(), buf.data(),
-            &output_size)) {
+    if (decoder_helper_->ConvertNalUnitStreamToByteStream(
+            src, static_cast<uint32_t>(src_size), buf.data(), &output_size) !=
+        VideoDecoderHelper::Status::kSucceed) {
       return media::DecoderStatus(
           media::DecoderStatus::Codes::kMalformedBitstream,
           "Unable to convert NALU to byte stream.");
@@ -563,7 +577,6 @@
     decoder_buffer->set_timestamp(chunk.buffer()->timestamp());
     decoder_buffer->set_duration(chunk.buffer()->duration());
   }
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
   bool is_key_frame = chunk.type() == "key";
   if (verify_key_frame) {
@@ -579,7 +592,7 @@
       // Use a more helpful error message if we think the user may have forgot
       // to provide a description for AVC H.264. We could try to guess at the
       // NAL unit size and see if a NAL unit parses out, but this seems fine.
-      if (!is_key_frame && !h264_converter_) {
+      if (!is_key_frame && !decoder_helper_) {
         return media::DecoderStatus(
             media::DecoderStatus::Codes::kKeyFrameRequired,
             "A key frame is required after configure() or flush(). If you're "
@@ -587,6 +600,20 @@
             "in the VideoDecoderConfig.");
       }
 #endif
+    } else if (current_codec_ == media::VideoCodec::kHEVC) {
+      ParseH265KeyFrame(*decoder_buffer, &is_key_frame);
+
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+      if (!is_key_frame && !decoder_helper_) {
+        return media::DecoderStatus(
+            media::DecoderStatus::Codes::kKeyFrameRequired,
+            "A key frame is required after configure() or flush(). If you're "
+            "using HEVC formatted H.265 you must fill out the description "
+            "field in the VideoDecoderConfig.");
+      }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
     }
 
     if (!is_key_frame) {
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/third_party/blink/renderer/modules/webcodecs/video_decoder.h
index 7910f8a..d3a4495 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.h
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_webcodecs_error_callback.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/modules/webcodecs/decoder_template.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_decoder_helper.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/heap/member.h"
@@ -29,13 +30,6 @@
 class DecoderBuffer;
 class MediaLog;
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-class H264ToAnnexBBitstreamConverter;
-namespace mp4 {
-struct AVCDecoderConfigurationRecord;
-}
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
 }  // namespace media
 
 namespace blink {
@@ -100,15 +94,11 @@
       const VideoDecoderConfig& config,
       String* js_error_message);
 
-  // For use by MediaSource and by ::MakeMediaConfig.
+  // For use by MediaSource
   static absl::optional<media::VideoDecoderConfig> MakeMediaVideoDecoderConfig(
       const ConfigType& config,
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-      std::unique_ptr<media::H264ToAnnexBBitstreamConverter>&
-          out_h264_converter,
-      std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord>& out_h264_avcc,
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-      String* js_error_message);
+      String* js_error_message,
+      bool* needs_converter_out = nullptr);
 
   VideoDecoder(ScriptState*, const VideoDecoderInit*, ExceptionState&);
   ~VideoDecoder() override = default;
@@ -125,10 +115,8 @@
   media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>>
   MakeDecoderBuffer(const InputType& input, bool verify_key_frame) override;
 
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  std::unique_ptr<media::H264ToAnnexBBitstreamConverter> h264_converter_;
-  std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord> h264_avcc_;
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  // Bitstream converter to annex B for AVC/HEVC.
+  std::unique_ptr<VideoDecoderHelper> decoder_helper_;
 
   media::VideoCodec current_codec_ = media::VideoCodec::kUnknown;
 
@@ -137,6 +125,13 @@
   HardwarePreference GetHardwarePreference(const ConfigType& config) override;
   bool GetLowDelayPreference(const ConfigType& config) override;
   void SetHardwarePreference(HardwarePreference preference) override;
+  // For use by ::MakeMediaConfig
+  static absl::optional<media::VideoDecoderConfig>
+  MakeMediaVideoDecoderConfigInternal(
+      const ConfigType& config,
+      std::unique_ptr<VideoDecoderHelper>& decoder_helper,
+      String* js_error_message,
+      bool* needs_converter_out = nullptr);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.cc
new file mode 100644
index 0000000..7c4f62b
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.cc
@@ -0,0 +1,141 @@
+// 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 "third_party/blink/renderer/modules/webcodecs/video_decoder_helper.h"
+
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+#include "media/filters/h264_to_annex_b_bitstream_converter.h"  // nogncheck
+#include "media/formats/mp4/box_definitions.h"                  // nogncheck
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#include "media/filters/h265_to_annex_b_bitstream_converter.h"  // nogncheck
+#include "media/formats/mp4/hevc.h"                             // nogncheck
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+#include "media/base/media_types.h"
+
+namespace blink {
+
+// static
+std::unique_ptr<VideoDecoderHelper> VideoDecoderHelper::Create(
+    media::VideoType video_type,
+    const uint8_t* configuration_record,
+    int configuration_record_size,
+    Status* status_out) {
+  DCHECK(configuration_record);
+  DCHECK(configuration_record_size);
+  DCHECK(status_out);
+  std::unique_ptr<VideoDecoderHelper> decoder_helper = nullptr;
+  if (video_type.codec != media::VideoCodec::kH264 &&
+      video_type.codec != media::VideoCodec::kHEVC) {
+    *status_out = Status::kUnsupportedCodec;
+  } else {
+#if !BUILDFLAG(USE_PROPRIETARY_CODECS)
+    if (video_type.codec == media::VideoCodec::kH264) {
+      *status_out = Status::kUnsupportedCodec;
+      return nullptr;
+    }
+#endif  // !BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if !BUILDFLAG(USE_PROPRIETARY_CODECS) || !BUILDFLAG(ENABLE_PLATFORM_HEVC)
+    if (video_type.codec == media::VideoCodec::kHEVC) {
+      *status_out = Status::kUnsupportedCodec;
+      return nullptr;
+    }
+#endif  // !BUILDFLAG(USE_PROPRIETARY_CODECS) ||
+        // !BUILDFLAG(ENABLE_PLATFORM_HEVC)
+
+    decoder_helper = std::make_unique<VideoDecoderHelper>(video_type);
+    *status_out = decoder_helper->Initialize(configuration_record,
+                                             configuration_record_size);
+  }
+  if (*status_out != Status::kSucceed) {
+    decoder_helper.reset();
+    return nullptr;
+  } else {
+    return decoder_helper;
+  }
+}
+
+VideoDecoderHelper::VideoDecoderHelper(media::VideoType video_type) {
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+  if (video_type.codec == media::VideoCodec::kH264) {
+    h264_avcc_ = std::make_unique<media::mp4::AVCDecoderConfigurationRecord>();
+    h264_converter_ = std::make_unique<media::H264ToAnnexBBitstreamConverter>();
+  }
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  if (video_type.codec == media::VideoCodec::kHEVC) {
+    h265_hvcc_ = std::make_unique<media::mp4::HEVCDecoderConfigurationRecord>();
+    h265_converter_ = std::make_unique<media::H265ToAnnexBBitstreamConverter>();
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+}
+
+VideoDecoderHelper::~VideoDecoderHelper() = default;
+
+VideoDecoderHelper::Status VideoDecoderHelper::Initialize(
+    const uint8_t* configuration_record,
+    int configuration_record_size) {
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+  bool initialized = false;
+  if (h264_converter_ && h264_avcc_) {
+    initialized = h264_converter_->ParseConfiguration(
+        configuration_record, configuration_record_size, h264_avcc_.get());
+  }
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  else if (h265_converter_ && h265_hvcc_) {
+    initialized = h265_converter_->ParseConfiguration(
+        configuration_record, configuration_record_size, h265_hvcc_.get());
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  if (initialized) {
+    return Status::kSucceed;
+  } else {
+    return Status::kDescriptionParseFailed;
+  }
+#else
+  return Status::kUnsupportedCodec;
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+}
+
+uint32_t VideoDecoderHelper::CalculateNeededOutputBufferSize(
+    const uint8_t* input,
+    uint32_t input_size) const {
+  uint32_t output_size = 0;
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+  if (h264_converter_ && h264_avcc_) {
+    output_size = h264_converter_->CalculateNeededOutputBufferSize(
+        input, input_size, h264_avcc_.get());
+  }
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  else if (h265_converter_ && h265_hvcc_) {
+    output_size = h265_converter_->CalculateNeededOutputBufferSize(
+        input, input_size, h265_hvcc_.get());
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  return output_size;
+}
+
+VideoDecoderHelper::Status VideoDecoderHelper::ConvertNalUnitStreamToByteStream(
+    const uint8_t* input,
+    uint32_t input_size,
+    uint8_t* output,
+    uint32_t* output_size) {
+  bool converted = false;
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+  if (h264_converter_ && h264_avcc_) {
+    converted = h264_converter_->ConvertNalUnitStreamToByteStream(
+        input, input_size, h264_avcc_.get(), output, output_size);
+  }
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  else if (h265_converter_ && h265_hvcc_) {
+    converted = h265_converter_->ConvertNalUnitStreamToByteStream(
+        input, input_size, h265_hvcc_.get(), output, output_size);
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  return converted ? Status::kSucceed : Status::kBitstreamConvertFailed;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.h b/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.h
new file mode 100644
index 0000000..b08e9e7
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_helper.h
@@ -0,0 +1,115 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_HELPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_HELPER_H_
+
+#include <memory>
+
+#include "media/base/media_types.h"
+#include "media/media_buildflags.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace media {
+
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+class H264ToAnnexBBitstreamConverter;
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+class H265ToAnnexBBitstreamConverter;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+namespace mp4 {
+struct AVCDecoderConfigurationRecord;
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+struct HEVCDecoderConfigurationRecord;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+}  // namespace mp4
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+
+}  // namespace media
+
+namespace blink {
+
+// VideoDecoderHelper is a class to convert stream from MP4 format (as
+// specified in ISO/IEC 14496-15) into Annex B bytestream (as specified
+// in ISO/IEC 14496-10). It is a shim to the underlying
+// H264ToAnnexBBitstreamConverter or H265ToAnnexBBitstreamConverter.
+class MODULES_EXPORT VideoDecoderHelper {
+ public:
+  enum class Status : uint8_t {
+    kGenericFailure,
+    kDescriptionParseFailed,
+    kUnsupportedCodec,
+    kBitstreamConvertFailed,
+    kSucceed,
+    kNumEvents,
+  };
+  explicit VideoDecoderHelper(media::VideoType video_type);
+  VideoDecoderHelper(const VideoDecoderHelper&) = delete;
+  VideoDecoderHelper& operator=(const VideoDecoderHelper&) = delete;
+
+  ~VideoDecoderHelper();
+
+  // Create an instance of this class. Failure reason  will be reported
+  // via |status_out|.
+  static std::unique_ptr<VideoDecoderHelper> Create(
+      media::VideoType video_type,
+      const uint8_t* configuration_record,
+      int configuration_record_size,
+      Status* status_out);
+
+  // Calculates needed buffer size for the bitstream converted into bytestream.
+  //
+  // Parameters
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
+  //   input_size
+  //     Size of the buffer in bytes.
+  // Returns
+  //   Required buffer size for the output NAL unit buffer when converted to
+  //   bytestream format, or 0 if could not determine the size of the output
+  //   buffer from the data in |input|.
+  uint32_t CalculateNeededOutputBufferSize(const uint8_t* input,
+                                           uint32_t input_size) const;
+
+  // ConvertNalUnitStreamToByteStream converts the NAL unit from MP4 format
+  // to bytestream format. Client is responsible for making sure the output
+  // buffer is large enough to hold the output data. Client can precalculate the
+  // needed output buffer size by using CalculateNeededOutputBufferSize.
+  //
+  // Parameters
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
+  //   input_size
+  //     Size of the buffer in bytes.
+  //   output
+  //     Pointer to buffer where the output should be written to.
+  //   output_size (i/o)
+  //     Pointer to the size of the output buffer. Will contain the number of
+  //     bytes written to output after successful call.
+  //
+  // Returns
+  //    kSucceed  if successful conversion
+  //    kBitstreamConvertFailed if conversion not successful (output_size will
+  //    hold the amount of converted data)
+  Status ConvertNalUnitStreamToByteStream(const uint8_t* input,
+                                          uint32_t input_size,
+                                          uint8_t* output,
+                                          uint32_t* output_size);
+
+ private:
+  Status Initialize(const uint8_t* configuration_record,
+                    int configuration_record_size);
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+  std::unique_ptr<media::H264ToAnnexBBitstreamConverter> h264_converter_;
+  std::unique_ptr<media::mp4::AVCDecoderConfigurationRecord> h264_avcc_;
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+  std::unique_ptr<media::H265ToAnnexBBitstreamConverter> h265_converter_;
+  std::unique_ptr<media::mp4::HEVCDecoderConfigurationRecord> h265_hvcc_;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_HELPER_H_
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
index 43a368b..058a097a 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
@@ -413,7 +413,7 @@
               device->GetHandle()),
           nullptr /*mailbox_texture*/,
           absl::nullopt /*media_video_frame_unique_id*/);
-  external_texture->Destroy();
+
   return external_texture;
 }
 
@@ -513,12 +513,10 @@
 }
 
 void GPUExternalTexture::Destroy() {
-  if (status_ == Status::Destroyed)
-    return;
+  DCHECK(!destroyed());
+  DCHECK(mailbox_texture_);
 
   status_ = Status::Destroyed;
-
-  DCHECK(mailbox_texture_);
   mailbox_texture_.reset();
 }
 
@@ -539,7 +537,7 @@
   DCHECK(video_);
   DCHECK(media_video_frame_unique_id_.has_value());
 
-  if (expired())
+  if (destroyed())
     return false;
 
   WebMediaPlayer* media_player = video_->GetWebMediaPlayer();
@@ -577,9 +575,6 @@
 }
 
 void GPUExternalTexture::ExpireExternalTexture() {
-  if (expired())
-    return;
-
   device()->RemoveActiveExternalTexture(this);
   Destroy();
 }
@@ -602,6 +597,9 @@
 void GPUExternalTexture::OnVideoFrameClosed() {
   DCHECK(task_runner_);
 
+  if (destroyed())
+    return;
+
   // Expire the GPUExternalTexture here in the main thread to prevent it from
   // being used again (because WebGPU runs on the main thread). Expiring the
   // texture later in ExpireExternalTextureFromVideoFrame() could occur on a
@@ -625,4 +623,8 @@
   return status_ == Status::Expired || status_ == Status::Destroyed;
 }
 
+bool GPUExternalTexture::destroyed() const {
+  return status_ == Status::Destroyed;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
index 9f35f2a..1cdd2d3b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
@@ -109,6 +109,8 @@
 
   void ExpireExternalTexture();
 
+  bool destroyed() const;
+
   scoped_refptr<WebGPUMailboxTexture> mailbox_texture_;
 
   absl::optional<int> media_video_frame_unique_id_;
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc b/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
index 0577f1c4..f04269a 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
@@ -224,7 +224,7 @@
   ++num_cached_new_subsequences_;
 
   if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
-    EnsureUnderInvalidationChecker().WouldUseCachedSubsequence(client);
+    EnsureUnderInvalidationChecker().WouldUseCachedSubsequence(client.Id());
     // Return false to let the painter actually paint. We will check if the new
     // painting is the same as the cached one.
     return false;
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.cc b/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.cc
index b254548..7a03acf 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.cc
@@ -27,19 +27,19 @@
 bool PaintUnderInvalidationChecker::IsChecking() const {
   if (old_item_index_ != kNotFound) {
     DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled());
-    DCHECK(!subsequence_client_ ||
+    DCHECK(subsequence_client_id_ == kInvalidDisplayItemClientId ||
            (old_chunk_index_ != kNotFound && new_chunk_index_ != kNotFound));
     return true;
   }
 
-  DCHECK(!subsequence_client_);
+  DCHECK_EQ(subsequence_client_id_, kInvalidDisplayItemClientId);
   DCHECK_EQ(old_chunk_index_, kNotFound);
   DCHECK_EQ(new_chunk_index_, kNotFound);
   return false;
 }
 
 bool PaintUnderInvalidationChecker::IsCheckingSubsequence() const {
-  if (subsequence_client_) {
+  if (subsequence_client_id_ != kInvalidDisplayItemClientId) {
     DCHECK(IsChecking());
     return true;
   }
@@ -51,7 +51,7 @@
   old_chunk_index_ = kNotFound;
   new_chunk_index_ = kNotFound;
   old_item_index_ = kNotFound;
-  subsequence_client_ = nullptr;
+  subsequence_client_id_ = kInvalidDisplayItemClientId;
 }
 
 void PaintUnderInvalidationChecker::WouldUseCachedItem(
@@ -91,7 +91,7 @@
       old_item.IsCacheable() ? PaintInvalidationReason::kNone
                              : PaintInvalidationReason::kUncacheable);
 
-  if (subsequence_client_) {
+  if (subsequence_client_id_ != kInvalidDisplayItemClientId) {
     // We are checking under-invalidation of a cached subsequence.
     ++old_item_index_;
   } else {
@@ -101,15 +101,15 @@
 }
 
 void PaintUnderInvalidationChecker::WouldUseCachedSubsequence(
-    const DisplayItemClient& client) {
+    DisplayItemClientId client_id) {
   DCHECK(!IsChecking());
 
-  const auto* markers = paint_controller_.GetSubsequenceMarkers(client.Id());
+  const auto* markers = paint_controller_.GetSubsequenceMarkers(client_id);
   DCHECK(markers);
   old_chunk_index_ = markers->start_chunk_index;
   new_chunk_index_ = NewPaintChunks().size();
   old_item_index_ = OldPaintChunks()[markers->start_chunk_index].begin_index;
-  subsequence_client_ = &client;
+  subsequence_client_id_ = client_id;
 }
 
 void PaintUnderInvalidationChecker::CheckNewChunk() {
@@ -151,14 +151,14 @@
     }
   }
 
-  if (subsequence_client_->Id() == client_id)
+  if (subsequence_client_id_ == client_id)
     Stop();
 }
 
 void PaintUnderInvalidationChecker::CheckNewChunkInternal() {
-  DCHECK(subsequence_client_);
+  DCHECK_NE(subsequence_client_id_, kInvalidDisplayItemClientId);
   const auto* markers =
-      paint_controller_.GetSubsequenceMarkers(subsequence_client_->Id());
+      paint_controller_.GetSubsequenceMarkers(subsequence_client_id_);
   DCHECK(markers);
   const auto& new_chunk = NewPaintChunks()[new_chunk_index_];
   if (old_chunk_index_ >= markers->end_chunk_index) {
@@ -179,9 +179,11 @@
     const char* reason,
     const DisplayItem& new_item,
     const DisplayItem* old_item) const {
-  if (subsequence_client_) {
+  if (subsequence_client_id_ != kInvalidDisplayItemClientId) {
     LOG(ERROR) << "(In cached subsequence for "
-               << subsequence_client_->DebugName() << ")";
+               << paint_controller_.new_paint_artifact_->ClientDebugName(
+                      subsequence_client_id_)
+               << ")";
   }
   LOG(ERROR) << "Under-invalidation: " << reason;
 #if DCHECK_IS_ON()
@@ -217,14 +219,16 @@
     DisplayItemClientId client_id,
     const PaintChunk* new_chunk,
     const PaintChunk* old_chunk) {
-  if (subsequence_client_) {
+  if (subsequence_client_id_ != kInvalidDisplayItemClientId) {
     LOG(ERROR) << "(In cached subsequence for "
-               << subsequence_client_->DebugName() << ")";
+               << paint_controller_.new_paint_artifact_->ClientDebugName(
+                      subsequence_client_id_)
+               << ")";
   }
   LOG(ERROR) << "Under-invalidation: " << reason;
   if (client_id != kInvalidDisplayItemClientId) {
-    // |client| may be different from |subsequence_client_| if the error occurs
-    // in a descendant subsequence of the cached subsequence.
+    // |client_id| may be different from |subsequence_client_id_| if the error
+    // occurs in a descendant subsequence of the cached subsequence.
     LOG(ERROR) << "Subsequence client: "
                << paint_controller_.new_paint_artifact_->ClientDebugName(
                       client_id);
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.h b/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.h
index 1cae282..33efdc7 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_under_invalidation_checker.h
@@ -6,13 +6,11 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_UNDER_INVALIDATION_CHECKER_H_
 
 #include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
 
 class DisplayItem;
-class DisplayItemClient;
 class DisplayItemList;
 class PaintController;
 struct PaintChunk;
@@ -37,7 +35,7 @@
   // Called from PaintController::UseCachedSubsequenceIfPossible() to inform
   // that PaintController would use a cached subsequence if we were not checking
   // under-invalidations.
-  void WouldUseCachedSubsequence(const DisplayItemClient&);
+  void WouldUseCachedSubsequence(DisplayItemClientId);
   void CheckNewChunk();
   void WillEndSubsequence(DisplayItemClientId client_id,
                           wtf_size_t start_chunk_index);
@@ -70,7 +68,8 @@
   // Points to the next new paint chunk which will be checked when it's
   // complete.
   wtf_size_t new_chunk_index_ = kNotFound;
-  WeakPersistent<const DisplayItemClient> subsequence_client_ = nullptr;
+
+  DisplayItemClientId subsequence_client_id_ = kInvalidDisplayItemClientId;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.cc b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.cc
index 04d2dc7..cf32bbf 100644
--- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.cc
+++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.cc
@@ -147,7 +147,17 @@
   DCHECK(ri);
   unsigned query_id = 0;
   ri->GenQueriesEXT(1, &query_id);
-  ri->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query_id);
+
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+  // On Windows and Mac, GMB data read will do synchronization on its own.
+  // No need for GL_COMMANDS_COMPLETED_CHROMIUM QueryEXT.
+  GLenum queryTarget = GL_COMMANDS_ISSUED_CHROMIUM;
+#else
+  // QueryEXT functions are used to make sure that CopyRGBATextureToVideoFrame()
+  // texture copy is complete before we access GMB data.
+  GLenum queryTarget = GL_COMMANDS_COMPLETED_CHROMIUM;
+#endif
+  ri->BeginQueryEXT(queryTarget, query_id);
 
   const bool copy_succeeded = media::CopyRGBATextureToVideoFrame(
       raster_context_provider, src_format, src_size, src_color_space,
@@ -157,9 +167,7 @@
     return false;
   }
 
-  // QueryEXT functions are used to make sure that CopyRGBATextureToVideoFrame()
-  // texture copy before we access GMB data.
-  ri->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
+  ri->EndQueryEXT(queryTarget);
 
   auto on_query_done_cb =
       [](scoped_refptr<media::VideoFrame> frame,
diff --git a/third_party/blink/renderer/platform/loader/child_url_loader_factory_bundle.cc b/third_party/blink/renderer/platform/loader/child_url_loader_factory_bundle.cc
index d3a7424..65a7e9e 100644
--- a/third_party/blink/renderer/platform/loader/child_url_loader_factory_bundle.cc
+++ b/third_party/blink/renderer/platform/loader/child_url_loader_factory_bundle.cc
@@ -72,9 +72,12 @@
     client_sink_->OnReceiveEarlyHints(std::move(early_hints));
   }
 
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head,
-                         mojo::ScopedDataPipeConsumerHandle body) override {
-    client_sink_->OnReceiveResponse(std::move(head), std::move(body));
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override {
+    client_sink_->OnReceiveResponse(std::move(head), std::move(body),
+                                    std::move(cached_metadata));
   }
 
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -89,10 +92,6 @@
                                    std::move(callback));
   }
 
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {
-    client_sink_->OnReceiveCachedMetadata(std::move(data));
-  }
-
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
     client_sink_->OnTransferSizeUpdated(transfer_size_diff);
   }
@@ -196,7 +195,8 @@
     mojo::Remote<network::mojom::URLLoaderClient> client_remote(
         std::move(client));
     client_remote->OnReceiveResponse(std::move(transferrable_loader->head),
-                                     std::move(transferrable_loader->body));
+                                     std::move(transferrable_loader->body),
+                                     absl::nullopt);
     mojo::MakeSelfOwnedReceiver(
         std::make_unique<URLLoaderRelay>(
             std::move(transferrable_loader->url_loader),
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
index bfa833c3..0615ba2 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
@@ -324,7 +324,8 @@
 
 void MojoURLLoaderClient::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   TRACE_EVENT1("loading", "MojoURLLoaderClient::OnReceiveResponse", "url",
                last_loaded_url_.GetString().Utf8());
 
@@ -343,6 +344,23 @@
   if (!weak_this)
     return;
 
+  // Send the cached metadata, if any, before starting to load the body, so that
+  // resources using the cached data (e.g. script resources deserialising the
+  // code cache) immediately know whether the cache is available before starting
+  // to process the response body.
+  if (cached_metadata) {
+    if (NeedsStoringMessage()) {
+      StoreAndDispatch(std::make_unique<DeferredOnReceiveCachedMetadata>(
+          std::move(*cached_metadata)));
+    } else {
+      resource_request_sender_->OnReceivedCachedMetadata(
+          std::move(*cached_metadata));
+    }
+
+    if (!weak_this)
+      return;
+  }
+
   if (!body)
     return;
 
@@ -461,15 +479,6 @@
   std::move(ack_callback).Run();
 }
 
-void MojoURLLoaderClient::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  if (NeedsStoringMessage()) {
-    StoreAndDispatch(
-        std::make_unique<DeferredOnReceiveCachedMetadata>(std::move(data)));
-  } else {
-    resource_request_sender_->OnReceivedCachedMetadata(std::move(data));
-  }
-}
-
 void MojoURLLoaderClient::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   if (NeedsStoringMessage()) {
     accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.h
index a56efee..7c06b6e 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.h
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.h
@@ -59,15 +59,16 @@
 
   // network::mojom::URLLoaderClient implementation
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback ack_callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client_unittest.cc
index 6d3d3cb..ab87af27 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client_unittest.cc
@@ -269,7 +269,8 @@
 
 TEST_P(WebMojoURLLoaderClientTest, OnReceiveResponse) {
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        mojo::ScopedDataPipeConsumerHandle());
+                                        mojo::ScopedDataPipeConsumerHandle(),
+                                        absl::nullopt);
 
   EXPECT_FALSE(context_->received_response);
   base::RunLoop().RunUntilIdle();
@@ -283,7 +284,8 @@
   EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, data_pipe_producer,
                                                  data_pipe_consumer));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
 
   EXPECT_FALSE(context_->received_response);
   base::RunLoop().RunUntilIdle();
@@ -310,14 +312,14 @@
   EXPECT_EQ(1, context_->seen_redirects);
 }
 
-TEST_P(WebMojoURLLoaderClientTest, OnReceiveCachedMetadata) {
+TEST_P(WebMojoURLLoaderClientTest, OnReceiveResponseWithCachedMetadata) {
   std::vector<uint8_t> data;
   data.push_back('a');
   mojo_base::BigBuffer metadata(data);
 
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        mojo::ScopedDataPipeConsumerHandle());
-  url_loader_client_->OnReceiveCachedMetadata(std::move(metadata));
+                                        mojo::ScopedDataPipeConsumerHandle(),
+                                        std::move(metadata));
 
   EXPECT_FALSE(context_->received_response);
   EXPECT_EQ(0u, context_->cached_metadata.size());
@@ -329,7 +331,8 @@
 
 TEST_P(WebMojoURLLoaderClientTest, OnTransferSizeUpdated) {
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        mojo::ScopedDataPipeConsumerHandle());
+                                        mojo::ScopedDataPipeConsumerHandle(),
+                                        absl::nullopt);
   url_loader_client_->OnTransferSizeUpdated(4);
   url_loader_client_->OnTransferSizeUpdated(4);
 
@@ -349,7 +352,8 @@
   EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, data_pipe_producer,
                                                  data_pipe_consumer));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   uint32_t size = 5;
   MojoResult result =
       data_pipe_producer->WriteData("hello", &size, MOJO_WRITE_DATA_FLAG_NONE);
@@ -385,7 +389,8 @@
   EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, data_pipe_producer,
                                                  data_pipe_consumer));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnComplete(status);
 
   base::RunLoop().RunUntilIdle();
@@ -413,7 +418,8 @@
   EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, data_pipe_producer,
                                                  data_pipe_consumer));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnComplete(status);
 
   EXPECT_FALSE(context_->received_response);
@@ -436,7 +442,8 @@
                                                  data_pipe_consumer));
   data_pipe_producer.reset();  // Empty body.
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnComplete(status);
 
   EXPECT_FALSE(context_->received_response);
@@ -473,7 +480,8 @@
   data_pipe_producer.reset();
 
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnComplete(status);
 
   EXPECT_FALSE(context_->received_response);
@@ -509,7 +517,8 @@
   ASSERT_EQ(MOJO_RESULT_OK,
             mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(consumer_handle));
+                                        std::move(consumer_handle),
+                                        absl::nullopt);
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(context_->received_response);
   EXPECT_FALSE(context_->complete);
@@ -574,7 +583,8 @@
   ASSERT_EQ(MOJO_RESULT_OK,
             mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(consumer_handle));
+                                        std::move(consumer_handle),
+                                        absl::nullopt);
   network::URLLoaderCompletionStatus status;
   url_loader_client_->OnComplete(status);
   base::RunLoop().RunUntilIdle();
@@ -633,7 +643,8 @@
   ASSERT_EQ(MOJO_RESULT_OK,
             mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle));
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(consumer_handle));
+                                        std::move(consumer_handle),
+                                        absl::nullopt);
   network::URLLoaderCompletionStatus status;
   url_loader_client_->OnComplete(status);
   base::RunLoop().RunUntilIdle();
@@ -705,7 +716,8 @@
   data_pipe_producer.reset();
 
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnTransferSizeUpdated(4);
   url_loader_client_->OnComplete(status);
 
@@ -756,7 +768,8 @@
   data_pipe_producer.reset();
 
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
   url_loader_client_->OnTransferSizeUpdated(4);
   url_loader_client_->OnComplete(status);
 
@@ -813,7 +826,8 @@
                                                  data_pipe_consumer));
   data_pipe_producer.reset();  // Empty body.
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New(),
-                                        std::move(data_pipe_consumer));
+                                        std::move(data_pipe_consumer),
+                                        absl::nullopt);
 
   url_loader_client_->OnTransferSizeUpdated(4);
   url_loader_client_->OnComplete(status);
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
index 8376d4c..9b2cde9a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
@@ -61,7 +61,8 @@
 
 void NavigationBodyLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    mojo::ScopedDataPipeConsumerHandle body,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // This has already happened in the browser process.
   NOTREACHED();
 }
@@ -80,20 +81,6 @@
   NOTREACHED();
 }
 
-void NavigationBodyLoader::OnReceiveCachedMetadata(mojo_base::BigBuffer data) {
-  // Even if IsolatedCodeCaching is landed, this code is still used by
-  // ServiceWorker.
-  // TODO(horo, kinuko): Make a test to cover this function.
-  // TODO(https://crbug.com/930000): Add support for inline script code caching
-  // with the service worker service.
-  base::UmaHistogramBoolean(
-      base::StrCat({"V8.InlineCodeCache.",
-                    is_main_frame_ ? "MainFrame" : "Subframe",
-                    ".CacheTimesMatch"}),
-      true);
-  client_->BodyCodeCacheReceived(std::move(data));
-}
-
 void NavigationBodyLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
   resource_load_info_notifier_wrapper_->NotifyResourceTransferSizeUpdated(
       transfer_size_diff);
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
index b2534e4..77c75ae 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
@@ -90,15 +90,16 @@
 
   // network::mojom::URLLoaderClient implementation.
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle body,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_resource_request_sender_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_resource_request_sender_unittest.cc
index e8ba6a33..96673e0 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_resource_request_sender_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_resource_request_sender_unittest.cc
@@ -229,7 +229,7 @@
     head->headers = new net::HttpResponseHeaders(raw_headers);
     head->mime_type = kTestPageMimeType;
     head->charset = kTestPageCharset;
-    client->OnReceiveResponse(std::move(head), std::move(body));
+    client->OnReceiveResponse(std::move(head), std::move(body), absl::nullopt);
   }
 
   std::unique_ptr<network::ResourceRequest> CreateResourceRequest() {
@@ -419,7 +419,8 @@
         std::move(loader_and_clients_[0].second));
     loader_and_clients_.clear();
     client->OnReceiveResponse(std::move(response_head),
-                              mojo::ScopedDataPipeConsumerHandle());
+                              mojo::ScopedDataPipeConsumerHandle(),
+                              absl::nullopt);
   }
 
   const network::mojom::URLResponseHead& response_info() const {
@@ -501,7 +502,7 @@
               MOJO_RESULT_OK);
 
     client->OnReceiveResponse(std::move(response_head),
-                              std::move(consumer_handle));
+                              std::move(consumer_handle), absl::nullopt);
     producer_handle.reset();  // The response is empty.
 
     network::URLLoaderCompletionStatus status;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
index 712bae90..cc82baa7 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
@@ -130,7 +130,8 @@
 
 void WorkerMainScriptLoader::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr response_head,
-    mojo::ScopedDataPipeConsumerHandle handle) {
+    mojo::ScopedDataPipeConsumerHandle handle,
+    absl::optional<mojo_base::BigBuffer> cached_metadata) {
   // This has already happened in the browser process.
   NOTREACHED();
 }
@@ -150,9 +151,6 @@
   NOTREACHED();
 }
 
-void WorkerMainScriptLoader::OnReceiveCachedMetadata(
-    mojo_base::BigBuffer data) {}
-
 void WorkerMainScriptLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
 }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.h
index 2c35e75..600b493 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.h
@@ -61,15 +61,16 @@
 
   // Implements network::mojom::URLLoaderClient.
   void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
-  void OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head,
-                         mojo::ScopedDataPipeConsumerHandle handle) override;
+  void OnReceiveResponse(
+      network::mojom::URLResponseHeadPtr response_head,
+      mojo::ScopedDataPipeConsumerHandle handle,
+      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(
       const net::RedirectInfo& redirect_info,
       network::mojom::URLResponseHeadPtr response_head) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
                         OnUploadProgressCallback callback) override;
-  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 3a80d7bc..f3a615a 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2503,6 +2503,11 @@
       name: "WebAuthenticationConditionalUI",
       status: "test",
     },
+    // https://github.com/w3c/webauthn/pull/1663
+    {
+      name: "WebAuthenticationDevicePublicKey",
+      status: "experimental",
+    },
     {
       name: "WebAuthenticationLargeBlobExtension",
       status: "experimental",
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index 440933a..2b1fcd9 100644
--- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -100,7 +100,6 @@
   void DidCommitProvisionalLoad(bool, FrameScheduler::NavigationType) override {
   }
   void OnFirstContentfulPaintInMainFrame() override {}
-  void OnDomContentLoaded() override {}
   void OnFirstMeaningfulPaint() override {}
   void OnLoad() override {}
   bool IsExemptFromBudgetBasedThrottling() const override { return false; }
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.cc b/third_party/blink/renderer/platform/scheduler/common/features.cc
index 4aee285..020e33b 100644
--- a/third_party/blink/renderer/platform/scheduler/common/features.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/features.cc
@@ -94,22 +94,6 @@
       kForegroundTimersThrottledWakeUpIntervalMills.Get());
 }
 
-const base::Feature kDeprioritizeDOMTimersDuringPageLoading{
-    "DeprioritizeDOMTimersDuringPageLoading",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
-const base::FeatureParam<DeprioritizeDOMTimersPhase>::Option
-    kDeprioritizeDOMTimersPhaseOptions[] = {
-        {DeprioritizeDOMTimersPhase::kOnDOMContentLoaded, "ondomcontentloaded"},
-        {DeprioritizeDOMTimersPhase::kFirstContentfulPaint, "fcp"},
-        {DeprioritizeDOMTimersPhase::kOnLoad, "onload"}};
-
-const base::FeatureParam<DeprioritizeDOMTimersPhase>
-    kDeprioritizeDOMTimersPhase{&kDeprioritizeDOMTimersDuringPageLoading,
-                                "phase",
-                                DeprioritizeDOMTimersPhase::kOnDOMContentLoaded,
-                                &kDeprioritizeDOMTimersPhaseOptions};
-
 const base::Feature kThreadedScrollPreventRenderingStarvation{
     "ThreadedScrollPreventRenderingStarvation",
     base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.h b/third_party/blink/renderer/platform/scheduler/common/features.h
index 1028cdb..5330284 100644
--- a/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -132,26 +132,6 @@
 // feature is enabled.
 PLATFORM_EXPORT base::TimeDelta GetForegroundTimersThrottledWakeUpInterval();
 
-// Deprioritizes JS timer tasks during a particular phase of page loading.
-PLATFORM_EXPORT extern const base::Feature
-    kDeprioritizeDOMTimersDuringPageLoading;
-
-// The phase in which we deprioritize JS timer tasks.
-enum class DeprioritizeDOMTimersPhase {
-  // Until the DOMContentLoaded event is fired.
-  kOnDOMContentLoaded,
-  // Until First Contentful Paint is reached.
-  kFirstContentfulPaint,
-  // Until the load event is fired.
-  kOnLoad,
-};
-
-PLATFORM_EXPORT extern const base::FeatureParam<
-    DeprioritizeDOMTimersPhase>::Option kDeprioritizeDOMTimersPhaseOptions[];
-
-PLATFORM_EXPORT extern const base::FeatureParam<DeprioritizeDOMTimersPhase>
-    kDeprioritizeDOMTimersPhase;
-
 // Finch flag for preventing rendering starvation during threaded scrolling.
 // With this feature enabled, the existing delay-based rendering anti-starvation
 // applies, and the compositor task queue priority is controlled with the
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 63dcd55..5b72dd03 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -168,11 +168,6 @@
           "FrameScheduler.PageVisibility",
           &tracing_controller_,
           PageVisibilityStateToString),
-      waiting_for_dom_content_loaded_(
-          true,
-          "FrameScheduler.WaitingForDOMContentLoaded",
-          &tracing_controller_,
-          YesNoStateToString),
       waiting_for_contentful_paint_(true,
                                     "FrameScheduler.WaitingForContentfulPaint",
                                     &tracing_controller_,
@@ -181,10 +176,6 @@
                                     "FrameScheduler.WaitingForMeaningfulPaint",
                                     &tracing_controller_,
                                     YesNoStateToString),
-      waiting_for_load_(true,
-                        "FrameScheduler.WaitingForLoad",
-                        &tracing_controller_,
-                        YesNoStateToString),
       loading_power_mode_voter_(
           power_scheduler::PowerModeArbiter::GetInstance()->NewVoter(
               "PowerModeVoter.Loading")) {
@@ -594,20 +585,8 @@
     loading_power_mode_voter_->ResetVoteAfterTimeout(
         power_scheduler::PowerModeVoter::kStuckLoadingTimeout);
 
-    waiting_for_dom_content_loaded_ = true;
     waiting_for_contentful_paint_ = true;
     waiting_for_meaningful_paint_ = true;
-    waiting_for_load_ = true;
-
-    // If DeprioritizeDOMTimersDuringPageLoading is enabled, UpdatePolicy()
-    // needs to be called to change JavaScript timer task queues to low priority
-    // during reload and other navigations.
-    //
-    // TODO(shaseley): Think about merging this with MainThreadSchedulerImpl's
-    // policy update.
-    if (base::FeatureList::IsEnabled(kDeprioritizeDOMTimersDuringPageLoading)) {
-      UpdatePolicy();
-    }
   }
 
   if (is_outermost_main_frame && !is_same_document) {
@@ -835,20 +814,9 @@
 void FrameSchedulerImpl::OnFirstContentfulPaintInMainFrame() {
   waiting_for_contentful_paint_ = false;
   DCHECK_EQ(GetFrameType(), FrameScheduler::FrameType::kMainFrame);
-  parent_page_scheduler_->OnFirstContentfulPaintInMainFrame();
   main_thread_scheduler_->OnMainFramePaint();
 }
 
-void FrameSchedulerImpl::OnDomContentLoaded() {
-  waiting_for_dom_content_loaded_ = false;
-
-  if (base::FeatureList::IsEnabled(kDeprioritizeDOMTimersDuringPageLoading) &&
-      kDeprioritizeDOMTimersPhase.Get() ==
-          DeprioritizeDOMTimersPhase::kOnDOMContentLoaded) {
-    UpdatePolicy();
-  }
-}
-
 void FrameSchedulerImpl::OnFirstMeaningfulPaint() {
   waiting_for_meaningful_paint_ = false;
 
@@ -861,19 +829,6 @@
 }
 
 void FrameSchedulerImpl::OnLoad() {
-  waiting_for_load_ = false;
-
-  // FrameSchedulerImpl::OnFirstContentfulPaint() is NOT guaranteed to be called
-  // during the loading process, so we also try to do the recomputation in case
-  // of the DeprioritizeDOMTimersPhase::kFirstContentfulPaint option.
-  if (base::FeatureList::IsEnabled(kDeprioritizeDOMTimersDuringPageLoading) &&
-      (kDeprioritizeDOMTimersPhase.Get() ==
-           DeprioritizeDOMTimersPhase::kOnLoad ||
-       kDeprioritizeDOMTimersPhase.Get() ==
-           DeprioritizeDOMTimersPhase::kFirstContentfulPaint)) {
-    UpdatePolicy();
-  }
-
   loading_power_mode_voter_->ResetVoteAfterTimeout(
       power_scheduler::PowerModeVoter::kLoadingTimeout);
 }
@@ -1042,23 +997,6 @@
     return TaskQueue::QueuePriority::kHighestPriority;
   }
 
-  // Deprioritize JS timer tasks to speed up the page loading process.
-  if (base::FeatureList::IsEnabled(kDeprioritizeDOMTimersDuringPageLoading) &&
-      task_queue->GetPrioritisationType() ==
-          MainThreadTaskQueue::QueueTraits::PrioritisationType::
-              kJavaScriptTimer &&
-      waiting_for_load_ &&
-      (kDeprioritizeDOMTimersPhase.Get() ==
-           DeprioritizeDOMTimersPhase::kOnLoad ||
-       (kDeprioritizeDOMTimersPhase.Get() ==
-            DeprioritizeDOMTimersPhase::kOnDOMContentLoaded &&
-        waiting_for_dom_content_loaded_) ||
-       (kDeprioritizeDOMTimersPhase.Get() ==
-            DeprioritizeDOMTimersPhase::kFirstContentfulPaint &&
-        parent_page_scheduler_->IsWaitingForMainFrameContentfulPaint()))) {
-    return TaskQueue::QueuePriority::kLowPriority;
-  }
-
   if (task_queue->GetPrioritisationType() ==
           MainThreadTaskQueue::QueueTraits::PrioritisationType::kInput &&
       base::FeatureList::IsEnabled(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index b61751b..e3e7009 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -122,7 +122,6 @@
   scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
 
   void OnFirstContentfulPaintInMainFrame() override;
-  void OnDomContentLoaded() override;
   void OnFirstMeaningfulPaint() override;
   void OnLoad() override;
   bool IsWaitingForContentfulPaint() const;
@@ -343,10 +342,8 @@
   TraceableState<PageVisibilityState, TracingCategory::kInfo>
       page_visibility_for_tracing_;
 
-  TraceableState<bool, TracingCategory::kInfo> waiting_for_dom_content_loaded_;
   TraceableState<bool, TracingCategory::kInfo> waiting_for_contentful_paint_;
   TraceableState<bool, TracingCategory::kInfo> waiting_for_meaningful_paint_;
-  TraceableState<bool, TracingCategory::kInfo> waiting_for_load_;
 
   std::unique_ptr<power_scheduler::PowerModeVoter> loading_power_mode_voter_;
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index 7cfd92b7..6be6cec2 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -424,27 +424,6 @@
             PrioritisationType::kJavaScriptTimer));
   }
 
-  scoped_refptr<MainThreadTaskQueue>
-  JavaScriptTimerNormalThrottleableTaskQueueForFrame(
-      FrameSchedulerImpl* frame_scheduler) {
-    return GetTaskQueueForFrame(frame_scheduler,
-                                TaskType::kJavascriptTimerDelayedLowNesting);
-  }
-
-  scoped_refptr<MainThreadTaskQueue>
-  JavaScriptTimerIntensivelyThrottleableTaskQueueForFrame(
-      FrameSchedulerImpl* frame_scheduler) {
-    return GetTaskQueueForFrame(frame_scheduler,
-                                TaskType::kJavascriptTimerDelayedHighNesting);
-  }
-
-  scoped_refptr<MainThreadTaskQueue>
-  JavaScriptTimerNonThrottleableTaskQueueForFrame(
-      FrameSchedulerImpl* frame_scheduler) {
-    return GetTaskQueueForFrame(frame_scheduler,
-                                TaskType::kJavascriptTimerImmediate);
-  }
-
   scoped_refptr<MainThreadTaskQueue> LoadingTaskQueue() {
     return GetTaskQueue(FrameSchedulerImpl::LoadingTaskQueueTraits());
   }
@@ -482,12 +461,6 @@
     return frame_scheduler_->GetTaskQueue(type);
   }
 
-  scoped_refptr<MainThreadTaskQueue> GetTaskQueueForFrame(
-      FrameSchedulerImpl* frame_scheduler,
-      TaskType type) {
-    return frame_scheduler->GetTaskQueue(type);
-  }
-
   std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl>
   GetResourceLoadingTaskRunnerHandleImpl() {
     return frame_scheduler_->CreateResourceLoadingTaskRunnerHandleImpl();
@@ -514,21 +487,6 @@
         /*is_web_history_inert_commit=*/false, navigation_type);
   }
 
-  void DidCommitProvisionalLoadForFrame(
-      FrameSchedulerImpl* frame_scheduler,
-      FrameScheduler::NavigationType navigation_type) {
-    frame_scheduler->DidCommitProvisionalLoad(
-        /*is_web_history_inert_commit=*/false, navigation_type);
-  }
-
-  void OnDomContentLoadedForFrame(FrameSchedulerImpl* frame_scheduler) {
-    frame_scheduler->OnDomContentLoaded();
-  }
-
-  void OnLoadForFrame(FrameSchedulerImpl* frame_scheduler) {
-    frame_scheduler->OnLoad();
-  }
-
   base::test::ScopedFeatureList& scoped_feature_list() { return feature_list_; }
 
   base::test::ScopedFeatureList feature_list_;
@@ -3147,244 +3105,6 @@
             GetIntensiveWakeUpThrottlingGracePeriod(false));
 }
 
-class DeprioritizeDOMTimerTest : public FrameSchedulerImplTest {
- public:
-  DeprioritizeDOMTimerTest(DeprioritizeDOMTimersPhase phase)
-      : FrameSchedulerImplTest(
-            blink::scheduler::kDeprioritizeDOMTimersDuringPageLoading,
-            base::FieldTrialParams(
-                {{"phase", blink::scheduler::kDeprioritizeDOMTimersPhase
-                               .GetName(phase)}}),
-            {}) {}
-
-  void SetUp() override {
-    FrameSchedulerImplTest::SetUp();
-    scheduler_of_main_frame_ = CreateFrameScheduler(
-        page_scheduler_.get(), frame_scheduler_delegate_.get(),
-        /*is_in_embedded_frame_tree=*/false,
-        FrameScheduler::FrameType::kMainFrame);
-  }
-
-  void TearDown() override {
-    scheduler_of_main_frame_.reset();
-    FrameSchedulerImplTest::TearDown();
-  }
-
-  void ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      FrameSchedulerImpl* frame_scheduler,
-      TaskQueue::QueuePriority expected_priority) {
-    EXPECT_EQ(
-        JavaScriptTimerNormalThrottleableTaskQueueForFrame(frame_scheduler)
-            ->GetQueuePriority(),
-        expected_priority);
-    EXPECT_EQ(
-        JavaScriptTimerIntensivelyThrottleableTaskQueueForFrame(frame_scheduler)
-            ->GetQueuePriority(),
-        expected_priority);
-    EXPECT_EQ(JavaScriptTimerNonThrottleableTaskQueueForFrame(frame_scheduler)
-                  ->GetQueuePriority(),
-              expected_priority);
-  }
-
- protected:
-  std::unique_ptr<FrameSchedulerImpl> scheduler_of_main_frame_;
-};
-
-class DeprioritizeDOMTimerUntilDOMContentLoadedTest
-    : public DeprioritizeDOMTimerTest {
- public:
-  DeprioritizeDOMTimerUntilDOMContentLoadedTest()
-      : DeprioritizeDOMTimerTest(
-            DeprioritizeDOMTimersPhase::kOnDOMContentLoaded) {}
-};
-
-// Test whether the JavaScript timer task queues' priorities are properly
-// updated on DOMContentLoaded event for frame load and reloads.
-TEST_F(DeprioritizeDOMTimerUntilDOMContentLoadedTest,
-       MainAndNonMainFrameLoadAndReload) {
-  FrameSchedulerImpl* frame_schedulers[2] = {scheduler_of_main_frame_.get(),
-                                             frame_scheduler_.get()};
-  for (FrameSchedulerImpl* frame_scheduler : frame_schedulers) {
-    // Initial priority is low.
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal when DOMContentLoaded triggered.
-    OnDomContentLoadedForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After reload navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kReload);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal when DOMContentLoaded triggered.
-    OnDomContentLoadedForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After other type navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kOther);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal when DOMContentLoaded triggered.
-    OnDomContentLoadedForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-  }
-}
-
-class DeprioritizeDOMTimerUntilFCPTest : public DeprioritizeDOMTimerTest {
- public:
-  DeprioritizeDOMTimerUntilFCPTest()
-      : DeprioritizeDOMTimerTest(
-            DeprioritizeDOMTimersPhase::kFirstContentfulPaint) {}
-};
-
-// Test whether the JavaScript timer task queues' priorities are properly
-// updated when FCP is triggered for frame load and reloads.
-TEST_F(DeprioritizeDOMTimerUntilFCPTest, MainAndNonMainFrameLoadAndReload) {
-  // Initial priorities are low.
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(), TaskQueue::QueuePriority::kLowPriority);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kLowPriority);
-
-  // Priority is set to normal when FCP triggered.
-  scheduler_of_main_frame_->OnFirstContentfulPaintInMainFrame();
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(),
-      TaskQueue::QueuePriority::kNormalPriority);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kNormalPriority);
-
-  // After reload type navigation, priority is reset to low.
-  DidCommitProvisionalLoadForFrame(scheduler_of_main_frame_.get(),
-                                   FrameScheduler::NavigationType::kReload);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(), TaskQueue::QueuePriority::kLowPriority);
-
-  DidCommitProvisionalLoadForFrame(frame_scheduler_.get(),
-                                   FrameScheduler::NavigationType::kReload);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kLowPriority);
-
-  // Priority is set to normal when FCP triggered.
-  scheduler_of_main_frame_->OnFirstContentfulPaintInMainFrame();
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(),
-      TaskQueue::QueuePriority::kNormalPriority);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kNormalPriority);
-
-  // After other type navigation, priority is reset to low.
-  DidCommitProvisionalLoadForFrame(scheduler_of_main_frame_.get(),
-                                   FrameScheduler::NavigationType::kOther);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(), TaskQueue::QueuePriority::kLowPriority);
-
-  DidCommitProvisionalLoadForFrame(frame_scheduler_.get(),
-                                   FrameScheduler::NavigationType::kOther);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kLowPriority);
-
-  // Priority is set to normal when FCP triggered.
-  scheduler_of_main_frame_->OnFirstContentfulPaintInMainFrame();
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      scheduler_of_main_frame_.get(),
-      TaskQueue::QueuePriority::kNormalPriority);
-  ExpectJavaScriptTimerTaskQueuePriorityToBe(
-      frame_scheduler_.get(), TaskQueue::QueuePriority::kNormalPriority);
-}
-
-// Test that if FCP is not triggered, the JavaScript timer task queues'
-// priorities are updated when load is triggered.
-TEST_F(DeprioritizeDOMTimerUntilFCPTest, FCPNotTriggered) {
-  FrameSchedulerImpl* frame_schedulers[2] = {scheduler_of_main_frame_.get(),
-                                             frame_scheduler_.get()};
-  for (FrameSchedulerImpl* frame_scheduler : frame_schedulers) {
-    // Initial priority is low.
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After reload type navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kReload);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After other type navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kOther);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-  }
-}
-
-class DeprioritizeDOMTimerUntilLoadedTest : public DeprioritizeDOMTimerTest {
- public:
-  DeprioritizeDOMTimerUntilLoadedTest()
-      : DeprioritizeDOMTimerTest(DeprioritizeDOMTimersPhase::kOnLoad) {}
-};
-
-// Test whether the JavaScript timer task queues' priorities are properly
-// updated on load event for frame load and reloads.
-TEST_F(DeprioritizeDOMTimerUntilLoadedTest, MainAndNonMainFrameLoadAndReload) {
-  FrameSchedulerImpl* frame_schedulers[2] = {scheduler_of_main_frame_.get(),
-                                             frame_scheduler_.get()};
-  for (FrameSchedulerImpl* frame_scheduler : frame_schedulers) {
-    // Initial priority is low.
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After reload type navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kReload);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-
-    // After other type navigation, priority is reset to low.
-    DidCommitProvisionalLoadForFrame(frame_scheduler,
-                                     FrameScheduler::NavigationType::kOther);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kLowPriority);
-
-    // Priority is set to normal on load event.
-    OnLoadForFrame(frame_scheduler);
-    ExpectJavaScriptTimerTaskQueuePriorityToBe(
-        frame_scheduler, TaskQueue::QueuePriority::kNormalPriority);
-  }
-}
-
 // Verify that non-delayed kWebSchedulingPostedTask tasks are not throttled.
 TEST_F(FrameSchedulerImplTest, ImmediateWebSchedulingTasksAreNotThrottled) {
   std::vector<base::TimeTicks> run_times;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index 400094e..c708a2e 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -493,16 +493,6 @@
   }
 }
 
-void PageSchedulerImpl::OnFirstContentfulPaintInMainFrame() {
-  // Now we get the FCP notification here only for the main frame, notify all
-  // frames within the page to recompute priority for JS timer tasks.
-  if (base::FeatureList::IsEnabled(kDeprioritizeDOMTimersDuringPageLoading) &&
-      kDeprioritizeDOMTimersPhase.Get() ==
-          DeprioritizeDOMTimersPhase::kFirstContentfulPaint) {
-    NotifyFrames();
-  }
-}
-
 bool PageSchedulerImpl::IsWaitingForMainFrameContentfulPaint() const {
   return std::any_of(frame_schedulers_.begin(), frame_schedulers_.end(),
                      [](const FrameSchedulerImpl* fs) {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 66671aa..538e4bb 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -112,8 +112,6 @@
 
   void OnTraceLogEnabled();
 
-  void OnFirstContentfulPaintInMainFrame();
-
   // Virtual for testing.
   virtual bool IsWaitingForMainFrameContentfulPaint() const;
   virtual bool IsWaitingForMainFrameMeaningfulPaint() const;
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
index 9ff0059..48ac65f 100644
--- a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -150,10 +150,6 @@
   virtual void DidCommitProvisionalLoad(bool is_web_history_inert_commit,
                                         NavigationType navigation_type) = 0;
 
-  // Tells the scheduler that the "DOMContentLoaded" event has occurred for this
-  // frame.
-  virtual void OnDomContentLoaded() = 0;
-
   // Tells the scheduler that the first contentful paint has occurred for this
   // frame. Only for main frames.
   virtual void OnFirstContentfulPaintInMainFrame() = 0;
diff --git a/third_party/blink/renderer/platform/text_codec_fuzzer.cc b/third_party/blink/renderer/platform/text_codec_fuzzer.cc
index 28a477f5..c69be64 100644
--- a/third_party/blink/renderer/platform/text_codec_fuzzer.cc
+++ b/third_party/blink/renderer/platform/text_codec_fuzzer.cc
@@ -65,16 +65,18 @@
 
   // Treat as blink 8-bit string (latin1).
   if (size % sizeof(LChar) == 0) {
-    std::unique_ptr<TextCodec> codec = NewTextCodec(encoding);
-    codec->Encode(reinterpret_cast<const LChar*>(byte_string.data()),
-                  byte_string.length() / sizeof(LChar), unencodable_handling);
+    std::unique_ptr<TextCodec> lchar_codec = NewTextCodec(encoding);
+    lchar_codec->Encode(reinterpret_cast<const LChar*>(byte_string.data()),
+                        byte_string.length() / sizeof(LChar),
+                        unencodable_handling);
   }
 
   // Treat as blink 16-bit string (utf-16) if there are an even number of bytes.
   if (size % sizeof(UChar) == 0) {
-    std::unique_ptr<TextCodec> codec = NewTextCodec(encoding);
-    codec->Encode(reinterpret_cast<const UChar*>(byte_string.data()),
-                  byte_string.length() / sizeof(UChar), unencodable_handling);
+    std::unique_ptr<TextCodec> uchar_codec = NewTextCodec(encoding);
+    uchar_codec->Encode(reinterpret_cast<const UChar*>(byte_string.data()),
+                        byte_string.length() / sizeof(UChar),
+                        unencodable_handling);
   }
 
   if (decoded.IsNull())
diff --git a/third_party/blink/tools/blinkpy/common/checkout/git.py b/third_party/blink/tools/blinkpy/common/checkout/git.py
index 94e7618a..62452e86 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/git.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/git.py
@@ -145,6 +145,10 @@
             command.extend(['--', pathspec])
         return self.run(command) != ''
 
+    def uncommitted_changes(self):
+        """List files with uncommitted changes, including untracked files."""
+        return [path for _, _, path in self._working_changes()]
+
     def unstaged_changes(self):
         """Lists files with unstaged changes, including untracked files.
 
@@ -152,20 +156,24 @@
         to one-character codes identifying the change, e.g. 'M' for modified,
         'D' for deleted, '?' for untracked.
         """
+        return {
+            path: unstaged_status
+            for _, unstaged_status, path in self._working_changes()
+            if unstaged_status
+        }
+
+    def _working_changes(self):
         # `git status -z` is a version of `git status -s`, that's recommended
         # for machine parsing. Lines are terminated with NUL rather than LF.
-        change_lines = self.run(['status', '-z',
-                                 '--untracked-files=all']).rstrip('\x00')
+        change_lines = self.run(
+            ['status', '-z', '--no-renames',
+             '--untracked-files=all']).rstrip('\x00')
         if not change_lines:
-            return {}  # No changes.
-        unstaged_changes = {}
+            return
         for line in change_lines.split('\x00'):
             assert len(line) >= 4, 'Unexpected change line format %s' % line
-            if line[1] == ' ':
-                continue  # Already staged for commit.
             path = line[3:]
-            unstaged_changes[path] = line[1]
-        return unstaged_changes
+            yield line[0].strip(), line[1].strip(), path
 
     def add_list(self, paths, return_exit_code=False):
         return self.run(['add'] + paths, return_exit_code=return_exit_code)
diff --git a/third_party/blink/tools/blinkpy/common/checkout/git_mock.py b/third_party/blink/tools/blinkpy/common/checkout/git_mock.py
index f5494d29..e2e895c 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/git_mock.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/git_mock.py
@@ -104,3 +104,6 @@
 
     def unstaged_changes(self):
         return {}
+
+    def uncommitted_changes(self):
+        return []
diff --git a/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
index 23e5899..2ce832b 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
@@ -232,3 +232,29 @@
                 'd/untracked.txt': '?',
                 'a': '?',
             })
+
+    def test_uncommitted_changes(self):
+        git = self.make_git()
+        status_lines = [
+            ' M d/modified.txt',
+            ' D d/deleted.txt',
+            '?? d/untracked.txt',
+            '?? a',
+            'D  d/deleted.txt',
+            'M  d/modified-staged.txt',
+            'A  d/added-staged.txt',
+            'AM d/added-then-modified.txt',
+            'MM d/modified-then-modified.txt',
+        ]
+        git.run = lambda args: '\x00'.join(status_lines) + '\x00'
+        self.assertEqual(git.uncommitted_changes(), [
+            'd/modified.txt',
+            'd/deleted.txt',
+            'd/untracked.txt',
+            'a',
+            'd/deleted.txt',
+            'd/modified-staged.txt',
+            'd/added-staged.txt',
+            'd/added-then-modified.txt',
+            'd/modified-then-modified.txt',
+        ])
diff --git a/third_party/blink/tools/blinkpy/tool/blink_tool_unittest.py b/third_party/blink/tools/blinkpy/tool/blink_tool_unittest.py
index b85ae5c4..187b04c 100644
--- a/third_party/blink/tools/blinkpy/tool/blink_tool_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/blink_tool_unittest.py
@@ -3,11 +3,17 @@
 # found in the LICENSE file.
 
 import unittest
+from unittest.mock import patch
 
+from blinkpy.common.checkout.git_mock import MockGit
 from blinkpy.common.system.output_capture import OutputCapture
 from blinkpy.tool.blink_tool import BlinkTool
 
 
+# Avoid creating a real `Git` object, since it runs a command in its
+# constructor.
+@patch('blinkpy.tool.blink_tool.BlinkTool.git',
+       lambda self, path=None: MockGit(path))
 class BlinkToolTest(unittest.TestCase):
     def test_split_args_basic(self):
         self.assertEqual(
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
index 725cd121e..5e3b1d5 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
@@ -12,12 +12,20 @@
 import pathlib
 import optparse
 import re
-from typing import Iterator, List, Literal, Mapping, Optional
+from typing import (
+    Iterable,
+    Iterator,
+    List,
+    Literal,
+    Mapping,
+    Optional,
+)
 
 from blinkpy.common import path_finder
 from blinkpy.common.host import Host
 from blinkpy.common.net.git_cl import BuildStatuses, GitCL
 from blinkpy.common.net.rpc import Build, RPCError
+from blinkpy.tool import grammar
 from blinkpy.tool.commands.build_resolver import (
     BuildResolver,
     UnresolvedBuildException,
@@ -116,8 +124,14 @@
         # to reduce download overhead. Expected results should be filtered out
         # (similar to '{full,failing}_results.json') and messages removed.
         self._io_pool = ThreadPoolExecutor(max_workers=max_io_workers)
+        self._path_finder = path_finder.PathFinder(self._tool.filesystem)
+        self.git = self._tool.git(path=self._path_finder.web_tests_dir())
         self.git_cl = git_cl or GitCL(self._tool)
 
+    @property
+    def _fs(self):
+        return self._tool.filesystem
+
     def execute(self, options: optparse.Values, args: List[str],
                 _tool: Host) -> Optional[int]:
         build_resolver = BuildResolver(
@@ -125,36 +139,104 @@
             self.git_cl,
             can_trigger_jobs=(options.trigger_jobs and not options.dry_run))
         updater = MetadataUpdater.from_path_finder(
-            path_finder.PathFinder(self._tool.filesystem),
+            self._path_finder,
             self._explicit_include_patterns(options, args),
             overwrite_conditions=options.overwrite_conditions,
             disable_intermittent=options.disable_intermittent,
             keep_statuses=options.keep_statuses,
-            bug=options.bug)
+            bug=options.bug,
+            dry_run=options.dry_run)
         try:
+            test_files = updater.test_files_to_update()
+            if options.only_changed_tests:
+                test_files = self._filter_unchanged_test_files(test_files)
+            self._check_test_files(test_files)
             build_statuses = build_resolver.resolve_builds(
                 self._select_builds(options), options.patchset)
             with contextlib.ExitStack() as stack:
                 stack.enter_context(self._trace('Updated metadata'))
                 stack.enter_context(self._io_pool)
-                for report in self.gather_reports(build_statuses,
-                                                  options.reports or []):
-                    updater.collect_results(report)
-                test_files = updater.test_files_to_update()
-                for i, test_file in enumerate(
-                        self._io_pool.map(updater.update, test_files)):
-                    _log.info("Updated '%s' (%d/%d)",
-                              pathlib.Path(test_file.test_path).as_posix(),
-                              i + 1, len(test_files))
+                updater.collect_results(
+                    self.gather_reports(build_statuses, options.reports or []))
+                self.update_and_stage(updater,
+                                      test_files,
+                                      dry_run=options.dry_run)
         except RPCError as error:
             _log.error('%s', error)
             _log.error('Request payload: %s',
                        json.dumps(error.request_body, indent=2))
             return 1
-        except (UnresolvedBuildException, OSError) as error:
+        except (UnresolvedBuildException, UpdateAbortError, OSError) as error:
             _log.error('%s', error)
             return 1
 
+    def update_and_stage(self,
+                         updater: 'MetadataUpdater',
+                         test_files: List[metadata.TestFileData],
+                         dry_run: bool = False,
+                         chunk_size: int = 128):
+        test_files_to_stage = []
+        update_results = self._io_pool.map(updater.update, test_files)
+        for i, (test_file,
+                modified) in enumerate(zip(test_files, update_results)):
+            test_path = pathlib.Path(test_file.test_path).as_posix()
+            _log.info("Updated '%s' (%d/%d%s)", test_path, i + 1,
+                      len(test_files), ', modified' if modified else '')
+            if modified:
+                test_files_to_stage.append(test_file)
+
+        if not dry_run:
+            paths = self._metadata_paths(test_files_to_stage)
+            # Stage the files in chunks to avoid a Windows command line length
+            # limit. The chunk size was picked heuristically.
+            for chunk_start in range(0, len(paths), chunk_size):
+                self.git.add_list(paths[chunk_start:chunk_start + chunk_size])
+            _log.info(
+                'Staged %s.',
+                grammar.pluralize('metadata file', len(test_files_to_stage)))
+
+    def _filter_unchanged_test_files(
+            self,
+            test_files: List[metadata.TestFileData],
+    ) -> List[metadata.TestFileData]:
+        files_changed_since_branch = {
+            self._path_finder.path_from_chromium_base(path)
+            for path in self.git.changed_files(diff_filter='AM')
+        }
+        return [
+            test_file for test_file in test_files
+            if self._fs.join(test_file.metadata_path, test_file.test_path) in
+            files_changed_since_branch
+        ]
+
+    def _check_test_files(self, test_files: List[metadata.TestFileData]):
+        if not test_files:
+            raise UpdateAbortError('No metadata to update.')
+        uncommitted_changes = {
+            self._path_finder.path_from_chromium_base(path)
+            for path in self.git.uncommitted_changes()
+        }
+        metadata_paths = set(self._metadata_paths(test_files))
+        uncommitted_metadata = uncommitted_changes & metadata_paths
+        if uncommitted_metadata:
+            _log.error('Aborting: there are uncommitted metadata files:')
+            web_tests_root = self._path_finder.web_tests_dir()
+            for path in sorted(uncommitted_metadata):
+                rel_path = pathlib.Path(path).relative_to(web_tests_root)
+                _log.error('  %s', rel_path.as_posix())
+            raise UpdateAbortError('Please commit or reset these files '
+                                   'to continue.')
+
+    def _metadata_paths(
+            self,
+            test_files: List[metadata.TestFileData],
+    ) -> List[str]:
+        return [
+            metadata.expected_path(test_file.metadata_path,
+                                   test_file.test_path)
+            for test_file in test_files
+        ]
+
     def _select_builds(self, options: optparse.Values) -> List[Build]:
         if options.builds:
             return options.builds
@@ -212,9 +294,8 @@
             urls: List[str],
             report_paths: List[str],
     ) -> Iterator[io.TextIOBase]:
-        fs = self._tool.filesystem
         for path in report_paths:
-            with fs.open_text_file_for_reading(path) as file_handle:
+            with self._fs.open_text_file_for_reading(path) as file_handle:
                 yield file_handle
             _log.debug('Read report from %r', path)
         responses = self._io_pool.map(self._tool.web.get_binary, urls)
@@ -235,14 +316,13 @@
     def _append_reports(self, option: optparse.Option, _opt_str: str,
                         value: str, parser: optparse.OptionParser):
         reports = getattr(parser.values, option.dest, None) or []
-        fs = self._tool.filesystem
-        path = fs.expanduser(value)
-        if fs.isfile(path):
+        path = self._fs.expanduser(value)
+        if self._fs.isfile(path):
             reports.append(path)
-        elif fs.isdir(path):
-            for filename in fs.listdir(path):
-                child_path = fs.join(path, filename)
-                if fs.isfile(child_path):
+        elif self._fs.isdir(path):
+            for filename in self._fs.listdir(path):
+                child_path = self._fs.join(path, filename)
+                if self._fs.isfile(child_path):
                     reports.append(child_path)
         else:
             raise optparse.OptionValueError(
@@ -250,6 +330,10 @@
         setattr(parser.values, option.dest, reports)
 
 
+class UpdateAbortError(Exception):
+    """Exception raised when the update should be aborted."""
+
+
 TestFileMap = Mapping[str, metadata.TestFileData]
 
 
@@ -264,9 +348,9 @@
             disable_intermittent: Optional[str] = None,
             keep_statuses: bool = False,
             bug: Optional[int] = None,
+            dry_run: bool = False,
     ):
         self._test_files = test_files
-        self._updater = metadata.ExpectedUpdater(self._test_files)
         self._default_expected = _default_expected_by_type()
         self._primary_properties = primary_properties or [
             'debug',
@@ -283,6 +367,7 @@
         self._disable_intermittent = disable_intermittent
         self._keep_statuses = keep_statuses
         self._bug = bug
+        self._dry_run = dry_run
 
     @classmethod
     def from_path_finder(
@@ -332,9 +417,11 @@
                 metadata.create_test_tree(paths['metadata_path'], manifest))
         return MetadataUpdater(test_files, **options)
 
-    def collect_results(self, report: io.TextIOBase):
+    def collect_results(self, reports: Iterable[io.TextIOBase]):
         """Parse and record test results."""
-        self._updater.update_from_log(report)
+        updater = metadata.ExpectedUpdater(self._test_files)
+        for report in reports:
+            updater.update_from_log(report)
 
     def test_files_to_update(self) -> List[metadata.TestFileData]:
         test_files = {
@@ -357,8 +444,12 @@
         else:
             return False
 
-    def update(self, test_file: metadata.TestFileData):
-        """Update the AST of each metadata file and serialize them to disk."""
+    def update(self, test_file: metadata.TestFileData) -> bool:
+        """Update and serialize the AST of a metadata file.
+
+        Returns:
+            Whether the test file's metadata was modified.
+        """
         expected = test_file.update(
             self._default_expected,
             (self._primary_properties, self._dependent_properties),
@@ -369,11 +460,14 @@
             #   https://github.com/web-platform-tests/wpt/blob/merge_pr_35624/tools/wptrunner/wptrunner/manifestupdate.py#L422-L436
             update_intermittent=(not self._disable_intermittent),
             remove_intermittent=(not self._keep_statuses))
-        if expected and expected.modified:
+
+        modified = expected and expected.modified
+        if modified:
             if self._bug:
                 self._add_bug_url(expected)
-            metadata.write_new_expected(test_file.metadata_path, expected)
-        return test_file
+            if not self._dry_run:
+                metadata.write_new_expected(test_file.metadata_path, expected)
+        return modified
 
     def _add_bug_url(self, expected: conditional.ManifestItem):
         for test_id_section in expected.iterchildren():
diff --git a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
index 10e5d582..3f06f5f9 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata_unittest.py
@@ -156,12 +156,17 @@
         self.assertLog([
             'INFO: All builds finished.\n',
             'INFO: Processing wptrunner report (1/1)\n',
-            "INFO: Updated 'crash.html' (1/5)\n",
+            "INFO: Updated 'crash.html' (1/5, modified)\n",
             "INFO: Updated 'dir/multiglob.https.any.js' (2/5)\n",
             "INFO: Updated 'fail.html' (3/5)\n",
             "INFO: Updated 'pass.html' (4/5)\n",
             "INFO: Updated 'variant.html' (5/5)\n",
+            'INFO: Staged 1 metadata file.\n',
         ])
+        self.assertEqual(self.command.git.added_paths, {
+            self.finder.path_from_web_tests('external', 'wpt',
+                                            'crash.html.ini')
+        })
 
     def test_execute_explicit_include_patterns(self):
         self.tool.filesystem.write_text_file(
@@ -184,6 +189,7 @@
             "INFO: Updated 'dir/multiglob.https.any.js' (1/3)\n",
             "INFO: Updated 'pass.html' (2/3)\n",
             "INFO: Updated 'variant.html' (3/3)\n",
+            'INFO: Staged 0 metadata files.\n',
         ])
 
     def test_execute_with_no_issue_number_aborts(self):
@@ -246,6 +252,74 @@
         ])
         self.assertEqual(self.command.git_cl.calls, [])
 
+    def test_execute_dry_run(self):
+        files_before = dict(self.tool.filesystem.files)
+        with self._patch_builtins():
+            exit_code = self.command.main(['--dry-run'])
+        self.assertEqual(exit_code, 0)
+        self.assertLog([
+            'INFO: All builds finished.\n',
+            'INFO: Processing wptrunner report (1/1)\n',
+            "INFO: Updated 'crash.html' (1/5, modified)\n",
+            "INFO: Updated 'dir/multiglob.https.any.js' (2/5)\n",
+            "INFO: Updated 'fail.html' (3/5)\n",
+            "INFO: Updated 'pass.html' (4/5)\n",
+            "INFO: Updated 'variant.html' (5/5)\n",
+        ])
+        self.assertEqual(self.tool.filesystem.files, files_before)
+        self.assertEqual(self.tool.executive.calls, [['luci-auth', 'token']])
+        self.assertEqual(self.tool.git().added_paths, set())
+
+    def test_execute_only_changed_tests(self):
+        changed_files = [
+            'third_party/blink/web_tests/external/wpt/crash.html',
+        ]
+        with self._patch_builtins() as stack:
+            stack.enter_context(
+                patch.object(self.command.git,
+                             'changed_files',
+                             return_value=changed_files))
+            exit_code = self.command.main(['--only-changed-tests'])
+        self.assertEqual(exit_code, 0)
+        self.assertLog([
+            'INFO: All builds finished.\n',
+            'INFO: Processing wptrunner report (1/1)\n',
+            "INFO: Updated 'crash.html' (1/1, modified)\n",
+            'INFO: Staged 1 metadata file.\n',
+        ])
+
+    def test_execute_only_changed_tests_none(self):
+        with self._patch_builtins() as stack:
+            stack.enter_context(
+                patch.object(self.command.git,
+                             'changed_files',
+                             return_value=[]))
+            exit_code = self.command.main(['--only-changed-tests'])
+        self.assertEqual(exit_code, 1)
+        self.assertLog([
+            'ERROR: No metadata to update.\n',
+        ])
+
+    def test_execute_abort_with_uncommitted_change(self):
+        uncommitted_changes = [
+            'third_party/blink/web_tests/external/wpt/fail.html.ini',
+            'third_party/blink/web_tests/external/wpt/pass.html.ini',
+            'third_party/blink/web_tests/external/wpt/variant.html.ini',
+        ]
+        with self._patch_builtins() as stack:
+            stack.enter_context(
+                patch.object(self.command.git,
+                             'uncommitted_changes',
+                             return_value=uncommitted_changes))
+            exit_code = self.command.main(['fail.html', 'pass.html'])
+        self.assertEqual(exit_code, 1)
+        self.assertLog([
+            'ERROR: Aborting: there are uncommitted metadata files:\n',
+            'ERROR:   external/wpt/fail.html.ini\n',
+            'ERROR:   external/wpt/pass.html.ini\n',
+            'ERROR: Please commit or reset these files to continue.\n',
+        ])
+
     def test_gather_reports(self):
         local_report = {
             'run_info': {
@@ -314,7 +388,7 @@
                     **result
                 } for result in report['results']]
                 buf = io.StringIO(json.dumps(report))
-                updater.collect_results(buf)
+                updater.collect_results([buf])
             for test_file in updater.test_files_to_update():
                 updater.update(test_file)
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
index 09e11b1..69f7b04 100644
--- a/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
+++ b/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
@@ -204,15 +204,18 @@
 
         self._printer.write_update('Summarizing results ...')
         summarized_full_results = test_run_results.summarize_results(
-            self._port, self._expectations, initial_results, all_retry_results)
+            self._port, self._options, self._expectations, initial_results,
+            all_retry_results)
         summarized_failing_results = test_run_results.summarize_results(
             self._port,
+            self._options,
             self._expectations,
             initial_results,
             all_retry_results,
             only_include_failing=True)
         run_histories = test_run_results.test_run_histories(
-            self._port, self._expectations, initial_results, all_retry_results)
+            self._options, self._expectations, initial_results,
+            all_retry_results)
 
         exit_code = summarized_failing_results['num_regressions']
         if exit_code > exit_codes.MAX_FAILURES_EXIT_STATUS:
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
index 2e4a92f01..91f6e1a 100644
--- a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
+++ b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
@@ -158,6 +158,7 @@
 
 
 def summarize_results(port_obj,
+                      options,
                       expectations,
                       initial_results,
                       all_retry_results,
@@ -261,6 +262,9 @@
         test_dict['expected'] = expected
         test_dict['actual'] = ' '.join(actual)
 
+        if hasattr(options, 'shard_index'):
+            test_dict['shard'] = options.shard_index
+
         # If a flag was added then add flag specific test expectations to the per test field
         flag_exp = expectations.get_flag_expectations(test_name)
         if flag_exp:
@@ -381,10 +385,14 @@
     results['interrupted'] = initial_results.interrupted
     results['layout_tests_dir'] = port_obj.web_tests_dir()
     results['seconds_since_epoch'] = int(time.time())
-    results['build_number'] = port_obj.get_option('build_number')
-    results['builder_name'] = port_obj.get_option('builder_name')
-    if port_obj.get_option('order') == 'random':
-        results['random_order_seed'] = port_obj.get_option('seed')
+
+    if hasattr(options, 'build_number'):
+        results['build_number'] = options.build_number
+    if hasattr(options, 'builder_name'):
+        results['builder_name'] = options.builder_name
+    if getattr(options, 'order', None) == 'random' and hasattr(
+            options, 'seed'):
+        results['random_order_seed'] = options.seed
     results['path_delimiter'] = '/'
 
     # If there is a flag name then add the flag name field
@@ -394,7 +402,7 @@
     # Don't do this by default since it takes >100ms.
     # It's only used for rebaselining and uploading data to the flakiness dashboard.
     results['chromium_revision'] = ''
-    if port_obj.get_option('builder_name'):
+    if getattr(options, 'builder_name', None):
         path = port_obj.repository_path()
         git = port_obj.host.git(path=path)
         if git:
@@ -450,7 +458,7 @@
     return ret
 
 
-def test_run_histories(port_obj, expectations, initial_results,
+def test_run_histories(options, expectations, initial_results,
                        all_retry_results):
     """Returns a dictionary containing a flattened list of all test runs, with
     the following fields:
@@ -463,8 +471,9 @@
     """
     ret = {}
     ret['version'] = 1
-    if port_obj.get_option('order') == 'random':
-        ret['random_order_seed'] = port_obj.get_option('seed')
+    if getattr(options, 'order', None) == 'random' and hasattr(
+            options, 'seed'):
+        ret['random_order_seed'] = options.seed
 
     run_histories = []
     for test_run_results in [initial_results] + all_retry_results:
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
index dd6f3b4..10536f4 100644
--- a/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
@@ -29,6 +29,7 @@
 import json
 import mock
 import unittest
+import optparse
 
 from blinkpy.common.host_mock import MockHost
 from blinkpy.web_tests.models import test_expectations
@@ -210,6 +211,7 @@
 
 
 def summarized_results(port,
+                       options,
                        expected,
                        passing,
                        flaky,
@@ -219,6 +221,7 @@
         port, expected, passing, flaky, extra_skipped_tests)
     return test_run_results.summarize_results(
         port,
+        options,
         initial_results.expectations,
         initial_results,
         all_retry_results,
@@ -303,16 +306,24 @@
 class SummarizedResultsTest(unittest.TestCase):
     def setUp(self):
         host = MockHost()
-        self.port = host.port_factory.get(port_name='test')
+        self.options = optparse.Values()
+        self.port = host.port_factory.get(port_name='test',
+                                          options=self.options)
 
     def test_no_chromium_revision(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         self.assertNotIn('revision', summary)
 
     def test_num_failures_by_type(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         self.assertEquals(summary['num_failures_by_type'], {
             'CRASH': 1,
             'PASS': 1,
@@ -321,8 +332,11 @@
             'FAIL': 2,
         })
 
-        summary = summarized_results(
-            self.port, expected=True, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=True,
+                                     passing=False,
+                                     flaky=False)
         self.assertEquals(summary['num_failures_by_type'], {
             'CRASH': 1,
             'PASS': 1,
@@ -331,8 +345,11 @@
             'FAIL': 2,
         })
 
-        summary = summarized_results(
-            self.port, expected=False, passing=True, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False)
         self.assertEquals(summary['num_failures_by_type'], {
             'CRASH': 0,
             'PASS': 5,
@@ -342,33 +359,50 @@
         })
 
     def test_chromium_revision(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         self.assertNotEquals(summary['chromium_revision'], '')
 
     def test_bug_entry(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port, expected=False, passing=True, flaky=False)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False)
         self.assertEquals(
             summary['tests']['passes']['skipped']['skip.html']['bugs'],
             ['crbug.com/123'])
 
+    def test_shard_index(self):
+        self.options.shard_index = 42
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False)
+        self.assertEquals(
+            summary['tests']['passes']['skipped']['skip.html']['shard'], 42)
+
     def test_extra_skipped_tests(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port,
-            expected=False,
-            passing=True,
-            flaky=False,
-            extra_skipped_tests=['passes/text.html'])
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False,
+                                     extra_skipped_tests=['passes/text.html'])
         actual = summary['tests']['passes']['text.html']['expected']
         self.assertEquals(sorted(list(actual.split(" "))), ['PASS', 'SKIP'])
 
     def test_summarized_results_image_diff_stats(self):
-        self.port._options.builder_name = 'dummy builder'
+        self.options.builder_name = 'dummy builder'
         summary = summarized_results(self.port,
+                                     self.options,
                                      expected=False,
                                      passing=False,
                                      flaky=False)
@@ -380,9 +414,12 @@
             summary['tests']['failures']['expected']['keyboard.html'])
 
     def test_summarized_results_wontfix(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         actual = summary['tests']['failures']['expected']['keyboard.html'][
             'expected']
         self.assertEquals(sorted(list(actual.split(" "))), ['CRASH', 'SKIP'])
@@ -393,22 +430,25 @@
         self.assertEqual(summary['num_flaky'], 0)
 
     def test_summarized_results_expected_pass(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port, expected=False, passing=True, flaky=False)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False)
         self.assertTrue(summary['tests']['passes']['text.html'])
         self.assertEqual(summary['num_passes'], 5)
         self.assertEqual(summary['num_regressions'], 0)
         self.assertEqual(summary['num_flaky'], 0)
 
     def test_summarized_results_expected_only_include_failing(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port,
-            expected=True,
-            passing=False,
-            flaky=False,
-            only_include_failing=True)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=True,
+                                     passing=False,
+                                     flaky=False,
+                                     only_include_failing=True)
         self.assertNotIn('passes', summary['tests'])
         self.assertTrue(summary['tests']['failures']['expected']['audio.html'])
         self.assertTrue(
@@ -420,29 +460,35 @@
         self.assertEqual(summary['num_flaky'], 0)
 
     def test_summarized_results_skipped(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port, expected=False, passing=True, flaky=False)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False)
         self.assertEquals(
             summary['tests']['passes']['skipped']['skip.html']['expected'],
             'SKIP')
 
     def test_summarized_results_only_include_failing(self):
-        self.port._options.builder_name = 'dummy builder'
-        summary = summarized_results(
-            self.port,
-            expected=False,
-            passing=True,
-            flaky=False,
-            only_include_failing=True)
+        self.options.builder_name = 'dummy builder'
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=True,
+                                     flaky=False,
+                                     only_include_failing=True)
         self.assertTrue('passes' not in summary['tests'])
         self.assertEqual(summary['num_passes'], 5)
         self.assertEqual(summary['num_regressions'], 0)
         self.assertEqual(summary['num_flaky'], 0)
 
     def test_rounded_run_times(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         self.assertEquals(summary['tests']['passes']['text.html']['time'], 1)
         self.assertTrue('time' not in summary['tests']['failures']['expected']
                         ['audio.html'])
@@ -474,8 +520,10 @@
             get_result(test_name, ResultType.Pass, run_time=0.1), False, False)
         all_retry_results[2].add(
             get_result(test_name, ResultType.Pass, run_time=0.1), False, False)
-        summary = test_run_results.summarize_results(
-            self.port, expectations, initial_results, all_retry_results)
+        summary = test_run_results.summarize_results(self.port, self.options,
+                                                     expectations,
+                                                     initial_results,
+                                                     all_retry_results)
         self.assertIn('is_unexpected',
                       summary['tests']['failures']['expected']['text.html'])
         self.assertEquals(
@@ -489,8 +537,11 @@
         self.assertEquals(summary['num_flaky'], 0)
 
     def test_summarized_results_flaky(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=True)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=True)
 
         self.assertEquals(
             summary['tests']['failures']['expected']['crash.html']['expected'],
@@ -561,8 +612,10 @@
             get_result(test_name, ResultType.Pass), True, False)
         all_retry_results[2].add(
             get_result(test_name, ResultType.Pass), True, False)
-        summary = test_run_results.summarize_results(
-            self.port, expectations, initial_results, all_retry_results)
+        summary = test_run_results.summarize_results(self.port, self.options,
+                                                     expectations,
+                                                     initial_results,
+                                                     all_retry_results)
         self.assertTrue(
             'is_unexpected' not in summary['tests']['passes']['text.html'])
         self.assertEquals(summary['tests']['passes']['text.html']['expected'],
@@ -592,8 +645,10 @@
         all_retry_results[0].add(
             get_result(test_name, ResultType.Failure), False, False)
 
-        summary = test_run_results.summarize_results(
-            self.port, expectations, initial_results, all_retry_results)
+        summary = test_run_results.summarize_results(self.port, self.options,
+                                                     expectations,
+                                                     initial_results,
+                                                     all_retry_results)
         self.assertEquals(summary['tests']['passes']['text.html']['expected'],
                           'PASS')
         self.assertEquals(summary['tests']['passes']['text.html']['actual'],
@@ -603,8 +658,11 @@
         self.assertEquals(summary['num_regressions'], 1)
 
     def test_summarized_results_regression(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
 
         self.assertTrue(summary['tests']['failures']['expected']
                         ['timeout.html']['is_unexpected'])
@@ -652,8 +710,11 @@
         self.assertEquals(summary['num_flaky'], 0)
 
     def test_results_contains_path_delimiter(self):
-        summary = summarized_results(
-            self.port, expected=False, passing=False, flaky=False)
+        summary = summarized_results(self.port,
+                                     self.options,
+                                     expected=False,
+                                     passing=False,
+                                     flaky=False)
         self.assertEqual(summary['path_delimiter'], '/')
 
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/results.html b/third_party/blink/tools/blinkpy/web_tests/results.html
index dc88bd44..0309d64 100644
--- a/third_party/blink/tools/blinkpy/web_tests/results.html
+++ b/third_party/blink/tools/blinkpy/web_tests/results.html
@@ -869,6 +869,9 @@
       toolbars.push(new SimpleLinkToolbar().createDom(
             pathParser.resultLink("-command.txt"), "Command", "command"));
     }
+    if (test.shard != undefined && test.shard != "null") {
+      toolbars.push(new PlainHtmlToolbar().createDom("Shard: " + test.shard))
+    }
     return toolbars;
   },
   getResultsDiv: (test) => {
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations
index addc04a..f5e923e 100644
--- a/third_party/blink/web_tests/LeakExpectations
+++ b/third_party/blink/web_tests/LeakExpectations
@@ -60,9 +60,6 @@
 crbug.com/1350279 [ Linux ] external/wpt/accessibility/crashtests/svg-mouse-listener.html [ Failure Pass ]
 
 # Sheriff 2022-08-29
-crbug.com/1356276 [ Linux ] virtual/async-script-scheduling-apply-to-cross-site-only/wpt_internal/async-script-scheduling/execution-order.sub.html [ Failure ]
-
-# Sheriff 2022-08-29
 crbug.com/1357182 [ Linux ] external/wpt/webauthn/getcredential-abort.https.html [ Failure Pass ]
 
 ###########################################################################
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations
index ed4dc262..1a2d16d 100644
--- a/third_party/blink/web_tests/MSANExpectations
+++ b/third_party/blink/web_tests/MSANExpectations
@@ -96,9 +96,9 @@
 crbug.com/1215390 [ Linux ] external/wpt/pointerevents/pointerevent_pointerId_scope.html [ Pass Failure Timeout ]
 
 # Sheriff 2022-08-29
-crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html [ Failure ]
-crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html [ Failure ]
-crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html [ Failure ]
+crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html [ Timeout ]
+crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html [ Timeout ]
+crbug.com/1357443 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html [ Timeout ]
 
 # Flaking on WebKit Linux MSAN
 crbug.com/1126305 [ Linux ] virtual/prerender/external/wpt/speculation-rules/prerender/fetch-blob.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 9edfb45..122f2d8 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1950,6 +1950,8 @@
 crbug.com/1299585 [ Mac11 ] external/wpt/css/css-color-adjust/inheritance.html [ Failure ]
 crbug.com/1299585 external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-mismatch-opaque-cross-origin.sub.html [ Failure Pass ]
 
+crbug.com/1357623 external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-preferred.html [ Failure ]
+
 # @supports
 crbug.com/1269580 external/wpt/css/css-conditional/at-supports-namespace-001.html [ Failure ]
 crbug.com/1269580 external/wpt/css/css-conditional/at-supports-namespace-002.html [ Failure ]
@@ -3268,10 +3270,9 @@
 crbug.com/626703 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html [ Skip Timeout ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Mac10.14 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip Timeout ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip Timeout ]
+crbug.com/626703 [ Win10.20h2 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html [ Failure Crash ]
+crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-quirks-mode.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/MediaRecorder-mimetype.html [ Timeout ]
-crbug.com/626703 [ Mac10.13 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip Timeout ]
 crbug.com/626703 [ Mac12 ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html [ Failure Timeout ]
 crbug.com/626703 [ Win10.20h2 ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html [ Failure Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html [ Skip Timeout ]
@@ -3281,16 +3282,10 @@
 crbug.com/626703 [ Win ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html [ Skip Timeout ]
 crbug.com/626703 [ Mac12 ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html [ Skip Timeout ]
 crbug.com/626703 [ Win ] external/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html [ Skip Timeout ]
-crbug.com/626703 [ Mac11 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip Timeout ]
-crbug.com/626703 [ Mac12 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip Timeout ]
 crbug.com/626703 [ Win10.20h2 ] wpt_internal/orientation-event/motion/page-visibility.https.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-conditional/at-supports-font-format-001.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-conditional/at-supports-font-tech-001.html [ Failure ]
-crbug.com/626703 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-zero-intersection-area.html [ Timeout ]
 crbug.com/626703 [ Mac10.15 ] virtual/document-transition/wpt_internal/document-transition/commit-timeout-crash.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-preferred.html [ Failure ]
-crbug.com/626703 virtual/dark-color-scheme/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-preferred.html [ Failure ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/service-workers/cache-storage/cross-partition.https.tentative.html [ Skip Timeout ]
 crbug.com/626703 external/wpt/custom-elements/form-associated/ElementInternals-target-element-is-held-strongly.html [ Timeout ]
 crbug.com/626703 external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-xml-parser.xhtml [ Crash ]
 crbug.com/626703 [ Linux ] external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-xml-parser.xhtml [ Crash ]
@@ -4149,6 +4144,9 @@
 # Test times out for unknown reasons on chromium-based browsers and Safari.
 crbug.com/1328330 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-move-into-script-disabled-iframe.html [ Timeout ]
 
+# Test times out for some reason on Chromium browsers
+crbug.com/1357623 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-zero-intersection-area.html [ Timeout ]
+
 # Sheriff failures 2017-05-23
 crbug.com/725470 editing/shadow/doubleclick-on-meter-in-shadow-crash.html [ Crash Failure Pass ]
 
@@ -4178,6 +4176,7 @@
 crbug.com/832157 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-after-controls-added.html [ Skip ]
 crbug.com/832169 media/media-controls-fit-properly-while-zoomed.html [ Failure Pass ]
 crbug.com/849694 [ Mac ] http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Failure Pass ]
+crbug.com/1348591 [ Win ] http/tests/media/controls/playback-speed-button-infinite-duration.html [ Failure Pass ]
 
 # Tests currently failing on Windows when run on Swarming
 crbug.com/757165 [ Win ] compositing/culling/filter-occlusion-blur.html [ Skip ]
@@ -5079,12 +5078,12 @@
 crbug.com/v8/11992 external/wpt/wasm/jsapi/tag/* [ Skip ]
 
 # Assorted virtual/threaded/.../wpt/scroll-animations tests
-crbug.com/1279648 [ Mac ] virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe.html [ Failure ]
-crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-quirks-mode.html [ Failure ]
-crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl.html [ Failure ]
-crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html [ Failure ]
+crbug.com/1279648 [ Mac ] virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-descriptors-iframe.html [ Failure ]
+crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-descriptors-quirks-mode.html [ Failure ]
+crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-descriptors-writing-mode-rl.html [ Failure ]
+crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-descriptors.html [ Failure ]
 crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-frame-size-changed.html [ Failure ]
-crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation.html [ Failure ]
+crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation.html [ Failure ]
 
 crbug.com/971031 [ Mac ] fast/dom/timer-throttling-hidden-page.html [ Failure Pass ]
 
@@ -6216,7 +6215,7 @@
 crbug.com/1276201 [ Mac ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-top-left.html [ Skip ]
 crbug.com/1276201 [ Mac ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-screenx-screeny.html [ Skip ]
 crbug.com/1276201 [ Mac ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-innerheight-innerwidth.html [ Skip ]
-crbug.com/1276201 [ Mac11-arm64 ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip ]
+crbug.com/1276201 [ Mac ] external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization-width-height.html [ Skip ]
 crbug.com/1275967 [ Linux ] external/wpt/permissions-policy/permissions-policy-frame-policy-timing.https.sub.html [ Failure Pass ]
 crbug.com/1275944 [ Mac ] http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js [ Failure Pass ]
 crbug.com/1276207 virtual/gpu-rasterization/images/color-profile-image-object-fit.html [ Failure Pass ]
@@ -6826,6 +6825,7 @@
 
 # Sheriff 2022-08-19
 crbug.com/1354433 [ Mac ] external/wpt/html/browsers/the-window-object/window-properties.https.html [ Failure Pass ]
+crbug.com/1354433 [ Linux ] external/wpt/html/browsers/the-window-object/window-properties.https.html [ Failure Pass ]
 
 # Sheriff 2022-08-24
 crbug.com/1356118 [ Mac ] virtual/fenced-frame-shadow-dom/external/wpt/html/anonymous-iframe/local-storage-initial-empty-document.tentative.https.window.html [ Failure Pass ]
@@ -6840,3 +6840,8 @@
 crbug.com/1356118 [ Linux ] external/wpt/html/anonymous-iframe/local-storage-initial-empty-document.tentative.https.window.html [ Failure Pass ]
 crbug.com/1356118 [ Linux ] virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/local-storage-initial-empty-document.tentative.https.window.html [ Failure Pass ]
 crbug.com/1356118 [ Linux ] virtual/partitioned-cookies/external/wpt/html/anonymous-iframe/local-storage-initial-empty-document.tentative.https.window.html [ Failure Pass ]
+
+# Sheriff 2022-08-30
+crbug.com/1357621 [ Linux ] external/wpt/webauthn/getcredential-abort.https.html [ Failure Timeout Pass ]
+crbug.com/1357917 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default.html [ Failure Pass ]
+crbug.com/1357917 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/compositing/direct-image-compositing.html b/third_party/blink/web_tests/compositing/direct-image-compositing.html
index 3c82799e..aa277b05 100644
--- a/third_party/blink/web_tests/compositing/direct-image-compositing.html
+++ b/third_party/blink/web_tests/compositing/direct-image-compositing.html
@@ -6,6 +6,9 @@
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <title>Testing direct image layer optimization</title>
   <style type="text/css" media="screen">
+    body {
+      overflow: hidden;
+    }
     img {
       float: left;
       width: 150px;
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 5cb47fb..72147ac 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -16441,32 +16441,6 @@
    },
    "scroll-animations": {
     "css": {
-     "at-scroll-timeline-default-descriptors-iframe-print.html": [
-      "0b73d7f03474d617767ec636a2712a56eed6c79c",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "at-scroll-timeline-default-descriptors-print.tentative.html": [
-      "418ed3c5495b77d58bcc87c7519264491c29462a",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
      "at-scroll-timeline-specified-scroller-print.html": [
       "5543088324d60ab425b1f5ad1775f6406c85a768",
       [
@@ -16479,6 +16453,32 @@
        ],
        {}
       ]
+     ],
+     "scroll-timeline-default-iframe-print.html": [
+      "fc8e4f193e161fe4fd896f26d4bf55ca62b2abb6",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-iframe-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "scroll-timeline-default-print.tentative.html": [
+      "e17a40e941f69d827f1bb744cd9afa0d16f4e924",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
      ]
     }
    },
@@ -244456,58 +244456,6 @@
    },
    "scroll-animations": {
     "css": {
-     "at-scroll-timeline-default-descriptors-iframe.html": [
-      "ddb06693c77d80cdcde9b4cecb13cfdad7ef20bf",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "at-scroll-timeline-default-descriptors-quirks-mode.html": [
-      "1bba34d5866a2dfc581d8f1a97c16d0fd2344a6c",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "at-scroll-timeline-default-descriptors-writing-mode-rl.html": [
-      "4d276497bc685ceba6ebece2df70f8dc8478c351",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "at-scroll-timeline-default-descriptors.html": [
-      "58225341938822b6d9ff5d13034b1dc7617cd183",
-      [
-       null,
-       [
-        [
-         "/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
      "at-scroll-timeline-frame-size-changed.html": [
       "e41af998c26ef375e6ce990b6dfba90200796c3e",
       [
@@ -244533,6 +244481,58 @@
        ],
        {}
       ]
+     ],
+     "scroll-timeline-default-iframe.html": [
+      "46ede5d88f8ff989d214064ed5deb622b0e916a2",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-iframe-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "scroll-timeline-default-quirks-mode.html": [
+      "1ef02978bd89c2783dba0116ac5d938c8fd760c7",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "scroll-timeline-default-writing-mode-rl.html": [
+      "5ef774396592c9419b0b576c9df5fe5fc5d5737f",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-writing-mode-rl-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "scroll-timeline-default.html": [
+      "aff9f541b7fd56b0063302b625b0a2c745569dda",
+      [
+       null,
+       [
+        [
+         "/scroll-animations/css/scroll-timeline-default-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
      ]
     },
     "scroll-timelines": {
@@ -332071,7 +332071,7 @@
      []
     ],
     "MediaDevices-enumerateDevices-persistent-permission.https-expected.txt": [
-     "91119ce94ad223d9054eadcf0c62cd742563dd24",
+     "95a92cc33302b66bc6315d2580834239997a507f",
      []
     ],
     "MediaDevices-enumerateDevices-returned-objects.https-expected.txt": [
@@ -337503,18 +337503,6 @@
      []
     ],
     "css": {
-     "at-scroll-timeline-default-descriptors-iframe-ref.html": [
-      "b05627d99400026dde2c568788a90a25af81f932",
-      []
-     ],
-     "at-scroll-timeline-default-descriptors-ref.html": [
-      "b72a4e8b733a57e119d01366cf44f32f28f0ca97",
-      []
-     ],
-     "at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html": [
-      "2ea7d17577c2af1943f01784625a07dbea4e1605",
-      []
-     ],
      "at-scroll-timeline-frame-size-changed-ref.html": [
       "745c2f5472ee59f6a5bcaccff0a1181763bf720a",
       []
@@ -337534,6 +337522,18 @@
      "scroll-timeline-cssom.tentative-expected.txt": [
       "116f38ce142edb0efb004461c1a8a9a314c36283",
       []
+     ],
+     "scroll-timeline-default-iframe-ref.html": [
+      "1ab5646c8bddbec83b29c3d335b0e33fb1a3465c",
+      []
+     ],
+     "scroll-timeline-default-ref.html": [
+      "cb3b60e4bd6c529d5d516f32d3b85510e7d0d3f6",
+      []
+     ],
+     "scroll-timeline-default-writing-mode-rl-ref.html": [
+      "3c072829e6f8cd5c2b94f12a8feeb5d860abc6cd",
+      []
      ]
     },
     "idlharness.window-expected.txt": [
@@ -337791,7 +337791,7 @@
      []
     ],
     "enrollment.https-expected.txt": [
-     "f9c50fc46685b90a6540ae85112dd061f30ace1a",
+     "d3dd35b3578b4f5bdc3c43348a36f99a572f1e7f",
      []
     ],
     "resources": {
@@ -341366,6 +341366,10 @@
        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
        []
       ],
+      "encrypted-media.https.html": [
+       "1c3a3ab0ea03794663e00446afa4d19743c9c069",
+       []
+      ],
       "exec.html": [
        "80e0c5999e7f06fb1899984f247010f8cba0e5c9",
        []
@@ -341394,6 +341398,14 @@
        "1ab609f11bf2be22696f0b132b88d8fc86546b93",
        []
       ],
+      "media-device-info.https.html": [
+       "09e85e77b18111b7a32a1cea244e606a4e3ff453",
+       []
+      ],
+      "media-devices-access.https.html": [
+       "462ce53e1b91fb7e19ff254917925d38a9040b63",
+       []
+      ],
       "notification-before-activation.html": [
        "16aab488a572506abda901d89384e3798c7670ca",
        []
@@ -341482,6 +341494,10 @@
        "fb00852caa9d6eaa0134662b7fe01f085641509e",
        []
       ],
+      "web-hid.https.html": [
+       "e9531293eadde0a863e292eb2f2df5e0a2946514",
+       []
+      ],
       "web-nfc.https.html": [
        "61207ab346db4393d2045bcad3cc50da1a47e38a",
        []
@@ -384158,7 +384174,7 @@
      ]
     ],
     "otpcredential-get-basics.https.html": [
-     "3907f85450fe4642720b2c8ec374f7f689bfbdd1",
+     "c0cac166de91c242a16bd4d6fc2edfa93aa37680",
      [
       null,
       {}
@@ -388485,7 +388501,7 @@
        ]
       ],
       "custom-property-style-queries.html": [
-       "6e5acbffb8ee35c939fea34e3294250f5e2bb8be",
+       "10e8e55561f346ef49d5b12cac144805d4375264",
        [
         null,
         {}
@@ -492104,7 +492120,7 @@
        ]
       ],
       "popup-attribute-basic.tentative.html": [
-       "4f508ee5baed7a027fcabbaa45b2d8ae0aee702a",
+       "dfce21b0c16d85c7da7efd7d738fd949ce5bc273",
        [
         null,
         {}
@@ -508787,7 +508803,7 @@
      ]
     ],
     "MediaDevices-enumerateDevices-persistent-permission.https.html": [
-     "c53309ca1a97831fc0301a8da3ceac5b92598711",
+     "58aacf9856ce99e606d3feedd55f768f2592304e",
      [
       null,
       {
@@ -534772,10 +534788,12 @@
      ]
     ],
     "object-not-found-after-cross-origin-redirect.html": [
-     "278c78e320e98ce65c62cfc2d4a612e3b84b82f0",
+     "c1a82d49708d72931a20c46d39902a3c92abd483",
      [
       null,
-      {}
+      {
+       "timeout": "long"
+      }
      ]
     ],
     "opaque-origin.html": [
@@ -537037,6 +537055,13 @@
        {}
       ]
      ],
+     "animation-timeline-ignored.tentative.html": [
+      "32cb89c4ef8ba42416be57ca015215557451c559",
+      [
+       null,
+       {}
+      ]
+     ],
      "animation-timeline-in-keyframe.html": [
       "75483331390d9fb6571307c3158cc37adcd893ee",
       [
@@ -537045,7 +537070,7 @@
       ]
      ],
      "animation-timeline-multiple.html": [
-      "d223860a069e865388c3eb630d9c196e96c008d1",
+      "8ae37bf751982355ef89c3db2c491e4e68b27ba0",
       [
        null,
        {}
@@ -537086,13 +537111,6 @@
        {}
       ]
      ],
-     "at-scroll-timeline-ignored.tentative.html": [
-      "44d4155f74bbbef2f7408abde84918b78e5bdfdf",
-      [
-       null,
-       {}
-      ]
-     ],
      "at-scroll-timeline-inactive-phase.html": [
       "a50583dfd0641855fc59f3fd55f6085bbfd9654d",
       [
@@ -537128,13 +537146,6 @@
        {}
       ]
      ],
-     "at-scroll-timeline-sampling.html": [
-      "cc3507732922c644788a9a240c6902f260a2a4e7",
-      [
-       null,
-       {}
-      ]
-     ],
      "at-scroll-timeline-source-invalidation.tentative.html": [
       "f1ffc35c80c7da31c9ba453647d0bca7aa97cbf8",
       [
@@ -537212,6 +537223,13 @@
        {}
       ]
      ],
+     "scroll-timeline-sampling.html": [
+      "1fe354edfd694a8d0cb03ffff78d030508452356",
+      [
+       null,
+       {}
+      ]
+     ],
      "scroll-timeline-shorthand.tentative.html": [
       "b340ff34ffe4e2ba0d93014ce114656ec3fb5373",
       [
@@ -537728,7 +537746,7 @@
      ]
     ],
     "enrollment.https.html": [
-     "b93822c7f18e5d265499ade28a254cf85cf5fe1a",
+     "7a370aa7b7ebecdcebb832f8e54f284ac5011b85",
      [
       null,
       {
@@ -543895,6 +543913,24 @@
        }
       ]
      ],
+     "restriction-encrypted-media-unsupported-config.https.html": [
+      "6a5cc0e89a3a0a0f4fd4dc90f5f1100bfac43903",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "restriction-encrypted-media.https.html": [
+      "9c375f59c9aa5247294bd3512cfea83fefecc6d4",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "restriction-focus.html": [
       "1149b8bd0981e8cf0109f2bca9dd974b9cd9a604",
       [
@@ -543913,6 +543949,33 @@
        }
       ]
      ],
+     "restriction-media-camera.https.html": [
+      "78f7dd098db9f55c27ca02f5802b00bd3f3796a2",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "restriction-media-device-info.https.html": [
+      "2e419c027e099b2dd0721ce06958334b62c9ef79",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "restriction-media-microphone.https.html": [
+      "09385be4b10d7de2d723e546d733ce71e0ca44c8",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "restriction-notification.https.html": [
       "205d020ccb88fa0db498f80275384984e96e8783",
       [
@@ -544064,6 +544127,15 @@
        }
       ]
      ],
+     "restriction-web-hid.https.html": [
+      "c96173ac17821d4309fd5a8db3962c1f2fd1176d",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "restriction-web-nfc.https.html": [
       "8e0825537e3882cbe431933b3ea9ac79ce7da1e7",
       [
@@ -564511,16 +564583,6 @@
       }
      ]
     ],
-    "createcredential-abort.https.html": [
-     "15b2b8b6f0bb9269111639f968d4f1f20e66f351",
-     [
-      null,
-      {
-       "testdriver": true,
-       "timeout": "long"
-      }
-     ]
-    ],
     "createcredential-attachment.https.html": [
      "e9458ad5604875e2ba430647cd434e561556a675",
      [
@@ -564691,16 +564753,6 @@
       }
      ]
     ],
-    "getcredential-abort.https.html": [
-     "1cd5a7ed0b513b732edf0ac85d8b6474b6b8b1b1",
-     [
-      null,
-      {
-       "testdriver": true,
-       "timeout": "long"
-      }
-     ]
-    ],
     "getcredential-attachment.https.html": [
      "7ab7235af501287bd9bc96d09ec549702e359dce",
      [
diff --git a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html
index 0ccb899..7d23896 100644
--- a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html
+++ b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html
@@ -27,41 +27,4 @@
     verifyAlsSensorReading,
     ['ambient-light-sensor']);
 
-sensor_test(async (t, sensorProvider) => {
-  const sensor1 = new AmbientLightSensor();
-  const sensor2 = new AmbientLightSensor();
-
-  return new Promise((resolve, reject) => {
-    sensor1.addEventListener('reading', () => {
-      sensor2.addEventListener('activate', () => {
-        try {
-          assert_true(sensor1.activated);
-          assert_true(sensor1.hasReading);
-          assert_not_equals(sensor1.illuminance, null);
-          assert_not_equals(sensor1.timestamp, null);
-
-          assert_true(sensor2.activated);
-          assert_not_equals(sensor2.illuminance, null);
-          assert_not_equals(sensor2.timestamp, null);
-        } catch (e) {
-          reject(e);
-        }
-      }, { once: true });
-      sensor2.addEventListener('reading', () => {
-        try {
-          assert_true(sensor2.activated);
-          assert_true(sensor2.hasReading);
-          assert_equals(sensor1.illuminance, sensor2.illuminance);
-          assert_equals(sensor1.timestamp, sensor2.timestamp);
-          resolve();
-        } catch (e) {
-          reject(e);
-        }
-      }, { once: true });
-      sensor2.start();
-    }, { once: true });
-    sensor1.start();
-  });
-}, "Readings delivered by shared platform sensor are immediately accessible to all sensors.");
-
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html b/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
index 3907f854..c0cac166 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
+++ b/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
@@ -66,12 +66,4 @@
     {otp: {transport: ["sms"]}, signal: signal}));
 }, 'Should abort request');
 
-promise_test(async t => {
-  const controller = new AbortController();
-  const signal = controller.signal;
-
-  controller.abort('CustomError');
-  await promise_rejects_exactly(t, 'CustomError', navigator.credentials.get(
-    {otp: {transport: ["sms"]}, signal: signal}));
-}, 'Should abort request with reason');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/layer-scroll-timeline-override.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/layer-scroll-timeline-override.html
deleted file mode 100644
index abdbed0..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-cascade/layer-scroll-timeline-override.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<!DOCTYPE html>
-<title>Resolving @scroll-timeline name conflicts with cascade layers</title>
-<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#layering">
-<link rel="author" href="mailto:xiaochengh@chromium.org">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<style>
-#scroller {
-  overflow: hidden;
-  width: 100px;
-  height: 100px;
-}
-
-#scroller div {
-  height: 200px;
-}
-
-@keyframes expand {
-  from { width: 100px; }
-  to { width: 200px; }
-}
-
-#target, #reference {
-  height: 100px;
-}
-
-#reference {
-  width: 125px;
-}
-
-#target {
-  animation: expand 10s linear;
-  height: 100px;
-}
-</style>
-
-<div id="scroller">
-  <div></div>
-</div>
-<div id="target"></div>
-<div id="reference"></div>
-
-<script>
-// In all tests, width of #target should be 150px, same as #reference
-
-const testCases = [
-  {
-    title: '@scroll-timeline unlayered overrides layered',
-    style: `
-      #target {
-        animation-timeline: timeline;
-      }
-
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        orientation: block;
-      }
-
-      @layer {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: inline;
-        }
-      }
-    `
-  },
-
-  {
-    title: '@scroll-timeline override between layers',
-    style: `
-      @layer base, override;
-
-      #target {
-        animation-timeline: timeline;
-      }
-
-      @layer override {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: block;
-        }
-      }
-
-      @layer base {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: inline;
-        }
-      }
-    `
-  },
-
-  {
-    title: '@scroll-timeline override update with appended sheet 1',
-    style: `
-      @layer base, override;
-
-      #target {
-        animation-timeline: timeline;
-      }
-
-      @layer override {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: block;
-        }
-      }
-    `,
-    append: `
-      @layer base {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: inline;
-        }
-      }
-    `
-  },
-
-  {
-    title: '@scroll-timeline override update with appended sheet 2',
-    style: `
-      @layer base, override;
-
-      #target {
-        animation-timeline: timeline;
-      }
-
-      @layer base {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: inline;
-        }
-      }
-    `,
-    append: `
-      @layer override {
-        @scroll-timeline timeline {
-          source: selector(#scroller);
-          orientation: block;
-        }
-      }
-    `
-  },
-];
-
-for (let testCase of testCases) {
-  promise_test(async function() {
-    assert_true(
-      CSS.supports('animation-timeline', 'foo'),
-      'This test requires @scroll-timeline support');
-
-    var documentStyle = document.createElement('style');
-    documentStyle.appendChild(document.createTextNode(testCase['style']));
-    document.head.appendChild(documentStyle);
-
-    var appendedStyle;
-    if (testCase['append']) {
-      document.body.offsetLeft;  // Force style update
-      appendedStyle = document.createElement('style');
-      appendedStyle.appendChild(document.createTextNode(testCase['append']));
-      document.head.appendChild(appendedStyle);
-    }
-
-    scroller.scrollTop = 25;
-    await waitForNextFrame();
-    assert_equals(getComputedStyle(target).width,
-                  getComputedStyle(reference).width);
-
-    if (appendedStyle)
-      appendedStyle.remove();
-    documentStyle.remove();
-  }, testCase['title']);
-}
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-query-change.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-query-change.html
index add85c4d9..6669ede 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-query-change.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-query-change.html
@@ -43,3 +43,47 @@
     assert_equals(getComputedStyle(grandchild).color, green);
   }, "Target grandchild");
 </script>
+
+<style>
+  @property --length {
+    syntax: "<length>";
+    inherits: false;
+    initial-value: 0px;
+  }
+
+  #reg_container {
+    container-name: my-reg-container;
+    font-size: 50px;
+  }
+  #reg_child, #reg_grandchild { color: red; }
+  @container style(--length: 100px) {
+    #reg_child { color: green; }
+  }
+  @container my-reg-container style(--length: 200px) {
+    #reg_grandchild { color: green; }
+  }
+</style>
+<div id="reg_container">
+  <div id="reg_child"></div>
+  <div>
+    <div id="reg_grandchild"></div>
+  </div>
+</div>
+<script>
+  test(() => {
+    assert_equals(getComputedStyle(reg_child).color, red);
+    assert_equals(getComputedStyle(reg_grandchild).color, red);
+  }, "Initially no queries for registered property match.");
+
+  test(() => {
+    reg_container.style.setProperty("--length", "2em");
+    assert_equals(getComputedStyle(reg_child).color, green);
+    assert_equals(getComputedStyle(reg_grandchild).color, red);
+  }, "Registered property query child");
+
+  test(() => {
+    reg_container.style.setProperty("--length", "200px");
+    assert_equals(getComputedStyle(reg_child).color, red);
+    assert_equals(getComputedStyle(reg_grandchild).color, green);
+  }, "Registered property query grandchild");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-toggle/parsing/support/toggle-root-values.js b/third_party/blink/web_tests/external/wpt/css/css-toggle/parsing/support/toggle-root-values.js
index 0bedfb9..de20611 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-toggle/parsing/support/toggle-root-values.js
+++ b/third_party/blink/web_tests/external/wpt/css/css-toggle/parsing/support/toggle-root-values.js
@@ -23,6 +23,7 @@
   test_computed_value(property, 'mytoggle calc(-9.5) at calc(6.5)', 'mytoggle 1 at 7');
   test_computed_value(property, 'mytoggle group sticky self, yourtoggle self sticky', 'mytoggle sticky group self, yourtoggle sticky self');
   test_computed_value(property, 'mytoggle group 2 at 1', 'mytoggle 2 at 1 group');
+  test_computed_value(property, 'mytoggle [one two]');
   test_computed_value(property, 'mytoggle [one two three]');
   test_computed_value(property, 'mytoggle [one two three] at 0', 'mytoggle [one two three]');
   test_computed_value(property, 'mytoggle [ one two three ] at 0', 'mytoggle [one two three]');
@@ -56,6 +57,7 @@
   test_valid_value(property, 'mytoggle calc(-9.5) at calc(6.5)');
   test_valid_value(property, 'mytoggle group sticky self, yourtoggle self sticky', 'mytoggle sticky group self, yourtoggle sticky self');
   test_valid_value(property, 'mytoggle group 2 at 1', 'mytoggle 2 at 1 group');
+  test_valid_value(property, 'mytoggle [one two]');
   test_valid_value(property, 'mytoggle [one two three]');
   test_valid_value(property, 'mytoggle [one two three] at 0');
   test_valid_value(property, 'mytoggle [ one two three ] at 0', 'mytoggle [one two three] at 0');
@@ -83,7 +85,8 @@
   test_invalid_value(property, 'mytoggle, none');
   test_invalid_value(property, 'mytoggle 1 at');
   test_invalid_value(property, 'mytoggle []');
-  test_invalid_value(property, 'mytoggle [one] at');
+  test_invalid_value(property, 'mytoggle [one]');
+  test_invalid_value(property, 'mytoggle [one two] at');
   test_invalid_value(property, 'mytoggle [one two two three]');
   test_invalid_value(property, 'mytoggle [one two one three]');
   test_invalid_value(property, 'mytoggle 0 sticky self');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation-with-groups.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation-with-groups.tentative.html
index 1d731d90..d8aeeb4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation-with-groups.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation-with-groups.tentative.html
@@ -265,6 +265,71 @@
   }, `toggle groups test: ${t}`);
 }
 
+promise_test(async () => {
+  container.innerHTML = `
+    <div id="e" style="toggle: tog [a b] at b self group"></div>
+    <div id="f" style="toggle: tog [a b] at a self group"></div>
+  `;
+  let e = document.getElementById("e");
+  let f = document.getElementById("f");
+  await Promise.all([wait_for_toggle_creation(e),
+                     wait_for_toggle_creation(f)]);
+
+  let te = e.toggles.get("tog");
+  let tf = f.toggles.get("tog");
+  assert_equals(te.value, "b", "e value before first click");
+  assert_true(e.matches(':toggle(tog b):toggle(tog 1)'),
+              "e selector matching before first click");
+  assert_equals(tf.value, "a", "f value before first click");
+  assert_true(f.matches(':toggle(tog a):toggle(tog 0)'),
+              "f selector matching before first click");
+  f.click();
+  assert_equals(te.value, 0, "e value after first click");
+  assert_equals(tf.value, "b", "f value after first click");
+  f.click();
+  assert_equals(te.value, 0, "e value after second click");
+  assert_equals(tf.value, "a", "f value after second click");
+  te.value = "b";
+  assert_equals(te.value, "b", "e value after first value set");
+  assert_equals(tf.value, 0, "f value after first value set");
+  tf.value = "b";
+  assert_equals(te.value, 0, "e value after second value set");
+  assert_equals(tf.value, "b", "f value after second value set");
+  tf.value = "a";
+  assert_equals(te.value, 0, "e value after third value set");
+  assert_equals(tf.value, "a", "f value after third value set");
+
+  // Swap the order of the state names in 'toggle-root'.  This does not affect
+  // the states on the toggle, but still affects the override specifier used
+  // in some algorithms.
+  e.style.toggleRoot = "tog [b a] at 0 self group";
+  f.style.toggleRoot = "tog [b a] at 0 self group";
+  await Promise.all([wait_for_toggle_creation(e),
+                     wait_for_toggle_creation(f)]);
+
+  assert_equals(te.value, 0, "e value after changing toggle-root");
+  assert_equals(tf.value, "a", "f value after changing toggle-root");
+  e.click();
+  assert_equals(te.value, "a", "e value after third click");
+  assert_equals(tf.value, 0, "f value after third click");
+  e.click();
+  assert_equals(te.value, "b", "e value after fourth click");
+  assert_equals(tf.value, 0, "f value after fourth click");
+  assert_true(e.matches(':toggle(tog b):toggle(tog 1)'),
+              "e selector matching after changing toggle-root");
+  assert_true(f.matches(':toggle(tog a):toggle(tog 0)'),
+              "f selector matching after changing toggle-root");
+  tf.value = "a";
+  assert_equals(te.value, 0, "e value after fourth value set");
+  assert_equals(tf.value, "a", "f value after fourth value set");
+  tf.value = "b";
+  assert_equals(te.value, 0, "e value after fifth value set");
+  assert_equals(tf.value, "b", "f value after fifth value set");
+  te.value = "b";
+  assert_equals(te.value, "b", "e value after sixth value set");
+  assert_equals(tf.value, "b", "f value after sixth value set");
+}, "zeroing toggle group uses states from override specifier");
+
 // TODO(dbaron): This could probably use a few additional tests for multiple
 // values of the list-valued properties.  (But they're hard to auto-generate.)
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation.tentative.html
index fca06d1a..c013314b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-activation.tentative.html
@@ -157,7 +157,62 @@
   e.click();
   assert_true(e.matches(":toggle(test-states 0)"));
   assert_equals(cs.getPropertyValue("--test-states"), "0");
-}, "states used from toggle or toggle specifier as appropriate");
+}, "states used from toggle or toggle specifier as appropriate (integer)");
+
+promise_test(async function() {
+  let e = await set_up_single_toggle_in(container, "test-states [one two] at 0");
+  let cs = getComputedStyle(e);
+  let t = e.toggles.get("test-states");
+  assert_equals(t.value, 0);
+  assert_true(e.matches(":toggle(test-states 0)"));
+  assert_true(e.matches(":toggle(test-states one)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "0");
+  e.click();
+  assert_equals(t.value, "two");
+  assert_true(e.matches(":toggle(test-states 1)"));
+  assert_true(e.matches(":toggle(test-states two)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "1");
+  e.click();
+  assert_equals(t.value, "one");
+  assert_true(e.matches(":toggle(test-states 0)"));
+  assert_true(e.matches(":toggle(test-states one)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "0");
+  e.style.toggleRoot = "test-states [zero one two] at 2";
+  await wait_for_toggle_creation(e);
+  assert_equals(t.value, "one");
+  assert_true(e.matches(":toggle(test-states 0)"));
+  assert_true(e.matches(":toggle(test-states one)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "0");
+  e.click();
+  assert_equals(t.value, "two");
+  assert_true(e.matches(":toggle(test-states 1)"));
+  assert_true(e.matches(":toggle(test-states two)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "1");
+  e.click();
+  assert_equals(t.value, "zero");
+  assert_true(e.matches(":toggle(test-states zero)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "");
+  e.style.toggleRoot = "";
+  await wait_for_toggle_creation(e);
+  assert_equals(t.value, "zero");
+  assert_true(e.matches(":toggle(test-states zero)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "");
+  e.click();
+  assert_equals(t.value, "one");
+  assert_true(e.matches(":toggle(test-states 0)"));
+  assert_true(e.matches(":toggle(test-states one)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "0");
+  e.click();
+  assert_equals(t.value, "two");
+  assert_true(e.matches(":toggle(test-states 1)"));
+  assert_true(e.matches(":toggle(test-states two)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "1");
+  e.click();
+  assert_equals(t.value, "one");
+  assert_true(e.matches(":toggle(test-states 0)"));
+  assert_true(e.matches(":toggle(test-states one)"));
+  assert_equals(cs.getPropertyValue("--test-states"), "0");
+}, "states used from toggle or toggle specifier as appropriate (names)");
 
 promise_test(async function() {
   container.innerHTML = `
diff --git a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-api.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-api.tentative.html
index 275c4d53..f47ec55e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-api.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-api.tentative.html
@@ -85,6 +85,20 @@
   assert_equals(b.toggles.size, 1, "b.toggles.size after failed set");
   assert_equals(b.toggles.get("newname"), t, "b.toggles.get after failed set");
 
+  assert_throws_dom("SyntaxError", () => { let t = new CSSToggle({ "states": [] }); },
+                    "toggle constructor with empty list of states");
+  assert_throws_dom("SyntaxError", () => { let t = new CSSToggle({ "states": ["one"] }); },
+                    "toggle constructor with only one state");
+  assert_throws_dom("SyntaxError", () => { let t = new CSSToggle({ "states": ["one", "two", "one"] }); },
+                    "toggle constructor with duplicate states");
+  let c = new CSSToggle({ "states": ["one", "two", "three"] });
+  assert_throws_dom("SyntaxError", () => { c.states = []; },
+                    "toggle states setter with empty list of states");
+  assert_throws_dom("SyntaxError", () => { c.states = ["one"]; },
+                    "toggle states setter with only one state");
+  assert_throws_dom("SyntaxError", () => { c.states = ["one", "two", "one"]; },
+                    "toggle states setter with duplicate states");
+
   // TODO(https://crbug.com/1250716): Should the toggle on a be
   // re-created at some point?  If so, when?
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-events.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-events.tentative.html
index e70704ba..bc4db7d5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-events.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-toggle/toggle-events.tentative.html
@@ -40,15 +40,10 @@
     assert_equals(toggle.value, 2, "value after first change");
   });
 
-  // Test that the event still fires even when the toggle doesn't change
-  // due to being "sticky" and stuck, although
-  // https://github.com/tabatkins/css-toggle/issues/35 suggests that
-  // maybe this is the wrong behavior.
-  await click_while_waiting_for_togglechange(watcher, element).then(ev => {
-    assert_equals(ev.toggleName, "mytoggle", "event.toggleName after second change");
-    assert_equals(ev.toggle, toggle, "event.toggle after second change");
-    assert_equals(toggle.value, 2, "value after second change");
-  });
+  // Test that the event does not fire when the toggle doesn't change due to
+  // being "sticky" and stuck.  EventWatcher will assert if there is an event.
+  element.click();
+  assert_equals(toggle.value, 2, "value after second change");
 
   toggle.value = 0;
   // there should be no event; EventWatcher will assert if there is one.
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js
index 26ff6919..4282146 100644
--- a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js
+++ b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js
@@ -407,6 +407,45 @@
     }, "Sampling frequency has dropped to slowSensor's requested frequency");
   }, `${sensorName}: frequency hint works.`);
 
+  sensor_test(async (t, sensorProvider) => {
+    assert_implements(sensorName in self, `${sensorName} is not supported.`);
+
+    const sensor1 = new sensorType();
+    const sensor2 = new sensorType();
+
+    return new Promise((resolve, reject) => {
+      sensor1.addEventListener('reading', () => {
+        sensor2.addEventListener('activate', () => {
+          try {
+            assert_true(sensor1.activated);
+            assert_true(sensor1.hasReading);
+            assert_false(verificationFunction(null, sensor1, /*isNull=*/true));
+            assert_not_equals(sensor1.timestamp, null);
+
+            assert_true(sensor2.activated);
+            assert_false(verificationFunction(null, sensor2, /*isNull=*/true));
+            assert_not_equals(sensor2.timestamp, null);
+          } catch (e) {
+            reject(e);
+          }
+        }, { once: true });
+        sensor2.addEventListener('reading', () => {
+          try {
+            assert_true(sensor2.activated);
+            assert_true(sensor2.hasReading);
+            assert_sensor_equals(sensor1, sensor2);
+            resolve();
+          } catch (e) {
+            reject(e);
+          }
+        }, { once: true });
+        sensor2.start();
+      }, { once: true });
+      sensor1.start();
+    });
+  }, `${sensorName}: Readings delivered by shared platform sensor are\
+ immediately accessible to all sensors.`);
+
 //  Re-enable after https://github.com/w3c/sensors/issues/361 is fixed.
 //  test(() => {
 //     assert_throws_dom("NotSupportedError",
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js
index 7070daa0..aa101547 100644
--- a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js
+++ b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js
@@ -86,3 +86,56 @@
 function verifyProximitySensorReading(pattern, {distance, max, near, timestamp}, isNull) {
   return verifySensorReading(pattern, [distance, max, near], timestamp, isNull);
 }
+
+// Assert that two Sensor objects have the same properties and values.
+//
+// Verifies that ``actual`` and ``expected`` have the same sensor properties
+// and, if so, that their values are the same.
+//
+// @param {Sensor} actual - Test value.
+// @param {Sensor} expected - Expected value.
+function assert_sensor_equals(actual, expected) {
+  assert_true(
+      actual instanceof Sensor,
+      'assert_sensor_equals: actual must be a Sensor');
+  assert_true(
+      expected instanceof Sensor,
+      'assert_sensor_equals: expected must be a Sensor');
+
+  // These properties vary per sensor type.
+  const CUSTOM_PROPERTIES = [
+    ['illuminance'], ['quaternion'], ['x', 'y', 'z'],
+    [
+      'latitude', 'longitude', 'altitude', 'accuracy', 'altitudeAccuracy',
+      'heading', 'speed'
+    ]
+  ];
+
+  // These properties are present on all objects derived from Sensor.
+  const GENERAL_PROPERTIES = ['timestamp'];
+
+  for (let customProperties of CUSTOM_PROPERTIES) {
+    if (customProperties.every(p => p in actual) &&
+        customProperties.every(p => p in expected)) {
+      customProperties.forEach(p => {
+        if (customProperties == 'quaternion') {
+          assert_array_equals(
+              actual[p], expected[p],
+              `assert_sensor_equals: property '${p}' does not match`);
+        } else {
+          assert_equals(
+              actual[p], expected[p],
+              `assert_sensor_equals: property '${p}' does not match`);
+        }
+      });
+      GENERAL_PROPERTIES.forEach(p => {
+        assert_equals(
+            actual[p], expected[p],
+            `assert_sensor_equals: property '${p}' does not match`);
+      });
+      return;
+    }
+  }
+
+  assert_true(false, 'assert_sensor_equals: sensors have different attributes');
+}
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt
index 908101b0..11f9fa8c 100644
--- a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt
@@ -15,6 +15,7 @@
 FAIL GeolocationSensor: no exception is thrown when calling stop() on already stopped sensor. assert_implements: GeolocationSensor is not supported. undefined
 FAIL GeolocationSensor: Test that fresh reading is fetched on start(). assert_implements: GeolocationSensor is not supported. undefined
 FAIL GeolocationSensor: frequency hint works. assert_implements: GeolocationSensor is not supported. undefined
+FAIL GeolocationSensor: Readings delivered by shared platform sensor are immediately accessible to all sensors. assert_implements: GeolocationSensor is not supported. undefined
 FAIL GeolocationSensor: throw 'TypeError' if frequency is invalid. assert_implements: GeolocationSensor is not supported. undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-attribute-basic.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-attribute-basic.tentative.html
index 4f508ee..dfce21b 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-attribute-basic.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-attribute-basic.tentative.html
@@ -17,6 +17,8 @@
   <header popup>Different element type</header>
   <nav popup>Different element type</nav>
   <input type=text popup value="Different element type">
+  <dialog popup>Dialog with popup attribute</dialog>
+  <dialog popup="manual">Dialog with popup=manual</dialog>
   <div popup=true>Invalid popup value - defaults to popup=manual</div>
   <div popup=popup>Invalid popup value - defaults to popup=manual</div>
   <div popup=invalid>Invalid popup value - defaults to popup=manual</div>
@@ -24,6 +26,7 @@
 
 <div id=nonpopups>
   <div>Not a pop-up</div>
+  <dialog open>Dialog without popup attribute</dialog>
 </div>
 
 <div popup class=animated>Animated pop-up</div>
diff --git a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt
index f8572ea..7ec2483 100644
--- a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt
@@ -15,6 +15,7 @@
 PASS Magnetometer: no exception is thrown when calling stop() on already stopped sensor.
 PASS Magnetometer: Test that fresh reading is fetched on start().
 PASS Magnetometer: frequency hint works.
+PASS Magnetometer: Readings delivered by shared platform sensor are immediately accessible to all sensors.
 PASS Magnetometer: throw 'TypeError' if frequency is invalid.
 PASS Magnetometer: sensor reading is correct when options.referenceFrame is 'screen'.
 PASS Magnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values.
@@ -34,6 +35,7 @@
 FAIL UncalibratedMagnetometer: no exception is thrown when calling stop() on already stopped sensor. assert_implements: UncalibratedMagnetometer is not supported. undefined
 FAIL UncalibratedMagnetometer: Test that fresh reading is fetched on start(). assert_implements: UncalibratedMagnetometer is not supported. undefined
 FAIL UncalibratedMagnetometer: frequency hint works. assert_implements: UncalibratedMagnetometer is not supported. undefined
+FAIL UncalibratedMagnetometer: Readings delivered by shared platform sensor are immediately accessible to all sensors. assert_implements: UncalibratedMagnetometer is not supported. undefined
 FAIL UncalibratedMagnetometer: throw 'TypeError' if frequency is invalid. assert_implements: UncalibratedMagnetometer is not supported. undefined
 FAIL UncalibratedMagnetometer: sensor reading is correct when options.referenceFrame is 'screen'. assert_implements: UncalibratedMagnetometer is not supported. undefined
 FAIL UncalibratedMagnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values. assert_implements: UncalibratedMagnetometer is not supported. undefined
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https-expected.txt
index 91119ce9..95a92cc3 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL enumerateDevices depends only on capture state, not permission state assert_equals: expected (string) "At most one of a kind prior to capture" but got (boolean) false
+FAIL enumerateDevices depends only on capture state, not permission state assert_equals: At most one of a kind prior to capture expected 3 but got 7
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html
index c53309c..58aacf9 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html
@@ -28,7 +28,7 @@
     const e = await msgWatcher.wait_for('message');
     const iframeDevices = e.data.devices;
     const kinds = iframeDevices.map(({kind}) => kind);
-    assert_equals(kinds.length == new Set(kinds).size, "At most one of a kind prior to capture");
+    assert_equals(kinds.length, new Set(kinds).size, "At most one of a kind prior to capture");
     for (const device of iframeDevices) {
       assert_equals(device.deviceId, "", "deviceId pre-capture is empty");
       assert_equals(device.label, "", "label pre-capture is empty");
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-ignored.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-ignored.tentative.html
similarity index 94%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-ignored.tentative.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-ignored.tentative.html
index 44d4155..32cb89c 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-ignored.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-ignored.tentative.html
@@ -20,17 +20,14 @@
     from { width: 100px; }
     to { width: 200px; }
   }
-  @scroll-timeline timeline1 {
-    source: selector(#scroller1);
-    orientation: auto;
+  #scroller1 {
+    scroll-timeline: timeline1;
   }
-  @scroll-timeline timeline2 {
-    source: selector(#scroller2);
-    orientation: auto;
+  #scroller2 {
+    scroll-timeline: timeline2;
   }
-  @scroll-timeline timeline3 {
-    source: selector(#scroller3);
-    orientation: auto;
+  #scroller3 {
+    scroll-timeline: timeline3;
   }
   #element {
     width: 0px;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-multiple.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-multiple.html
index d223860..8ae37bf 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-multiple.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-multiple.html
@@ -32,21 +32,17 @@
     to { right: 200px; }
   }
 
-  @scroll-timeline top_timeline {
-    source: selector(#scroller1);
-    orientation: block;
+  #top_scroller {
+    scroll-timeline: block top_timeline;
   }
-  @scroll-timeline bottom_timeline {
-    source: selector(#scroller1);
-    orientation: inline;
+  #bottom_scroller {
+    scroll-timeline: inline bottom_timeline;
   }
-  @scroll-timeline left_timeline {
-    source: selector(#scroller2);
-    orientation: block;
+  #left_scroller {
+    scroll-timeline: block left_timeline;
   }
-  @scroll-timeline right_timeline {
-    source: selector(#scroller2);
-    orientation: inline;
+  #right_scroller {
+    scroll-timeline: inline right_timeline;
   }
 
   #element {
@@ -61,19 +57,27 @@
   }
 </style>
 <main>
-  <div id=scroller1><div></div></div>
-  <div id=scroller2><div></div></div>
+  <div id=top_scroller><div></div></div>
+  <div id=bottom_scroller><div></div></div>
+  <div id=left_scroller><div></div></div>
+  <div id=right_scroller><div></div></div>
   <div id=element></div>
 </main>
 <script>
   // Force layout of scrollers.
-  scroller1.offsetTop;
-  scroller2.offsetTop;
+  top_scroller.offsetTop;
+  bottom_scroller.offsetTop;
+  left_scroller.offsetTop;
+  right_scroller.offsetTop;
 
-  scroller1.scrollTop = 20;
-  scroller1.scrollLeft = 40;
-  scroller2.scrollTop = 60;
-  scroller2.scrollLeft = 80;
+  top_scroller.scrollTop = 20;
+  top_scroller.scrollLeft = 40;
+  bottom_scroller.scrollTop = 20;
+  bottom_scroller.scrollLeft = 40;
+  left_scroller.scrollTop = 60;
+  left_scroller.scrollLeft = 80;
+  right_scroller.scrollTop = 60;
+  right_scroller.scrollLeft = 80;
 
   promise_test(async (t) => {
     await waitForNextFrame();
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-named-scroll-progress-timeline.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-named-scroll-progress-timeline.tentative.html
index 915aaa1..b31e402 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-named-scroll-progress-timeline.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-named-scroll-progress-timeline.tentative.html
@@ -38,7 +38,7 @@
 <script>
 "use strict";
 
-function createScrollerAndTarget(t, scrollerSizeClass) {
+function createScroller(t, scrollerSizeClass) {
   let scroller = document.createElement('div');
   let className = scrollerSizeClass || 'square';
   scroller.className = `scroller ${className}`;
@@ -47,16 +47,27 @@
 
   scroller.appendChild(content);
 
+  t.add_cleanup(function() {
+    content.remove();
+    scroller.remove();
+  });
+
+  return scroller;
+}
+
+function createTarget(t) {
   let target = document.createElement('div');
   target.id = 'target';
 
   t.add_cleanup(function() {
-    content.remove();
-    scroller.remove();
     target.remove();
   });
 
-  return [scroller, target];
+  return target;
+}
+
+function createScrollerAndTarget(t, scrollerSizeClass) {
+  return [createScroller(t, scrollerSizeClass), createTarget(t)];
 }
 
 // -------------------------
@@ -251,6 +262,106 @@
   main.remove();
 }, 'scroll-timeline-name affects subsequent siblings when changed');
 
+promise_test(async t => {
+  let target = createTarget(t);
+
+  // <div id='target'></div>
+  document.body.appendChild(target);
+
+  target.style.animation = 'anim 10s linear timeline';
+
+  // Unknown animation-timeline, current time held at zero.
+  assert_equals(getComputedStyle(target).translate, '50px');
+
+  let scroller = createScroller(t);
+  // <div class='scroller'> ... </div>
+  // <div id='target'></div>
+  document.body.insertBefore(scroller, target);
+  scroller.style.scrollTimelineName = 'timeline';
+
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(target).translate, '50px');
+
+  // Ensure that time is not just held at zero.
+  scroller.scrollTop = 50; // 50%, in [50, 150].
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(target).translate, '100px');
+}, 'scroll-timeline-name on inserted element affects subsequent siblings');
+
+promise_test(async t => {
+  let [scroller, target] = createScrollerAndTarget(t);
+
+  // <div class='scroller'> ... </div>
+  // <div id='target'></div>
+  document.body.appendChild(scroller);
+  document.body.appendChild(target);
+
+  scroller.scrollTop = 50; // 50%, in [50, 150].
+  await waitForNextFrame();
+
+  scroller.style.scrollTimelineName = 'timeline';
+  target.style.animation = 'anim 10s linear timeline';
+
+  assert_equals(getComputedStyle(target).translate, '100px');
+
+  // This effectively removes the CSS-created ScrollTimeline on this element,
+  // thus invoking "setting the timeline of an animation" [1] with a null-
+  // timeline on affected elements. This in turn causes the current time to
+  // become unresolved [2], ultimately resulting in no effect value.
+  //
+  // [1] https://drafts.csswg.org/web-animations-1/#setting-the-timeline
+  // [2] https://drafts.csswg.org/web-animations-1/#the-current-time-of-an-animation
+  scroller.remove();
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(target).translate, 'none');
+}, 'scroll-timeline-name on removed element affects subsequent siblings');
+
+promise_test(async t => {
+  let [scroller, target] = createScrollerAndTarget(t);
+
+  // <div class='scroller' style='display:none'> ... </div>
+  // <div id='target'></div>
+  scroller.style.display = 'none';
+  document.body.appendChild(scroller);
+  document.body.appendChild(target);
+
+  scroller.style.scrollTimelineName = 'timeline';
+  target.style.animation = 'anim 10s linear timeline';
+
+  // Unknown animation-timeline, current time held at zero.
+  assert_equals(getComputedStyle(target).translate, '50px');
+
+  scroller.style.display = 'block';
+  scroller.scrollTop = 50; // 50%, in [50, 150].
+  await waitForNextFrame();
+
+  assert_equals(getComputedStyle(target).translate, '100px');
+}, 'scroll-timeline-name on element leaving display:none affects subsequent siblings');
+
+promise_test(async t => {
+  let [scroller, target] = createScrollerAndTarget(t);
+
+  // <div class='scroller'> ... </div>
+  // <div id='target'></div>
+  document.body.appendChild(scroller);
+  document.body.appendChild(target);
+
+  scroller.scrollTop = 50; // 50%, in [50, 150].
+  await waitForNextFrame();
+
+  scroller.style.scrollTimelineName = 'timeline';
+  target.style.animation = 'anim 10s linear timeline';
+
+  assert_equals(getComputedStyle(target).translate, '100px');
+
+  // See comment in the test "scroll-timeline-name on removed element ..." for
+  // an explantation of this result. (Setting display:none is similar to
+  // removing the element).
+  scroller.style.display = 'none';
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(target).translate, 'none');
+}, 'scroll-timeline-name on element becoming display:none affects subsequent siblings');
+
 // TODO: Add more tests which change scroll-timeline-name property.
 // Those animations which use this timeline should be restyled propertly.
 
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-cascade.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-cascade.html
deleted file mode 100644
index 9ba3a260..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-cascade.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<style>
-  #scroller {
-    overflow: hidden;
-    width: 100px;
-    height: 100px;
-  }
-  #contents {
-    height: 200px;
-  }
-  @keyframes expand {
-    from { width: 100px; }
-    to { width: 200px; }
-  }
-  @scroll-timeline timeline {
-    /* default source */
-  }
-  @scroll-timeline timeline {
-    source: selector(#scroller);
-  }
-  #element {
-    animation: expand 10s linear;
-    animation-timeline: timeline;
-  }
-  /* Ensure stable expectations if feature is not supported */
-  @supports not (animation-timeline:foo) {
-    #element { animation-play-state: paused; }
-  }
-</style>
-<div id=scroller>
-  <div id=contents></div>
-</div>
-<div id=element></div>
-<script>
-  promise_test(async (t) => {
-    scroller.scrollTop = 25;
-    await waitForNextFrame();
-    assert_equals(getComputedStyle(element).width, '125px');
-  }, 'Latest @scroll-timeline rule wins');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-print.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-print.tentative.html
deleted file mode 100644
index 418ed3c5..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-print.tentative.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML>
-<html class="reftest-wait">
-<title>The default scroll-timeline at rule for print</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-ref.html">
-
-<style>
-  @keyframes update {
-    from { transform: translateY(0px); }
-    to { transform: translateY(200px); }
-  }
-
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
-  html {
-    min-height: 100%;
-    padding-bottom: 100px;
-  }
-
-  #box {
-    width: 100px;
-    height: 100px;
-    background-color: green;
-    animation: update 1s linear;
-    animation-timeline: test-timeline;
-  }
-
-  #covered {
-    width: 100px;
-    height: 100px;
-    background-color: red;
-  }
-
-  * {
-    margin-top: 0px;
-    margin-bottom: 0px;
-  }
-</style>
-
-<div id="box"></div>
-<div id="covered"></div>
-
-<script>
-  window.addEventListener('load', function() {
-    const scroller = document.scrollingElement;
-
-    // Move the scroller to the halfway point.
-    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-    scroller.scrollTop = 0.5 * maxScroll;
-
-    window.requestAnimationFrame(() => {
-      document.documentElement.classList.remove("reftest-wait");
-    });
-  });
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source-invalidation.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source-invalidation.tentative.html
deleted file mode 100644
index f1ffc35..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source-invalidation.tentative.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!DOCTYPE html>
-<title>@scroll-timeline source invalidation</title>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<style>
-  .scroller {
-    overflow: hidden;
-    width: 100px;
-    height: 100px;
-  }
-  .contents {
-    height: 200px;
-  }
-  @keyframes expand {
-    from { width: 100px; }
-    to { width: 200px; }
-  }
-  @scroll-timeline timeline {
-    source: selector(#scroller);
-  }
-  #element {
-    width: 0px;
-    height: 20px;
-    animation: expand 1000s linear;
-    animation-timeline: timeline;
-  }
-  /* Ensure stable expectations if feature is not supported */
-  @supports not (animation-timeline:foo) {
-    #element { animation-play-state: paused; }
-  }
-</style>
-<main id=main>
-  <div id=element></div>
-</main>
-<script>
-
-  function createScroller() {
-    let scroller = document.createElement('div');
-    let contents = document.createElement('div');
-    scroller.classList.add('scroller');
-    contents.classList.add('contents');
-    scroller.append(contents);
-    return scroller;
-  }
-
-  function wrapInDiv(element) {
-    let div = document.createElement('div');
-    div.append(element);
-    return div;
-  }
-
-  function scrollerAt(n) {
-    return document.querySelectorAll('.scroller')[n];
-  }
-
-  function insertScroller(scroller) {
-    main.insertBefore(scroller, element);
-  }
-
-  // Resets #scrollers to a state where it has three .scroller children with
-  // scrollTop offsets 10, 20 and 30.
-  function cleanup() {
-    for (let e of document.querySelectorAll('.scroller'))
-      e.remove();
-
-    for (let i = 0; i < 3; i++)
-      insertScroller(createScroller());
-
-    scrollerAt(0).scrollTop = 10;
-    scrollerAt(1).scrollTop = 20;
-    scrollerAt(2).scrollTop = 30;
-  }
-
-  // Do an initial "cleanup" to set up the first test.
-  cleanup();
-
-  function invalidation_test(func, description) {
-    promise_test(async (t) => {
-      t.add_cleanup(cleanup);
-      await func();
-    }, description);
-  }
-
-  invalidation_test(() => {
-    assert_equals(getComputedStyle(element).width, '0px');
-  }, 'Nonexistent source');
-
-  invalidation_test(() => {
-    assert_equals(getComputedStyle(element).width, '0px');
-    scrollerAt(0).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '110px');
-    scrollerAt(1).setAttribute('id', 'scroller'); // No effect
-    assert_equals(getComputedStyle(element).width, '110px');
-    scrollerAt(2).setAttribute('id', 'scroller'); // No effect
-    assert_equals(getComputedStyle(element).width, '110px');
-  }, 'Setting id attribute');
-
-  invalidation_test(() => {
-    assert_equals(getComputedStyle(element).width, '0px');
-    scrollerAt(0).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '110px');
-    scrollerAt(0).removeAttribute('id');
-    assert_equals(getComputedStyle(element).width, '0px');
-  }, 'Removing id attribute');
-
-  invalidation_test(() => {
-    assert_equals(getComputedStyle(element).width, '0px');
-    scrollerAt(2).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '130px');
-    scrollerAt(1).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '120px');
-    scrollerAt(0).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '110px');
-  }, 'Setting id attribute earlier in the tree');
-
-  invalidation_test(async () => {
-    assert_equals(getComputedStyle(element).width, '0px');
-
-    // Appending a new element with id 'scroller' already set before
-    // insertion into the tree.
-    let scroller = createScroller();
-    scroller.setAttribute('id', 'scroller');
-    insertScroller(scroller);
-
-    // Make sure |scroller| has a layout box.
-    //
-    // https://drafts.csswg.org/scroll-animations-1/#avoiding-cycles
-    //
-    // TODO: Depending on the outcome of Issue 5261, the call to offsetTop
-    // might be unnecessary.
-    // https://github.com/w3c/csswg-drafts/issues/5261
-    scroller.offsetTop;
-    await waitForNextFrame();
-
-    assert_equals(getComputedStyle(element).width, '100px');
-  }, 'Appending a new element');
-
-  invalidation_test(() => {
-    assert_equals(getComputedStyle(element).width, '0px');
-
-    scrollerAt(0).setAttribute('id', 'scroller');
-    scrollerAt(1).setAttribute('id', 'scroller');
-    scrollerAt(2).setAttribute('id', 'scroller');
-    assert_equals(getComputedStyle(element).width, '110px');
-
-    scrollerAt(0).remove();
-    assert_equals(getComputedStyle(element).width, '120px');
-
-    scrollerAt(0).remove();
-    assert_equals(getComputedStyle(element).width, '130px');
-
-    scrollerAt(0).remove();
-    assert_equals(getComputedStyle(element).width, '0px');
-  }, 'Removing source element');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source.html
deleted file mode 100644
index 0264438..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-source.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE html>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#descdef-scroll-timeline-source">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<style>
-  :root {
-    height: 100vh;
-    overflow: scroll;
-  }
-  body {
-    height: 200vh;
-  }
-  .scroller {
-    overflow: scroll;
-    width: 100px;
-    height: 100px;
-  }
-  #boxless {
-    display: none;
-  }
-  .contents {
-    height: 300px;
-  }
-  @keyframes expand {
-    from { width: 100px; }
-    to { width: 200px; }
-  }
-  @scroll-timeline timeline_source_none {
-    source: none;
-  }
-  @scroll-timeline timeline_source_auto {
-    source: auto;
-  }
-  @scroll-timeline timeline_source_selector {
-    source: selector(#scroller);
-  }
-  @scroll-timeline timeline_source_unspecified {
-  }
-  @scroll-timeline timeline_source_nonexistent_id {
-    source: selector(#doesnotexist);
-  }
-  @scroll-timeline timeline_source_no_layout_box {
-    source: selector(#boxless);
-  }
-  #container > div {
-    width: 0px;
-    animation-name: expand;
-    animation-duration: 10s;
-    animation-timing-function: linear;
-  }
-  /* Ensure stable expectations if feature is not supported */
-  @supports not (animation-timeline:foo) {
-    #container > div { animation-play-state: paused; }
-  }
-  #element_source_none { animation-timeline: timeline_source_none; }
-  #element_source_auto { animation-timeline: timeline_source_auto; }
-  #element_source_unspecified { animation-timeline: timeline_source_unspecified; }
-  #element_source_selector { animation-timeline: timeline_source_selector; }
-  #element_source_nonexistent_id { animation-timeline: timeline_source_nonexistent_id; }
-  #element_source_no_layout_box { animation-timeline: timeline_source_no_layout_box; }
-</style>
-<body>
-  <div class=scroller id=scroller>
-    <div class=contents></div>
-  </div>
-  <div class=scroller id=boxless>
-    <div class=contents></div>
-  </div>
-  <div id=container>
-    <div id=element_source_none></div>
-    <div id=element_source_auto></div>
-    <div id=element_source_unspecified></div>
-    <div id=element_source_selector></div>
-    <div id=element_source_nonexistent_id></div>
-    <div id=element_source_no_layout_box></div>
-  </div>
-  <script>
-    // Set progress of animations linked to #scroller to 75%.
-    scroller.scrollTop = 75;
-    // Set progress of animations linked to document.scrollingElement to 25%.
-    document.scrollingElement.scrollTop = 25;
-
-    function expectedWidth(scrollingElement) {
-      const maxScroll =
-          scrollingElement.scrollHeight - scrollingElement.clientHeight;
-      return 100 * (1 + scrollingElement.scrollTop / maxScroll);
-    }
-
-    function assert_near(actual, expected, tolerance) {
-      assert_approx_equals(parseFloat(actual), expected, 1);
-    }
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_equals(getComputedStyle(element_source_none).width, '0px');
-    }, 'Source none causes inactive timeline');
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_near(getComputedStyle(element_source_auto).width,
-                  expectedWidth(document.scrollingElement));
-    }, 'Source auto selects scrollingElement of the document');
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_near(getComputedStyle(element_source_unspecified).width,
-                  expectedWidth(document.scrollingElement));
-    }, 'Unspecified source behaves like auto');
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_near(getComputedStyle(element_source_selector).width,
-                  expectedWidth(scroller));
-    }, 'Source selector(<id-selector>) selects an element');
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_equals(getComputedStyle(element_source_nonexistent_id).width, '0px');
-    }, 'Unknown source causes inactive timeline');
-
-    promise_test(async (t) => {
-      await waitForNextFrame();
-      assert_equals(getComputedStyle(element_source_no_layout_box).width, '0px');
-    }, 'Source with no layout box causes inactive timeline');
-
-    // TODO(https://github.com/w3c/csswg-drafts/issues/5289): Add tests for
-    // sources that change when behavior is clarified.
-
-  </script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-unknown-descriptor.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-unknown-descriptor.tentative.html
deleted file mode 100644
index 3534c9a..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-unknown-descriptor.tentative.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<title>@scroll-timeline: Unknown Descriptors</title>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<link rel="help" src="https://github.com/w3c/csswg-drafts/issues/5109">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<style>
-  #scroller {
-    overflow: hidden;
-    width: 100px;
-    height: 100px;
-  }
-  #contents {
-    height: 200px;
-  }
-  @keyframes expand {
-    from { width: 100px; }
-    to { width: 200px; }
-  }
-  @scroll-timeline timeline {
-    unknown: 100px;
-    source: selector(#scroller);
-    time-range: 10s;
-    foo: bar;
-  }
-  #element {
-    width: 0px;
-    animation: expand 10s linear timeline;
-  }
-</style>
-<div id=scroller>
-  <div id=contents></div>
-</div>
-<div id=element></div>
-<script>
-  promise_test(async (t) => {
-    scroller.scrollTop = 50;
-    await waitForNextFrame();
-    assert_equals(getComputedStyle(element).width, '150px');
-  }, 'Unknown descriptors do not invalidate the @scroll-timeline rule');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt
deleted file mode 100644
index 116f38c..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-This is a testharness.js-based test.
-Found 98 tests; 44 PASS, 54 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Empty block
-PASS EOF ends block
-PASS Timeline name can be a <string>
-PASS Missing prelude
-PASS Missing block
-PASS Missing timeline name
-PASS Timeline name must be an identifier
-PASS Timeline name must match <custom-ident>
-PASS Timeline name must match <custom-ident> (caps)
-PASS Timeline name must match <custom-ident> (mixed)
-PASS Timeline name may not be initial
-PASS Timeline name may not be inherit
-PASS Timeline name may not be unset
-PASS Timeline name may not be revert
-PASS Timeline name may not be default
-PASS Extra timeline name
-PASS CSSRule.type returns 0
-PASS CSSScrollTimelineRule.name foo
-PASS CSSScrollTimelineRule.name Foo
-PASS CSSScrollTimelineRule.name f___123
-PASS CSSScrollTimelineRule.name a\9 b
-PASS CSSScrollTimelineRule.name "foo"
-PASS CSSScrollTimelineRule.name "none"
-PASS CSSScrollTimelineRule.cssText: empty rule
-PASS CSSScrollTimelineRule.cssText: escaped name
-PASS CSSScrollTimelineRule.cssText: source descriptor
-PASS CSSScrollTimelineRule.cssText: orientation descriptor
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (none) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: none; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (auto) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: auto; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (container-based offset, px) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: 100px; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (container-based offset, percentage) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: 100%; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar); }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with edge) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with threshold) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) 1; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with edge and threshold) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with threshold and edge) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (multiple offsets) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: auto, selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
-FAIL CSSScrollTimelineRule.cssText: defaults assert_equals: expected "@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }" but got "@scroll-timeline timeline { source: auto; orientation: auto; }"
-FAIL CSSScrollTimelineRule.cssText: order assert_equals: expected "@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }" but got "@scroll-timeline timeline { source: auto; orientation: auto; }"
-PASS CSSScrollTimelineRule.source selector(#foo)
-PASS CSSScrollTimelineRule.source selector( #foo )
-PASS CSSScrollTimelineRule.source  selector(#foo) 
-PASS CSSScrollTimelineRule.source none
-PASS CSSScrollTimelineRule.source  none 
-PASS CSSScrollTimelineRule.source selector(#a\9 b)
-PASS CSSScrollTimelineRule.source auto
-FAIL CSSScrollTimelineRule.source #foo assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source  assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source element(#foo) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(#foo more) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(html) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(foo) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(:before) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(*) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(.a) assert_equals: serialization should be canonical expected "auto" but got "none"
-FAIL CSSScrollTimelineRule.source selector(.a, .b) assert_equals: serialization should be canonical expected "auto" but got "none"
-PASS CSSScrollTimelineRule.orientation auto
-PASS CSSScrollTimelineRule.orientation block
-PASS CSSScrollTimelineRule.orientation inline
-PASS CSSScrollTimelineRule.orientation horizontal
-PASS CSSScrollTimelineRule.orientation vertical
-PASS CSSScrollTimelineRule.orientation   vertical  
-PASS CSSScrollTimelineRule.orientation 
-PASS CSSScrollTimelineRule.orientation foo
-PASS CSSScrollTimelineRule.orientation 10px
-PASS CSSScrollTimelineRule.orientation red
-FAIL CSSScrollTimelineRule.scrollOffsets none assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets  none  assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets  assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets red assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets #fff assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets unset assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets unknown(#foo) assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets start assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets end assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 3 assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 start 10 assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 0%, 100%, selector(.a) assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 end, start assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets auto assert_equals: serialization should be canonical expected (string) "auto" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 10em assert_equals: serialization should be canonical expected (string) "10em" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 10% assert_equals: serialization should be canonical expected (string) "10%" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets calc(1px + 1%) assert_in_array: serialization should be sound value undefined not in array ["calc(1px + 1%)", "calc(1% + 1px)"]
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) assert_equals: serialization should be canonical expected (string) "selector(#foo)" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets  selector(#foo) assert_equals: serialization should be canonical expected (string) "selector(#foo)" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) start assert_equals: serialization should be canonical expected (string) "selector(#foo) start" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) start 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) start 3" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) 3" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3.5 assert_equals: serialization should be canonical expected (string) "selector(#foo) 3.5" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end assert_equals: serialization should be canonical expected (string) "selector(#foo) end" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 end assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets  auto , auto  assert_equals: serialization should be canonical expected (string) "auto, auto" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 10%, 100px assert_equals: serialization should be canonical expected (string) "10%, 100px" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets auto, 100% assert_equals: serialization should be canonical expected (string) "auto, 100%" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 0%, selector(  #foo)  3  end   assert_equals: serialization should be canonical expected (string) "0%, selector(#foo) end 3" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end 3, selector(#bar) assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3, selector(#bar)" but got (undefined) undefined
-FAIL CSSScrollTimelineRule.scrollOffsets 0%, auto, selector(#foo) start, auto, selector(#bar) 12.3 assert_equals: serialization should be canonical expected (string) "0%, auto, selector(#foo) start, auto, selector(#bar) 12.3" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html
deleted file mode 100644
index 8724ddd..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html
+++ /dev/null
@@ -1,273 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/css/support/parsing-testcommon.js"></script>
-<div id="target"></div>
-<script>
-
-// Runs a function while a stylesheet is temporarily inserted into the
-// document.
-function with_stylesheet(text, func) {
-  let s = document.createElement('style');
-  try {
-    s.textContent = text;
-    document.documentElement.append(s);
-    func(s.sheet.rules);
-  } finally {
-    s.remove();
-  }
-}
-
-// Runs a test while a stylesheet is temporarily inserted into the
-// document.
-function test_stylesheet(text, func, description) {
-  test(() => {
-    with_stylesheet(text, func);
-  }, description);
-}
-
-function test_valid_rule(text, description) {
-  test_stylesheet(text, (rules) => {
-    assert_equals(rules.length, 1);
-    assert_equals(rules[0].constructor.name, 'CSSScrollTimelineRule');
-  }, description);
-}
-
-function test_invalid_rule(text, description) {
-  test_stylesheet(text, (rules) => {
-    assert_equals(rules.length, 0);
-  }, description);
-}
-
-// Verify that for the _specifed_ value for a given _descriptor_, the _expected_
-// string can be observed via the equivalent attribute on CSSScrollTimelineRule.
-function test_descriptor(descriptor, specified, expected) {
-  if (typeof(expected) == 'undefined')
-    expected = specified;
-  let attribute = descriptor.replaceAll(/\-./g, x => x[1].toUpperCase());
-  test_stylesheet(`@scroll-timeline test { ${descriptor}:${specified}; }`, (rules) => {
-    assert_equals(rules.length, 1);
-    assert_equals(rules[0].constructor.name, 'CSSScrollTimelineRule');
-    if (Array.isArray(expected)) {
-      assert_in_array(rules[0][attribute], expected, "serialization should be sound");
-    } else {
-      assert_equals(rules[0][attribute], expected, "serialization should be canonical");
-    }
-  }, `CSSScrollTimelineRule.${attribute} ${specified}`);
-}
-
-test_valid_rule('@scroll-timeline foo {}', 'Empty block');
-test_valid_rule('@scroll-timeline foo {', 'EOF ends block');
-test_valid_rule('@scroll-timeline "foo" {}', 'Timeline name can be a <string>');
-
-test_invalid_rule('@scroll-timeline', 'Missing prelude');
-test_invalid_rule('@scroll-timeline foo', 'Missing block');
-test_invalid_rule('@scroll-timeline {}', 'Missing timeline name');
-test_invalid_rule('@scroll-timeline 123 {}', 'Timeline name must be an identifier');
-test_invalid_rule('@scroll-timeline none {}', 'Timeline name must match <custom-ident>');
-test_invalid_rule('@scroll-timeline NONE {}', 'Timeline name must match <custom-ident> (caps)');
-test_invalid_rule('@scroll-timeline NoNe {}', 'Timeline name must match <custom-ident> (mixed)');
-test_invalid_rule('@scroll-timeline initial {}', 'Timeline name may not be initial');
-test_invalid_rule('@scroll-timeline inherit {}', 'Timeline name may not be inherit');
-test_invalid_rule('@scroll-timeline unset {}', 'Timeline name may not be unset');
-test_invalid_rule('@scroll-timeline revert {}', 'Timeline name may not be revert');
-test_invalid_rule('@scroll-timeline default {}', 'Timeline name may not be default');
-test_invalid_rule('@scroll-timeline foo bar {}', 'Extra timeline name');
-
-// CSSRule.type
-
-test(() => {
-  with_stylesheet(`@scroll-timeline valid { }`, (rules) => {
-    assert_equals(rules.length, 1);
-    let rule = rules[0];
-    assert_equals(rule.constructor.name, 'CSSScrollTimelineRule');
-    assert_equals(rule.type, 0);
-  });
-}, 'CSSRule.type returns 0');
-
-// CSSScrollTimelineRule.name
-
-function test_name(specified, expected) {
-  if (typeof(expected) == 'undefined')
-    expected = specified;
-  test_stylesheet(`@scroll-timeline ${specified} { }`, (rules) => {
-    assert_equals(rules.length, 1);
-    assert_equals(rules[0].constructor.name, 'CSSScrollTimelineRule');
-    assert_equals(rules[0].name, expected);
-  }, `CSSScrollTimelineRule.name ${specified}`);
-}
-
-test_name('foo');
-test_name('Foo');
-test_name('f___123');
-test_name('a\\9 b', 'a\tb'); // U+0009 CHARACTER TABULATION
-test_name('"foo"', 'foo');
-test_name('"none"', 'none');
-
-// CSSScrollTimelineRule.cssText
-
-function test_csstext(description, specified, expected) {
-  if (typeof(expected) == 'undefined')
-    expected = specified;
-  test_stylesheet(specified, (rules) => {
-    assert_equals(rules.length, 1);
-    assert_equals(rules[0].constructor.name, 'CSSScrollTimelineRule');
-    assert_equals(rules[0].cssText, expected);
-  }, `CSSScrollTimelineRule.cssText: ${description}`);
-}
-
-test_csstext(
-  'empty rule',
-  `@scroll-timeline timeline {}`,
-  `@scroll-timeline timeline { }`);
-
-// U+0009 CHARACTER TABULATION
-test_csstext(
-  'escaped name',
-  `@scroll-timeline tab\\9 tab {}`,
-  `@scroll-timeline tab\\9 tab { }`);
-
-test_csstext(
-  'source descriptor',
-  `@scroll-timeline timeline { source: selector(#foo); }`);
-
-test_csstext(
-  'orientation descriptor',
-  `@scroll-timeline timeline { orientation: inline; }`);
-
-// https://github.com/w3c/csswg-drafts/issues/6617
-test_csstext(
-  'scroll-offsets descriptor (none)',
-  `@scroll-timeline timeline { scroll-offsets: none; }`,
-  `@scroll-timeline timeline { scroll-offsets: none; }`,);
-
-test_csstext(
-  'scroll-offsets descriptor (auto)',
-  `@scroll-timeline timeline { scroll-offsets: auto; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (container-based offset, px)',
-  `@scroll-timeline timeline { scroll-offsets: 100px; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (container-based offset, percentage)',
-  `@scroll-timeline timeline { scroll-offsets: 100%; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (element offset)',
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar); }`);
-
-test_csstext(
-  'scroll-offsets descriptor (element offset with edge)',
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (element offset with threshold)',
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar) 1; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (element offset with edge and threshold)',
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (element offset with threshold and edge)',
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar) 1 start; }`,
-  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }`);
-
-test_csstext(
-  'scroll-offsets descriptor (multiple offsets)',
-  `@scroll-timeline timeline { scroll-offsets: auto, selector(#bar) start 1; }`);
-
-test_csstext(
-  'defaults',
-  `@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }`);
-
-test_csstext(
-  'order',
-  `@scroll-timeline timeline { orientation: auto; source: auto; scroll-offsets: none; }`,
-  `@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }`);
-
-// CSSScrollTimelineRule.source
-
-function test_source(specified, expected) {
-  test_descriptor('source', specified, expected);
-}
-
-test_source('selector(#foo)');
-test_source('selector( #foo )', 'selector(#foo)');
-test_source(' selector(#foo) ', 'selector(#foo)');
-test_source('none');
-test_source(' none ', 'none');
-test_source('selector(#a\\9 b)');
-test_source('auto');
-
-test_source('#foo', 'auto');
-test_source('', 'auto');
-test_source('element(#foo)', 'auto');
-test_source('selector(#foo more)', 'auto');
-test_source('selector(html)', 'auto');
-test_source('selector(foo)', 'auto');
-test_source('selector(:before)', 'auto');
-test_source('selector(*)', 'auto');
-test_source('selector(.a)', 'auto');
-test_source('selector(.a, .b)', 'auto');
-
-// CSSScrollTimelineRule.orientation
-
-function test_orientation(specified, expected) {
-  test_descriptor('orientation', specified, expected);
-}
-
-test_orientation('auto');
-test_orientation('block');
-test_orientation('inline');
-test_orientation('horizontal');
-test_orientation('vertical');
-test_orientation('  vertical  ', 'vertical');
-
-test_orientation('', 'auto');
-test_orientation('foo', 'auto');
-test_orientation('10px', 'auto');
-test_orientation('red', 'auto');
-
-// CSSScrollTimelineRule.scrollOffsets
-
-function test_offsets(specified, expected) {
-  test_descriptor('scroll-offsets', specified, expected);
-}
-
-test_offsets('none');
-test_offsets(' none ', 'none');
-test_offsets('', 'none');
-test_offsets('red', 'none');
-test_offsets('#fff', 'none');
-test_offsets('unset', 'none');
-test_offsets('unknown(#foo)', 'none');
-test_offsets('start', 'none');
-test_offsets('end', 'none');
-test_offsets('3', 'none');
-test_offsets('selector(#foo) 3 start 10', 'none');
-test_offsets('0%, 100%, selector(.a)', 'none');
-test_offsets('selector(#foo) 3 end, start', 'none');
-
-test_offsets('auto');
-test_offsets('10em');
-test_offsets('10%');
-test_offsets('calc(1px + 1%)', ['calc(1px + 1%)', 'calc(1% + 1px)']);
-test_offsets('selector(#foo)');
-test_offsets(' selector(#foo)', 'selector(#foo)');
-test_offsets('selector(#foo) start');
-test_offsets('selector(#foo) start 3');
-test_offsets('selector(#foo) 3');
-test_offsets('selector(#foo) 3.5');
-test_offsets('selector(#foo) end');
-test_offsets('selector(#foo) end 3');
-test_offsets('selector(#foo) 3 end', 'selector(#foo) end 3');
-test_offsets(' auto , auto ', 'auto, auto');
-test_offsets('10%, 100px');
-test_offsets('auto, 100%');
-test_offsets('0%, selector(  #foo)  3  end  ', "0%, selector(#foo) end 3");
-test_offsets('selector(#foo) end 3, selector(#bar)');
-test_offsets('0%, auto, selector(#foo) start, auto, selector(#bar) 12.3');
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-print.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-print.html
similarity index 78%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-print.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-print.html
index 0b73d7f..fc8e4f1 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-print.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-print.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule in the iframe for print</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>The default scroll() timeline in the iframe for print</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-iframe-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using the default scroll() timeline">
+<link rel="match" href="scroll-timeline-default-iframe-ref.html">
 
 <iframe id="target" width="400" height="400" srcdoc='
   <html>
@@ -13,11 +13,6 @@
       from { transform: translateY(0px); }
       to { transform: translateY(200px); }
     }
-    @scroll-timeline test-timeline {
-      source: auto;
-      orientation: auto;
-      scroll-offsets: none;
-    }
     html {
       min-height: 100%;
       padding-bottom: 100px;
@@ -27,7 +22,7 @@
       height: 100px;
       background-color: green;
       animation: update 1s linear;
-      animation-timeline: test-timeline;
+      animation-timeline: scroll();
     }
     #covered {
       width: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-ref.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-ref.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-ref.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-ref.html
index b05627d99..1ab5646 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe-ref.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe-ref.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Reference for default @scroll-timeline</title>
+<title>Reference for default scroll() timeline</title>
 <iframe width="400" height="400" srcdoc='
   <html>
   <style>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe.html
similarity index 79%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe.html
index ddb0669..46ede5d 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-iframe.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-iframe.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule in the iframe</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>The default scroll() timeline in the iframe</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-iframe-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using the default scroll() timeline">
+<link rel="match" href="scroll-timeline-default-iframe-ref.html">
 
 <iframe id="target" width="400" height="400" srcdoc='
   <html>
@@ -13,11 +13,6 @@
       from { transform: translateY(0px); }
       to { transform: translateY(200px); }
     }
-    @scroll-timeline test-timeline {
-      source: auto;
-      orientation: auto;
-      scroll-offsets: none;
-    }
     html {
       min-height: 100%;
       padding-bottom: 100px;
@@ -27,7 +22,7 @@
       height: 100px;
       background-color: green;
       animation: update 1s linear;
-      animation-timeline: test-timeline;
+      animation-timeline: scroll();
     }
     #covered {
       width: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-print.tentative.html
similarity index 76%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-print.tentative.html
index 5822534..e17a40e9 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-print.tentative.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>The default scroll() timeline for print</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using the default scroll() timeline">
+<link rel="match" href="scroll-timeline-default-ref.html">
 
 <style>
   @keyframes update {
@@ -12,12 +12,6 @@
     to { transform: translateY(200px); }
   }
 
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
   html {
     min-height: 100%;
     padding-bottom: 100px;
@@ -28,7 +22,7 @@
     height: 100px;
     background-color: green;
     animation: update 1s linear;
-    animation-timeline: test-timeline;
+    animation-timeline: scroll();
   }
 
   #covered {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-quirks-mode.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-quirks-mode.html
similarity index 75%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-quirks-mode.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-quirks-mode.html
index 1bba34d..1ef0297 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-quirks-mode.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-quirks-mode.html
@@ -1,9 +1,9 @@
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule in quirks mode</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>The default scroll() timeline in quirks mode</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using the default scroll() timeline">
+<link rel="match" href="scroll-timeline-default-ref.html">
 
 <style>
   @keyframes update {
@@ -11,12 +11,6 @@
     to { transform: translateY(200px); }
   }
 
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
   html {
     min-height: 100%;
     padding-bottom: 100px;
@@ -27,7 +21,7 @@
     height: 100px;
     background-color: green;
     animation: update 1s linear;
-    animation-timeline: test-timeline;
+    animation-timeline: scroll();
   }
 
   #covered {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-ref.html
similarity index 90%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-ref.html
index b72a4e8..cb3b60e 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-ref.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-ref.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Reference for default @scroll-timeline</title>
+<title>Reference for default scroll() timeline</title>
 <style>
   html {
     min-height: 100%;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl-ref.html
similarity index 89%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl-ref.html
index 2ea7d175..3c07282 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl-ref.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Reference for default @scroll-timeline with vertical-rl</title>
+<title>Reference for default scroll() timeline with vertical-rl</title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
 <style>
   html {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl.html
similarity index 73%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl.html
index 4d276497..5ef7743 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors-writing-mode-rl.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default-writing-mode-rl.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule with writing-mode:vertical-rl</title>
+<title>The default scroll() timeline with writing-mode:vertical-rl</title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
 <meta name="assert" content="CSS animation correctly updates values when using
-                             the default scroll-timeline at rule with writing-mode:vertical-rl">
-<link rel="match" href="at-scroll-timeline-default-descriptors-writing-mode-rl-ref.html">
+                             the default scroll() timeline with writing-mode:vertical-rl">
+<link rel="match" href="scroll-timeline-default-writing-mode-rl-ref.html">
 
 <style>
   @keyframes update {
@@ -14,12 +14,6 @@
     to { transform: translateX(-200px); }
   }
 
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
   html {
     min-block-size: 100%;
     padding-block-end: 100px;
@@ -31,7 +25,7 @@
     height: 100px;
     background-color: green;
     animation: update 1s linear;
-    animation-timeline: test-timeline;
+    animation-timeline: scroll();
   }
 
   #covered {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default.html
similarity index 76%
copy from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html
copy to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default.html
index 5822534..aff9f541 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-default-descriptors.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-default.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The default scroll-timeline at rule</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>The default scroll() timeline</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the default scroll-timeline at rule">
-<link rel="match" href="at-scroll-timeline-default-descriptors-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using the default scroll() timeline">
+<link rel="match" href="scroll-timeline-default-ref.html">
 
 <style>
   @keyframes update {
@@ -12,12 +12,6 @@
     to { transform: translateY(200px); }
   }
 
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
   html {
     min-height: 100%;
     padding-bottom: 100px;
@@ -28,7 +22,7 @@
     height: 100px;
     background-color: green;
     animation: update 1s linear;
-    animation-timeline: test-timeline;
+    animation-timeline: scroll();
   }
 
   #covered {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inactive-phase.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inactive.html
similarity index 78%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inactive-phase.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inactive.html
index a50583d..92165d70 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inactive-phase.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inactive.html
@@ -1,6 +1,5 @@
 <!DOCTYPE html>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#phase-algorithm">
+<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timelines">
 <link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#avoiding-cycles">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -32,16 +31,10 @@
 promise_test(async (t) => {
   let div = document.createElement('div');
   div.setAttribute('id', 'scroller');
+  div.style.scrollTimeline = 'timeline';
   div.innerHTML = '<div id=contents></div>';
-  let style = document.createElement('style');
-  style.textContent = `
-    @scroll-timeline timeline {
-      source: selector(#scroller);
-    }
-  `;
   try {
-    container.insertBefore(style, element);
-    container.insertBefore(div, style);
+    container.insertBefore(div, element);
 
     // The source has no layout box at the time the scroll timeline is created.
     assert_equals(getComputedStyle(element).width, '0px');
@@ -51,7 +44,6 @@
     // The timeline should now be active, and the animation should apply:
     assert_equals(getComputedStyle(element).width, '100px');
   } finally {
-    style.remove();
     div.remove();
   }
 }, 'Animation does not apply when timeline is initially inactive');
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation-ref.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation-ref.html
similarity index 88%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation-ref.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation-ref.html
index e87901e..7b87b1d 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation-ref.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation-ref.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Reference for @scroll-timeline with inline orientation</title>
+<title>Reference for scroll timeline with inline orientation and root scroller</title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
 <style>
   html {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation.html
similarity index 82%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation.html
index a10a3e0..a109e31 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-inline-orientation.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-inline-orientation.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The scroll-timeline at rule with inline orientation and default source</title>
+<title>Scroll timeline with inline orientation and root scroller</title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#descdef-scroll-timeline-orientation">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
 <meta name="assert" content="CSS animation correctly updates values when using the inline orientation">
-<link rel="match" href="at-scroll-timeline-inline-orientation-ref.html">
+<link rel="match" href="scroll-timeline-inline-orientation-ref.html">
 
 <style>
   @keyframes update {
@@ -14,11 +14,6 @@
     to { transform: translateX(200px); }
   }
 
-  @scroll-timeline test-timeline {
-    source: auto;
-    orientation: inline;
-  }
-
   html {
     min-width: 100%;
     padding-right: 100px;
@@ -30,7 +25,7 @@
     height: 100px;
     background-color: green;
     animation: update 1s linear;
-    animation-timeline: test-timeline;
+    animation-timeline: scroll(inline root);
     display: inline-block;
   }
 
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-paused-animations.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-paused-animations.html
similarity index 90%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-paused-animations.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-paused-animations.html
index 93aae81..a8117fa 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-paused-animations.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-paused-animations.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<title>The default scroll-timeline at rule with paused animations</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>Scroll timeline with paused animations</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/css-animations/#animation-play-state">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -13,11 +13,6 @@
     to { width: 200px; }
   }
 
-  @scroll-timeline timeline {
-    source: auto;
-    orientation: auto;
-  }
-
   .fill-vh {
     width: 100px;
     height: 100vh;
@@ -40,7 +35,7 @@
   const scroller = document.scrollingElement;
   t.add_cleanup(resetScrollPosition);
 
-  div.style.animation = 'anim 100s linear timeline paused';
+  div.style.animation = 'anim 100s linear paused scroll(root)';
   const anim = div.getAnimations()[0];
   await anim.ready;
   assert_percents_equal(anim.currentTime, 0, 'timeline time reset');
@@ -59,7 +54,7 @@
   const scroller = document.scrollingElement;
   await waitForNextFrame();
 
-  div.style.animation = 'anim 100s linear forwards timeline';
+  div.style.animation = 'anim 100s linear forwards scroll(root)';
   const anim = div.getAnimations()[0];
   await anim.ready;
   assert_percents_equal(anim.currentTime, 0, 'timeline time reset');
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-responsiveness-from-endpoint.html
similarity index 87%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-responsiveness-from-endpoint.html
index 883f94b..5555fd0 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-responsiveness-from-endpoint.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<title>The default scroll-timeline at rule with animation moving from end point</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>Root-scrolling timeline with animation moving from end point</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-notation">
 <link rel="help" href="https://drafts.csswg.org/web-animations/#update-an-animations-finished-state">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -14,11 +14,6 @@
     to { width: 200px; }
   }
 
-  @scroll-timeline timeline {
-    source: auto;
-    orientation: auto;
-  }
-
   .fill-vh {
     width: 100px;
     height: 100vh;
@@ -36,7 +31,7 @@
   scroller.scrollTop = 0;
   await waitForNextFrame();
 
-  div.style.animation = 'anim 100s linear timeline';
+  div.style.animation = 'anim 100s linear scroll(root)';
   const anim = div.getAnimations()[0];
   await anim.ready;
   assert_percents_equal(anim.timeline.currentTime, 0,
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-sampling.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-sampling.html
similarity index 89%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-sampling.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-sampling.html
index cc35077..1fe354e 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-sampling.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-sampling.html
@@ -1,5 +1,4 @@
 <!DOCTYPE html>
-<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
 <link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#avoiding-cycles">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -9,6 +8,7 @@
     overflow: hidden;
     width: 100px;
     height: 100px;
+    scroll-timeline: timeline;
   }
   #contents {
     height: 200px;
@@ -17,9 +17,6 @@
     from { width: 100px; }
     to { width: 200px; }
   }
-  @scroll-timeline timeline {
-    source: selector(#scroller);
-  }
   #element {
     width: 0px;
     animation: expand 10s linear;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print-ref.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print-ref.html
similarity index 91%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print-ref.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print-ref.html
index fa945ce7..9074f24 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print-ref.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print-ref.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
-<title>Reference for @scroll-timeline with a specified scroller</title>
+<title>Reference for scroll timeline with a specified scroller</title>
 <style>
   #scroller {
     overflow: scroll;
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print.html
similarity index 76%
rename from third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print.html
rename to third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print.html
index 5543088..0d262c2 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-specified-scroller-print.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-specified-scroller-print.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
-<title>The scroll-timeline at rule with a specified scroller for print</title>
-<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
+<title>A scroll timeline with a specified scroller for print</title>
+<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#scroll-timelines">
 <link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-timeline">
-<meta name="assert" content="CSS animation correctly updates values when using the a specified scroller">
-<link rel="match" href="at-scroll-timeline-specified-scroller-print-ref.html">
+<meta name="assert" content="CSS animation correctly updates values when using a specified scroller">
+<link rel="match" href="scroll-timeline-specified-scroller-print-ref.html">
 
 <style>
   @keyframes anim {
@@ -12,13 +12,8 @@
     to { transform: translateX(100px); }
   }
 
-  @scroll-timeline timeline {
-    source: selector(#scroller);
-    orientation: auto;
-    scroll-offsets: none;
-  }
-
   #scroller {
+    scroll-timeline: timeline;
     overflow: scroll;
     width: 100px;
     height: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
index f9c50fc4..d3dd35b 100644
--- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
@@ -5,8 +5,6 @@
 PASS Payment credential requires userVerification to be "required", not "discouraged".
 PASS Payment credential does not allow residentKey to be "discouraged".
 PASS Payment credential requires authenticatorAttachment to be "platform", not "cross-platform".
-PASS Payment credential abort without reason
-PASS Payment credential abort reason with Error
 PASS Clean up the test environment
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
index b93822c..7a370aa 100644
--- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
+++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
@@ -41,19 +41,6 @@
       .runTest('Payment credential does not allow residentKey to be "discouraged".', "NotSupportedError");
   new CreatePaymentCredentialsTest({authenticatorAttachment: 'cross-platform'})
       .runTest('Payment credential requires authenticatorAttachment to be "platform", not "cross-platform".', "NotSupportedError");
-
-  // abort creates
-  let abortController = new AbortController();
-  abortController.abort();
-  new CreatePaymentCredentialsTest()
-      .modify("options.signal", abortController.signal)
-      .runTest("Payment credential abort without reason", "AbortError");
-
-  abortController = new AbortController();
-  abortController.abort(new Error('error'));
-  new CreatePaymentCredentialsTest()
-      .modify("options.signal", abortController.signal)
-      .runTest("Payment credential abort reason with Error", Error);
 }, {
   protocol: 'ctap2_1',
   transport: 'internal',
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/midi.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/midi.https.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/prerender/resources/midi.https.html
rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/midi.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-midi-sysex.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi-sysex.https.html
similarity index 91%
rename from third_party/blink/web_tests/wpt_internal/prerender/restriction-midi-sysex.https.html
rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi-sysex.https.html
index 5dc639bc..2d67555 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-midi-sysex.https.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi-sysex.https.html
@@ -1,9 +1,4 @@
 <!DOCTYPE html>
-<!--
-This file cannot be upstreamed to WPT until:
-* The code that allows the test to pass when navigator.requestMIDIAccess()
-  rejects in resources/midi.https.html is removed.
--->
 <title>Access to the Midi API with sysex=true is deferred</title>
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
@@ -14,6 +9,7 @@
 <script src="/speculation-rules/prerender/resources/utils.js"></script>
 <body>
 <script>
+setup(() => assertSpeculationRulesIsSupported());
 
 promise_test(async t => {
   const uid = token();
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-midi.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi.https.html
similarity index 91%
rename from third_party/blink/web_tests/wpt_internal/prerender/restriction-midi.https.html
rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi.https.html
index 7f6227a4..b61ed736 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-midi.https.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-midi.https.html
@@ -1,9 +1,4 @@
 <!DOCTYPE html>
-<!--
-This file cannot be upstreamed to WPT until:
-* The code that allows the test to pass when navigator.requestMIDIAccess()
-  rejects in resources/midi.https.html is removed.
--->
 <title>Access to the Midi API with sysex=false is deferred</title>
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
@@ -14,6 +9,7 @@
 <script src="/speculation-rules/prerender/resources/utils.js"></script>
 <body>
 <script>
+setup(() => assertSpeculationRulesIsSupported());
 
 promise_test(async t => {
   const uid = token();
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html b/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html
deleted file mode 100644
index 15b2b8b..0000000
--- a/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>WebAuthn navigator.credentials.create() abort Tests</title>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src=helpers.js></script>
-<body></body>
-<script>
-standardSetup(function() {
-    "use strict";
-
-    let abortController = new AbortController();
-    abortController.abort();
-    new CreateCredentialsTest("options.signal", abortController.signal)
-      .runTest("navigator.credentials.create() abort without reason", "AbortError");
-
-    abortController = new AbortController();
-    abortController.abort(new Error('error'));
-    new CreateCredentialsTest("options.signal", abortController.signal)
-      .runTest("navigator.credentials.create() abort reason with Error", Error);
-});
-
-/* JSHINT */
-/* globals standardSetup, CreateCredentialsTest */
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html b/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html
deleted file mode 100644
index 1cd5a7e..0000000
--- a/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>WebAuthn navigator.credentials.get() abort Tests</title>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src=helpers.js></script>
-<body></body>
-<script>
-"use strict";
-
-virtualAuthenticatorPromiseTest(async t => {
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  const promise = navigator.credentials.get({
-    publicKey: {
-      challenge: new Uint8Array(),
-      allowCredentials: [{
-        id: (await createCredential()).rawId,
-        type: "public-key",
-      }]
-    },
-    signal: signal,
-  });
-  abortController.abort();
-  return promise_rejects_dom(t, "AbortError", promise);
-}, {
-  protocol: "ctap1/u2f",
-  transport: "usb",
-}, "navigator.credentials.get() abort without reason");
-
-virtualAuthenticatorPromiseTest(async t => {
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  const promise = navigator.credentials.get({
-    publicKey: {
-      challenge: new Uint8Array(),
-      allowCredentials: [{
-        id: (await createCredential()).rawId,
-        type: "public-key",
-      }]
-    },
-    signal: signal,
-  });
-  abortController.abort("CustomError");
-  return promise_rejects_exactly(t, "CustomError", promise);
-}, {
-  protocol: "ctap1/u2f",
-  transport: "usb",
-}, "navigator.credentials.get() abort reason");
-
-virtualAuthenticatorPromiseTest(async t => {
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  const promise = navigator.credentials.get({
-    publicKey: {
-      challenge: new Uint8Array(),
-      allowCredentials: [{
-        id: (await createCredential()).rawId,
-        type: "public-key",
-      }]
-    },
-    signal: signal,
-  });
-  abortController.abort(new Error('error'));
-  return promise_rejects_js(t, Error, promise);
-}, {
-  protocol: "ctap1/u2f",
-  transport: "usb",
-}, "navigator.credentials.get() abort reason with Error");
-
-</script>
diff --git a/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/fast/canvas/canvas-pattern-video-expected.png b/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/fast/canvas/canvas-pattern-video-expected.png
new file mode 100644
index 0000000..4cea3d2
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/fast/canvas/canvas-pattern-video-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/compositing/direct-image-compositing-expected.png b/third_party/blink/web_tests/platform/linux/compositing/direct-image-compositing-expected.png
index 1065126..e952761 100644
--- a/third_party/blink/web_tests/platform/linux/compositing/direct-image-compositing-expected.png
+++ b/third_party/blink/web_tests/platform/linux/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/direct-image-compositing-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/direct-image-compositing-expected.png
index 103a86e8..df4262e1 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/direct-image-compositing-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/compositing/direct-image-compositing-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/compositing/direct-image-compositing-expected.png
index 103a86e8..df4262e1 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/compositing/direct-image-compositing-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/direct-image-compositing-expected.png b/third_party/blink/web_tests/platform/mac/compositing/direct-image-compositing-expected.png
index aa006d6b..26027886 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/direct-image-compositing-expected.png
+++ b/third_party/blink/web_tests/platform/mac/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/direct-image-compositing-expected.png b/third_party/blink/web_tests/platform/win/compositing/direct-image-compositing-expected.png
index 17f5a6f7..2e0539a 100644
--- a/third_party/blink/web_tests/platform/win/compositing/direct-image-compositing-expected.png
+++ b/third_party/blink/web_tests/platform/win/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/storage-access-api/requestStorageAccessForSite.sub.tentative.window.js b/third_party/blink/web_tests/wpt_internal/storage-access-api/requestStorageAccessForSite.sub.tentative.window.js
index 8e82dbe..d0ea847c 100644
--- a/third_party/blink/web_tests/wpt_internal/storage-access-api/requestStorageAccessForSite.sub.tentative.window.js
+++ b/third_party/blink/web_tests/wpt_internal/storage-access-api/requestStorageAccessForSite.sub.tentative.window.js
@@ -28,6 +28,22 @@
   }
 });
 
+// TODO(crbug.com/1351540): when/if requestStorageAccessForSite is standardized,
+// upstream with the Storage Access API helpers file.
+function RunRequestStorageAccessForSiteInDetachedFrame(site) {
+  let nestedFrame = document.createElement('iframe');
+  document.body.append(nestedFrame);
+  const inner_doc = nestedFrame.contentDocument;
+  nestedFrame.remove();
+  return inner_doc.requestStorageAccessForSite(site);
+}
+
+function RunRequestStorageAccessForSiteViaDomParser(site) {
+  let parser = new DOMParser();
+  let doc = parser.parseFromString('<html></html>', 'text/html');
+  return doc.requestStorageAccessForSite(site);
+}
+
 // Common tests to run in all frames.
 test(
     () => {
@@ -51,6 +67,29 @@
       '[' + testPrefix +
           '] document.requestStorageAccessForSite() should be rejected by default with no user gesture');
 
+  promise_test(async t => {
+    let promise =
+        RunRequestStorageAccessForSiteInDetachedFrame('https://foo.com');
+    let description =
+        'document.requestStorageAccessForSite() call in a detached frame';
+    return promise
+        .then(t.unreached_func('Should have rejected: ' + description))
+        .catch(function(e) {
+          assert_equals(e.name, 'SecurityError', description);
+        });
+  }, '[non-fully-active] document.requestStorageAccessForSite() should not resolve when run in a detached frame');
+
+  promise_test(async t => {
+    let promise = RunRequestStorageAccessForSiteViaDomParser('https://foo.com');
+    let description =
+        'document.requestStorageAccessForSite() in a detached DOMParser result';
+    return promise
+        .then(t.unreached_func('Should have rejected: ' + description))
+        .catch(function(e) {
+          assert_equals(e.name, 'SecurityError', description);
+        });
+  }, '[non-fully-active] document.requestStorageAccessForSite() should not resolve when run in a detached DOMParser document');
+
   // Create a test with a single-child same-origin iframe.
   // This will validate that calls to requestStorageAccessForSite are rejected
   // in non-top-level contexts.
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js
index 725a8bd..431cadd 100644
--- a/third_party/closure_compiler/externs/automation.js
+++ b/third_party/closure_compiler/externs/automation.js
@@ -1269,6 +1269,20 @@
 chrome.automation.AutomationNode.prototype.name;
 
 /**
+ * Explains what will happen when the doDefault action is performed.
+ * @type {(string|undefined)}
+ * @see https://developer.chrome.com/extensions/automation#type-doDefaultLabel
+ */
+chrome.automation.AutomationNode.prototype.doDefaultLabel;
+
+/**
+ * Explains what will happen when the long click action is performed.
+ * @type {(string|undefined)}
+ * @see https://developer.chrome.com/extensions/automation#type-longClickLabel
+ */
+chrome.automation.AutomationNode.prototype.longClickLabel;
+
+/**
  * The tooltip of the node, if any.
  * @type {(string|undefined)}
  * @see https://developer.chrome.com/extensions/automation#type-tooltip
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js
index c0310622..df3333e 100644
--- a/third_party/closure_compiler/externs/file_manager_private.js
+++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -742,6 +742,7 @@
  *   totalBytes: number,
  *   taskId: number,
  *   remainingSeconds: number,
+ *   showNotification: boolean,
  *   errorName: string,
  *   outputs: (Array<Entry>|undefined),
  * }}
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 49ba1042..6c59013 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-79-g4797b2ff2
-Revision: 4797b2ff22906ce4ff4e6dcee300a70f94dcc43a
+Version: VER-2-12-1-80-gdd91f6e7f
+Revision: dd91f6e7f5a051818070c49715125fb72074023e
 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/subresource-filter-ruleset/README.chromium b/third_party/subresource-filter-ruleset/README.chromium
index 265de197..37c8e5e 100644
--- a/third_party/subresource-filter-ruleset/README.chromium
+++ b/third_party/subresource-filter-ruleset/README.chromium
@@ -1,6 +1,6 @@
 Name: EasyList
 URL: https://easylist.to/easylist/easylist.txt
-Version: 202207071731
+Version: 202208151610
 License: Creative Commons Attribution-ShareAlike 3.0 Unported
 License Android Compatible: yes
 License File: LICENSE
diff --git a/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1 b/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1
index 447e00d1..bfaaedd 100644
--- a/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1
+++ b/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1
@@ -1 +1 @@
-553161b8146b701e6088a07c56561959f3405f20
\ No newline at end of file
+d26fee22ae18ede362eda438c0062e8778ec7722
diff --git a/third_party/subresource-filter-ruleset/manifest.json b/third_party/subresource-filter-ruleset/manifest.json
index 58b9cdd..3786271 100644
--- a/third_party/subresource-filter-ruleset/manifest.json
+++ b/third_party/subresource-filter-ruleset/manifest.json
@@ -2,5 +2,5 @@
   "manifest_version": 2,
   "name": "Subresource Filtering Rules",
   "ruleset_format": 1,
-  "version": "9.37.2"
+  "version": "9.38.0"
 }
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn
index 0b65ea5c..f5ddfd5 100644
--- a/third_party/wayland-protocols/BUILD.gn
+++ b/third_party/wayland-protocols/BUILD.gn
@@ -4,17 +4,38 @@
 
 import("//third_party/wayland/wayland_protocol.gni")
 
-wayland_protocol("gtk_shell_protocol") {
-  sources = [ "gtk/gdk/wayland/protocol/gtk-shell.xml" ]
+# ATTENTION! Please keep these rules alphabetized!
+
+wayland_protocol("alpha_compositing_protocol") {
+  sources = [ "unstable/alpha-compositing/alpha-compositing-unstable-v1.xml" ]
+}
+
+wayland_protocol("content_type_protocol") {
+  sources = [ "unstable/content-type/content-type-v1.xml" ]
+}
+
+wayland_protocol("cursor_shapes_protocol") {
+  sources = [ "unstable/cursor-shapes/cursor-shapes-unstable-v1.xml" ]
+}
+
+wayland_protocol("extended_drag") {
+  sources = [ "unstable/extended-drag/extended-drag-unstable-v1.xml" ]
+}
+
+wayland_protocol("fullscreen_shell_protocol") {
+  sources = [ "src/unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml" ]
+}
+
+wayland_protocol("gaming_input_protocol") {
+  sources = [ "unstable/gaming-input/gaming-input-unstable-v2.xml" ]
 }
 
 wayland_protocol("gtk_primary_selection_protocol") {
   sources = [ "unstable/gtk-primary-selection/gtk-primary-selection.xml" ]
 }
 
-wayland_protocol("primary_selection_protocol") {
-  sources =
-      [ "src/unstable/primary-selection/primary-selection-unstable-v1.xml" ]
+wayland_protocol("gtk_shell_protocol") {
+  sources = [ "gtk/gdk/wayland/protocol/gtk-shell.xml" ]
 }
 
 wayland_protocol("idle_inhibit_protocol") {
@@ -25,6 +46,122 @@
   sources = [ "src/unstable/input-method/input-method-unstable-v1.xml" ]
 }
 
+wayland_protocol("input_timestamps_protocol") {
+  sources = [ "src/unstable/input-timestamps/input-timestamps-unstable-v1.xml" ]
+}
+
+wayland_protocol("keyboard_configuration_protocol") {
+  sources = [ "unstable/keyboard/keyboard-configuration-unstable-v1.xml" ]
+}
+
+wayland_protocol("keyboard_extension_protocol") {
+  sources = [ "unstable/keyboard/keyboard-extension-unstable-v1.xml" ]
+}
+
+wayland_protocol("keyboard_shortcuts_inhibit_protocol") {
+  sources = [ "src/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" ]
+}
+
+wayland_protocol("linux_dmabuf_protocol") {
+  sources = [ "src/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" ]
+}
+
+wayland_protocol("linux_explicit_synchronization_protocol") {
+  sources = [ "src/unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml" ]
+}
+
+wayland_protocol("notification_shell_protocol") {
+  sources = [ "unstable/notification-shell/notification-shell-unstable-v1.xml" ]
+}
+
+wayland_protocol("org_kde_kwin_idle") {
+  sources = [ "kde/src/protocols/idle.xml" ]
+}
+
+wayland_protocol("pointer_constraints_protocol") {
+  sources =
+      [ "src/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" ]
+}
+
+wayland_protocol("pointer_gestures_protocol") {
+  sources = [ "src/unstable/pointer-gestures/pointer-gestures-unstable-v1.xml" ]
+}
+
+wayland_protocol("presentation_time_protocol") {
+  sources = [ "src/stable/presentation-time/presentation-time.xml" ]
+}
+
+wayland_protocol("primary_selection_protocol") {
+  sources =
+      [ "src/unstable/primary-selection/primary-selection-unstable-v1.xml" ]
+}
+
+wayland_protocol("relative_pointer_protocol") {
+  sources = [ "src/unstable/relative-pointer/relative-pointer-unstable-v1.xml" ]
+}
+
+wayland_protocol("remote_shell_protocol") {
+  sources = [
+    "unstable/remote-shell/remote-shell-unstable-v1.xml",
+    "unstable/remote-shell/remote-shell-unstable-v2.xml",
+  ]
+}
+
+wayland_protocol("secure_output_protocol") {
+  sources = [ "unstable/secure-output/secure-output-unstable-v1.xml" ]
+}
+
+wayland_protocol("stylus_protocol") {
+  sources = [ "unstable/stylus/stylus-unstable-v2.xml" ]
+}
+
+wayland_protocol("stylus_tools_protocol") {
+  sources = [ "unstable/stylus-tools/stylus-tools-unstable-v1.xml" ]
+}
+
+wayland_protocol("text_input_extension_protocol") {
+  sources = [ "unstable/text-input/text-input-extension-unstable-v1.xml" ]
+}
+
+wayland_protocol("text_input_protocol") {
+  sources = [ "src/unstable/text-input/text-input-unstable-v1.xml" ]
+}
+
+wayland_protocol("touchpad_haptics_protocol") {
+  sources = [ "unstable/touchpad-haptics/touchpad-haptics-unstable-v1.xml" ]
+}
+
+wayland_protocol("viewporter_protocol") {
+  sources = [ "src/stable/viewporter/viewporter.xml" ]
+}
+
+wayland_protocol("vsync_feedback_protocol") {
+  sources = [ "unstable/vsync-feedback/vsync-feedback-unstable-v1.xml" ]
+}
+
+wayland_protocol("wayland_drm_protocol") {
+  sources = [ "mesa/wayland-drm/wayland-drm.xml" ]
+}
+
+wayland_protocol("weston_test") {
+  sources = [ "unstable/weston-test/weston-test.xml" ]
+}
+
+wayland_protocol("xdg_activation") {
+  sources = [ "src/staging/xdg-activation/xdg-activation-v1.xml" ]
+}
+
+wayland_protocol("xdg_decoration_protocol") {
+  sources = [ "src/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ]
+}
+
+wayland_protocol("xdg_foreign") {
+  sources = [
+    "src/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml",
+    "src/unstable/xdg-foreign/xdg-foreign-unstable-v2.xml",
+  ]
+}
+
 wayland_protocol("xdg_output_protocol") {
   sources = [ "src/unstable/xdg-output/xdg-output-unstable-v1.xml" ]
 }
@@ -35,134 +172,3 @@
     "src/unstable/xdg-shell/xdg-shell-unstable-v6.xml",
   ]
 }
-
-wayland_protocol("linux_dmabuf_protocol") {
-  sources = [ "src/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" ]
-}
-
-wayland_protocol("xdg_decoration_protocol") {
-  sources = [ "src/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ]
-}
-
-wayland_protocol("viewporter_protocol") {
-  sources = [ "src/stable/viewporter/viewporter.xml" ]
-}
-
-wayland_protocol("presentation_time_protocol") {
-  sources = [ "src/stable/presentation-time/presentation-time.xml" ]
-}
-
-wayland_protocol("vsync_feedback_protocol") {
-  sources = [ "unstable/vsync-feedback/vsync-feedback-unstable-v1.xml" ]
-}
-
-wayland_protocol("secure_output_protocol") {
-  sources = [ "unstable/secure-output/secure-output-unstable-v1.xml" ]
-}
-
-wayland_protocol("alpha_compositing_protocol") {
-  sources = [ "unstable/alpha-compositing/alpha-compositing-unstable-v1.xml" ]
-}
-
-wayland_protocol("remote_shell_protocol") {
-  sources = [
-    "unstable/remote-shell/remote-shell-unstable-v1.xml",
-    "unstable/remote-shell/remote-shell-unstable-v2.xml",
-  ]
-}
-
-wayland_protocol("gaming_input_protocol") {
-  sources = [ "unstable/gaming-input/gaming-input-unstable-v2.xml" ]
-}
-
-wayland_protocol("stylus_protocol") {
-  sources = [ "unstable/stylus/stylus-unstable-v2.xml" ]
-}
-
-wayland_protocol("pointer_gestures_protocol") {
-  sources = [ "src/unstable/pointer-gestures/pointer-gestures-unstable-v1.xml" ]
-}
-
-wayland_protocol("pointer_constraints_protocol") {
-  sources =
-      [ "src/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" ]
-}
-
-wayland_protocol("relative_pointer_protocol") {
-  sources = [ "src/unstable/relative-pointer/relative-pointer-unstable-v1.xml" ]
-}
-
-wayland_protocol("keyboard_configuration_protocol") {
-  sources = [ "unstable/keyboard/keyboard-configuration-unstable-v1.xml" ]
-}
-
-wayland_protocol("stylus_tools_protocol") {
-  sources = [ "unstable/stylus-tools/stylus-tools-unstable-v1.xml" ]
-}
-
-wayland_protocol("keyboard_extension_protocol") {
-  sources = [ "unstable/keyboard/keyboard-extension-unstable-v1.xml" ]
-}
-
-wayland_protocol("keyboard_shortcuts_inhibit_protocol") {
-  sources = [ "src/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" ]
-}
-
-wayland_protocol("input_timestamps_protocol") {
-  sources = [ "src/unstable/input-timestamps/input-timestamps-unstable-v1.xml" ]
-}
-
-wayland_protocol("cursor_shapes_protocol") {
-  sources = [ "unstable/cursor-shapes/cursor-shapes-unstable-v1.xml" ]
-}
-
-wayland_protocol("text_input_protocol") {
-  sources = [ "src/unstable/text-input/text-input-unstable-v1.xml" ]
-}
-
-wayland_protocol("text_input_extension_protocol") {
-  sources = [ "unstable/text-input/text-input-extension-unstable-v1.xml" ]
-}
-
-wayland_protocol("notification_shell_protocol") {
-  sources = [ "unstable/notification-shell/notification-shell-unstable-v1.xml" ]
-}
-
-wayland_protocol("fullscreen_shell_protocol") {
-  sources = [ "src/unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml" ]
-}
-
-wayland_protocol("linux_explicit_synchronization_protocol") {
-  sources = [ "src/unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml" ]
-}
-
-wayland_protocol("wayland_drm_protocol") {
-  sources = [ "mesa/wayland-drm/wayland-drm.xml" ]
-}
-
-wayland_protocol("xdg_activation") {
-  sources = [ "src/staging/xdg-activation/xdg-activation-v1.xml" ]
-}
-
-wayland_protocol("xdg_foreign") {
-  sources = [
-    "src/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml",
-    "src/unstable/xdg-foreign/xdg-foreign-unstable-v2.xml",
-  ]
-}
-
-wayland_protocol("extended_drag") {
-  sources = [ "unstable/extended-drag/extended-drag-unstable-v1.xml" ]
-}
-
-wayland_protocol("weston_test") {
-  sources = [ "unstable/weston-test/weston-test.xml" ]
-}
-
-wayland_protocol("org_kde_kwin_idle") {
-  sources = [ "kde/src/protocols/idle.xml" ]
-}
-
-wayland_protocol("touchpad_haptics_protocol") {
-  sources = [ "unstable/touchpad-haptics/touchpad-haptics-unstable-v1.xml" ]
-}
diff --git a/third_party/wayland-protocols/unstable/content-type/README b/third_party/wayland-protocols/unstable/content-type/README
new file mode 100644
index 0000000..63258e0
--- /dev/null
+++ b/third_party/wayland-protocols/unstable/content-type/README
@@ -0,0 +1,5 @@
+Content type hint protocol
+
+Maintainers:
+Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Xaver Hugl <xaver.hugl@gmail.com>
diff --git a/third_party/wayland-protocols/unstable/content-type/content-type-v1.xml b/third_party/wayland-protocols/unstable/content-type/content-type-v1.xml
new file mode 100644
index 0000000..e5de7ab
--- /dev/null
+++ b/third_party/wayland-protocols/unstable/content-type/content-type-v1.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="content_type_v1">
+  <copyright>
+    Copyright © 2021 Emmanuel Gil Peyrot
+    Copyright © 2022 Xaver Hugl
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice (including the next
+    paragraph) shall be included in all copies or substantial portions of the
+    Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+  </copyright>
+
+  <interface name="wp_content_type_manager_v1" version="1">
+    <description summary="surface content type manager">
+      This interface allows a client to describe the kind of content a surface
+      will display, to allow the compositor to optimize its behavior for it.
+
+      Warning! The protocol described in this file is currently in the testing
+      phase. Backward compatible changes may be added together with the
+      corresponding interface version bump. Backward incompatible changes can
+      only be done by creating a new major version of the extension.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the content type manager object">
+        Destroy the content type manager. This doesn't destroy objects created
+        with the manager.
+      </description>
+    </request>
+
+    <enum name="error">
+      <entry name="already_constructed" value="0"
+             summary="wl_surface already has a content type object"/>
+    </enum>
+
+    <request name="get_surface_content_type">
+      <description summary="create a new toplevel decoration object">
+        Create a new content type object associated with the given surface.
+
+        Creating a wp_content_type_v1 from a wl_surface which already has one
+        attached is a client error: already_constructed.
+      </description>
+      <arg name="id" type="new_id" interface="wp_content_type_v1"/>
+      <arg name="surface" type="object" interface="wl_surface"/>
+    </request>
+  </interface>
+
+  <interface name="wp_content_type_v1" version="1">
+    <description summary="content type object for a surface">
+      The content type object allows the compositor to optimize for the kind
+      of content shown on the surface. A compositor may for example use it to
+      set relevant drm properties like "content type".
+
+      The client may request to switch to another content type at any time.
+      When the associated surface gets destroyed, this object becomes inert and
+      the client should destroy it.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the content type object">
+        Switch back to not specifying the content type of this surface. This is
+        equivalent to setting the content type to none, including double
+        buffering semantics. See set_content_type for details.
+      </description>
+    </request>
+
+    <enum name="type">
+      <description summary="possible content types">
+        These values describe the available content types for a surface.
+      </description>
+      <entry name="none" value="0">
+        <description summary="no content type applies">
+          The content type none means that either the application has no data
+          about the content type, or that the content doesn't fit into one of
+          the other categories.
+        </description>
+      </entry>
+      <entry name="photo" value="1">
+        <description summary="photo content type">
+          The content type photo describes content derived from digital still
+          pictures and may be presented with minimal processing.
+        </description>
+      </entry>
+      <entry name="video" value="2">
+        <description summary="video content type">
+          The content type video describes a video or animation that may be
+          presented with reduced changes in latency in order to avoid stutter.
+          Where scaling is needed, scaling methods more appropriate for video
+          may be used.
+        </description>
+      </entry>
+      <entry name="game" value="3">
+        <description summary="game content type">
+          The content type game describes a running game. Its content may be
+          presented with reduced latency.
+        </description>
+      </entry>
+    </enum>
+
+    <request name="set_content_type">
+      <description summary="specify the content type">
+        Set the surface content type. This informs the compositor that the
+        client believes it is displaying buffers matching this content type.
+
+        This is purely a hint for the compositor, which can be used to adjust
+        its behavior or hardware settings to fit the presented content best.
+
+        The content type is double-buffered state, see wl_surface.commit for
+        details.
+      </description>
+      <arg name="content_type" type="uint" enum="content_type"
+           summary="the content type"/>
+    </request>
+  </interface>
+</protocol>
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index a6aa26d..801ea38 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -126,7 +126,6 @@
 src/webgpu/api/operation/uncapturederror.spec.ts
 src/webgpu/api/operation/adapter/requestAdapterInfo.spec.ts
 src/webgpu/api/operation/adapter/requestDevice.spec.ts
-src/webgpu/api/operation/adapter/requestDevice_limits.spec.ts
 src/webgpu/api/operation/buffers/mapping_test.ts
 src/webgpu/api/operation/buffers/map.spec.ts
 src/webgpu/api/operation/buffers/map_ArrayBuffer.spec.ts
@@ -237,7 +236,6 @@
 src/webgpu/api/validation/image_copy/buffer_texture_copies.spec.ts
 src/webgpu/api/validation/image_copy/layout_related.spec.ts
 src/webgpu/api/validation/image_copy/texture_related.spec.ts
-src/webgpu/api/validation/initialization/requestDevice.spec.ts
 src/webgpu/api/validation/query_set/create.spec.ts
 src/webgpu/api/validation/query_set/destroy.spec.ts
 src/webgpu/api/validation/queue/buffer_mapped.spec.ts
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium
index d197c73..49faf8ec 100644
--- a/third_party/wpt_tools/README.chromium
+++ b/third_party/wpt_tools/README.chromium
@@ -1,7 +1,7 @@
 Name: web-platform-tests - Test Suites for Web Platform specifications
 Short Name: wpt
 URL: https://github.com/web-platform-tests/wpt/
-Version: a0ece3bbdbfdf1bd0f66f841b06d54c1d927af0a
+Version: 1ebef47552fb17ccf8b78cb318cbf7118914e64c
 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
 License File: NOT_SHIPPED
 Security Critical: no
diff --git a/third_party/wpt_tools/WPTIncludeList b/third_party/wpt_tools/WPTIncludeList
index 837e1ec..200c7e0 100644
--- a/third_party/wpt_tools/WPTIncludeList
+++ b/third_party/wpt_tools/WPTIncludeList
@@ -52,6 +52,7 @@
 ./tools/manifest/jsonlib.py
 ./tools/manifest/log.py
 ./tools/manifest/manifest.py
+./tools/manifest/requirements.txt
 ./tools/manifest/sourcefile.py
 ./tools/manifest/testpaths.py
 ./tools/manifest/typedata.py
diff --git a/third_party/wpt_tools/wpt/tools/manifest/requirements.txt b/third_party/wpt_tools/wpt/tools/manifest/requirements.txt
new file mode 100644
index 0000000..9f5bc8a
--- /dev/null
+++ b/third_party/wpt_tools/wpt/tools/manifest/requirements.txt
@@ -0,0 +1 @@
+zstandard==0.17.0
diff --git a/third_party/wpt_tools/wpt/tools/wpt/browser.py b/third_party/wpt_tools/wpt/tools/wpt/browser.py
index 15ed5c1..07ef298 100644
--- a/third_party/wpt_tools/wpt/tools/wpt/browser.py
+++ b/third_party/wpt_tools/wpt/tools/wpt/browser.py
@@ -1570,10 +1570,10 @@
         requirement = re.compile(
             r"""(?x)  # (extended regexp syntax for comments)
             ^\s*Requires\s+macOS\s+  # Starting with the magic string
-            ([0-9\.]+)  # A macOS version number of numbers and dots
+            ([0-9]+(?:\.[0-9]+)*)  # A macOS version number of numbers and dots
             (?:\s+beta(?:\s+[0-9]+)?)?  # Optionally a beta, itself optionally with a number (no dots!)
             (?:\s+or\s+later)?  # Optionally an 'or later'
-            \.\s*$  # Ending with a literal dot
+            \.?\s*$  # Optionally ending with a literal dot
             """
         )
 
diff --git a/third_party/xdg_shared_mime_info/BUILD.gn b/third_party/xdg_shared_mime_info/BUILD.gn
new file mode 100644
index 0000000..4b5e4ce8
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/BUILD.gn
@@ -0,0 +1,11 @@
+# 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.
+
+source_set("xdg_shared_mime_info") {
+  sources = [
+    "mime_cache.gen.cc",
+    "mime_cache.h",
+  ]
+  deps = [ "//base" ]
+}
diff --git a/third_party/xdg_shared_mime_info/DEPS b/third_party/xdg_shared_mime_info/DEPS
new file mode 100644
index 0000000..4e143b6
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  '+base',
+]
diff --git a/third_party/xdg_shared_mime_info/LICENSE b/third_party/xdg_shared_mime_info/LICENSE
new file mode 100644
index 0000000..d159169d
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/LICENSE
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/third_party/xdg_shared_mime_info/OWNERS b/third_party/xdg_shared_mime_info/OWNERS
new file mode 100644
index 0000000..a33be2b
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/OWNERS
@@ -0,0 +1 @@
+file://chrome/browser/ash/guest_os/OWNERS
diff --git a/third_party/xdg_shared_mime_info/README.chromium b/third_party/xdg_shared_mime_info/README.chromium
new file mode 100644
index 0000000..6ea40661
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/README.chromium
@@ -0,0 +1,25 @@
+Name: XDG Shared Mime Info
+Short Name: xdg-shared-mime-info
+URL: http://freedesktop.org
+Version: 0
+Date: 2022/08/23
+License: GPL v2
+License File: LICENSE
+Security Critical: no
+
+Description:
+File freedesktop.org.xml.in synced from
+https://github.com/freedesktop/xdg-shared-mime-info
+f4e7cbc86e67e7bc39cf8167823fcf0d8ace9ce1 on 2022/08/23
+
+generate.py will fetch the latest version of the xml file from the freedesktop
+repo and save it to this dir, and generate mime_cache.cc.
+
+This script can be run from time to time as the freedesktop database is updated.
+About once a year or so would be fine since the database does not change often.
+If there are missing or wrong values, we should first try to get changes
+accepted upstream.
+
+Local Modifications:
+No modifications, but after running this script, you may need to run
+`git cl format` and possibly add some `nocheck` comments.
diff --git a/third_party/xdg_shared_mime_info/freedesktop.org.xml.in b/third_party/xdg_shared_mime_info/freedesktop.org.xml.in
new file mode 100644
index 0000000..03f8ae1
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/freedesktop.org.xml.in
@@ -0,0 +1,8031 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mime-info [
+  <!ELEMENT mime-info (mime-type)+>
+  <!ATTLIST mime-info xmlns CDATA #FIXED "http://www.freedesktop.org/standards/shared-mime-info">
+
+  <!ELEMENT mime-type (comment+, (acronym,expanded-acronym)? , (icon? | generic-icon? | glob | magic | treemagic | root-XML | alias | sub-class-of)*)>
+  <!ATTLIST mime-type type CDATA #REQUIRED>
+
+  <!-- a comment describing a document with the respective MIME type. Example: "WMV video" -->
+  <!ELEMENT comment (#PCDATA)>
+  <!ATTLIST comment xml:lang CDATA #IMPLIED>
+
+  <!-- a comment describing the respective unexpanded MIME type acronym. Example: "WMV" -->
+  <!ELEMENT acronym (#PCDATA)>
+
+  <!-- a comment describing the respective expanded MIME type acronym. Example: "Windows Media Video" -->
+  <!ELEMENT expanded-acronym (#PCDATA)>
+
+  <!ELEMENT icon EMPTY>
+  <!ATTLIST icon name CDATA #REQUIRED>
+
+  <!-- a generic icon name as per the Icon Naming Specification, only required if computing
+  it from the mime-type would not work, See "generic-icon" in the Shared Mime Specification -->
+  <!ELEMENT generic-icon EMPTY>
+  <!ATTLIST generic-icon name (application-x-executable|audio-x-generic|folder|font-x-generic|image-x-generic|package-x-generic|text-html|text-x-generic|text-x-generic-template|text-x-script|video-x-generic|x-office-address-book|x-office-calendar|x-office-document|x-office-presentation|x-office-spreadsheet) #REQUIRED>
+
+  <!ELEMENT glob EMPTY>
+  <!ATTLIST glob pattern CDATA #REQUIRED>
+  <!ATTLIST glob weight CDATA "50">
+  <!ATTLIST glob case-sensitive CDATA #IMPLIED>
+
+  <!ELEMENT magic (match)+>
+  <!ATTLIST magic priority CDATA "50">
+
+  <!ELEMENT match (match)*>
+  <!ATTLIST match offset CDATA #REQUIRED>
+  <!ATTLIST match type (string|big16|big32|little16|little32|host16|host32|byte) #REQUIRED>
+  <!ATTLIST match value CDATA #REQUIRED>
+  <!ATTLIST match mask CDATA #IMPLIED>
+
+  <!ELEMENT treemagic (treematch)+>
+  <!ATTLIST treemagic priority CDATA "50">
+
+  <!ELEMENT treematch (treematch)*>
+  <!ATTLIST treematch path CDATA #REQUIRED>
+  <!ATTLIST treematch type (file|directory|link) #IMPLIED>
+  <!ATTLIST treematch match-case (true|false) #IMPLIED>
+  <!ATTLIST treematch executable (true|false) #IMPLIED>
+  <!ATTLIST treematch non-empty (true|false) #IMPLIED>
+  <!ATTLIST treematch mimetype CDATA #IMPLIED>
+
+  <!ELEMENT root-XML EMPTY>
+  <!ATTLIST root-XML namespaceURI CDATA #REQUIRED>
+  <!ATTLIST root-XML localName CDATA #REQUIRED>
+
+  <!ELEMENT alias EMPTY>
+  <!ATTLIST alias type CDATA #REQUIRED>
+
+  <!ELEMENT sub-class-of EMPTY>
+  <!ATTLIST sub-class-of type CDATA #REQUIRED>
+]>
+
+<!--
+The freedesktop.org shared MIME database (this file) was created by merging
+several existing MIME databases (all released under the GNU GPL).
+
+It comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law. You may
+redistribute copies of freedesktop.org.xml under the terms of the GNU General
+Public License version 2 or later. For more information about these matters,
+see the file named COPYING.
+
+The latest version is available from:
+
+	http://www.freedesktop.org/wiki/Software/shared-mime-info/
+
+To extend this database, users and applications should create additional
+XML files in the 'packages' directory and run the update-mime-database
+command to generate the output files.
+-->
+
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+  <mime-type type="application/x-atari-2600-rom">
+    <comment>Atari 2600 ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.a26"/>
+  </mime-type>
+  <mime-type type="application/x-atari-7800-rom">
+    <comment>Atari 7800 ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.a78"/>
+    <magic>
+      <match type="string" value="ATARI7800" offset="1"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-atari-lynx-rom">
+    <comment>Atari Lynx ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.lnx"/>
+    <magic>
+      <match type="string" value="LYNX" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/andrew-inset">
+    <comment>ATK inset</comment>
+    <acronym>ATK</acronym>
+    <expanded-acronym>Andrew Toolkit</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.ez"/>
+  </mime-type>
+  <mime-type type="application/epub+zip">
+    <comment>electronic book document</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/epub+zip" offset="38"/>
+          <match type="string" value="application/epub+zip" offset="43"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.epub"/>
+  </mime-type>
+  <mime-type type="application/vnd.amazon.mobi8-ebook">
+    <comment>Kindle book document</comment>
+    <sub-class-of type="application/x-mobipocket-ebook"/>
+    <glob pattern="*.azw3"/>
+    <glob pattern="*.kfx"/>
+    <alias type="application/x-mobi8-ebook"/>
+  </mime-type>
+  <mime-type type="application/illustrator">
+    <comment>Adobe Illustrator document</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.ai"/>
+    <alias type="application/vnd.adobe.illustrator"/>
+  </mime-type>
+  <mime-type type="application/mac-binhex40">
+    <comment>Macintosh BinHex-encoded file</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="must be converted with BinHex" offset="11"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/mathematica">
+    <comment>Mathematica Notebook file</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.nb" />
+    <magic>
+      <match value="(************** Content-type: application/mathematica"
+             type="string" offset="0" />
+      <match value="This notebook can be used on any computer system with Mathematica"
+             type="string" offset="100:256" />
+      <match value="This is a Mathematica Notebook file.  It contains ASCII text"
+             type="string" offset="10:256" />
+    </magic>
+    <alias type="application/x-mathematica"/>
+  </mime-type>
+  <mime-type type="application/mathml+xml">
+    <comment>MathML document</comment>
+    <acronym>MathML</acronym>
+    <expanded-acronym>Mathematical Markup Language</expanded-acronym>
+    <alias type="text/mathml"/>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.mml"/>
+    <root-XML namespaceURI="http://www.w3.org/1998/Math/MathML" localName="math"/>
+  </mime-type>
+  <mime-type type="application/mbox">
+    <comment>mailbox file</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+    <magic priority="20">
+      <match type="string" value="From " offset="0"/>
+    </magic>
+    <glob pattern="*.mbox"/>
+  </mime-type>
+  <mime-type type="application/metalink+xml">
+    <comment>Metalink file</comment>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;metalink version=&quot;3.0&quot;" offset="0:256"/>
+    </magic>
+    <glob pattern="*.metalink"/>
+    <root-XML namespaceURI="http://www.metalinker.org/" localName="metalink"/>
+  </mime-type>
+  <mime-type type="application/metalink4+xml">
+    <comment>Metalink file</comment>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;metalink xmlns=&quot;urn" offset="0:256"/>
+    </magic>
+    <glob pattern="*.meta4"/>
+    <root-XML namespaceURI="urn:ietf:params:xml:ns:metalink" localName="metalink"/>
+  </mime-type>
+  <mime-type type="application/octet-stream">
+    <comment>unknown</comment>
+  </mime-type>
+  <mime-type type="application/x-partial-download">
+    <comment>Partially downloaded file</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.wkdownload"/>
+    <glob pattern="*.crdownload"/>
+    <glob pattern="*.part"/>
+  </mime-type>
+  <mime-type type="application/oda">
+    <comment>ODA document</comment>
+    <acronym>ODA</acronym>
+    <expanded-acronym>Office Document Architecture</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.oda"/>
+  </mime-type>
+  <mime-type type="application/x-wwf">
+    <comment>WWF document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.wwf"/>
+    <sub-class-of type="application/pdf"/>
+    <alias type="application/wwf"/>
+  </mime-type>
+  <mime-type type="application/pdf">
+    <comment>PDF document</comment>
+    <acronym>PDF</acronym>
+    <expanded-acronym>Portable Document Format</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="%PDF-" offset="0:1024"/>
+    </magic>
+    <glob pattern="*.pdf"/>
+    <alias type="application/x-pdf"/>
+    <alias type="image/pdf"/>
+    <alias type="application/acrobat"/>
+    <alias type="application/nappdf"/>
+  </mime-type>
+  <mime-type type="application/xspf+xml">
+    <comment>XSPF playlist</comment>
+    <acronym>XSPF</acronym>
+    <expanded-acronym>XML Shareable Playlist Format</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="audio-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;playlist version=&quot;1" offset="0:64"/>
+      <match type="string" value="&lt;playlist version='1" offset="0:64"/>
+    </magic>
+    <glob pattern="*.xspf"/>
+    <root-XML namespaceURI="http://xspf.org/ns/0/" localName="playlist"/>
+    <alias type="application/x-xspf+xml"/>
+  </mime-type>
+  <mime-type type="application/x-windows-themepack">
+    <comment>Microsoft Windows theme pack</comment>
+    <sub-class-of type="application/vnd.ms-cab-compressed"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.themepack"/>
+  </mime-type>
+  <mime-type type="audio/x-amzxml">
+    <comment>AmazonMP3 download file</comment>
+    <glob pattern="*.amz"/>
+  </mime-type>
+  <mime-type type="audio/x-gsm">
+    <comment>GSM 06.10 audio</comment>
+    <acronym>GSM</acronym>
+    <expanded-acronym>Global System for Mobile communications</expanded-acronym>
+    <glob pattern="*.gsm"/>
+  </mime-type>
+  <mime-type type="audio/x-iriver-pla">
+    <comment>iRiver playlist</comment>
+    <magic>
+      <match type="string" value="iriver UMS PLA" offset="4"/>
+    </magic>
+    <glob pattern="*.pla"/>
+  </mime-type>
+  <mime-type type="application/pgp-encrypted">
+    <comment>PGP/MIME-encrypted message header</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="-----BEGIN PGP MESSAGE-----" offset="0"/>
+    </magic>
+    <glob pattern="*.pgp"/>
+    <glob pattern="*.gpg"/>
+    <glob pattern="*.asc" weight="10"/>
+    <alias type="application/pgp"/>
+  </mime-type>
+  <mime-type type="application/pgp-keys">
+    <comment>PGP keys</comment>
+    <acronym>PGP</acronym>
+    <expanded-acronym>Pretty Good Privacy</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="-----BEGIN PGP PUBLIC KEY BLOCK-----" offset="0"/>
+      <match type="string" value="-----BEGIN PGP PRIVATE KEY BLOCK-----" offset="0"/>
+      <match type="big16" value="0x9501" offset="0"/>
+      <match type="big16" value="0x9500" offset="0"/>
+      <match type="big16" value="0x9900" offset="0"/>
+      <match type="big16" value="0x9901" offset="0"/>
+    </magic>
+    <glob pattern="*.skr"/>
+    <glob pattern="*.pkr"/>
+    <glob pattern="*.asc" weight="10"/>
+    <glob pattern="*.pgp"/>
+    <glob pattern="*.gpg"/>
+    <glob pattern="*.key"/>
+  </mime-type>
+  <mime-type type="application/pgp-signature">
+    <comment>detached OpenPGP signature</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="-----BEGIN PGP SIGNATURE-----" offset="0"/>
+    </magic>
+    <glob pattern="*.asc" weight="10"/>
+    <glob pattern="*.sig"/>
+    <glob pattern="*.pgp"/>
+    <glob pattern="*.gpg"/>
+  </mime-type>
+  <!-- defined in RFC 2311 -->
+  <mime-type type="application/pkcs7-mime">
+    <comment>PKCS#7 file</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.p7c"/>
+    <glob pattern="*.p7m"/>
+  </mime-type>
+  <mime-type type="application/pkcs7-signature">
+    <comment>detached S/MIME signature</comment>
+    <acronym>S/MIME</acronym>
+    <expanded-acronym>Secure/Multipurpose Internet Mail Extensions</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.p7s"/>
+  </mime-type>
+  <mime-type type="application/pkcs8">
+    <comment>PKCS#8 private key</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <glob pattern="*.p8"/>
+  </mime-type>
+  <mime-type type="application/pkcs8-encrypted">
+    <comment>PKCS#8 private key (encrypted)</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <glob pattern="*.p8e"/>
+  </mime-type>
+  <mime-type type="application/pkcs10">
+    <comment>PKCS#10 certification request</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.p10"/>
+  </mime-type>
+  <mime-type type="application/pkix-cert">
+    <comment>X.509 certificate</comment>
+    <magic>
+      <match type="string" value="-----BEGIN CERTIFICATE-----" offset="0"/>
+      <match type="string" value="-----BEGIN X509 CERTIFICATE-----" offset="0"/>
+    </magic>
+    <glob pattern="*.cer"/>
+  </mime-type>
+  <mime-type type="application/pkix-crl">
+    <comment>certificate revocation list</comment>
+    <magic>
+      <match type="string" value="-----BEGIN X509 CRL-----" offset="0"/>
+    </magic>
+    <glob pattern="*.crl"/>
+  </mime-type>
+  <mime-type type="application/pkix-pkipath">
+    <comment>PkiPath certification path</comment>
+    <glob pattern="*.pkipath"/>
+  </mime-type>
+  <mime-type type="application/postscript">
+    <comment>PostScript document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="\004%!" offset="0"/>
+      <match type="string" value="%!" offset="0"/>
+    </magic>
+    <glob pattern="*.ps"/>
+  </mime-type>
+  <mime-type type="application/prs.plucker">
+    <comment>Plucker document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="80">
+      <match type="string" value="DataPlkr" offset="60"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/raml+yaml">
+    <comment>RAML document</comment>
+    <acronym>RAML</acronym>
+    <expanded-acronym>RESTful API Modeling Language</expanded-acronym>
+    <sub-class-of type="application/x-yaml"/>
+    <magic>
+      <match type="string" value="#%RAML " offset="0"/>
+    </magic>
+    <glob pattern="*.raml"/>
+  </mime-type>
+  <mime-type type="application/relax-ng-compact-syntax">
+    <comment>RELAX NG XML schema</comment>
+    <acronym>RELAX NG</acronym>
+    <expanded-acronym>REgular LAnguage for XML Next Generation</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.rnc"/>
+    <alias type="application/x-rnc"/>
+  </mime-type>
+  <mime-type type="application/rtf">
+    <comment>RTF document</comment>
+    <acronym>RTF</acronym>
+    <expanded-acronym>Rich Text Format</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="{\\rtf" offset="0"/>
+    </magic>
+    <glob pattern="*.rtf"/>
+    <alias type="text/rtf"/>
+  </mime-type>
+  <mime-type type="application/sieve">
+    <comment>Sieve mail filter script</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.siv"/>
+  </mime-type>
+  <mime-type type="application/smil+xml">
+    <comment>SMIL document</comment>
+    <acronym>SMIL</acronym>
+    <expanded-acronym>Synchronized Multimedia Integration Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <alias type="application/smil"/>
+    <generic-icon name="video-x-generic"/>
+    <glob pattern="*.smil"/>
+    <glob pattern="*.smi"/>
+    <glob pattern="*.sml"/>
+    <glob pattern="*.kino"/>
+    <magic priority="55">
+      <match type="string" value="&lt;smil" offset="0:256"/>
+    </magic>
+    <root-XML namespaceURI="http://www.w3.org/2001/SMIL20/Language" localName="smil"/>
+    <root-XML namespaceURI="http://www.w3.org/2005/SMIL21/Language" localName="smil"/>
+    <root-XML namespaceURI="http://www.w3.org/ns/SMIL" localName="smil"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-wpl">
+    <comment>WPL playlist</comment>
+    <acronym>WPL</acronym>
+    <expanded-acronym>Windows Media Player Playlist</expanded-acronym>
+    <generic-icon name="video-x-generic"/>
+    <glob pattern="*.wpl"/>
+    <magic priority="60">
+      <match type="string" value="&lt;?wpl" offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-sqlite2">
+    <comment>SQLite2 database</comment>
+    <glob pattern="*.sqlite2"/>
+    <magic>
+      <match type="string" value="** This file contains an SQLite" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/vnd.sqlite3">
+    <comment>SQLite3 database</comment>
+    <glob pattern="*.sqlite3"/>
+    <magic>
+      <match type="string" value="SQLite format 3" offset="0"/>
+    </magic>
+    <alias type="application/x-sqlite3"/>
+  </mime-type>
+  <mime-type type="application/x-apple-systemprofiler+xml">
+    <comment>Apple System Profiler</comment>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;plist version=&quot;1.0&quot;" offset="0:256">
+        <match type="string" value="&lt;key&gt;_SPCommandLineArguments&lt;/key&gt;" offset="34:384"/>
+      </match>
+    </magic>
+    <glob pattern="*.spx" weight="40"/>
+    <root-XML namespaceURI="http://www.apple.com/DTDs/PropertyList-1.0.dtd" localName="plist"/>
+  </mime-type>
+  <mime-type type="application/x-gedcom">
+    <comment>GEDCOM family history</comment>
+    <acronym>GEDCOM</acronym>
+    <expanded-acronym>GEnealogical Data COMmunication</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="0 HEAD" offset="0"/>
+    </magic>
+    <glob pattern="*.ged"/>
+    <glob pattern="*.gedcom"/>
+    <alias type="text/gedcom"/>
+  </mime-type>
+  <mime-type type="video/x-flv">
+    <comment>Flash video</comment>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="FLV" offset="0"/>
+    </magic>
+    <glob pattern="*.flv"/>
+    <alias type="application/x-flash-video"/>
+    <alias type="flv-application/octet-stream"/>
+    <alias type="video/flv"/>
+  </mime-type>
+  <mime-type type="video/x-javafx">
+    <comment>JavaFX video</comment>
+    <generic-icon name="video-x-generic"/>
+    <magic priority="40">
+      <match type="string" value="FLV" offset="0"/>
+    </magic>
+    <glob pattern="*.fxm"/>
+    <sub-class-of type="video/x-flv"/>
+  </mime-type>
+  <mime-type type="application/x-go-sgf">
+    <!-- translators: a record is in this context a description of a board game
+         that has been played, and that can be played back again:
+         http://www.red-bean.com/sgf/ -->
+    <comment>SGF record</comment>
+    <acronym>SGF</acronym>
+    <expanded-acronym>Smart Game Format</expanded-acronym>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.sgf"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="(;FF[3]" offset="0"/>
+      <match type="string" value="(;FF[4]" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-godot-project">
+    <comment>Godot Engine project</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="project.godot"/>
+  </mime-type>
+  <mime-type type="application/x-godot-resource">
+    <comment>Godot Engine resource</comment>
+    <glob pattern="*.res"/>
+    <glob pattern="*.tres"/>
+    <magic>
+      <match type="string" value="[gd_resource " offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-godot-scene">
+    <comment>Godot Engine scene</comment>
+    <glob pattern="*.scn"/>
+    <glob pattern="*.tscn"/>
+    <glob pattern="*.escn"/>
+    <magic>
+      <match type="string" value="[gd_scene " offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-godot-shader">
+    <comment>Godot Engine shader</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.gdshader"/>
+  </mime-type>
+  <mime-type type="application/x-gdscript">
+    <comment>GDScript script</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.gd"/>
+  </mime-type>
+  <mime-type type="application/xliff+xml">
+    <comment>XLIFF translation file</comment>
+    <acronym>XLIFF</acronym>
+    <expanded-acronym>XML Localization Interchange File Format</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.xlf"/>
+    <glob pattern="*.xliff"/>
+    <magic priority="80">
+      <match type="string" value="&lt;xliff" offset="0:256"/>
+    </magic>
+    <root-XML namespaceURI='urn:oasis:names:tc:xliff:document:1.1' localName='xliff'/>
+    <alias type="application/x-xliff"/>
+  </mime-type>
+  <mime-type type="application/toml">
+    <comment>TOML document</comment>
+    <acronym>TOML</acronym>
+    <expanded-acronym>Tom's Obvious Minimal Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.toml"/>
+  </mime-type>
+  <mime-type type="application/x-yaml">
+    <comment>YAML document</comment>
+    <acronym>YAML</acronym>
+    <expanded-acronym>YAML Ain't Markup Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="%YAML" offset="0"/>
+    </magic>
+    <glob pattern="*.yaml"/>
+    <glob pattern="*.yml"/>
+    <alias type="text/yaml"/>
+    <alias type="text/x-yaml"/>
+  </mime-type>
+  <mime-type type="application/vnd.corel-draw">
+    <comment>Corel Draw drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="80">
+      <match type="string" value="CDRXvrsn" mask="0xffffff00ffffffff" offset="8"/>
+    </magic>
+    <glob pattern="*.cdr"/>
+    <alias type="application/cdr"/>
+    <alias type="application/coreldraw"/>
+    <alias type="application/x-cdr"/>
+    <alias type="application/x-coreldraw"/>
+    <alias type="image/cdr"/>
+    <alias type="image/x-cdr"/>
+    <alias type="zz-application/zz-winassoc-cdr"/>
+  </mime-type>
+  <mime-type type="application/vnd.hp-hpgl">
+    <comment>HPGL file</comment>
+    <acronym>HPGL</acronym>
+    <expanded-acronym>HP Graphics Language</expanded-acronym>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.hpgl"/>
+  </mime-type>
+  <mime-type type="application/vnd.hp-pcl">
+    <comment>PCL file</comment>
+    <acronym>PCL</acronym>
+    <expanded-acronym>HP Printer Control Language</expanded-acronym>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.pcl"/>
+  </mime-type>
+  <mime-type type="application/vnd.lotus-1-2-3">
+    <comment>Lotus 1-2-3 spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="\x00\x00\x02\x00\x06\x04\x06\x00\x08\x00\x00\x00\x00\x00" offset="0"/>
+    </magic>
+    <glob pattern="*.123"/>
+    <glob pattern="*.wk1"/>
+    <glob pattern="*.wk3"/>
+    <glob pattern="*.wk4"/>
+    <glob pattern="*.wks"/>
+    <alias type="application/x-lotus123"/>
+    <alias type="application/x-123"/>
+    <alias type="application/lotus123"/>
+    <alias type="application/wk1"/>
+    <alias type="zz-application/zz-winassoc-123"/>
+  </mime-type>
+  <mime-type type="application/vnd.lotus-wordpro">
+    <comment>Lotus Word Pro document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="WordPro" offset="0"/>
+    </magic>
+    <glob pattern="*.lwp"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-access">
+    <comment>JET database</comment>
+    <acronym>JET</acronym>
+    <expanded-acronym>Joint Engine Technology</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match offset="0" type="string" value="\x00\x01\x00\x00Standard Jet DB" />
+    </magic>
+    <glob pattern="*.mdb" />
+    <alias type="application/msaccess"/>
+    <alias type="application/vnd.msaccess"/>
+    <alias type="application/x-msaccess"/>
+    <alias type="application/mdb"/>
+    <alias type="application/x-mdb"/>
+    <alias type="zz-application/zz-winassoc-mdb"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-cab-compressed">
+    <comment>Microsoft Cabinet archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match offset="0" type="string" value="MSCF\0\0\0\0" />
+    </magic>
+    <glob pattern="*.cab"/>
+    <alias type="zz-application/zz-winassoc-cab"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-excel">
+    <comment>Excel spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="Microsoft Excel 5.0 Worksheet" offset="2080"/>
+    </magic>
+    <glob pattern="*.xls"/>
+    <glob pattern="*.xlc"/>
+    <glob pattern="*.xll"/>
+    <glob pattern="*.xlm"/>
+    <glob pattern="*.xlw"/>
+    <glob pattern="*.xla"/>
+    <glob pattern="*.xlt"/>
+    <glob pattern="*.xld"/>
+    <alias type="application/msexcel"/>
+    <alias type="application/x-msexcel"/>
+    <alias type="zz-application/zz-winassoc-xls"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-excel.addin.macroEnabled.12">
+    <comment>Excel add-in</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.xlam"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-excel.sheet.binary.macroEnabled.12">
+    <comment>Excel 2007 binary spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.xlsb"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-excel.sheet.macroEnabled.12">
+    <comment>Excel spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.xlsm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-excel.template.macroEnabled.12">
+    <comment>Excel spreadsheet template</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.xltm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.spreadsheetml.template"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint">
+    <comment>PowerPoint presentation</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.ppz"/>
+    <glob pattern="*.ppt"/>
+    <glob pattern="*.pps"/>
+    <glob pattern="*.pot"/>
+    <alias type="application/powerpoint"/>
+    <alias type="application/mspowerpoint"/>
+    <alias type="application/x-mspowerpoint"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint.addin.macroEnabled.12">
+    <comment>PowerPoint add-in</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.ppam"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint.presentation.macroEnabled.12">
+    <comment>PowerPoint presentation</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.pptm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.presentationml.presentation"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint.slide.macroEnabled.12">
+    <comment>PowerPoint slide</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.sldm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.presentationml.slide"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint.slideshow.macroEnabled.12">
+    <comment>PowerPoint presentation</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.ppsm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.presentationml.slideshow"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-powerpoint.template.macroEnabled.12">
+    <comment>PowerPoint presentation template</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.potm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.presentationml.template"/>
+  </mime-type>
+    <mime-type type="application/vnd.ms-visio.drawing.main+xml">
+    <comment>Office Open XML Visio drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vsdx"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-visio.template.main+xml">
+    <comment>Office Open XML Visio template</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vstx"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-visio.stencil.main+xml">
+    <comment>Office Open XML Visio stencil</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vssx"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-visio.drawing.macroEnabled.main+xml">
+    <comment>Office Open XML Visio drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vsdm"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-visio.template.macroEnabled.main+xml">
+    <comment>Office Open XML Visio template</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vstm"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-visio.stencil.macroEnabled.main+xml">
+    <comment>Office Open XML Visio stencil</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.vssm"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-word.document.macroEnabled.12">
+    <comment>Word document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.docm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-word.template.macroEnabled.12">
+    <comment>Word document template</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.dotm"/>
+    <sub-class-of type="application/vnd.openxmlformats-officedocument.wordprocessingml.template"/>
+  </mime-type>
+  <mime-type type="application/oxps">
+    <comment>OpenXPS document</comment>
+    <acronym>OpenXPS</acronym>
+    <expanded-acronym>Open XML Paper Specification</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.oxps"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-xpsdocument">
+    <comment>XPS document</comment>
+    <acronym>XPS</acronym>
+    <expanded-acronym>XML Paper Specification</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.xps"/>
+    <alias type="application/xps"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-works">
+    <comment>Microsoft Works document</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.wcm"/>
+    <glob pattern="*.wdb"/>
+    <glob pattern="*.wks"/>
+    <glob pattern="*.wps"/>
+    <glob pattern="*.xlr"/>
+  </mime-type>
+  <mime-type type="application/vnd.visio">
+    <comment>Microsoft Visio document</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.vsd"/>
+    <glob pattern="*.vst"/>
+    <glob pattern="*.vsw"/>
+    <glob pattern="*.vss"/>
+  </mime-type>
+  <mime-type type="application/msword">
+    <comment>Word document</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="60">
+      <match type="string" value="\x31\xbe\x00\x00" offset="0"/>
+      <match type="string" value="PO^Q`" offset="0"/>
+      <match type="string" value="\376\067\0\043" offset="0"/>
+      <match type="string" value="\333\245-\0\0\0" offset="0"/>
+      <match type="string" value="MSWordDoc" offset="2112"/>
+      <match type="string" value="MSWordDoc" offset="2108"/>
+      <match type="string" value="Microsoft Word document data" offset="2112"/>
+      <match type="string" value="bjbj" offset="546"/>
+      <match type="string" value="jbjb" offset="546"/>
+    </magic>
+    <glob pattern="*.doc"/>
+    <alias type="application/vnd.ms-word"/>
+    <alias type="application/x-msword"/>
+    <alias type="zz-application/zz-winassoc-doc"/>
+  </mime-type>
+  <mime-type type="application/msword-template">
+    <comment>Word template</comment>
+    <sub-class-of type="application/msword"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.dot"/>
+  </mime-type>
+  <mime-type type="application/gml+xml">
+    <comment>GML document</comment>
+    <acronym>GML</acronym>
+    <expanded-acronym>Geography Markup Language</expanded-acronym>
+    <glob pattern="*.gml"/>
+    <root-XML namespaceURI="http://www.opengis.net/gml/3.2" localName="gml"/>
+    <sub-class-of type="application/xml"/>
+  </mime-type>
+  <mime-type type="application/gnunet-directory">
+    <comment>GNUnet search file</comment>
+    <magic>
+      <match type="string" value="\211GND\r\n\032\n" offset="0"/>
+    </magic>
+    <glob pattern="*.gnd"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-tnef">
+    <comment>TNEF message</comment>
+    <acronym>TNEF</acronym>
+    <expanded-acronym>Transport Neutral Encapsulation Format</expanded-acronym>
+    <magic>
+      <match type="little32" value="0x223e9f78" offset="0"/>
+    </magic>
+    <glob pattern="*.tnef"/>
+    <glob pattern="*.tnf"/>
+    <glob pattern="winmail.dat"/>
+    <alias type="application/ms-tnef"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.calc">
+    <comment>StarCalc spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.sdc"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.chart">
+    <comment>StarChart chart</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.sds"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.draw">
+    <comment>StarDraw drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.sda"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.impress">
+    <comment>StarImpress presentation</comment>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.sdd"/>
+    <glob pattern="*.sdp"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.mail">
+    <comment>StarMail email</comment>
+    <glob pattern="*.smd"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.math">
+    <comment>StarMath formula</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.smf"/>
+  </mime-type>
+  <mime-type type="application/vnd.stardivision.writer">
+    <comment>StarWriter document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.sdw"/>
+    <glob pattern="*.vor"/>
+    <glob pattern="*.sgl"/>
+    <magic priority="90">
+      <match type="string" value="StarWriter" offset="2089" />
+    </magic>
+    <alias type="application/vnd.stardivision.writer-global"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.calc">
+    <comment>LibreOffice Calc spreadsheet</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.calc"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxc"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.calc.template">
+    <comment>LibreOffice Calc template</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.calc"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.stc"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.draw">
+    <comment>LibreOffice Draw drawing</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.draw"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxd"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.draw.template">
+    <comment>LibreOffice Draw template</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.draw"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.std"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.impress">
+    <comment>LibreOffice Impress presentation</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.impress"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxi"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.impress.template">
+    <comment>LibreOffice Impress template</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.impress"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sti"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.math">
+    <comment>LibreOffice Math formula</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.math"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxm"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.writer">
+    <comment>LibreOffice Writer document</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.writer"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxw"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.writer.global">
+    <comment>LibreOffice Writer global document</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.writer"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.sxg"/>
+  </mime-type>
+  <mime-type type="application/vnd.sun.xml.writer.template">
+    <comment>LibreOffice Writer template</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" offset="38" value="application/vnd.sun.xml.writer"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.stw"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.text">
+    <comment>ODT document</comment>
+    <acronym>ODT</acronym>
+    <expanded-acronym>OpenDocument Text</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.text" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odt"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.text-flat-xml">
+    <comment>ODT document (Flat XML)</comment>
+    <acronym>FODT</acronym>
+    <expanded-acronym>OpenDocument Text (Flat XML)</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.fodt"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.text-template">
+    <comment>ODT template</comment>
+    <acronym>ODT</acronym>
+    <expanded-acronym>OpenDocument Text</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.text-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ott"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.text-web">
+    <comment>OTH template</comment>
+    <acronym>OTH</acronym>
+    <expanded-acronym>OpenDocument HTML</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="text-html"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.text-web" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.oth"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.text-master"><!-- nocheck -->
+    <comment>ODM document</comment>
+    <acronym>ODM</acronym>
+    <expanded-acronym>OpenDocument Master</expanded-acronym><!-- nocheck -->
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.text-master" offset="38"/><!-- nocheck -->
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odm"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.graphics">
+    <comment>ODG drawing</comment>
+    <acronym>ODG</acronym>
+    <expanded-acronym>OpenDocument Drawing</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.graphics" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odg"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.graphics-flat-xml">
+    <comment>ODG drawing (Flat XML)</comment>
+    <acronym>FODG</acronym>
+    <expanded-acronym>OpenDocument Drawing (Flat XML)</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.fodg"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.graphics-template">
+    <comment>ODG template</comment>
+    <acronym>ODG</acronym>
+    <expanded-acronym>OpenDocument Drawing</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.graphics-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.otg"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.presentation">
+    <comment>ODP presentation</comment>
+    <acronym>ODP</acronym>
+    <expanded-acronym>OpenDocument Presentation</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.presentation" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odp"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.presentation-flat-xml">
+    <comment>ODP presentation (Flat XML)</comment>
+    <acronym>FODP</acronym>
+    <expanded-acronym>OpenDocument Presentation (Flat XML)</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.fodp"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.presentation-template">
+    <comment>ODP template</comment>
+    <acronym>ODP</acronym>
+    <expanded-acronym>OpenDocument Presentation</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.presentation-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.otp"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.spreadsheet">
+    <comment>ODS spreadsheet</comment>
+    <acronym>ODS</acronym>
+    <expanded-acronym>OpenDocument Spreadsheet</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.spreadsheet" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ods"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.spreadsheet-flat-xml">
+    <comment>ODS spreadsheet (Flat XML)</comment>
+    <acronym>FODS</acronym>
+    <expanded-acronym>OpenDocument Spreadsheet (Flat XML)</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.fods"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.spreadsheet-template">
+    <comment>ODS template</comment>
+    <acronym>ODS</acronym>
+    <expanded-acronym>OpenDocument Spreadsheet</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.spreadsheet-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ots"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.chart">
+    <comment>ODC chart</comment>
+    <acronym>ODC</acronym>
+    <expanded-acronym>OpenDocument Chart</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.chart" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odc"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.chart-template">
+    <comment>ODC template</comment>
+    <acronym>ODC</acronym>
+    <expanded-acronym>OpenDocument Chart</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.chart-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.otc"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.formula">
+    <comment>ODF formula</comment>
+    <acronym>ODF</acronym>
+    <expanded-acronym>OpenDocument Formula</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.formula" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odf"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.formula-template">
+    <comment>ODF template</comment>
+    <acronym>ODF</acronym>
+    <expanded-acronym>OpenDocument Formula</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.formula-template" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.otf"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.database">
+    <comment>ODB database</comment>
+    <acronym>ODB</acronym>
+    <expanded-acronym>OpenDocument Database</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.base" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odb"/>
+    <alias type="application/vnd.sun.xml.base"/>
+  </mime-type>
+  <mime-type type="application/vnd.oasis.opendocument.image">
+    <comment>ODI image</comment>
+    <acronym>ODI</acronym>
+    <expanded-acronym>OpenDocument Image</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/vnd.oasis.opendocument.image" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.odi"/>
+  </mime-type>
+  <mime-type type="application/vnd.openofficeorg.extension">
+    <comment>OpenOffice.org extension</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.oxt" />
+  </mime-type>
+  <mime-type type="application/vnd.android.package-archive">
+    <comment>Android package</comment>
+    <sub-class-of type="application/x-java-archive"/>
+    <glob pattern="*.apk"/>
+  </mime-type>
+  <mime-type type="application/vnd.symbian.install">
+    <comment>SIS package</comment>
+    <acronym>SIS</acronym>
+    <expanded-acronym>Symbian Installation File</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="little32" value="0x10000419" offset="8"/>
+    </magic>
+    <glob pattern="*.sis"/>
+  </mime-type>
+  <mime-type type="x-epoc/x-sisx-app">
+    <comment>SISX package</comment>
+    <acronym>SIS</acronym>
+    <expanded-acronym>Symbian Installation File</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="little32" value="0x10201a7a" offset="0"/>
+    </magic>
+    <glob pattern="*.sisx"/>
+  </mime-type>
+  <mime-type type="application/vnd.tcpdump.pcap">
+    <comment>network packet capture</comment>
+    <magic>
+      <match type="host32" value="0xa1b2c3d4" offset="0"/>
+      <match type="host32" value="0xd4c3b2a1" offset="0"/>
+    </magic>
+    <glob pattern="*.pcap"/>
+    <glob pattern="*.cap"/>
+    <glob pattern="*.dmp"/>
+    <alias type="application/x-pcap"/>
+    <alias type="application/pcap"/>
+  </mime-type>
+  <mime-type type="application/vnd.wordperfect">
+    <comment>WordPerfect document</comment>
+    <alias type="application/x-wordperfect"/>
+    <alias type="application/wordperfect"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="WPC" offset="1"/>
+      <!-- <match type="big32" value="0xff575053c405" offset="0"/> -->
+    </magic>
+    <glob pattern="*.wp"/>
+    <glob pattern="*.wp4"/>
+    <glob pattern="*.wp5"/>
+    <glob pattern="*.wp6"/>
+    <glob pattern="*.wpd"/>
+    <glob pattern="*.wpp"/>
+  </mime-type>
+  <mime-type type="video/vnd.youtube.yt">
+    <comment>YouTube media archive</comment>
+    <alias type="application/vnd.youtube.yt"/>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="ftypyt4 " offset="4"/>
+    </magic>
+    <glob pattern="*.yt"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+  <mime-type type="application/x-spss-por">
+    <comment>SPSS portable data file</comment>
+    <acronym>SPSS</acronym>
+    <expanded-acronym>Statistical Package for the Social Sciences</expanded-acronym>
+    <magic>
+      <match type="string" offset="40" value="ASCII SPSS PORT FILE"/>
+    </magic>
+    <glob pattern="*.por"/>
+  </mime-type>
+  <mime-type type="application/x-spss-sav">
+    <comment>SPSS data file</comment>
+    <acronym>SPSS</acronym>
+    <expanded-acronym>Statistical Package for the Social Sciences</expanded-acronym>
+    <alias type="application/x-spss-savefile"/>
+    <magic>
+      <match type="string" offset="0" value="$FL2"/>
+      <match type="string" offset="0" value="$FL3"/>
+    </magic>
+    <glob pattern="*.sav"/>
+    <glob pattern="*.zsav"/>
+  </mime-type>
+  <mime-type type="application/x-xbel">
+    <comment>XBEL bookmarks</comment>
+    <acronym>XBEL</acronym>
+    <expanded-acronym>XML Bookmark Exchange Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-html"/>
+    <magic>
+      <match type="string" value="&lt;!DOCTYPE\ xbel" offset="0:256"/>
+    </magic>
+    <glob pattern="*.xbel"/>
+  </mime-type>
+  <mime-type type="application/x-7z-compressed">
+    <comment>7-zip archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="7z\274\257\047\034" offset="0"/>
+    </magic>
+    <glob pattern="*.7z"/>
+    <glob pattern="*.7z.001"/>
+  </mime-type>
+  <mime-type type="application/x-abiword">
+    <comment>AbiWord document</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="&lt;abiword" offset="0:256"/>
+      <match type="string" value="&lt;!DOCTYPE abiword" offset="0:256"/>
+    </magic>
+    <glob pattern="*.abw"/>
+    <glob pattern="*.abw.CRASHED"/>
+    <glob pattern="*.abw.gz"/>
+    <glob pattern="*.zabw"/>
+    <root-XML namespaceURI="http://www.abisource.com/awml.dtd" localName="abiword"/>
+  </mime-type>
+  <mime-type type="application/x-cue">
+    <comment>CD image cuesheet</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.cue"/>
+  </mime-type>
+  <mime-type type="application/x-amipro">
+    <comment>Lotus AmiPro document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.sam"/>
+  </mime-type>
+  <mime-type type="application/x-aportisdoc">
+    <comment>AportisDoc document</comment>
+    <sub-class-of type="application/vnd.palm"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="TEXtREAd" offset="60"/>
+      <match type="string" value="TEXtTlDc" offset="60"/>
+    </magic>
+    <glob pattern="*.pdb"/>
+    <glob pattern="*.pdc"/>
+  </mime-type>
+  <mime-type type="application/x-applix-spreadsheet">
+    <comment>Applix Spreadsheets spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="*BEGIN SPREADSHEETS" offset="0"/>
+      <match type="string" value="*BEGIN" offset="0">
+        <match type="string" value="SPREADSHEETS" offset="7"/>
+      </match>
+    </magic>
+    <glob pattern="*.as"/>
+  </mime-type>
+  <mime-type type="application/x-applix-word">
+    <comment>Applix Words document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="*BEGIN" offset="0">
+        <match type="string" value="WORDS" offset="7"/>
+      </match>
+    </magic>
+    <glob pattern="*.aw"/>
+  </mime-type>
+  <mime-type type="application/x-arc">
+    <comment>ARC archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="little32" mask="0x8080ffff" value="0x0000081a" offset="0"/>
+      <match type="little32" mask="0x8080ffff" value="0x0000091a" offset="0"/>
+      <match type="little32" mask="0x8080ffff" value="0x0000021a" offset="0"/>
+      <match type="little32" mask="0x8080ffff" value="0x0000031a" offset="0"/>
+      <match type="little32" mask="0x8080ffff" value="0x0000041a" offset="0"/>
+      <match type="little32" mask="0x8080ffff" value="0x0000061a" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-archive">
+    <comment>AR archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="45">
+      <match type="string" value="&lt;ar&gt;" offset="0"/>
+      <match type="string" value="!&lt;arch&gt;" offset="0"/>
+    </magic>
+    <glob pattern="*.a"/>
+    <glob pattern="*.ar"/>
+  </mime-type>
+  <mime-type type="application/x-arj">
+    <comment>ARJ archive</comment>
+    <acronym>ARJ</acronym>
+    <expanded-acronym>Archived by Robert Jung</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="little16" value="0xea60" offset="0"/>
+    </magic>
+    <glob pattern="*.arj"/>
+  </mime-type>
+  <mime-type type="application/x-asar">
+    <comment>Electron Archive (ASAR)</comment>
+    <acronym>ASAR</acronym>
+    <expanded-acronym>Atom Shell Archive Format</expanded-acronym>
+    <magic>
+      <match type="string" value="\004\000\000\000" offset="0">
+        <match type="string" value="{&quot;files&quot;:" offset="16"/>
+      </match>
+    </magic>
+    <glob pattern="*.asar"/>
+  </mime-type>
+  <mime-type type="application/x-asp">
+    <comment>ASP page</comment>
+    <acronym>ASP</acronym>
+    <expanded-acronym>Active Server Page</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.asp"/>
+  </mime-type>
+  <mime-type type="application/x-awk">
+    <comment>AWK script</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <magic>
+      <match type="string" value="#!/bin/gawk" offset="0"/>
+      <match type="string" value="#! /bin/gawk" offset="0"/>
+      <match type="string" value="#!/usr/bin/gawk" offset="0"/>
+      <match type="string" value="#! /usr/bin/gawk" offset="0"/>
+      <match type="string" value="#!/usr/local/bin/gawk" offset="0"/>
+      <match type="string" value="#! /usr/local/bin/gawk" offset="0"/>
+      <match type="string" value="#!/bin/awk" offset="0"/>
+      <match type="string" value="#! /bin/awk" offset="0"/>
+      <match type="string" value="#!/usr/bin/awk" offset="0"/>
+      <match type="string" value="#! /usr/bin/awk" offset="0"/>
+    </magic>
+    <glob pattern="*.awk"/>
+  </mime-type>
+  <mime-type type="application/x-bcpio">
+    <comment>BCPIO archive</comment>
+    <acronym>BCPIO</acronym>
+    <expanded-acronym>Binary CPIO</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.bcpio"/>
+  </mime-type>
+  <mime-type type="application/x-bittorrent">
+    <comment>BitTorrent seed file</comment>
+    <magic>
+      <match type="string" value="d8:announce" offset="0"/>
+    </magic>
+    <glob pattern="*.torrent"/>
+  </mime-type>
+  <mime-type type="application/x-blender">
+    <comment>Blender scene</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.blend"/>
+    <glob pattern="*.BLEND"/>
+    <glob pattern="*.blender"/>
+    <magic>
+      <match type="string" value="BLENDER" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-bzdvi">
+    <comment>TeX DVI document (bzip-compressed)</comment>
+    <sub-class-of type="application/x-bzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.dvi.bz2"/>
+  </mime-type>
+  <mime-type type="application/x-bzip">
+    <comment>Bzip archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="BZh" offset="0"/>
+    </magic>
+    <glob pattern="*.bz2"/>
+    <glob pattern="*.bz"/>
+    <alias type="application/x-bzip2"/>
+    <alias type="application/bzip2"/>
+  </mime-type>
+  <mime-type type="application/x-bzip-compressed-tar">
+    <comment>Tar archive (bzip-compressed)</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/x-bzip"/>
+    <glob pattern="*.tar.bz2"/>
+    <glob pattern="*.tar.bz"/>
+    <glob pattern="*.tbz2"/>
+    <glob pattern="*.tbz"/>
+    <glob pattern="*.tb2"/>
+  </mime-type>
+  <mime-type type="application/x-bzpdf">
+    <comment>PDF document (bzip-compressed)</comment>
+    <sub-class-of type="application/x-bzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.pdf.bz2"/>
+  </mime-type>
+  <mime-type type="application/x-bzpostscript">
+    <comment>PostScript document (bzip-compressed)</comment>
+    <sub-class-of type="application/x-bzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.ps.bz2"/>
+  </mime-type>
+  <mime-type type="application/vnd.comicbook-rar">
+    <comment>comic book archive (rar container)</comment>
+    <sub-class-of type="application/vnd.rar"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cbr"/>
+    <alias type="application/x-cbr"/>
+  </mime-type>
+  <mime-type type="application/x-cb7">
+    <comment>comic book archive (7z container)</comment>
+    <sub-class-of type="application/x-7z-compressed"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cb7"/>
+  </mime-type>
+  <mime-type type="application/x-cbt">
+    <comment>comic book archive (tar container)</comment>
+    <sub-class-of type="application/x-tar"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cbt"/>
+  </mime-type>
+  <mime-type type="application/vnd.comicbook+zip">
+    <comment>comic book archive (zip container)</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cbz"/>
+    <alias type="application/x-cbz"/>
+  </mime-type>
+  <mime-type type="application/x-lrzip">
+    <comment>Lrzip archive</comment>
+    <acronym>Lrzip</acronym>
+    <expanded-acronym>Long Range Zip</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="LRZI" offset="0"/>
+    </magic>
+    <glob pattern="*.lrz"/>
+  </mime-type>
+  <mime-type type="application/x-lrzip-compressed-tar">
+    <comment>Tar archive (lrzip-compressed)</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/x-lrzip"/>
+    <glob pattern="*.tar.lrz"/>
+    <glob pattern="*.tlrz"/>
+  </mime-type>
+  <mime-type type="application/x-apple-diskimage">
+    <comment>Apple disk image</comment>
+    <glob pattern="*.dmg"/>
+  </mime-type>
+  <mime-type type="application/x-raw-disk-image">
+    <comment>Raw disk image</comment>
+    <glob pattern="*.raw-disk-image"/>
+    <glob pattern="*.img"/>
+  </mime-type>
+  <mime-type type="application/x-raw-floppy-disk-image">
+    <comment>Floppy disk image</comment>
+    <sub-class-of type="application/x-raw-disk-image"/>
+    <alias type="application/x-fd-file"/>
+    <glob pattern="*.fd"/>
+    <glob pattern="*.qd"/>
+  </mime-type>
+  <mime-type type="application/x-raw-disk-image-xz-compressed">
+    <comment>Raw disk image (XZ-compressed)</comment>
+    <sub-class-of type="application/x-xz"/>
+    <glob pattern="*.raw-disk-image.xz"/>
+    <glob pattern="*.img.xz"/>
+  </mime-type>
+  <mime-type type="application/x-cd-image">
+    <comment>raw CD image</comment>
+    <sub-class-of type="application/x-raw-disk-image"/>
+    <alias type="application/x-iso9660-image"/>
+    <!-- No magic, see https://bugs.freedesktop.org/show_bug.cgi?id=10049 -->
+    <glob pattern="*.iso" weight="80"/>
+    <glob pattern="*.iso9660"/>
+  </mime-type>
+  <mime-type type="application/x-compressed-iso">
+    <comment>Compressed CD image</comment>
+    <magic>
+      <match value="CISO" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.cso"/>
+  </mime-type>
+  <mime-type type="application/x-iso9660-appimage">
+    <comment>AppImage application bundle</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="application/x-cd-image"/>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match value="ELF" type="string" offset="1" >
+        <match value="0x41" type="byte" offset="8">
+          <match value="0x49" type="byte" offset="9">
+            <match value="0x01" type="byte" offset="10"/>
+          </match>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.appimage"/>
+  </mime-type>
+  <mime-type type="application/x-cdrdao-toc">
+    <comment>CD Table Of Contents</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="CD_ROM\n" offset="0"/>
+      <match type="string" value="CD_DA\n" offset="0"/>
+      <match type="string" value="CD_ROM_XA\n" offset="0"/>
+      <match type="string" value="CD_TEXT " offset="0"/>
+      <match type="string" value="CATALOG &quot;" offset="0">
+        <match type="string" value="&quot;" offset="22"/>
+      </match>
+    </magic>
+    <glob pattern="*.toc"/>
+  </mime-type>
+  <mime-type type="application/x-gd-rom-cue">
+    <comment>GD-ROM image cuesheet</comment>
+    <!-- It is a non-standard cuesheet used only for Dreamcast GD-ROM images, it
+         is typically surrounded by the .bin and .raw files it lists, each one
+         matching a disc track.
+         The first file should have the application/x-dreamcast-rom type. -->
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.gdi"/>
+  </mime-type>
+  <mime-type type="application/x-discjuggler-cd-image">
+    <comment>Padus DiscJuggler CD image</comment>
+    <glob pattern="*.cdi"/>
+  </mime-type>
+  <mime-type type="application/vnd.chess-pgn">
+    <comment>PGN chess game notation</comment>
+    <acronym>PGN</acronym>
+    <expanded-acronym>Portable Game Notation</expanded-acronym>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.pgn"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[Event " offset="0"/>
+    </magic>
+    <alias type="application/x-chess-pgn"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-htmlhelp">
+    <comment>CHM document</comment>
+    <acronym>CHM</acronym>
+    <expanded-acronym>Compiled Help Modules</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.chm"/>
+    <alias type="application/x-chm"/>
+  </mime-type>
+  <mime-type type="application/x-class-file">
+    <comment>Java byte code</comment>
+  </mime-type>
+  <mime-type type="application/x-compress">
+    <comment>UNIX-compressed file</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="\037\235" offset="0"/>
+    </magic>
+    <glob pattern="*.Z"/>
+  </mime-type>
+  <mime-type type="application/x-compressed-tar">
+    <comment>Tar archive (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.tar.gz"/>
+    <glob pattern="*.tgz"/>
+  </mime-type>
+  <mime-type type="application/x-core">
+    <comment>program crash data</comment>
+    <magic>
+      <match type="string" mask="0xffffffff000000000000000000000000ff" value="\177ELF            \004" offset="0"/>
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="1" offset="5">
+          <match type="little16" value="4" offset="16"/>
+        </match>
+      </match>
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="2" offset="5">
+          <match type="big16" value="4" offset="16"/>
+        </match>
+      </match>
+      <match type="string" value="Core\001" offset="0"/>
+      <match type="string" value="Core\002" offset="0"/>
+    </magic>
+    <glob pattern="core" case-sensitive="true"/>
+  </mime-type>
+  <mime-type type="application/x-cpio">
+    <comment>CPIO archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="host16" value="070707" offset="0"/>
+      <match type="string" value="070701" offset="0"/>
+      <match type="string" value="070702" offset="0"/>
+      <match type="host16" value="0143561" offset="0"/>
+    </magic>
+    <glob pattern="*.cpio"/>
+  </mime-type>
+  <mime-type type="application/x-cpio-compressed">
+    <comment>CPIO archive (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.cpio.gz"/>
+  </mime-type>
+  <mime-type type="application/x-csh">
+    <comment>C shell script</comment>
+    <sub-class-of type="application/x-shellscript"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <magic>
+      <match type="string" value="/bin/tcsh" offset="2:16"/>
+      <match type="string" value="/bin/csh" offset="2:16"/>
+      <match type="string" value="/bin/env csh" offset="2:16"/>
+      <match type="string" value="/bin/env tcsh" offset="2:16"/>
+    </magic>
+    <glob pattern="*.csh"/>
+  </mime-type>
+  <mime-type type="application/x-dbf">
+    <comment>Xbase document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.dbf"/>
+    <alias type="application/x-dbase"/>
+    <alias type="application/dbf"/>
+    <alias type="application/dbase"/>
+  </mime-type>
+  <mime-type type="application/ecmascript">
+    <comment>ECMAScript program</comment>
+    <alias type="text/ecmascript"/>
+    <sub-class-of type='application/x-executable'/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.es"/>
+  </mime-type>
+  <mime-type type="application/x-mame-chd">
+    <comment>MAME compressed hard disk image</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="MComprHD" offset="0"/>
+    </magic>
+    <glob pattern="*.chd"/>
+  </mime-type>
+  <mime-type type="application/x-sega-cd-rom">
+    <!-- Translate this to Mega-CD if the console was known as such in your locale
+         Should be Mega-CD in all but en_US, Mexico, Canada and Brazil: https://en.wikipedia.org/wiki/Sega_CD -->
+    <comment>Sega CD disc image</comment>
+    <generic-icon name="application-x-executable"/>
+    <!-- Also matches the application/x-genesis-rom magic values, hence the higher priority -->
+    <magic priority="60">
+      <match type="string" value="SEGADISCSYSTEM" offset="0">
+        <match type="string" value="SEGA" offset="256"/>
+      </match>
+      <match type="string" value="SEGADISCSYSTEM" offset="16">
+        <match type="string" value="SEGA" offset="272"/>
+      </match>
+    </magic>
+    <glob pattern="*.iso"/>
+  </mime-type>
+  <mime-type type="application/x-sega-pico-rom">
+    <!-- Translate this to Kids Computer Pico if the console was known as such in your locale
+         Should be Sega Pico in all but Japan: https://en.wikipedia.org/wiki/Sega_Pico -->
+    <comment>Sega Pico ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="SEGA PICO" offset="256"/>
+    </magic>
+    <glob pattern="*.iso"/>
+  </mime-type>
+  <mime-type type="application/x-saturn-rom">
+    <comment>Sega Saturn disc image</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="SEGA SEGASATURN" offset="0"/>
+      <match type="string" value="SEGA SEGASATURN" offset="16"/>
+    </magic>
+    <glob pattern="*.iso"/>
+  </mime-type>
+  <mime-type type="application/x-dreamcast-rom">
+    <comment>Dreamcast disc image</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="SEGA SEGAKATANA" offset="16"/>
+    </magic>
+    <glob pattern="*.iso"/>
+  </mime-type>
+  <mime-type type="application/x-nintendo-ds-rom">
+    <comment>Nintendo DS ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.nds"/>
+  </mime-type>
+  <mime-type type="application/x-nintendo-3ds-rom">
+    <comment>Nintendo 3DS ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.3ds"/>
+    <glob pattern="*.cci"/>
+    <magic>
+      <match offset="256" type="string" value="NCSD"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-nintendo-3ds-executable">
+    <comment>Nintendo 3DS Executable</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.3dsx"/>
+    <magic priority="40">
+      <match offset="0" type="string" value="3DSX"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-pc-engine-rom">
+    <comment>PC Engine ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.pce"/>
+  </mime-type>
+  <mime-type type="application/x-wii-rom">
+    <comment>Wii disc image</comment>
+    <alias type="application/x-wii-iso-image"/>
+    <alias type="application/x-wbfs"/>
+    <alias type="application/x-wia"/>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.iso"/>
+    <magic>
+      <match offset="24" type="big32" value="0x5d1c9ea3"/>
+      <match offset="0" type="string" value="WBFS"/>
+      <match offset="0" type="string" value="WII\001DISC"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-wii-wad">
+    <comment>WiiWare bundle</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="Is\0\0" offset="4"/>
+      <match type="string" value="ib\0\0" offset="4"/>
+      <match type="string" value="Bk\0\0" offset="4"/>
+    </magic>
+    <glob pattern="*.wad"/>
+  </mime-type>
+  <mime-type type="application/x-gamecube-rom">
+    <comment>GameCube disc image</comment>
+    <generic-icon name="application-x-executable"/>
+    <alias type="application/x-gamecube-iso-image"/>
+    <glob pattern="*.iso"/>
+    <magic>
+      <match offset="28" type="big32" value="0xc2339f3d"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-thomson-cartridge-memo7">
+    <comment>Thomson Mémo7 cartridge</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.m7"/>
+  </mime-type>
+  <mime-type type="application/x-thomson-cassette">
+    <comment>Thomson cassette</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.k7"/>
+  </mime-type>
+  <mime-type type="application/x-hfe-floppy-image">
+    <comment>HFE floppy disk image</comment>
+    <acronym>HFE</acronym>
+    <expanded-acronym>HxC Floppy Emulator</expanded-acronym>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.hfe"/>
+    <magic>
+      <match offset="0" type="string" value="HXCPICFE"/>
+    </magic>
+    <alias type="application/x-hfe-file"/>
+  </mime-type>
+  <mime-type type="application/x-thomson-sap-image">
+    <comment>SAP Thomson floppy disk image</comment>
+    <acronym>SAP</acronym>
+    <expanded-acronym>Système d'Archivage Pukall</expanded-acronym>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.sap"/>
+    <magic>
+      <match offset="1" type="string" value="SYSTEME D'ARCHIVAGE PUKALL S.A.P. (c) Alexandre PUKALL Avril 1998"/>
+    </magic>
+    <alias type="application/x-sap-file"/>
+  </mime-type>
+  <mime-type type="application/vnd.debian.binary-package">
+    <comment>Debian package</comment>
+    <alias type="application/x-deb"/>
+    <alias type="application/x-debian-package"/>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="!&lt;arch&gt;" offset="0">
+        <match type="string" value="debian" offset="8"/>
+      </match>
+    </magic>
+    <glob pattern="*.deb"/>
+    <glob pattern="*.udeb"/>
+  </mime-type>
+  <mime-type type="application/x-designer">
+    <comment>Qt Designer interface document</comment>
+    <generic-icon name="x-office-document"/>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;ui " offset="0:256"/>
+      <match type="string" value="&lt;UI " offset="0:256"/>
+    </magic>
+    <glob pattern="*.ui"/>
+  </mime-type>
+  <mime-type type="text/x-kaitai-struct">
+    <comment>Kaitai Struct definition file</comment>
+    <sub-class-of type="application/x-yaml"/>
+    <glob pattern="*.ksy"/>
+  </mime-type>
+  <mime-type type="text/x-qml">
+    <comment>Qt Markup Language file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="/bin/env qml" offset="2:16"/>
+      <match type="string" value="import Qt" offset="0:3000">
+        <match type="string" value="{" offset="9:3009"/>
+      </match>
+      <match type="string" value="import Qml" offset="0:3000">
+        <match type="string" value="{" offset="9:3009"/>
+      </match>
+    </magic>
+    <glob pattern="*.qml"/>
+    <glob pattern="*.qmltypes"/>
+    <glob pattern="*.qmlproject"/>
+  </mime-type>
+  <mime-type type="application/x-desktop">
+    <comment>desktop entry</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="[Desktop Entry]" offset="0:32"/>
+      <match type="string" value="[Desktop Action" offset="0"/>
+      <match type="string" value="[KDE Desktop Entry]" offset="0"/>
+      <match type="string" value="# Config File" offset="0"/>
+      <match type="string" value="# KDE Config File" offset="0"/>
+    </magic>
+    <glob pattern="*.desktop"/>
+    <glob pattern="*.kdelnk"/>
+    <alias type="application/x-gnome-app-info"/>
+  </mime-type>
+  <mime-type type="application/x-fictionbook+xml">
+    <comment>FictionBook document</comment>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.fb2"/>
+    <magic priority="80">
+      <match type="string" value="&lt;FictionBook" offset="0:256"/>
+    </magic>
+    <alias type="application/x-fictionbook"/>
+    <root-XML namespaceURI="http://www.gribuser.ru/xml/fictionbook/2.0" localName="FictionBook"/>
+  </mime-type>
+  <mime-type type="application/x-zip-compressed-fb2">
+    <comment>Compressed FictionBook document</comment>
+    <sub-class-of type="application/zip"/>
+    <glob pattern="*.fb2.zip"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <!-- Okay, this is not ideal, but it should be good enough for normal cases -->
+        <match type="string" value=".fb2" offset="30:256"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-dia-diagram">
+    <comment>Dia diagram</comment>
+    <generic-icon name="image-x-generic"/>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.dia"/>
+    <magic>
+      <match offset="5:100" type="string" value="&lt;dia:"/>
+    </magic>
+    <root-XML namespaceURI="http://www.lysator.liu.se/~alla/dia/" localName="diagram"/>
+  </mime-type>
+  <mime-type type="application/x-dia-shape">
+    <comment>Dia shape</comment>
+    <generic-icon name="image-x-generic"/>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.shape"/>
+    <magic>
+      <match offset="5:100" type="string" value="&lt;shape"/>
+    </magic>
+    <root-XML namespaceURI="http://www.daa.com.au/~james/dia-shape-ns" localName="shape"/>
+  </mime-type>
+  <mime-type type="application/x-dvi">
+    <comment>TeX DVI document</comment>
+    <acronym>DVI</acronym>
+    <expanded-acronym>Device independent file format</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="little16" value="0x02f7" offset="0"/>
+    </magic>
+    <glob pattern="*.dvi"/>
+  </mime-type>
+  <mime-type type="application/x-e-theme">
+    <comment>Enlightenment theme</comment>
+    <glob pattern="*.etheme"/>
+  </mime-type>
+  <mime-type type="application/x-egon">
+    <comment>Egon Animator animation</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.egon"/>
+  </mime-type>
+  <mime-type type="application/x-executable">
+    <comment>executable</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic priority="40">
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="1" offset="5"/>
+      </match>
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="2" offset="5"/>
+      </match>
+      <match type="string" value="MZ" offset="0"/>
+      <match type="little16" value="0x521c" offset="0"/>
+      <match type="host16" value="0420" offset="0"/>
+      <match type="host16" value="0421" offset="0"/>
+      <match type="little16" value="0603" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-fluid">
+    <comment>FLTK Fluid file</comment>
+    <acronym>FLTK</acronym>
+    <expanded-acronym>Fast Light Toolkit</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="# data file for the Fltk" offset="0"/>
+    </magic>
+    <glob pattern="*.fl"/>
+  </mime-type>
+  <mime-type type="font/woff">
+    <comment>WOFF font</comment>
+    <acronym>WOFF</acronym>
+    <expanded-acronym>Web Open Font Format</expanded-acronym>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="big32" value="0x774f4646" offset="0"/>
+    </magic>
+    <glob pattern="*.woff"/>
+    <alias type="application/font-woff"/>
+  </mime-type>
+  <mime-type type="font/woff2">
+    <comment>WOFF2 font</comment>
+    <acronym>WOFF2</acronym>
+    <expanded-acronym>Web Open Font Format 2.0</expanded-acronym>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="big32" value="0x774f4632" offset="0"/>
+    </magic>
+    <glob pattern="*.woff2"/>
+  </mime-type>
+  <mime-type type="application/x-font-type1">
+    <comment>PostScript type-1 font</comment>
+    <sub-class-of type="application/postscript"/>
+    <generic-icon name="font-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="LWFN" offset="0"/>
+      <match type="string" value="LWFN" offset="65"/>
+      <match type="string" value="%!PS-AdobeFont-1." offset="0"/>
+      <match type="string" value="%!PS-AdobeFont-1." offset="6"/>
+      <match type="string" value="%!FontType1-1." offset="0"/>
+      <match type="string" value="%!FontType1-1." offset="6"/>
+    </magic>
+    <glob pattern="*.pfa"/>
+    <glob pattern="*.pfb"/>
+    <glob pattern="*.gsf"/>
+  </mime-type>
+  <mime-type type="application/x-font-afm">
+    <comment>Adobe font metrics</comment>
+    <generic-icon name="font-x-generic"/>
+    <glob pattern="*.afm"/>
+  </mime-type>
+  <mime-type type="application/x-font-bdf">
+    <comment>BDF font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="STARTFONT\040" offset="0"/>
+    </magic>
+    <glob pattern="*.bdf"/>
+  </mime-type>
+  <mime-type type="application/x-font-dos">
+    <comment>DOS font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\xff\x46\x4f\x4e" offset="0"/>
+      <match type="string" value="\x00\x45\x47\x41" offset="7"/>
+      <match type="string" value="\x00\x56\x49\x44" offset="7"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-font-framemaker">
+    <comment>Adobe FrameMaker font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;MakerScreenFont" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-font-libgrx">
+    <comment>LIBGRX font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\x14\x02\x59\x19" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-font-linux-psf">
+    <comment>Linux PSF console font</comment>
+    <acronym>PSF</acronym>
+    <expanded-acronym>PC Screen Font</expanded-acronym>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\x36\x04" offset="0"/>
+    </magic>
+    <glob pattern="*.psf"/>
+  </mime-type>
+  <mime-type type="application/x-gz-font-linux-psf">
+    <comment>Linux PSF console font (gzip-compressed)</comment>
+    <acronym>PSF</acronym>
+    <expanded-acronym>PC Screen Font</expanded-acronym>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="font-x-generic"/>
+    <glob pattern="*.psf.gz"/>
+  </mime-type>
+  <mime-type type="application/x-font-pcf">
+    <comment>PCF font</comment>
+    <acronym>PCF</acronym>
+    <expanded-acronym>Portable Compiled Format</expanded-acronym>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\001fcp" offset="0"/>
+    </magic>
+    <glob pattern="*.pcf"/>
+    <glob pattern="*.pcf.Z"/>
+    <glob pattern="*.pcf.gz"/>
+  </mime-type>
+  <mime-type type="font/otf">
+    <comment>OpenType font</comment>
+    <sub-class-of type="font/ttf"/>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="OTTO" offset="0"/>
+    </magic>
+    <glob pattern="*.otf"/>
+    <alias type="application/x-font-otf"/>
+  </mime-type>
+  <mime-type type="application/x-font-speedo">
+    <comment>Speedo font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="D1.0\015" offset="0"/>
+    </magic>
+    <glob pattern="*.spd"/>
+  </mime-type>
+  <mime-type type="application/x-font-sunos-news">
+    <comment>SunOS News font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="StartFont" offset="0"/>
+      <match type="string" value="\x13\x7A\x29" offset="0"/>
+      <match type="string" value="\x13\x7A\x2B" offset="8"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-font-tex">
+    <comment>TeX font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\367\203" offset="0"/>
+      <match type="string" value="\367\131" offset="0"/>
+      <match type="string" value="\367\312" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-font-tex-tfm">
+    <comment>TeX font metrics</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="\000\021" offset="2"/>
+      <match type="string" value="\000\022" offset="2"/>
+    </magic>
+  </mime-type>
+  <mime-type type="font/ttf">
+    <comment>TrueType font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="FFIL" offset="0"/>
+      <match type="string" value="FFIL" offset="65"/>
+      <match type="string" value="\000\001\000\000\000" offset="0"/>
+    </magic>
+    <glob pattern="*.ttf"/>
+    <alias type="application/x-font-ttf"/>
+  </mime-type>
+  <mime-type type="font/collection">
+    <comment>Font collection</comment>
+    <generic-icon name="font-x-generic"/>
+    <glob pattern="*.ttc"/>
+  </mime-type>
+  <mime-type type="application/x-font-ttx">
+    <comment>TrueType XML font</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;ttFont sfntVersion=&quot;\\x00\\x01\\x00\\x00&quot; ttLibVersion=&quot;" offset="0:256"/>
+    </magic>
+    <glob pattern="*.ttx"/>
+  </mime-type>
+  <mime-type type="application/x-font-vfont">
+    <comment>V font</comment>
+    <generic-icon name="font-x-generic"/>
+    <magic>
+      <match type="string" value="FONT" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/vnd.framemaker">
+    <comment>Adobe FrameMaker document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="&lt;MakerFile" offset="0"/>
+      <match type="string" value="&lt;MIFFile" offset="0"/>
+      <match type="string" value="&lt;MakerDictionary" offset="0"/>
+      <match type="string" value="&lt;MakerScreenFon" offset="0"/>
+      <match type="string" value="&lt;MML" offset="0"/>
+      <match type="string" value="&lt;Book" offset="0"/>
+      <match type="string" value="&lt;Maker" offset="0"/>
+    </magic>
+    <glob pattern="*.fm"/>
+    <alias type="application/x-frame"/>
+  </mime-type>
+  <mime-type type="application/x-gameboy-rom">
+    <comment>Game Boy ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="\xce\xed\x66\x66\xcc\x0d\x00\x0b\x03\x73\x00\x83\x00\x0c\x00\x0d\x00\x08\x11\x1f\x88\x89\x00\x0e" offset="260">
+        <match type="byte" value="0x0" mask="0x80" offset="323"/>
+      </match>
+    </magic>
+    <glob pattern="*.gb"/>
+    <glob pattern="*.sgb"/>
+  </mime-type>
+  <mime-type type="application/x-gameboy-color-rom">
+    <comment>Game Boy Color ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="\xce\xed\x66\x66\xcc\x0d\x00\x0b\x03\x73\x00\x83\x00\x0c\x00\x0d\x00\x08" offset="260">
+        <match type="byte" value="0x80" mask="0x80" offset="323"/>
+      </match>
+    </magic>
+    <glob pattern="*.gbc"/>
+    <glob pattern="*.cgb"/>
+  </mime-type>
+  <mime-type type="application/x-gba-rom">
+    <comment>Game Boy Advance ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.gba"/>
+    <glob pattern="*.agb"/>
+  </mime-type>
+  <mime-type type="application/x-virtual-boy-rom">
+    <comment>Virtual Boy ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.vb"/>
+  </mime-type>
+  <mime-type type="application/x-gdbm">
+    <comment>GDBM database</comment>
+    <acronym>GDBM</acronym>
+    <expanded-acronym>GNU Database Manager</expanded-acronym>
+    <magic>
+      <match type="big32" value="0x13579ace" offset="0"/>
+      <match type="little32" value="0x13579ace" offset="0"/>
+      <match type="string" value="GDBM" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-genesis-rom">
+    <!-- Translate this to Mega Drive if the console was known as such in your locale
+         Should be Mega Drive in all but en_US, Mexico and Canada: https://en.wikipedia.org/wiki/Sega_Genesis#History -->
+    <comment>Genesis ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="SEGA GENESIS" offset="256"/>
+      <match type="string" value="SEGA MEGA DRIVE" offset="256"/>
+      <match type="string" value="SEGA_MEGA_DRIVE" offset="256"/>
+      <match type="string" value="EAGN" offset="640"/>
+      <match type="string" value="EAMG" offset="640"/>
+    </magic>
+    <glob pattern="*.gen"/>
+    <glob pattern="*.smd"/>
+    <glob pattern="*.sgd"/>
+  </mime-type>
+  <mime-type type="application/x-genesis-32x-rom">
+    <!-- Translate this to Super 32X, Mega Drive 32X or Mega 32X if the system was known as such in your locale
+         Should be Super 32X in Japan, Mega Drive 32X in PAL region and Mega 32X in Brazil: https://en.wikipedia.org/wiki/32X -->
+    <comment>Genesis 32X ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="SEGA 32X" offset="256"/>
+    </magic>
+    <glob pattern="*.32x"/>
+    <glob pattern="*.mdx"/>
+  </mime-type>
+  <mime-type type="application/x-gettext-translation">
+    <comment>translated messages (machine-readable)</comment>
+    <magic>
+      <match type="string" value="\336\22\4\225" offset="0"/>
+      <match type="string" value="\225\4\22\336" offset="0"/>
+    </magic>
+    <glob pattern="*.gmo"/>
+    <glob pattern="*.mo"/>
+  </mime-type>
+  <mime-type type="application/x-gtk-builder">
+    <comment>GTK+ Builder interface document</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.ui"/>
+    <magic>
+      <match type="string" value="&lt;interface" offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-glade">
+    <comment>Glade project</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.glade"/>
+    <magic>
+      <match type="string" value="&lt;glade-interface" offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-gnucash">
+    <comment>GnuCash financial data</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.gnucash"/>
+    <glob pattern="*.gnc"/>
+    <glob pattern="*.xac"/>
+  </mime-type>
+  <mime-type type="application/x-gnumeric">
+    <comment>Gnumeric spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="gmr:Workbook" offset="0:64"/>
+      <match type="string" value="gnm:Workbook" offset="0:64"/>
+    </magic>
+    <glob pattern="*.gnumeric"/>
+  </mime-type>
+  <mime-type type="application/x-gnuplot">
+    <comment>Gnuplot document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.gp"/>
+    <glob pattern="*.gplt"/>
+    <glob pattern="*.gnuplot"/>
+  </mime-type>
+  <mime-type type="application/x-graphite">
+    <comment>Graphite scientific graph</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.gra"/>
+  </mime-type>
+  <mime-type type="application/x-gtktalog">
+    <comment>GTKtalog catalog</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="gtktalog " offset="4"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-gzdvi">
+    <comment>TeX DVI document (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.dvi.gz"/>
+  </mime-type>
+  <mime-type type="application/gzip">
+    <comment>Gzip archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="\037\213" offset="0"/>
+    </magic>
+    <glob pattern="*.gz"/>
+    <alias type="application/x-gzip"/>
+  </mime-type>
+  <mime-type type="application/x-gzpdf">
+    <comment>PDF document (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.pdf.gz"/>
+  </mime-type>
+  <mime-type type="application/x-gzpostscript">
+    <comment>PostScript document (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.ps.gz"/>
+  </mime-type>
+  <mime-type type="application/x-hdf">
+    <comment>HDF document</comment>
+    <acronym>HDF</acronym>
+    <expanded-acronym>Hierarchical Data Format</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" offset="0" value="\211HDF\r\n\032\n"/>
+      <match type="string" offset="0" value="\016\003\023\001"/>
+    </magic>
+    <glob pattern="*.hdf"/>
+    <glob pattern="*.hdf4"/>
+    <glob pattern="*.h4"/>
+    <glob pattern="*.hdf5"/>
+    <glob pattern="*.h5"/>
+  </mime-type>
+  <mime-type type="application/x-iff">
+    <comment>IFF file</comment>
+    <acronym>IFF</acronym>
+    <expanded-acronym>Interchange File Format</expanded-acronym>
+    <magic priority="40">
+      <match type="string" value="FORM" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-ipod-firmware">
+    <comment>iPod firmware</comment>
+    <magic>
+      <match type="string" value="S T O P" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-java-archive">
+    <comment>Java archive</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="package-x-generic"/>
+    <alias type="application/x-jar"/>
+    <alias type="application/java-archive"/>
+    <glob pattern="*.jar"/>
+  </mime-type>
+  <mime-type type="application/x-java">
+    <comment>Java class</comment>
+    <magic>
+      <match type="big32" value="0xcafebabe" offset="0"/>
+    </magic>
+    <alias type="application/java"/>
+    <alias type="application/java-byte-code"/>
+    <alias type="application/java-vm"/>
+    <alias type="application/x-java-class"/>
+    <alias type="application/x-java-vm"/>
+    <glob pattern="*.class"/>
+  </mime-type>
+  <mime-type type="text/x-groovy">
+    <comment>Groovy source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.groovy"/>
+    <glob pattern="*.gvy"/>
+    <glob pattern="*.gy"/>
+    <glob pattern="*.gsh"/>
+  </mime-type>
+  <mime-type type="text/x-gradle">
+    <comment>Gradle script</comment>
+    <sub-class-of type="text/x-groovy"/>
+    <glob pattern="*.gradle"/>
+  </mime-type>
+  <mime-type type="application/x-java-jnlp-file">
+    <comment>JNLP file</comment>
+    <acronym>JNLP</acronym>
+    <expanded-acronym>Java Network Launching Protocol</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.jnlp"/>
+    <magic>
+      <match type="string" value="&lt;jnlp" offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-java-keystore">
+    <comment>Java keystore</comment>
+    <magic>
+      <match type="big32" value="0xfeedfeed" offset="0"/>
+    </magic>
+    <glob pattern="*.jks"/>
+    <glob pattern="*.ks"/>
+    <glob pattern="cacerts"/>
+  </mime-type>
+  <mime-type type="application/x-java-jce-keystore">
+    <comment>Java JCE keystore</comment>
+    <acronym>JCE</acronym>
+    <expanded-acronym>Java Cryptography Extension</expanded-acronym>
+    <magic>
+      <match type="host32" value="0xcececece" offset="0"/>
+    </magic>
+    <glob pattern="*.jceks"/>
+  </mime-type>
+  <mime-type type="application/x-java-pack200">
+    <comment>Pack200 Java archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="big32" value="0xcafed00d" offset="0"/>
+    </magic>
+    <glob pattern="*.pack"/>
+  </mime-type>
+  <mime-type type="text/javascript">
+    <comment>JavaScript program</comment>
+    <alias type="application/x-javascript"/>
+    <alias type="application/javascript"/>
+    <sub-class-of type="application/ecmascript"/>
+    <generic-icon name="text-x-script"/>
+    <magic>
+      <match type="string" value="#!/bin/gjs" offset="0"/>
+      <match type="string" value="#! /bin/gjs" offset="0"/>
+      <match type="string" value='eval \"exec /bin/gjs' offset="0"/>
+      <match type="string" value="#!/usr/bin/gjs" offset="0"/>
+      <match type="string" value="#! /usr/bin/gjs" offset="0"/>
+      <match type="string" value='eval \"exec /usr/bin/gjs' offset="0"/>
+      <match type="string" value="#!/usr/local/bin/gjs" offset="0"/>
+      <match type="string" value="#! /usr/local/bin/gjs" offset="0"/>
+      <match type="string" value='eval \"exec /usr/local/bin/gjs' offset="0"/>
+      <match type="string" value='/bin/env gjs' offset="2:16"/>
+    </magic>
+    <glob pattern="*.js"/>
+    <glob pattern="*.jsm"/>
+    <glob pattern="*.mjs"/>
+  </mime-type>
+  <mime-type type="application/json">
+    <comment>JSON document</comment>
+    <acronym>JSON</acronym>
+    <expanded-acronym>JavaScript Object Notation</expanded-acronym>
+    <sub-class-of type="text/javascript"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.json"/>
+  </mime-type>
+  <mime-type type="application/jrd+json">
+    <comment>JRD document</comment>
+    <acronym>JRD</acronym>
+    <expanded-acronym>JSON Resource Descriptor</expanded-acronym>
+    <sub-class-of type="application/json"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.jrd"/>
+  </mime-type>
+  <mime-type type="application/json-patch+json">
+    <comment>JSON patch</comment>
+    <acronym>JSON</acronym>
+    <expanded-acronym>JavaScript Object Notation</expanded-acronym>
+    <sub-class-of type="application/json"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.json-patch"/>
+  </mime-type>
+  <mime-type type="application/ld+json">
+    <comment>JSON-LD document</comment>
+    <acronym>JSON-LD</acronym>
+    <expanded-acronym>JavaScript Object Notation for Linked Data</expanded-acronym>
+    <sub-class-of type="application/json"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.jsonld"/>
+  </mime-type>
+  <mime-type type="application/schema+json">
+    <comment>JSON schema</comment>
+    <sub-class-of type="application/json"/>
+    <generic-icon name="text-x-script"/>
+    <magic priority="80">
+      <match type="string" value="{" offset="0">
+        <match type="string" value="&quot;$schema&quot;:" offset="1:256"/>
+      </match>
+    </magic>
+    <glob pattern="*.json"/>
+  </mime-type>
+  <mime-type type="application/x-ipynb+json">
+    <comment>Jupyter notebook document</comment>
+    <sub-class-of type="application/json"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="{" offset="0">
+        <match type="string" value='"cells":' offset="1:256"/>
+      </match>
+    </magic>
+    <glob pattern="*.ipynb"/>
+  </mime-type>
+  <mime-type type="application/vnd.coffeescript">
+    <comment>CoffeeScript document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.coffee"/>
+  </mime-type>
+  <mime-type type="application/x-jbuilder-project">
+    <comment>JBuilder project</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.jpr"/>
+    <glob pattern="*.jpx"/>
+  </mime-type>
+  <mime-type type="application/x-karbon">
+    <comment>Karbon14 drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-karbon\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-karbon" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.karbon"/>
+  </mime-type>
+  <mime-type type="application/x-kchart">
+    <comment>KChart chart</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kchart\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kchart" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.chrt"/>
+  </mime-type>
+  <mime-type type="application/x-kexi-connectiondata">
+    <comment>Kexi settings</comment>
+    <glob pattern="*.kexic"/>
+  </mime-type>
+  <mime-type type="application/x-kexiproject-shortcut">
+    <comment>Kexi shortcut</comment>
+    <glob pattern="*.kexis"/>
+  </mime-type>
+  <mime-type type="application/x-kexiproject-sqlite2">
+    <comment>Kexi database file</comment>
+    <sub-class-of type="application/x-sqlite2"/>
+    <glob pattern="*.kexi"/>
+  </mime-type>
+  <mime-type type="application/x-kexiproject-sqlite3">
+    <comment>Kexi database file</comment>
+    <sub-class-of type="application/vnd.sqlite3"/>
+    <glob pattern="*.kexi"/>
+    <alias type="application/x-vnd.kde.kexi"/>
+    <alias type="application/x-kexiproject-sqlite"/>
+  </mime-type>
+  <mime-type type="application/x-kformula">
+    <comment>KFormula formula</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kformula\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kformula" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kfo"/>
+  </mime-type>
+  <mime-type type="application/x-killustrator">
+    <comment>KIllustrator drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-killustrator\004\006" offset="18"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kil"/>
+  </mime-type>
+  <mime-type type="application/x-kivio">
+    <comment>Kivio flowchart</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kivio\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kivio" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.flw"/>
+  </mime-type>
+  <mime-type type="application/x-kontour">
+    <comment>Kontour drawing</comment>
+    <generic-icon name="image-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kontour\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kontour" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kon"/>
+  </mime-type>
+  <mime-type type="application/x-kpovmodeler">
+    <comment>KPovModeler scene</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.kpm"/>
+  </mime-type>
+  <mime-type type="application/x-kpresenter">
+    <comment>KPresenter presentation</comment>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kpresenter\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kpresenter" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kpr"/>
+    <glob pattern="*.kpt"/>
+  </mime-type>
+  <mime-type type="application/x-krita">
+    <comment>Krita document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-krita\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <!-- Depending on the zip library and whether a 32 or 64 bits zip file is used, the offset is different. -->
+          <match type="string" value="application/x-krita" offset="38"/>
+          <match type="string" value="application/x-krita" offset="42"/>
+          <match type="string" value="application/x-krita" offset="63"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kra"/>
+    <glob pattern="*.krz"/>
+  </mime-type>
+  <mime-type type="application/x-kspread">
+    <comment>KSpread spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kspread\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kspread" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ksp"/>
+  </mime-type>
+  <mime-type type="application/x-kspread-crypt">
+    <comment>KSpread spreadsheet (encrypted)</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="big32" value="0x0d1a2702" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-ksysv-package">
+    <comment>KSysV init package</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="KSysV" offset="4">
+        <match type="byte" value="1" offset="15"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-kugar">
+    <comment>Kugar document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.kud"/>
+  </mime-type>
+  <mime-type type="application/x-kword">
+    <comment>KWord document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="60">
+      <match type="string" value="\037\213" offset="0">
+        <match type="string" value="KOffice" offset="10">
+          <match type="string" value="application/x-kword\004\006" offset="18"/>
+        </match>
+      </match>
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="application/x-kword" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.kwd"/>
+    <glob pattern="*.kwt"/>
+  </mime-type>
+  <mime-type type="application/x-kword-crypt">
+    <comment>KWord document (encrypted)</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="big32" value="0x0d1a2701" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-lha">
+    <comment>LHA archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="-lh -" offset="2"/>
+      <match type="string" value="-lh0-" offset="2"/>
+      <match type="string" value="-lh1-" offset="2"/>
+      <match type="string" value="-lh2-" offset="2"/>
+      <match type="string" value="-lh3-" offset="2"/>
+      <match type="string" value="-lh4-" offset="2"/>
+      <match type="string" value="-lh5-" offset="2"/>
+      <match type="string" value="-lh40-" offset="2"/>
+      <match type="string" value="-lhd-" offset="2"/>
+      <match type="string" value="-lz4-" offset="2"/>
+      <match type="string" value="-lz5-" offset="2"/>
+      <match type="string" value="-lzs-" offset="2"/>
+    </magic>
+    <glob pattern="*.lha"/>
+    <glob pattern="*.lzh"/>
+    <alias type="application/x-lzh-compressed"/>
+  </mime-type>
+  <mime-type type="application/x-lhz">
+    <comment>LHZ archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.lhz"/>
+  </mime-type>
+  <mime-type type="text/vnd.trolltech.linguist">
+    <comment>message catalog</comment>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;TS " offset="0:256"/>
+      <match type="string" value="&lt;TS&gt;" offset="0:256"/>
+    </magic>
+    <glob pattern="*.ts"/>
+    <alias type="application/x-linguist"/>
+    <alias type="text/vnd.qt.linguist"/>
+  </mime-type>
+  <mime-type type="application/x-lyx">
+    <comment>LyX document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="#LyX" offset="0"/>
+    </magic>
+    <glob pattern="*.lyx"/>
+    <alias type="text/x-lyx"/>
+  </mime-type>
+  <mime-type type="application/x-lz4">
+    <comment>LZ4 archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="little32" value="0x184d2204" offset="0"/>
+      <match type="little32" value="0x184c2102" offset="0"/>
+    </magic>
+    <glob pattern="*.lz4"/>
+  </mime-type>
+  <mime-type type="application/x-lz4-compressed-tar">
+    <comment>Tar archive (LZ4-compressed)</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/x-lz4"/>
+    <glob pattern="*.tar.lz4"/>
+  </mime-type>
+  <mime-type type="application/x-lzip">
+    <comment>Lzip archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="LZIP" offset="0"/>
+    </magic>
+    <glob pattern="*.lz"/>
+  </mime-type>
+  <mime-type type="application/x-lzip-compressed-tar">
+    <comment>Tar archive (lzip-compressed)</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/x-lzip"/>
+    <glob pattern="*.tar.lz"/>
+  </mime-type>
+  <mime-type type="application/x-lzpdf">
+    <comment>PDF document (lzip-compressed)</comment>
+    <sub-class-of type="application/x-lzip"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.pdf.lz"/>
+  </mime-type>
+  <mime-type type="application/x-lzma">
+    <comment>LZMA archive</comment>
+    <acronym>LZMA</acronym>
+    <expanded-acronym>Lempel-Ziv-Markov chain-Algorithm</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.lzma"/>
+  </mime-type>
+  <mime-type type="application/x-lzma-compressed-tar">
+    <comment>Tar archive (LZMA-compressed)</comment>
+    <sub-class-of type="application/x-lzma"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.tar.lzma"/>
+    <glob pattern="*.tlz"/>
+  </mime-type>
+  <mime-type type="application/x-lzop">
+    <comment>LZO archive</comment>
+    <acronym>LZO</acronym>
+    <expanded-acronym>Lempel-Ziv-Oberhumer</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" offset="0"/>
+    </magic>
+    <glob pattern="*.lzo"/>
+  </mime-type>
+  <mime-type type="application/x-qpress">
+    <comment>Qpress archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="qpress10" offset="0"/>
+    </magic>
+    <glob pattern="*.qp"/>
+  </mime-type>
+  <mime-type type="application/x-xar">
+    <comment>XAR archive</comment>
+    <acronym>XAR</acronym>
+    <expanded-acronym>eXtensible ARchive</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="big32" value="0x78617221" offset="0"/>
+    </magic>
+    <glob pattern="*.xar"/>
+    <!-- OS X 10.5+ installer package -->
+    <glob pattern="*.pkg"/>
+  </mime-type>
+  <mime-type type="application/zlib">
+    <comment>Zlib archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.zz"/>
+  </mime-type>
+  <mime-type type="application/x-magicpoint">
+    <comment>MagicPoint presentation</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-presentation"/>
+    <glob pattern="*.mgp"/>
+  </mime-type>
+  <mime-type type="application/x-macbinary">
+    <comment>Macintosh MacBinary file</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="mBIN" offset="102"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-matroska">
+    <comment>Matroska stream</comment>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <!-- EBML ID -->
+      <match type="big32" value="0x1a45dfa3" offset="0">
+        <!-- DocumentType ID -->
+        <match type="big16" value="0x4282" offset="5:65">
+          <!-- DocumentType -->
+          <match type="string" value="matroska" offset="8:75"/>
+        </match>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="video/x-matroska">
+    <comment>Matroska video</comment>
+    <glob pattern="*.mkv"/>
+    <sub-class-of type="application/x-matroska"/>
+  </mime-type>
+  <mime-type type="video/x-matroska-3d">
+    <comment>Matroska 3D video</comment>
+    <glob pattern="*.mk3d"/>
+    <sub-class-of type="application/x-matroska"/>
+  </mime-type>
+  <mime-type type="audio/x-matroska">
+    <comment>Matroska audio</comment>
+    <glob pattern="*.mka"/>
+    <sub-class-of type="application/x-matroska"/>
+  </mime-type>
+  <mime-type type="video/webm">
+    <comment>WebM video</comment>
+    <glob pattern="*.webm"/>
+    <magic>
+      <!-- EBML ID -->
+      <match type="big32" value="0x1a45dfa3" offset="0">
+        <!-- DocumentType ID -->
+        <match type="big16" value="0x4282" offset="5:65">
+          <!-- DocumentType -->
+          <match type="string" value="webm" offset="8:75"/>
+        </match>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="audio/webm">
+    <comment>WebM audio</comment>
+    <sub-class-of type="video/webm"/>
+  </mime-type>
+  <mime-type type="application/x-mimearchive">
+    <comment>MHTML web archive</comment>
+    <acronym>MHTML</acronym>
+    <expanded-acronym>MIME HTML</expanded-acronym>
+    <glob pattern="*.mhtml"/>
+    <glob pattern="*.mht"/>
+    <sub-class-of type="multipart/related"/>
+  </mime-type>
+  <mime-type type="application/mxf">
+    <comment>MXF video</comment>
+    <acronym>MXF</acronym>
+    <expanded-acronym>Material Exchange Format</expanded-acronym>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02\x01\x01\x02" offset="0:256"/>
+    </magic>
+    <glob pattern="*.mxf"/>
+  </mime-type>
+  <mime-type type="text/x-ocl">
+    <comment>OCL file</comment>
+    <acronym>OCL</acronym>
+    <expanded-acronym>Object Constraint Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.ocl"/>
+  </mime-type>
+  <mime-type type="text/x-cobol">
+    <comment>COBOL source code</comment>
+    <acronym>COBOL</acronym>
+    <expanded-acronym>COmmon Business Oriented Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.cbl"/>
+    <glob pattern="*.cob"/>
+  </mime-type>
+  <mime-type type="application/x-mobipocket-ebook">
+    <comment>Mobipocket e-book</comment>
+    <sub-class-of type="application/vnd.palm"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.mobi"/>
+    <glob pattern="*.prc"/>
+    <magic priority="30">
+      <!-- This also matches AportisDoc, so lower the priority and prefer extension -->
+      <match type="string" offset="60" value="TEXtREAd" />
+    </magic>
+    <magic priority="80">
+      <match type="string" offset="60" value="BOOKMOBI" />
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-mif">
+    <comment>Adobe FrameMaker MIF document</comment>
+    <glob pattern="*.mif"/>
+  </mime-type>
+  <mime-type type="application/x-mozilla-bookmarks">
+    <comment>Mozilla bookmarks</comment>
+    <sub-class-of type="text/html"/>
+    <generic-icon name="text-html"/>
+    <magic priority="80">
+      <match type="string" value="&lt;!DOCTYPE NETSCAPE-Bookmark-file-1&gt;" offset="0:64"/>
+    </magic>
+    <alias type="application/x-netscape-bookmarks"/>
+  </mime-type>
+  <mime-type type="application/x-ms-dos-executable">
+    <comment>DOS/Windows executable</comment>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="MZ" offset="0"/>
+    </magic>
+    <glob pattern="*.exe"/>
+  </mime-type>
+  <mime-type type="application/x-mswinurl">
+    <comment>Internet shortcut</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="InternetShortcut" offset="1"/>
+      <match type="string" value="DEFAULT" offset="1">
+        <match type="string" value="BASEURL=" offset="11"/>
+      </match>
+    </magic>
+    <glob pattern="*.url"/>
+  </mime-type>
+  <mime-type type="application/x-mswrite">
+    <comment>WRI document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.wri"/>
+  </mime-type>
+  <mime-type type="application/x-msx-rom">
+    <comment>MSX ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.msx"/>
+  </mime-type>
+  <mime-type type="application/x-m4">
+    <comment>M4 macro</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.m4"/>
+  </mime-type>
+  <mime-type type="application/x-n64-rom">
+    <comment>Nintendo64 ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.n64"/>
+    <glob pattern="*.z64"/>
+    <glob pattern="*.v64"/>
+    <magic>
+      <!-- native *.z64 -->
+      <match type="big32" offset="0" value="0x80371240"/>
+      <!-- byteswapped [BADC] *.v64 -->
+      <match type="big32" offset="0" value="0x37804012"/>
+      <!-- wordswapped [DCBA] *.n64 -->
+      <match type="big32" offset="0" value="0x40123780"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-nautilus-link">
+    <comment>Nautilus link</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;nautilus_object nautilus_link" offset="0:32"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-neo-geo-pocket-rom">
+    <comment>Neo-Geo Pocket ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.ngp"/>
+    <magic>
+      <match offset="35" type="byte" value="0x0">
+        <match offset="0" type="string" value="COPYRIGHT BY SNK CORPORATION"/>
+        <match offset="0" type="string" value=" LICENSED BY SNK CORPORATION"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-neo-geo-pocket-color-rom">
+    <comment>Neo-Geo Pocket Color ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.ngc"/>
+    <magic>
+      <match offset="35" type="byte" value="0x10">
+        <match offset="0" type="string" value="COPYRIGHT BY SNK CORPORATION"/>
+        <match offset="0" type="string" value=" LICENSED BY SNK CORPORATION"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-nes-rom">
+    <!-- Translate this to Famicom if the console was known as such in your locale -->
+    <comment>NES ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.nes"/>
+    <glob pattern="*.nez"/>
+    <glob pattern="*.unf"/>
+    <glob pattern="*.unif"/>
+  </mime-type>
+  <mime-type type="application/x-netcdf">
+    <comment>Unidata NetCDF document</comment>
+    <acronym>NetCDF</acronym>
+    <expanded-acronym>Network Common Data Form</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cdf"/>
+    <glob pattern="*.nc"/>
+  </mime-type>
+  <mime-type type="application/x-nzb">
+    <comment>NewzBin usenet index</comment>
+    <sub-class-of type="application/xml"/>
+    <magic priority="80">
+      <match type="string" value="&lt;nzb" offset="0:256"/>
+    </magic>
+    <glob pattern="*.nzb"/>
+  </mime-type>
+  <mime-type type="application/x-object">
+    <comment>object code</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="1" offset="5">
+          <match type="little16" value="1" offset="16"/>
+        </match>
+      </match>
+      <match type="string" value="\177ELF" offset="0">
+        <match type="byte" value="2" offset="5">
+          <match type="big16" value="1" offset="16"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.o"/>
+    <glob pattern="*.mod" weight="40"/>
+  </mime-type>
+  <mime-type type="application/annodex">
+    <comment>Annodex exchange format</comment>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="fishead\0" offset="28">
+          <match type="string" value="CMML\0\0\0\0" offset="56:512"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.anx"/>
+    <alias type="application/x-annodex"/>
+  </mime-type>
+  <mime-type type="video/annodex">
+    <comment>Annodex video</comment>
+    <sub-class-of type="application/annodex"/>
+    <magic>
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="fishead\0" offset="28">
+          <match type="string" value="CMML\0\0\0\0" offset="56:512"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.axv"/>
+    <alias type="video/x-annodex"/>
+  </mime-type>
+  <mime-type type="audio/annodex">
+    <comment>Annodex audio</comment>
+    <sub-class-of type="application/annodex"/>
+    <magic>
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="fishead\0" offset="28">
+          <match type="string" value="CMML\0\0\0\0" offset="56:512"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.axa"/>
+    <alias type="audio/x-annodex"/>
+  </mime-type>
+  <mime-type type="application/ogg">
+    <comment>Ogg multimedia file</comment>
+    <generic-icon name="video-x-generic"/>
+    <alias type="application/x-ogg"/>
+    <magic>
+      <match type="string" value="OggS" offset="0"/>
+    </magic>
+    <glob pattern="*.ogx"/>
+  </mime-type>
+  <mime-type type="audio/ogg">
+    <comment>Ogg audio</comment>
+    <sub-class-of type="application/ogg"/>
+    <magic>
+      <match type="string" value="OggS" offset="0"/>
+    </magic>
+    <glob pattern="*.oga"/>
+    <glob pattern="*.ogg"/>
+    <glob pattern="*.opus"/>
+    <alias type="audio/x-ogg"/>
+  </mime-type>
+  <mime-type type="video/ogg">
+    <comment>Ogg video</comment>
+    <sub-class-of type="application/ogg"/>
+    <magic>
+      <match type="string" value="OggS" offset="0"/>
+    </magic>
+    <glob pattern="*.ogv"/>
+    <glob pattern="*.ogg"/>
+    <alias type="video/x-ogg"/>
+  </mime-type>
+  <mime-type type="audio/x-vorbis+ogg">
+    <comment>Ogg Vorbis audio</comment>
+    <sub-class-of type="audio/ogg"/>
+    <alias type="audio/vorbis"/>
+    <alias type="audio/x-vorbis"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="\x01vorbis" offset="28"/>
+      </match>
+    </magic>
+    <glob pattern="*.oga"/>
+    <glob pattern="*.ogg"/>
+  </mime-type>
+  <mime-type type="audio/x-flac+ogg">
+    <comment>Ogg FLAC audio</comment>
+    <sub-class-of type="audio/ogg"/>
+    <alias type="audio/x-oggflac"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="fLaC" offset="28"/>
+      </match>
+      <match value="OggS" type="string" offset="0">
+        <match value="\177FLAC" type="string" offset="28"/>
+      </match>
+    </magic>
+    <glob pattern="*.oga"/>
+    <glob pattern="*.ogg"/>
+  </mime-type>
+  <mime-type type="audio/x-opus+ogg">
+    <comment>Opus audio</comment>
+    <sub-class-of type="audio/ogg"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="OpusHead" offset="28"/>
+      </match>
+    </magic>
+    <glob pattern="*.opus"/>
+  </mime-type>
+  <mime-type type="audio/x-speex+ogg">
+    <comment>Ogg Speex audio</comment>
+    <sub-class-of type="audio/ogg"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="Speex  " offset="28"/>
+      </match>
+    </magic>
+    <glob pattern="*.oga"/>
+    <glob pattern="*.ogg"/>
+    <glob pattern="*.spx"/>
+  </mime-type>
+  <mime-type type="audio/x-speex">
+    <comment>Speex audio</comment>
+    <magic>
+      <match type="string" value="Speex" offset="0"/>
+    </magic>
+    <glob pattern="*.spx"/>
+  </mime-type>
+  <mime-type type="video/x-theora+ogg">
+    <comment>Ogg Theora video</comment>
+    <sub-class-of type="video/ogg"/>
+    <alias type="video/x-theora"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="\x80theora" offset="28"/>
+      </match>
+    </magic>
+    <glob pattern="*.ogg"/>
+  </mime-type>
+  <mime-type type="video/x-ogm+ogg">
+    <comment>OGM video</comment>
+    <sub-class-of type="video/ogg"/>
+    <alias type="video/x-ogm"/>
+    <magic priority="80">
+      <match type="string" value="OggS" offset="0">
+        <match type="string" value="video" offset="29"/>
+      </match>
+    </magic>
+    <glob pattern="*.ogm"/>
+  </mime-type>
+  <!-- These are typically compount document of various types, so prefer
+       extensions for these -->
+  <mime-type type="application/x-ole-storage">
+    <comment>OLE2 compound document storage</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="\320\317\021\340\241\261\032\341" offset="0"/>
+      <match type="little32" value="0xe011cfd0" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/vnd.ms-publisher">
+    <comment>Microsoft Publisher document</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <glob pattern="*.pub"/>
+  </mime-type>
+  <mime-type type="application/x-msi">
+    <comment>Windows Installer package</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <glob pattern="*.msi"/>
+  </mime-type>
+  <mime-type type="application/x-oleo">
+    <comment>GNU Oleo spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="Oleo" offset="31"/>
+    </magic>
+    <glob pattern="*.oleo"/>
+  </mime-type>
+  <mime-type type="application/x-pak">
+    <comment>PAK archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="80">
+      <match offset="0" type="string" value="PACK" />
+    </magic>
+    <glob pattern="*.pak" />
+  </mime-type>
+  <mime-type type="application/vnd.palm">
+    <comment>Palm OS database</comment>
+    <glob pattern="*.prc"/>
+    <glob pattern="*.pdb"/>
+    <glob pattern="*.pqa"/>
+    <glob pattern="*.oprc"/>
+    <alias type="application/x-palm-database"/>
+  </mime-type>
+  <mime-type type="application/x-par2">
+    <comment>Parchive archive</comment>
+    <acronym>Parchive</acronym>
+    <expanded-acronym>Parity Volume Set Archive</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match offset="0" type="string" value="PAR2" />
+    </magic>
+    <glob pattern="*.PAR2" />
+    <glob pattern="*.par2" />
+  </mime-type>
+  <mime-type type="application/x-pef-executable">
+    <comment>PEF executable</comment>
+    <acronym>PEF</acronym>
+    <expanded-acronym>Preferred Executable Format</expanded-acronym>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match type="string" value="Joy!" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-perl">
+    <comment>Perl script</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <alias type="text/x-perl"/>
+    <magic>
+      <match type="string" value='eval \"exec /usr/local/bin/perl' offset="0"/>
+      <match type="string" value="/bin/perl" offset="2:16"/>
+      <match type="string" value="/bin/env perl" offset="2:16"/>
+      <match type="string" value="use Test::" offset="0:256"/>
+    </magic>
+    <magic priority="40">
+      <match type="string" value="use strict" offset="0:256"/>
+      <match type="string" value="use warnings" offset="0:256"/>
+      <match type="string" value="use diagnostics" offset="0:256"/>
+      <match type="string" value="\n=pod" offset="0:256"/>
+      <match type="string" value="\n=head1 NAME" offset="0:256"/>
+      <match type="string" value="\n=head1 DESCRIPTION" offset="0:256"/>
+      <match type="string" value="BEGIN {" offset="0:256"/>
+    </magic>
+    <glob pattern="*.pl"/>
+    <glob pattern="*.PL"/><!-- CPAN-style Perl build script -->
+    <glob pattern="*.pm"/><!-- module -->
+    <glob pattern="*.al"/><!-- autoloader -->
+    <glob pattern="*.perl"/>
+    <glob pattern="*.pod"/><!-- documentation -->
+    <glob pattern="*.t" weight="10"/><!-- CPAN-style Perl test script -->
+  </mime-type>
+  <mime-type type="application/x-php">
+    <comment>PHP script</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <magic priority="80">
+      <match type="string" value="&lt;?php" offset="0:64"/>
+    </magic>
+    <glob pattern="*.php"/>
+    <glob pattern="*.php3"/>
+    <glob pattern="*.php4"/>
+    <glob pattern="*.php5"/>
+    <glob pattern="*.phps"/>
+  </mime-type>
+  <mime-type type="application/x-pkcs7-certificates">
+    <comment>PKCS#7 certificate bundle</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <glob pattern="*.p7b"/>
+    <glob pattern="*.spc"/>
+  </mime-type>
+  <mime-type type="application/pkcs12">
+    <comment>PKCS#12 certificate bundle</comment>
+    <acronym>PKCS</acronym>
+    <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+    <glob pattern="*.p12"/>
+    <glob pattern="*.pfx"/>
+    <alias type="application/x-pkcs12"/>
+  </mime-type>
+  <mime-type type="application/x-planperfect">
+    <comment>PlanPerfect spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.pln"/>
+  </mime-type>
+  <mime-type type="application/x-pocket-word">
+    <comment>Pocket Word document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="{\\pwi" offset="0"/>
+    </magic>
+    <glob pattern="*.psw"/>
+  </mime-type>
+  <mime-type type="application/x-profile">
+    <comment>profiler results</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="gmon.out"/>
+  </mime-type>
+  <mime-type type="application/x-pw">
+    <comment>Pathetic Writer document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.pw"/>
+  </mime-type>
+  <mime-type type="application/x-python-bytecode">
+    <comment>Python bytecode</comment>
+    <magic>
+      <match type="big32" value="0x994e0d0a" offset="0"/>
+    </magic>
+    <glob pattern="*.pyc"/>
+    <glob pattern="*.pyo"/>
+  </mime-type>
+  <mime-type type="application/x-qtiplot">
+    <comment>QtiPlot document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match value="QtiPlot" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.qti"/>
+    <glob pattern="*.qti.gz"/>
+  </mime-type>
+  <mime-type type="application/x-quattropro">
+    <comment>Quattro Pro spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.wb1"/>
+    <glob pattern="*.wb2"/>
+    <glob pattern="*.wb3"/>
+  </mime-type>
+  <mime-type type="application/x-quicktime-media-link">
+    <comment>QuickTime playlist</comment>
+    <generic-icon name="video-x-generic"/>
+    <sub-class-of type="video/quicktime"/>
+    <alias type="application/x-quicktimeplayer"/>
+    <magic priority="60">
+      <match value="&lt;?xml" type="string" offset="0">
+        <match type="string" value="&lt;?quicktime" offset="0:64"/>
+      </match>
+      <match value="RTSPtext" type="string" offset="0"/>
+      <match value="rtsptext" type="string" offset="0"/>
+      <match value="SMILtext" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.qtl"/>
+  </mime-type>
+  <mime-type type="application/x-qw">
+    <comment>Quicken document</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.qif"/>
+  </mime-type>
+  <mime-type type="application/vnd.rar">
+    <comment>RAR archive</comment>
+    <acronym>RAR</acronym>
+    <expanded-acronym>Roshal ARchive</expanded-acronym>
+    <alias type="application/x-rar"/>
+    <alias type="application/x-rar-compressed"/>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="Rar!" offset="0"/>
+    </magic>
+    <glob pattern="*.rar"/>
+  </mime-type>
+  <mime-type type="application/x-dar">
+    <comment>DAR archive</comment>
+    <acronym>DAR</acronym>
+    <expanded-acronym>Disk ARchive</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="big32" value="123" offset="0"/>
+    </magic>
+    <glob pattern="*.dar"/>
+  </mime-type>
+  <mime-type type="application/x-alz">
+    <comment>Alzip archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="ALZ" offset="0"/>
+    </magic>
+    <glob pattern="*.alz"/>
+  </mime-type>
+  <mime-type type="text/x-reject">
+    <comment>rejected patch</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <alias type="application/x-reject"/>
+    <glob pattern="*.rej"/>
+  </mime-type>
+  <mime-type type="application/x-rpm">
+    <comment>RPM package</comment>
+    <generic-icon name="package-x-generic"/>
+    <alias type="application/x-redhat-package-manager" />
+    <magic>
+      <match type="string" value="\xed\xab\xee\xdb" offset="0"/>
+    </magic>
+    <glob pattern="*.rpm"/>
+  </mime-type>
+  <mime-type type="application/x-source-rpm">
+    <comment>Source RPM package</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/x-rpm"/>
+    <glob pattern="*.src.rpm"/>
+    <glob pattern="*.spm"/>
+  </mime-type>
+  <mime-type type="application/x-ruby">
+    <comment>Ruby script</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <magic>
+      <match type="string" value="/bin/env ruby" offset="2:16"/>
+      <match type="string" value="/bin/ruby" offset="2:16"/>
+    </magic>
+    <glob pattern="*.rb"/>
+  </mime-type>
+  <mime-type type="application/x-markaby">
+    <comment>Markaby script</comment>
+    <sub-class-of type="application/x-ruby"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.mab"/>
+  </mime-type>
+  <mime-type type="text/x-crystal">
+    <comment>Crystal source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.cr"/>
+    <alias type="text/crystal"/>
+  </mime-type>
+  <mime-type type="text/rust">
+    <comment>Rust source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.rs"/>
+  </mime-type>
+  <mime-type type="application/x-sc">
+    <comment>SC/Xspread spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic>
+      <match type="string" value="Spreadsheet" offset="38"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-shar">
+    <comment>shell archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.shar"/>
+  </mime-type>
+  <mime-type type="application/x-shared-library-la">
+    <comment>libtool shared library</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.la"/>
+  </mime-type>
+  <mime-type type="application/x-sharedlib">
+    <comment>shared library</comment>
+    <magic>
+      <match type="little16" value="0603" offset="0">
+        <match type="little16" mask="030000" value="020000" offset="22"/>
+      </match>
+    </magic>
+    <glob pattern="*.so"/>
+    <glob weight="60" pattern="*.so.[0-9]*"/>
+  </mime-type>
+  <mime-type type="application/x-shellscript">
+    <comment>shell script</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="text/plain"/>
+    <alias type="text/x-sh"/>
+    <generic-icon name="text-x-script"/>
+    <magic>
+      <match type="string" value="# This is a shell archive" offset="10"/>
+      <match type="string" value="/bin/bash" offset="2:16"/>
+      <match type="string" value="/bin/nawk" offset="2:16"/>
+      <match type="string" value="/bin/zsh" offset="2:16"/>
+      <match type="string" value="/bin/sh" offset="2:16"/>
+      <match type="string" value="/bin/ksh" offset="2:16"/>
+      <match type="string" value="/bin/dash" offset="2:16"/>
+      <match type="string" value="/bin/env sh" offset="2:16"/>
+      <match type="string" value="/bin/env bash" offset="2:16"/>
+      <match type="string" value="/bin/env zsh" offset="2:16"/>
+      <match type="string" value="/bin/env ksh" offset="2:16"/>
+    </magic>
+    <glob pattern="*.sh"/>
+  </mime-type>
+  <mime-type type="application/vnd.adobe.flash.movie">
+    <comment>Shockwave Flash file</comment>
+    <alias type="application/x-shockwave-flash"/>
+    <alias type="application/futuresplash"/>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="FWS" offset="0"/>
+      <match type="string" value="CWS" offset="0"/>
+    </magic>
+    <glob pattern="*.swf"/>
+    <glob pattern="*.spl"/>
+  </mime-type>
+  <mime-type type="application/x-shorten">
+    <!-- translators: "Shorten" is the name of an audio codec -->
+    <comment>Shorten audio</comment>
+    <generic-icon name="audio-x-generic"/>
+    <magic>
+      <match type="string" value="ajkg" offset="0"/>
+    </magic>
+    <glob pattern="*.shn"/>
+    <alias type="audio/x-shorten"/>
+  </mime-type>
+  <mime-type type="application/x-siag">
+    <comment>Siag spreadsheet</comment>
+    <generic-icon name="x-office-spreadsheet"/>
+    <glob pattern="*.siag"/>
+  </mime-type>
+  <mime-type type="image/x-skencil">
+    <comment>Skencil document</comment>
+    <glob pattern="*.sk"/>
+    <glob pattern="*.sk1"/>
+    <magic>
+      <match type="string" value="##Sketch" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-slp">
+    <comment>Stampede package</comment>
+    <generic-icon name="package-x-generic"/>
+  </mime-type>
+  <mime-type type="application/x-sg1000-rom">
+    <comment>SG-1000 ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.sg"/>
+  </mime-type>
+  <mime-type type="application/x-sms-rom">
+    <!-- Translate this to "Master System/Mark III" if the console was known as such in your locale (probably only in Japan) --><!-- nocheck -->
+    <comment>Master System ROM</comment><!-- nocheck -->
+    <generic-icon name="application-x-executable"/>
+    <!-- Disabled, the magic would be too far into the file
+    <magic>
+      <match type="string" value="TMR SEGA" offset="32752">
+        <match type="byte" value="0x30" offset="32767" mask="0xf0"/>
+        <match type="byte" value="0x40" offset="32767" mask="0xf0"/>
+      </match>
+    </magic> -->
+    <glob pattern="*.sms"/>
+  </mime-type>
+  <mime-type type="application/x-gamegear-rom">
+    <comment>Game Gear ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <!-- Disabled, the magic would be too far into the file
+    <magic>
+      <match type="string" value="TMR SEGA" offset="32752">
+        <match type="byte" value="0x50" offset="32767" mask="0xf0"/>
+        <match type="byte" value="0x60" offset="32767" mask="0xf0"/>
+        <match type="byte" value="0x70" offset="32767" mask="0xf0"/>
+      </match>
+    </magic> -->
+    <glob pattern="*.gg"/>
+  </mime-type>
+  <mime-type type="application/vnd.nintendo.snes.rom">
+    <!-- Translate this as Super Famicom (in Far East Asia) or Super Nintendo (in Europe) if the console was known as such in your locale -->
+    <comment>Super NES ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <alias type="application/x-snes-rom"/>
+    <glob pattern="*.sfc"/>
+    <glob pattern="*.smc"/>
+  </mime-type>
+  <mime-type type="application/x-stuffit">
+    <comment>StuffIt archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <alias type="application/stuffit"/>
+    <alias type="application/x-sit"/>
+    <magic priority="60">
+      <match type="string" value="StuffIt " offset="0"/>
+      <match type="string" value="SIT!" offset="0"/>
+    </magic>
+    <glob pattern="*.sit"/>
+  </mime-type>
+  <mime-type type="application/x-subrip">
+    <comment>SubRip subtitles</comment>
+    <alias type="application/x-srt"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="1" offset="0">
+        <match type="string" value=" --> " offset="0:256"/>
+      </match>
+    </magic>
+    <glob pattern="*.srt"/>
+  </mime-type>
+  <mime-type type="text/vtt">
+    <comment>WebVTT subtitles</comment>
+    <acronym>VTT</acronym>
+    <expanded-acronym>Video Text Tracks</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="WEBVTT" offset="0"/>
+    </magic>
+    <glob pattern="*.vtt"/>
+  </mime-type>
+  <mime-type type="application/x-sami">
+    <comment>SAMI subtitles</comment>
+    <acronym>SAMI</acronym>
+    <expanded-acronym>Synchronized Accessible Media Interchange</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;SAMI&gt;" offset="0:256"/>
+    </magic>
+    <glob pattern="*.smi"/>
+    <glob pattern="*.sami"/>
+  </mime-type>
+  <mime-type type="text/x-microdvd">
+    <comment>MicroDVD subtitles</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="{1}" offset="0"/>
+      <match type="string" value="{0}" offset="0"/>
+      <match type="string" value="}{" offset="0:6"/>
+    </magic>
+    <glob pattern="*.sub"/>
+  </mime-type>
+  <mime-type type="text/x-mpl2">
+    <comment>MPlayer2 subtitles</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[1]" offset="0"/>
+      <match type="string" value="[0]" offset="0"/>
+      <match type="string" value="][" offset="0:6"/>
+    </magic>
+    <glob pattern="*.mpl"/>
+  </mime-type>
+  <mime-type type="text/x-mpsub">
+    <comment>MPSub subtitles</comment>
+    <acronym>MPSub</acronym>
+    <expanded-acronym>MPlayer Subtitle</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="FORMAT=" offset="0:256"/>
+    </magic>
+    <glob pattern="*.sub"/>
+  </mime-type>
+  <mime-type type="text/x-ssa">
+    <comment>SSA subtitles</comment>
+    <acronym>SSA</acronym>
+    <expanded-acronym>SubStation Alpha</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[Script Info]" offset="0:256"/>
+      <match type="string" value="Dialogue: " offset="0:256"/>
+    </magic>
+    <glob pattern="*.ssa"/>
+    <glob pattern="*.ass"/>
+  </mime-type>
+  <mime-type type="text/x-subviewer">
+    <comment>SubViewer subtitles</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[INFORMATION]" offset="0"/>
+    </magic>
+    <glob pattern="*.sub"/>
+  </mime-type>
+  <mime-type type="text/x-iMelody">
+    <comment>iMelody ringtone</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="BEGIN:IMELODY" offset="0"/>
+    </magic>
+    <glob pattern="*.imy"/>
+    <glob pattern="*.ime"/>
+    <alias type="audio/x-iMelody"/>
+    <alias type="audio/iMelody" />
+  </mime-type>
+  <mime-type type="application/vnd.smaf">
+    <comment>SMAF audio</comment>
+    <acronym>SMAF</acronym>
+    <expanded-acronym>Synthetic music Mobile Application Format</expanded-acronym>
+    <generic-icon name="audio-x-generic"/>
+    <magic>
+      <match type="string" value="MMMD" offset="0"/>
+    </magic>
+    <glob pattern="*.mmf"/>
+    <glob pattern="*.smaf"/>
+    <alias type="application/x-smaf"/>
+  </mime-type>
+  <mime-type type="text/x-mrml">
+    <comment>MRML playlist</comment>
+    <acronym>MRML</acronym>
+    <expanded-acronym>Multimedia Retrieval Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <magic>
+      <match type="string" value="&lt;mrml " offset="0"/>
+    </magic>
+    <glob pattern="*.mrml"/>
+    <glob pattern="*.mrl"/>
+  </mime-type>
+  <mime-type type="audio/x-xmf">
+    <comment>XMF audio</comment>
+    <acronym>XMF</acronym>
+    <expanded-acronym>eXtensible Music Format</expanded-acronym>
+    <magic>
+      <match type="string" value="XMF_" offset="0"/>
+    </magic>
+    <glob pattern="*.xmf"/>
+    <alias type="audio/xmf"/>
+  </mime-type>
+  <mime-type type="audio/mobile-xmf">
+    <comment>Mobile XMF audio</comment>
+    <acronym>XMF</acronym>
+    <expanded-acronym>eXtensible Music Format</expanded-acronym>
+    <magic>
+      <match type="string" value="\130\115\106\137\062\056\060\060\000\000\000\002" offset="0"/>
+    </magic>
+    <glob pattern="*.mxmf"/>
+    <alias type="audio/vnd.nokia.mobile-xmf"/>
+  </mime-type>
+  <mime-type type="application/x-sv4cpio">
+    <comment>SV4 CPIO archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.sv4cpio"/>
+  </mime-type>
+  <mime-type type="application/x-sv4crc">
+    <comment>SV4 CPIO archive (with CRC)</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.sv4crc"/>
+  </mime-type>
+  <mime-type type="application/x-tar">
+    <comment>Tar archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <alias type="application/x-gtar"/>
+    <magic priority="60">
+      <match type="string" value="ustar\0" offset="257"/>
+      <match type="string" value="ustar\040\040\0" offset="257"/>
+    </magic>
+    <glob pattern="*.tar"/>
+    <glob pattern="*.gtar"/>
+    <glob pattern="*.gem"/>
+  </mime-type>
+  <mime-type type="application/x-tarz">
+    <comment>Tar archive (compressed)</comment>
+    <sub-class-of type="application/x-compress"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.tar.Z"/>
+    <glob pattern="*.taz"/>
+  </mime-type>
+  <mime-type type="application/x-tex-gf">
+    <comment>generic font file</comment>
+    <generic-icon name="font-x-generic"/>
+    <glob pattern="*.gf"/>
+  </mime-type>
+  <mime-type type="application/x-tex-pk">
+    <comment>packed font file</comment>
+    <generic-icon name="font-x-generic"/>
+    <glob pattern="*.pk"/>
+  </mime-type>
+  <mime-type type="application/x-tgif">
+    <comment>TGIF document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="%TGIF" offset="0"/>
+    </magic>
+    <glob pattern="*.obj"/>
+  </mime-type>
+  <mime-type type="application/x-theme">
+    <comment>theme</comment>
+    <sub-class-of type="application/x-desktop"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.theme"/>
+  </mime-type>
+  <mime-type type="application/x-toutdoux">
+    <comment>ToutDoux document</comment>
+    <generic-icon name="x-office-document"/>
+  </mime-type>
+  <mime-type type="application/x-trash">
+    <comment>backup file</comment>
+    <glob pattern="*~"/>
+    <glob pattern="*%"/>
+    <glob pattern="*.bak"/>
+    <glob pattern="*.old"/>
+    <glob pattern="*.sik"/>
+  </mime-type>
+  <mime-type type="text/troff">
+    <comment>Troff document</comment>
+    <sub-class-of type="text/plain"/>
+    <alias type="application/x-troff"/>
+    <alias type="text/x-troff"/>
+    <magic>
+      <match type="string" value='.\\\"' offset="0"/>
+      <match type="string" value="'\\\&quot;" offset="0"/>
+      <match type="string" value="'.\\\&quot;" offset="0"/>
+      <match type="string" value='\\\"' offset="0"/>
+    </magic>
+    <glob pattern="*.tr"/>
+    <glob pattern="*.roff"/>
+    <glob weight="10" pattern="*.t"/>
+  </mime-type>
+  <mime-type type="application/x-troff-man">
+    <comment>Manual page</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.man"/>
+    <glob pattern="*.[1-9]"/>
+  </mime-type>
+  <mime-type type="application/x-troff-man-compressed">
+    <comment>Manual page (compressed)</comment>
+    <generic-icon name="text-x-generic"/>
+  </mime-type>
+  <mime-type type="application/x-tzo">
+    <comment>Tar archive (LZO-compressed)</comment>
+    <sub-class-of type="application/x-lzop"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.tar.lzo"/>
+    <glob pattern="*.tzo"/>
+  </mime-type>
+  <mime-type type="application/x-xz">
+    <comment>XZ archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="\xfd\x37\x7a\x58\x5a\x00" offset="0"/>
+    </magic>
+    <glob pattern="*.xz"/>
+  </mime-type>
+  <mime-type type="application/x-xz-compressed-tar">
+    <comment>Tar archive (XZ-compressed)</comment>
+    <sub-class-of type="application/x-xz"/>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.tar.xz"/>
+    <glob pattern="*.txz"/>
+  </mime-type>
+  <mime-type type="application/zstd">
+    <comment>Zstandard archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="little32" value="0xFD2FB528" offset="0"/>
+    </magic>
+    <glob pattern="*.zst"/>
+  </mime-type>
+  <mime-type type="application/x-zstd-compressed-tar">
+    <comment>Tar archive (Zstandard-compressed)</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="application/zstd"/>
+    <glob pattern="*.tar.zst"/>
+    <glob pattern="*.tzst"/>
+  </mime-type>
+  <mime-type type="application/x-xzpdf">
+    <comment>PDF document (XZ-compressed)</comment>
+    <sub-class-of type="application/x-xz"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.pdf.xz"/>
+  </mime-type>
+  <mime-type type="application/x-ustar">
+    <comment>Ustar archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <glob pattern="*.ustar"/>
+  </mime-type>
+  <mime-type type="application/x-wais-source">
+    <comment>WAIS source code</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.src"/>
+  </mime-type>
+  <mime-type type="application/x-wpg">
+    <comment>WordPerfect/Drawperfect image</comment>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.wpg"/>
+  </mime-type>
+  <mime-type type="application/x-wonderswan-rom">
+    <comment>Bandai WonderSwan ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.ws"/>
+  </mime-type>
+  <mime-type type="application/x-wonderswan-color-rom">
+    <comment>Bandai WonderSwan Color ROM</comment>
+    <generic-icon name="application-x-executable"/>
+    <glob pattern="*.wsc"/>
+  </mime-type>
+  <mime-type type="application/x-x509-ca-cert">
+    <comment>DER/PEM/Netscape-encoded X.509 certificate</comment>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="-----BEGIN CA CERTIFICATE-----" offset="0"/>
+      <match type="string" value="-----BEGIN TRUSTED CERTIFICATE-----" offset="0"/>
+    </magic>
+    <glob pattern="*.der"/>
+    <glob pattern="*.crt"/>
+    <glob pattern="*.cert"/>
+    <glob pattern="*.pem"/>
+  </mime-type>
+  <mime-type type="application/x-zerosize">
+    <comment>empty document</comment>
+  </mime-type>
+  <mime-type type="application/x-zoo">
+    <comment>Zoo archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="little32" value="0xfdc4a7dc" offset="20"/>
+    </magic>
+    <glob pattern="*.zoo"/>
+  </mime-type>
+  <mime-type type="application/xhtml+xml">
+    <comment>XHTML page</comment>
+    <acronym>XHTML</acronym>
+    <expanded-acronym>Extensible HyperText Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-html"/>
+    <glob pattern="*.xhtml"/>
+    <glob pattern="*.xht"/>
+    <glob pattern="*.html"/>
+    <glob pattern="*.htm"/>
+    <magic priority="60">
+      <match type="string" value="//W3C//DTD XHTML " offset="0:256"/>
+      <match type="string" value="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" offset="0:256"/>
+      <match type="string" value="&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
+      <match type="string" value="&lt;HTML xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
+    </magic>
+    <root-XML namespaceURI='http://www.w3.org/1999/xhtml' localName='html'/>
+  </mime-type>
+  <mime-type type="application/zip">
+    <comment>Zip archive</comment>
+    <alias type="application/x-zip-compressed"/>
+    <alias type="application/x-zip"/>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="PK\003\004" offset="0"/>
+    </magic>
+    <glob pattern="*.zip"/>
+    <glob pattern="*.zipx"/>
+  </mime-type>
+  <mime-type type="application/x-ms-wim">
+    <comment>WIM disk image</comment>
+    <acronym>WIM</acronym>
+    <expanded-acronym>Windows Imaging Format</expanded-acronym>
+    <magic>
+      <match type="string" value="MSWIM\000\000\000" offset="0"/>
+    </magic>
+    <glob pattern="*.wim"/>
+    <glob pattern="*.swm"/>
+  </mime-type>
+  <mime-type type="audio/ac3">
+    <comment>Dolby Digital audio</comment>
+    <magic>
+      <match type="big16" value="0x0b77" offset="0"/>
+    </magic>
+    <glob pattern="*.ac3"/>
+  </mime-type>
+  <mime-type type="audio/vnd.dts">
+    <comment>DTS audio</comment>
+    <acronym>DTS</acronym>
+    <expanded-acronym>Digital Theater Systems</expanded-acronym>
+    <magic>
+      <match type="big32" value="0x7FFE8001" offset="0"/> <!-- 16bits core be -->
+      <match type="little32" value="0xFE7F0180" offset="0"/> <!-- 16bits core le -->
+      <match type="big32" value="0x1FFFE800" offset="0"/> <!-- 14bits core be -->
+      <match type="little32" value="0xFF1F00E8" offset="0"/> <!-- 14bits core le -->
+    </magic>
+    <alias type="audio/x-dts"/>
+    <glob pattern="*.dts"/>
+  </mime-type>
+  <mime-type type="audio/vnd.dts.hd">
+    <comment>DTS-HD audio</comment>
+    <acronym>DTS-HD</acronym>
+    <expanded-acronym>Digital Theater Systems High Definition</expanded-acronym>
+    <sub-class-of type="audio/vnd.dts"/>
+    <magic priority="60">
+      <match type="big32" value="0x7FFE8001" offset="0"> <!-- 16bits core be -->
+        <match type="big32" value="0x64582025" offset="4:18725"/> <!-- 16bits HD be -->
+      </match>
+    </magic>
+    <alias type="audio/x-dtshd"/>
+    <glob pattern="*.dtshd"/>
+  </mime-type>
+  <mime-type type="audio/AMR">
+    <comment>AMR audio</comment>
+    <acronym>AMR</acronym>
+    <expanded-acronym>Adaptive Multi-Rate</expanded-acronym>
+    <magic>
+      <match type="string" value="#!AMR\n" offset="0"/>
+      <match type="string" value="#!AMR_MC1.0\n" offset="0"/>
+    </magic>
+    <glob pattern="*.amr"/>
+    <alias type="audio/amr-encrypted"/>
+  </mime-type>
+  <mime-type type="audio/AMR-WB">
+    <comment>AMR-WB audio</comment>
+    <acronym>AMR-WB</acronym>
+    <expanded-acronym>Adaptive Multi-Rate Wideband</expanded-acronym>
+    <magic>
+      <match type="string" value="#!AMR-WB\n" offset="0"/>
+      <match type="string" value="#!AMR-WB_MC1.0\n" offset="0"/>
+    </magic>
+    <glob pattern="*.awb"/>
+    <alias type="audio/amr-wb-encrypted"/>
+  </mime-type>
+  <mime-type type="audio/basic">
+    <comment>ULAW (Sun) audio</comment>
+    <magic priority="40">
+      <match type="string" value=".snd" offset="0"/>
+    </magic>
+    <glob pattern="*.au"/>
+    <glob pattern="*.snd"/>
+  </mime-type>
+  <mime-type type="audio/prs.sid">
+    <comment>Commodore 64 audio</comment>
+    <magic>
+      <match type="string" value="PSID" offset="0"/>
+    </magic>
+    <glob pattern="*.sid"/>
+    <glob pattern="*.psid"/>
+  </mime-type>
+  <mime-type type="audio/x-adpcm">
+    <comment>PCM audio</comment>
+    <acronym>PCM</acronym>
+    <expanded-acronym>Pulse-code Modulation</expanded-acronym>
+    <magic>
+      <match type="string" value=".snd" offset="0">
+        <match type="big32" value="23" offset="12"/>
+      </match>
+      <match type="little32" value="0x0064732E" offset="0">
+        <match type="little32" value="1" offset="12"/>
+        <match type="little32" value="2" offset="12"/>
+        <match type="little32" value="3" offset="12"/>
+        <match type="little32" value="4" offset="12"/>
+        <match type="little32" value="5" offset="12"/>
+        <match type="little32" value="6" offset="12"/>
+        <match type="little32" value="7" offset="12"/>
+        <match type="little32" value="23" offset="12"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="audio/x-aifc">
+    <comment>AIFC audio</comment>
+    <acronym>AIFC</acronym>
+    <expanded-acronym>Audio Interchange File format Compressed</expanded-acronym>
+    <sub-class-of type="application/x-iff"/>
+    <magic>
+      <match type="string" value="AIFC" offset="8"/>
+    </magic>
+    <glob pattern="*.aifc"/>
+    <glob pattern="*.aiffc"/>
+    <alias type="audio/x-aiffc"/>
+  </mime-type>
+  <mime-type type="audio/x-aiff">
+    <comment>AIFF/Amiga/Mac audio</comment>
+    <acronym>AIFF</acronym>
+    <expanded-acronym>Audio Interchange File Format</expanded-acronym>
+    <sub-class-of type="application/x-iff"/>
+    <magic>
+      <match type="string" value="AIFF" offset="8"/>
+      <match type="string" value="8SVX" offset="8"/>
+    </magic>
+    <glob pattern="*.aiff"/>
+    <glob pattern="*.aif"/>
+  </mime-type>
+  <mime-type type="audio/x-ape">
+    <comment>Monkey's audio</comment>
+    <magic>
+      <match type="string" value="MAC " offset="0"/>
+    </magic>
+    <glob pattern="*.ape"/>
+  </mime-type>
+  <mime-type type="audio/x-pn-audibleaudio">
+    <comment>Audible.Com audio</comment>
+    <magic>
+      <!-- https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/aadec.c#L33 --><!-- nocheck -->
+      <match type="big32" value="1469084982" offset="4"/>
+    </magic>
+    <glob pattern="*.aa"/>
+    <alias type="audio/vnd.audible"/>
+  </mime-type>
+  <mime-type type="audio/vnd.audible.aax">
+    <comment>Audible Enhanced audio</comment>
+    <magic>
+      <match type="string" value="ftypaax " offset="4"/>
+    </magic>
+    <glob pattern="*.aax"/>
+  </mime-type>
+  <mime-type type="audio/x-dff">
+    <comment>DSDIFF audio</comment>
+    <acronym>DSDIFF</acronym>
+    <expanded-acronym>Direct Stream Digital Interchange File Format</expanded-acronym>
+    <magic>
+      <!-- from https://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf -->
+      <match value="FRM8" type="string" offset="0">
+        <match value="DSD " type="string" offset="12"/>
+      </match>
+    </magic>
+    <glob pattern="*.dff"/>
+    <alias type="audio/dff"/>
+  </mime-type>
+  <mime-type type="audio/x-dsf">
+    <comment>DSF audio</comment>
+    <acronym>DSF</acronym>
+    <expanded-acronym>Direct stream digital Stream File</expanded-acronym>
+    <magic>
+      <!-- from https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf -->
+      <match value="DSD " type="string" offset="0">
+        <match value="fmt " type="string" offset="28">
+          <match value="data" type="string" offset="80"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.dsf"/>
+    <alias type="audio/dsf"/>
+    <!-- Problematic because some clients expect these mime types to be DSDIFF files -->
+    <alias type="audio/x-dsd"/>
+    <alias type="audio/dsd"/>
+  </mime-type>
+  <mime-type type="audio/x-it">
+    <comment>Impulse Tracker audio</comment>
+    <magic>
+      <match type="string" value="IMPM" offset="0"/>
+    </magic>
+    <glob pattern="*.it"/>
+  </mime-type>
+  <mime-type type="audio/flac">
+    <comment>FLAC audio</comment>
+    <acronym>FLAC</acronym>
+    <expanded-acronym>Free Lossless Audio Codec</expanded-acronym>
+    <magic>
+      <match value="fLaC" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.flac"/>
+    <alias type="audio/x-flac"/>
+  </mime-type>
+  <mime-type type="audio/x-tak">
+    <comment>TAK audio</comment>
+    <acronym>TAK</acronym>
+    <expanded-acronym>Tom's lossless Audio Kompressor</expanded-acronym>
+    <magic>
+      <match type="string" value="tBaK" offset="0"/>
+    </magic>
+    <glob pattern="*.tak"/>
+  </mime-type>
+  <mime-type type="audio/x-wavpack">
+    <comment>WavPack audio</comment>
+    <magic>
+      <match type="string" value="wvpk" offset="0"/>
+    </magic>
+    <glob pattern="*.wv"/>
+    <glob pattern="*.wvp"/>
+  </mime-type>
+  <mime-type type="audio/x-wavpack-correction">
+    <comment>WavPack audio correction file</comment>
+    <magic>
+      <match type="string" value="wvpk" offset="0"/>
+    </magic>
+    <glob pattern="*.wvc"/>
+  </mime-type>
+  <mime-type type="audio/midi">
+    <comment>MIDI audio</comment>
+    <acronym>MIDI</acronym>
+    <expanded-acronym>Musical Instrument Digital Interface</expanded-acronym>
+    <alias type="audio/x-midi"/>
+    <magic>
+      <match type="string" value="MThd" offset="0"/>
+    </magic>
+    <glob pattern="*.mid"/>
+    <glob pattern="*.midi"/>
+    <glob pattern="*.kar"/>
+  </mime-type>
+  <mime-type type="audio/x-mo3">
+    <comment>compressed Tracker audio</comment>
+    <magic>
+      <match type="string" value="MO3" offset="0"/>
+    </magic>
+    <glob pattern="*.mo3"/>
+  </mime-type>
+  <mime-type type="audio/aac">
+    <comment>AAC audio</comment>
+    <acronym>AAC</acronym>
+    <expanded-acronym>Advanced Audio Coding</expanded-acronym>
+    <magic>
+      <match type="string" value="ADIF" offset="0"/>
+      <match type="big16" value="0xFFF0" mask="0xFFF6" offset="0"/>
+    </magic>
+    <glob pattern="*.aac"/>
+    <glob pattern="*.adts"/>
+    <glob pattern="*.ass" weight="10"/>
+    <alias type="audio/x-aac"/>
+  </mime-type>
+  <mime-type type="audio/usac">
+    <comment>USAC audio</comment>
+    <acronym>USAC</acronym>
+    <expanded-acronym>Unified Speech and Audio Coding</expanded-acronym>
+    <glob pattern="*.loas"/>
+    <glob pattern="*.xhe"/>
+  </mime-type>
+  <mime-type type="audio/mp4">
+    <comment>MPEG-4 audio</comment>
+    <alias type="audio/x-m4a"/>
+    <alias type="audio/m4a"/>
+    <magic>
+      <match type="string" value="ftypM4A" offset="4"/>
+    </magic>
+    <glob pattern="*.m4a"/>
+    <glob pattern="*.f4a"/>
+  </mime-type>
+  <mime-type type="audio/x-m4r">
+    <comment>MPEG-4 ringtone</comment>
+    <glob pattern="*.m4r"/>
+    <sub-class-of type="video/mp4"/>
+  </mime-type>
+  <mime-type type="video/mp4">
+    <comment>MPEG-4 video</comment>
+    <alias type="video/mp4v-es"/>
+    <magic>
+      <match type="string" value="ftypisom" offset="4"/>
+      <match type="string" value="ftypmp41" offset="4"/>
+      <match type="string" value="ftypmp42" offset="4"/>
+      <match type="string" value="ftypMSNV" offset="4"/>
+      <match type="string" value="ftypM4V " offset="4"/>
+      <match type="string" value="ftypf4v " offset="4"/>
+    </magic>
+    <glob pattern="*.mp4"/>
+    <glob pattern="*.m4v"/>
+    <glob pattern="*.f4v"/>
+    <glob pattern="*.lrv"/>
+    <alias type="video/x-m4v"/>
+  </mime-type>
+  <mime-type type="audio/x-m4b">
+    <comment>MPEG-4 audio book</comment>
+    <sub-class-of type="audio/mp4"/>
+    <magic>
+      <match type="string" value="ftypM4B" offset="4"/>
+    </magic>
+    <glob pattern="*.m4b"/>
+    <glob pattern="*.f4b"/>
+  </mime-type>
+  <mime-type type="video/3gpp">
+    <comment>3GPP multimedia file</comment>
+    <acronym>3GPP</acronym>
+    <expanded-acronym>3rd Generation Partnership Project</expanded-acronym>
+    <sub-class-of type="video/mp4"/>
+    <magic>
+      <match type="string" value="ftyp3ge" offset="4"/>
+      <match type="string" value="ftyp3gg" offset="4"/>
+      <match type="string" value="ftyp3gp" offset="4"/>
+      <match type="string" value="ftyp3gs" offset="4"/>
+    </magic>
+    <glob pattern="*.3gp"/>
+    <glob pattern="*.3gpp"/>
+    <glob pattern="*.3ga"/>
+    <alias type="video/3gp"/>
+    <alias type="audio/3gpp"/>
+    <alias type="video/3gpp-encrypted"/>
+    <alias type="audio/3gpp-encrypted"/>
+    <alias type="audio/x-rn-3gpp-amr"/>
+    <alias type="audio/x-rn-3gpp-amr-encrypted"/>
+    <alias type="audio/x-rn-3gpp-amr-wb"/>
+    <alias type="audio/x-rn-3gpp-amr-wb-encrypted"/>
+  </mime-type>
+  <mime-type type="video/3gpp2">
+    <comment>3GPP2 multimedia file</comment>
+    <acronym>3GPP2</acronym>
+    <expanded-acronym>3rd Generation Partnership Project 2</expanded-acronym>
+    <magic>
+      <match type="string" value="ftyp3g2" offset="4"/>
+    </magic>
+    <glob pattern="*.3g2"/>
+    <glob pattern="*.3gp2"/>
+    <glob pattern="*.3gpp2"/>
+    <alias type="audio/3gpp2"/>
+  </mime-type>
+  <mime-type type="audio/x-mod">
+    <comment>Amiga SoundTracker audio</comment>
+    <magic priority="40">
+      <match type="string" value="MTM" offset="0"/>
+      <match type="string" value="MMD0" offset="0"/>
+      <match type="string" value="MMD1" offset="0"/>
+      <!-- 669 composer files: "if" and "JN" -->
+      <match type="byte" value="0x0" mask="0x80" offset="112">
+        <match type="string" value="if" offset="0">
+          <!-- tempo list last byte: 0-31 (0 = known false positive) -->
+          <match type="byte" value="0x0" mask="0xe0" offset="368">
+            <!-- number of samples: 0-63 -->
+            <match type="byte" value="0x0" mask="0xc0" offset="110">
+              <!-- number of patterns: 0-128 -->
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+            <!-- number of samples: 64 -->
+            <match type="byte" value="0x40" offset="110">
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+          </match>
+          <!-- tempo list last byte: 32 -->
+          <match type="byte" value="0x20" offset="368">
+            <!-- number of samples: 0-63 -->
+            <match type="byte" value="0x0" mask="0xc0" offset="110">
+              <!-- number of patterns: 0-128 -->
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+            <!-- number of samples: 64 -->
+            <match type="byte" value="0x40" offset="110">
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+          </match>
+        </match>
+        <match type="string" value="JN" offset="0">
+          <match type="byte" value="0x0" mask="0xe0" offset="368">
+            <match type="byte" value="0x0" mask="0xc0" offset="110">
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+          </match>
+          <match type="byte" value="0x20" offset="368">
+            <match type="byte" value="0x40" offset="110">
+              <match type="byte" value="0x0" mask="0x80" offset="111"/>
+              <match type="byte" value="0x80" offset="111"/>
+            </match>
+          </match>
+        </match>
+      </match>
+      <match type="string" value="MAS_UTrack_V00" offset="0"/>
+      <match type="string" value="M.K." offset="1080"/>
+      <match type="string" value="M!K!" offset="1080"/>
+    </magic>
+    <glob pattern="*.mod"/>
+    <glob pattern="*.ult"/>
+    <glob pattern="*.uni"/>
+    <glob pattern="*.m15"/>
+    <glob pattern="*.mtm"/>
+    <glob pattern="*.669"/>
+    <glob pattern="*.med"/>
+  </mime-type>
+  <mime-type type="audio/mp2">
+    <comment>MP2 audio</comment>
+    <alias type="audio/x-mp2"/>
+    <glob pattern="*.mp2"/>
+  </mime-type>
+  <mime-type type="audio/mpeg">
+    <comment>MP3 audio</comment>
+    <alias type="audio/x-mp3" />
+    <alias type="audio/x-mpg"/>
+    <alias type="audio/x-mpeg"/>
+    <alias type="audio/mp3"/>
+    <magic>
+      <match type="big16" value="0xfffa" offset="0"/>
+      <match type="big16" value="0xfffb" offset="0"/>
+      <match type="big16" value="0xfff3" offset="0"/>
+      <match type="big16" value="0xfff2" offset="0"/>
+      <match type="big16" value="0xffe3" offset="0"/>
+      <match type="big16" value="0xffe2" offset="0"/>
+      <match type="string" value="ID3" offset="0"/>
+    </magic>
+    <glob pattern="*.mp3"/>
+    <glob pattern="*.mpga"/>
+  </mime-type>
+  <mime-type type="audio/x-mpegurl">
+    <comment>Media playlist</comment>
+    <sub-class-of type="text/plain"/>
+    <alias type="audio/mpegurl" />
+    <alias type="application/m3u"/>
+    <alias type="audio/x-mp3-playlist"/>
+    <alias type="audio/m3u"/>
+    <alias type="audio/x-m3u"/>
+    <glob pattern="*.m3u"/>
+    <glob pattern="*.m3u8"/>
+    <glob pattern="*.vlc"/>
+    <magic>
+      <match type="string" value="#EXTM3U" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/vnd.apple.mpegurl">
+    <comment>Media playlist</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.m3u"/>
+    <glob pattern="*.m3u8"/>
+    <magic priority="70">
+      <match type="string" value="#EXTM3U" offset="0">
+        <match type="string" value="#EXT-X-TARGETDURATION" offset="0:128"/>
+        <match type="string" value="#EXT-X-STREAM-INF" offset="0:128"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="audio/x-ms-asx">
+    <comment>Microsoft ASX playlist</comment>
+    <alias type="video/x-ms-wvx"/>
+    <alias type="video/x-ms-wax"/>
+    <alias type="video/x-ms-wmx"/>
+    <alias type="application/x-ms-asx"/>
+    <glob pattern="*.asx"/>
+    <glob pattern="*.wax"/>
+    <glob pattern="*.wvx"/>
+    <glob pattern="*.wmx"/>
+    <magic priority="51">
+      <match type="string" value="ASF " offset="0"/>
+      <match type="string" value="&lt;ASX" offset="0:64"/>
+      <match type="string" value="&lt;asx" offset="0:64"/>
+      <match type="string" value="&lt;Asx" offset="0:64"/>
+    </magic>
+  </mime-type>
+  <mime-type type="audio/x-psf">
+    <comment>PSF audio</comment>
+    <acronym>PSF</acronym>
+    <expanded-acronym>Portable Sound Format</expanded-acronym>
+    <magic>
+      <match type="string" value="PSF" offset="0"/>
+    </magic>
+    <glob pattern="*.psf"/>
+  </mime-type>
+  <mime-type type="audio/x-minipsf">
+    <comment>MiniPSF audio</comment>
+    <acronym>MiniPSF</acronym>
+    <expanded-acronym>Miniature Portable Sound Format</expanded-acronym>
+    <sub-class-of type="audio/x-psf"/>
+    <glob pattern="*.minipsf"/>
+  </mime-type>
+  <mime-type type="audio/x-psflib">
+    <comment>PSFlib audio library</comment>
+    <acronym>PSFlib</acronym>
+    <expanded-acronym>Portable Sound Format Library</expanded-acronym>
+    <sub-class-of type="audio/x-psf"/>
+    <glob pattern="*.psflib"/>
+  </mime-type>
+  <mime-type type="audio/x-ms-wma">
+    <comment>Windows Media audio</comment>
+    <sub-class-of type="application/vnd.ms-asf"/>
+    <glob pattern="*.wma"/>
+    <alias type="audio/wma"/>
+  </mime-type>
+  <mime-type type="audio/x-musepack">
+    <comment>Musepack audio</comment>
+    <magic>
+      <match type="string" value="MP+" offset="0"/>
+      <match type="string" value="MPCK" offset="0"/>
+    </magic>
+    <glob pattern="*.mpc"/>
+    <glob pattern="*.mpp"/>
+    <glob pattern="*.mp+"/>
+  </mime-type>
+  <mime-type type="audio/vnd.rn-realaudio">
+    <comment>RealAudio document</comment>
+    <glob pattern="*.ra"/>
+    <glob pattern="*.rax"/>
+    <alias type="audio/x-pn-realaudio"/>
+    <alias type="audio/vnd.m-realaudio"/>
+  </mime-type>
+  <mime-type type="application/ram">
+    <comment>RealMedia playlist</comment>
+    <glob pattern="*.ram" />
+  </mime-type>
+  <mime-type type="video/vnd.rn-realvideo">
+    <comment>RealVideo document</comment>
+    <glob pattern="*.rv"/>
+    <glob pattern="*.rvx"/>
+    <alias type="video/x-real-video"/>
+  </mime-type>
+  <mime-type type="application/vnd.rn-realmedia">
+    <comment>RealMedia document</comment>
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value=".RMF" offset="0"/>
+    </magic>
+    <glob pattern="*.rm"/>
+    <glob pattern="*.rmj"/>
+    <glob pattern="*.rmm"/>
+    <glob pattern="*.rms"/>
+    <glob pattern="*.rmx"/>
+    <glob pattern="*.rmvb"/>
+    <alias type="application/vnd.rn-realmedia-vbr"/>
+  </mime-type>
+  <mime-type type="image/vnd.rn-realpix">
+    <comment>RealPix document</comment>
+    <glob pattern="*.rp"/>
+  </mime-type>
+  <mime-type type="text/vnd.rn-realtext">
+    <comment>RealText document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.rt"/>
+  </mime-type>
+  <mime-type type="audio/x-riff">
+    <comment>RIFF audio</comment>
+  </mime-type>
+  <mime-type type="application/x-riff">
+    <comment>RIFF container</comment>
+    <!-- need to be lower prio than avi -->
+    <magic priority="45">
+      <match type="string" value="RIFF" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="audio/x-s3m">
+    <comment>Scream Tracker 3 audio</comment>
+    <magic>
+      <match value="SCRM" type="string" offset="44"/>
+    </magic>
+    <glob pattern="*.s3m"/>
+  </mime-type>
+  <mime-type type="audio/x-scpls">
+    <comment>MP3 ShoutCast playlist</comment>
+    <alias type="application/pls"/>
+    <alias type="audio/scpls"/>
+    <magic>
+      <match type="string" value="[playlist]" offset="0"/>
+      <match type="string" value="[Playlist]" offset="0"/>
+      <match type="string" value="[PLAYLIST]" offset="0"/>
+    </magic>
+    <glob pattern="*.pls"/>
+  </mime-type>
+  <mime-type type="audio/x-stm">
+    <comment>Scream Tracker audio</comment>
+    <magic>
+      <match type="string" value="!Scream!\x1A" offset="20"/>
+      <match type="string" value="!SCREAM!\x1A" offset="20"/>
+      <match type="string" value="BMOD2STM\x1A" offset="20"/>
+    </magic>
+    <glob pattern="*.stm"/>
+  </mime-type>
+  <mime-type type="audio/x-voc">
+    <comment>VOC audio</comment>
+    <glob pattern="*.voc"/>
+  </mime-type>
+  <mime-type type="audio/x-wav">
+    <comment>WAV audio</comment>
+    <alias type="audio/wav"/>
+    <alias type="audio/vnd.wave"/>
+    <sub-class-of type="application/x-riff"/>
+    <magic>
+      <match type="string" value="WAVE" offset="8"/>
+      <match type="string" value="WAV " offset="8"/>
+    </magic>
+    <glob pattern="*.wav"/>
+  </mime-type>
+  <mime-type type="audio/x-xi">
+    <comment>Scream Tracker instrument</comment>
+    <magic>
+      <match value="Extended Instrument:" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.xi"/>
+  </mime-type>
+  <mime-type type="audio/x-xm">
+    <comment>FastTracker II audio</comment>
+    <magic>
+      <match value="Extended Module:" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.xm"/>
+  </mime-type>
+  <mime-type type="audio/x-tta">
+    <comment>TrueAudio audio</comment>
+    <alias type="audio/tta"/>
+    <magic>
+      <match value="TTA1" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.tta"/>
+  </mime-type>
+  <mime-type type="image/bmp">
+    <comment>Windows BMP image</comment>
+    <magic>
+      <match type="string" mask="0xffff00000000ffff" value="BMxxxx\000\000" offset="0"/>
+      <match type="string" value="BM" offset="0">
+        <match type="byte" value="12" offset="14"/>
+        <match type="byte" value="64" offset="14"/>
+        <match type="byte" value="40" offset="14"/>
+      </match>
+    </magic>
+    <glob pattern="*.bmp"/>
+    <glob pattern="*.dib"/>
+    <alias type="image/x-bmp"/>
+    <alias type="image/x-MS-bmp"/>
+  </mime-type>
+  <mime-type type="image/vnd.wap.wbmp">
+    <comment>WBMP image</comment>
+    <acronym>WBMP</acronym>
+    <expanded-acronym>WAP bitmap</expanded-acronym>
+    <glob pattern="*.wbmp"/>
+  </mime-type>
+  <mime-type type="image/cgm">
+    <comment>CGM image</comment>
+    <acronym>CGM</acronym>
+    <expanded-acronym>Computer Graphics Metafile</expanded-acronym>
+    <glob pattern="*.cgm"/>
+  </mime-type>
+  <mime-type type="image/g3fax">
+    <comment>CCITT G3 fax image</comment>
+    <acronym>CCITT</acronym>
+    <expanded-acronym>Comité Consultatif International Téléphonique et Télégraphique</expanded-acronym>
+    <glob pattern="*.g3"/>
+    <alias type="image/fax-g3"/>
+  </mime-type>
+  <mime-type type="image/gif">
+    <comment>GIF image</comment>
+    <acronym>GIF</acronym>
+    <expanded-acronym>Graphics Interchange Format</expanded-acronym>
+    <magic>
+      <match type="string" value="GIF8" offset="0"/>
+    </magic>
+    <glob pattern="*.gif"/>
+  </mime-type>
+  <mime-type type="image/heif">
+    <comment>HEIF image</comment>
+    <acronym>HEIF</acronym>
+    <expanded-acronym>High Efficiency Image File</expanded-acronym>
+    <magic priority="40"><!-- less than AVIF due to ftypmif1 -->
+      <match type="string" value="ftypmif1" offset="4"/>
+      <match type="string" value="ftypmsf1" offset="4"/>
+      <match type="string" value="ftypheic" offset="4"/>
+      <match type="string" value="ftypheix" offset="4"/>
+      <match type="string" value="ftyphevc" offset="4"/>
+      <match type="string" value="ftyphevx" offset="4"/>
+    </magic>
+    <glob pattern="*.heic"/>
+    <glob pattern="*.heif"/>
+    <glob pattern="*.hif"/>
+    <alias type="image/heic"/>
+    <alias type="image/heic-sequence"/>
+    <alias type="image/heif-sequence"/>
+  </mime-type>
+  <mime-type type="image/ief">
+    <comment>IEF image</comment>
+    <glob pattern="*.ief"/>
+  </mime-type>
+  <mime-type type="image/jpeg">
+    <comment>JPEG image</comment>
+    <acronym>JPEG</acronym>
+    <expanded-acronym>Joint Photographic Experts Group</expanded-acronym>
+    <magic>
+      <match type="string" value="\377\330\377" offset="0"/>
+      <match type="big16" value="0xffd8" offset="0"/>
+    </magic>
+    <glob pattern="*.jpg"/>
+    <glob pattern="*.jpeg"/>
+    <glob pattern="*.jpe"/>
+    <alias type="image/pjpeg"/>
+  </mime-type>
+  <mime-type type="video/x-mjpeg">
+    <comment>MJPEG video stream</comment>
+    <acronym>MJPEG</acronym>
+    <expanded-acronym>Motion JPEG</expanded-acronym>
+    <sub-class-of type="image/jpeg"/>
+    <glob pattern="*.mjpeg"/>
+    <glob pattern="*.mjpg"/>
+  </mime-type>
+  <mime-type type="image/x-jp2-codestream">
+    <comment>JPEG-2000 codestream</comment>
+    <magic>
+      <match type="big32" value="0xff4fff51" offset="0"/>
+    </magic>
+    <glob pattern="*.j2c"/>
+    <glob pattern="*.j2k"/>
+    <glob pattern="*.jpc"/>
+  </mime-type>
+  <mime-type type="image/jp2">
+    <comment>JPEG-2000 JP2 image</comment>
+    <acronym>JP2</acronym>
+    <expanded-acronym>JPEG-2000</expanded-acronym>
+    <alias type="image/jpeg2000"/>
+    <alias type="image/jpeg2000-image"/>
+    <alias type="image/x-jpeg2000-image"/>
+    <magic>
+      <match type="string" mask="0xffffffffffffffffffffffff0000000000000000ffffffff" value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a        jp2\x20" offset="0"/>
+    </magic>
+    <glob pattern="*.jp2"/>
+    <glob pattern="*.jpg2"/>
+  </mime-type>
+  <mime-type type="image/jpx">
+    <comment>JPEG-2000 JPX image</comment>
+    <acronym>JPX</acronym>
+    <expanded-acronym>JPEG-2000 eXtended</expanded-acronym>
+    <magic>
+      <match type="string" mask="0xffffffffffffffffffffffff0000000000000000ffffffff" value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a        jpx\x20" offset="0"/>
+    </magic>
+    <glob pattern="*.jpf"/>
+    <glob pattern="*.jpx"/>
+  </mime-type>
+  <mime-type type="image/jpm">
+    <comment>JPEG-2000 JPM image</comment>
+    <acronym>JPM</acronym>
+    <expanded-acronym>JPEG-2000 Mixed</expanded-acronym>
+    <magic>
+      <match type="string" mask="0xffffffffffffffffffffffff0000000000000000ffffffff" value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a        jpm\x20" offset="0"/>
+    </magic>
+    <glob pattern="*.jpm"/>
+    <glob pattern="*.jpgm"/>
+  </mime-type>
+  <mime-type type="video/mj2">
+    <comment>JPEG-2000 MJ2 video</comment>
+    <acronym>MJ2</acronym>
+    <expanded-acronym>Motion JPEG-2000</expanded-acronym>
+    <magic>
+      <match type="string" mask="0xffffffffffffffffffffffff0000000000000000ffffffff" value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a        mjp2" offset="0"/>
+    </magic>
+    <glob pattern="*.mj2"/>
+    <glob pattern="*.mjp2"/>
+  </mime-type>
+  <mime-type type="image/jxl">
+    <comment>JPEG XL image</comment>
+    <magic>
+      <match type="string" offset="0" value="\xFF\x0A"/>
+      <match type="string" offset="0" value="\0\0\0\x0CJXL \x0D\x0A\x87\x0A"/>
+    </magic>
+    <glob pattern="*.jxl"/>
+  </mime-type>
+  <mime-type type="image/openraster">
+    <comment>OpenRaster image</comment>
+    <sub-class-of type="application/zip"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="mimetype" offset="30">
+          <match type="string" value="image/openraster" offset="38"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ora"/>
+  </mime-type>
+  <mime-type type="image/x-dds">
+    <comment>DirectDraw surface</comment>
+    <magic>
+      <match value="DDS" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.dds"/>
+  </mime-type>
+  <mime-type type="image/x-xcursor">
+    <comment>X11 cursor</comment>
+    <magic>
+      <match type="string" value="Xcur" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-exr">
+    <comment>EXR image</comment>
+    <magic>
+      <match type="little32" value="20000630" offset="0"/>
+    </magic>
+    <glob pattern="*.exr"/>
+  </mime-type>
+  <mime-type type="image/x-pict">
+    <comment>Macintosh Quickdraw/PICT drawing</comment>
+    <magic>
+      <match type="big16" value="0x0011" offset="10">
+        <match type="big16" value="0x02FF" offset="12">
+          <match type="big16" value="0x0C00" offset="14">
+            <match type="big16" value="0xFFFE" offset="16"/>
+          </match>
+        </match>
+      </match>
+    </magic>
+    <magic>
+      <match type="big16" value="0x0011" offset="522">
+        <match type="big16" value="0x02FF" offset="524">
+          <match type="big16" value="0x0C00" offset="526">
+            <match type="big16" value="0xFFFE" offset="528"/>
+          </match>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.pct"/>
+    <glob pattern="*.pict"/>
+    <glob pattern="*.pict1"/>
+    <glob pattern="*.pict2"/>
+  </mime-type>
+  <mime-type type="application/x-ufraw">
+    <comment>UFRaw ID image</comment>
+    <acronym>UFRaw</acronym>
+    <expanded-acronym>Unidentified Flying Raw</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="*.ufraw"/>
+  </mime-type>
+  <mime-type type="image/x-dcraw">
+    <comment>digital raw image</comment>
+  </mime-type>
+  <mime-type type="image/x-adobe-dng">
+    <comment>Adobe DNG negative</comment>
+    <acronym>DNG</acronym>
+    <expanded-acronym>Digital Negative</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.dng"/>
+  </mime-type>
+  <!-- Canon has 3 formats: CRW, CR2 and CR3 !-->
+  <!-- CRW is easy !-->
+  <mime-type type="image/x-canon-crw">
+    <comment>Canon CRW raw image</comment>
+    <acronym>CRW</acronym>
+    <expanded-acronym>Canon RaW</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <match value="II\x1a\x00\x00\x00HEAPCCDR" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.crw"/>
+  </mime-type>
+  <!-- CR2 is a TIFF !-->
+  <mime-type type="image/x-canon-cr2">
+    <comment>Canon CR2 raw image</comment>
+    <acronym>CR2</acronym>
+    <expanded-acronym>Canon Raw 2</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.cr2"/>
+  </mime-type>
+  <mime-type type="image/x-canon-cr3">
+    <comment>Canon CR3 raw image</comment>
+    <acronym>CR3</acronym>
+    <expanded-acronym>Canon Raw 3</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <glob pattern="*.cr3"/>
+  </mime-type>
+  <mime-type type="image/x-fuji-raf">
+    <comment>Fuji RAF raw image</comment>
+    <acronym>RAF</acronym>
+    <expanded-acronym>RAw Format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <match value="FUJIFILMCCD-RAW " type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.raf"/>
+  </mime-type>
+  <mime-type type="image/x-kodak-dcr">
+    <comment>Kodak DCR raw image</comment>
+    <acronym>DCR</acronym>
+    <expanded-acronym>Digital Camera Raw</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.dcr"/>
+  </mime-type>
+  <mime-type type="image/x-kodak-k25">
+    <comment>Kodak K25 raw image</comment>
+    <acronym>K25</acronym>
+    <expanded-acronym>Kodak DC25</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.k25"/>
+  </mime-type>
+  <mime-type type="image/x-kodak-kdc">
+    <comment>Kodak KDC raw image</comment>
+    <acronym>KDC</acronym>
+    <expanded-acronym>Kodak Digital Camera</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <magic priority="80">
+      <match value="EASTMAN KODAK COMPANY" type="string" offset="242"/>
+    </magic>
+    <glob pattern="*.kdc"/>
+  </mime-type>
+  <mime-type type="image/x-minolta-mrw">
+    <comment>Minolta MRW raw image</comment>
+    <acronym>MRW</acronym>
+    <expanded-acronym>Minolta RaW</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <match value="\x00MRM" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.mrw" />
+  </mime-type>
+  <mime-type type="image/x-nikon-nef">
+    <comment>Nikon NEF raw image</comment>
+    <acronym>NEF</acronym>
+    <expanded-acronym>Nikon Electronic Format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.nef"/>
+  </mime-type>
+  <mime-type type="image/x-nikon-nrw">
+    <comment>Nikon NRW raw image</comment>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.nrw"/>
+  </mime-type>
+  <mime-type type="image/x-olympus-orf">
+    <comment>Olympus ORF raw image</comment>
+    <acronym>ORF</acronym>
+    <expanded-acronym>Olympus Raw Format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <!-- an ORF file is basically a TIFF file with a non standard !-->
+      <!-- header IIRO which is not nice since it is only composed  !-->
+      <!-- of ASCII codes. Fortunately, the TIFF header is followed !-->
+      <!-- by the offset of the first TIFF ifd which is always      !-->
+      <!-- 0x00000008 (Little endian) for an ORF                    !-->
+      <match value="IIRO\x08\x00\x00\x00" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.orf"/>
+  </mime-type>
+  <mime-type type="image/x-panasonic-rw">
+    <comment>Panasonic raw image</comment>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <!-- Some kind of TIFF file with a non-standard version in prefix !-->
+      <match value="IIU\x00\x08\x00\x00\x00" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.raw"/>
+    <alias type="image/x-panasonic-raw"/>
+  </mime-type>
+  <mime-type type="image/x-panasonic-rw2">
+    <comment>Panasonic raw image</comment>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <!-- Some kind of TIFF file with a non-standard version in prefix !-->
+      <match value="IIU\x00\x18\x00\x00\x00" type="string" offset="0"/>
+    </magic>
+    <glob pattern="*.rw2"/>
+    <alias type="image/x-panasonic-raw2"/>
+  </mime-type>
+  <mime-type type="image/x-pentax-pef">
+    <comment>Pentax PEF raw image</comment>
+    <acronym>PEF</acronym>
+    <expanded-acronym>Pentax Electronic Format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.pef"/>
+  </mime-type>
+  <mime-type type="image/x-sigma-x3f">
+    <comment>Sigma X3F raw image</comment>
+    <acronym>X3F</acronym>
+    <expanded-acronym>X3 Foveon</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <magic>
+      <!-- The header is "FOVb" (Foveon) !-->
+      <match value="FOVb" type="string" offset="0">
+        <!-- Followed by a 32bit LSB specifying the version number (major.minor) !-->
+        <match value="0x00FF00FF" type="little32" offset="4" mask="0xFF00FF00" />
+      </match>
+    </magic>
+    <glob pattern="*.x3f"/>
+  </mime-type>
+  <mime-type type="image/x-sony-srf">
+    <comment>Sony SRF raw image</comment>
+    <acronym>SRF</acronym>
+    <expanded-acronym>Sony Raw Format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.srf"/>
+  </mime-type>
+  <mime-type type="image/x-sony-sr2">
+    <comment>Sony SR2 raw image</comment>
+    <acronym>SR2</acronym>
+    <expanded-acronym>Sony Raw format 2</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.sr2"/>
+  </mime-type>
+  <mime-type type="image/x-sony-arw">
+    <comment>Sony ARW raw image</comment>
+    <acronym>ARW</acronym>
+    <expanded-acronym>Alpha Raw format</expanded-acronym>
+    <sub-class-of type="image/x-dcraw"/>
+    <sub-class-of type="image/tiff"/>
+    <glob pattern="*.arw"/>
+  </mime-type>
+  <mime-type type="image/png">
+    <comment>PNG image</comment>
+    <acronym>PNG</acronym>
+    <expanded-acronym>Portable Network Graphics</expanded-acronym>
+    <magic>
+      <match type="string" value="\x89PNG" offset="0"/>
+    </magic>
+    <glob pattern="*.png"/>
+  </mime-type>
+  <mime-type type="image/rle">
+    <comment>RLE bitmap image</comment>
+    <acronym>RLE</acronym>
+    <expanded-acronym>Run Length Encoded</expanded-acronym>
+    <glob pattern="*.rle"/>
+  </mime-type>
+  <mime-type type="image/svg+xml">
+    <comment>SVG image</comment>
+    <acronym>SVG</acronym>
+    <expanded-acronym>Scalable Vector Graphics</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <magic priority="80">
+      <match type="string" value="&lt;!DOCTYPE svg" offset="0:256"/>
+    </magic>
+    <magic priority="80">
+      <match type="string" value="&lt;!-- Created with Inkscape" offset="0"/>
+      <match type="string" value="&lt;svg" offset="0"/>
+    </magic>
+    <magic priority="45">
+      <match type="string" value="&lt;svg" offset="1:256"/>
+    </magic>
+    <glob pattern="*.svg"/>
+    <root-XML namespaceURI="http://www.w3.org/2000/svg" localName="svg"/>
+  </mime-type>
+  <mime-type type="image/svg+xml-compressed">
+    <comment>compressed SVG image</comment>
+    <acronym>SVG</acronym>
+    <expanded-acronym>Scalable Vector Graphics</expanded-acronym>
+    <sub-class-of type="application/gzip"/>
+    <glob pattern="*.svgz"/>
+    <glob pattern="*.svg.gz"/>
+  </mime-type>
+  <mime-type type="image/tiff">
+    <comment>TIFF image</comment>
+    <acronym>TIFF</acronym>
+    <expanded-acronym>Tagged Image File Format</expanded-acronym>
+    <magic>
+      <match type="string" value="MM\x00\x2a" offset="0"/>
+      <match type="string" value="II\x2a\x00" offset="0"/>
+    </magic>
+    <glob pattern="*.tif"/>
+    <glob pattern="*.tiff"/>
+  </mime-type>
+  <mime-type type="image/x-tiff-multipage">
+    <comment>Multi-page TIFF image</comment>
+    <acronym>TIFF</acronym>
+    <expanded-acronym>Tagged Image File Format</expanded-acronym>
+    <sub-class-of type="image/tiff"/>
+  </mime-type>
+  <mime-type type="image/vnd.dwg">
+    <comment>AutoCAD image</comment>
+    <glob pattern="*.dwg"/>
+  </mime-type>
+  <mime-type type="image/vnd.dxf">
+    <comment>DXF vector image</comment>
+    <glob pattern="*.dxf"/>
+    <magic>
+      <match type="string" value="\nHEADER\n" offset="0:64"/>
+      <match type="string" value="\x0d\nHEADER\x0d\n" offset="0:64"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/vnd.ms-modi">
+    <comment>MDI image</comment>
+    <acronym>MDI</acronym>
+    <expanded-acronym>Microsoft Document Imaging</expanded-acronym>
+    <glob pattern="*.mdi"/>
+    <magic>
+      <match type="string" value="\x45\x50\x2A\x00" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/webp">
+    <comment>WebP image</comment>
+    <magic>
+      <match type="string" value="RIFF" offset="0">
+        <match type="string" value="WEBP" offset="8"/>
+      </match>
+    </magic>
+    <glob pattern="*.webp"/>
+  </mime-type>
+  <mime-type type="image/x-3ds">
+    <comment>3D Studio image</comment>
+    <glob pattern="*.3ds"/>
+    <magic priority="30">
+      <match offset="0" type="big16" value="0x4d4d"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-applix-graphics">
+    <comment>Applix Graphics image</comment>
+    <magic>
+      <match type="string" value="*BEGIN" offset="0">
+        <match type="string" value="GRAPHICS" offset="7"/>
+      </match>
+    </magic>
+    <glob pattern="*.ag"/>
+  </mime-type>
+  <mime-type type="image/x-bzeps">
+    <comment>EPS image (bzip-compressed)</comment>
+    <sub-class-of type="application/x-bzip"/>
+    <glob pattern="*.eps.bz2"/>
+    <glob pattern="*.epsi.bz2"/>
+    <glob pattern="*.epsf.bz2"/>
+  </mime-type>
+  <mime-type type="image/x-cmu-raster">
+    <comment>CMU raster image</comment>
+    <glob pattern="*.ras"/>
+  </mime-type>
+  <mime-type type="image/x-compressed-xcf">
+    <comment>compressed GIMP image</comment>
+    <glob pattern="*.xcf.gz"/>
+    <glob pattern="*.xcf.bz2"/>
+  </mime-type>
+  <mime-type type="application/dicom">
+    <comment>DICOM image</comment>
+    <acronym>DICOM</acronym>
+    <expanded-acronym>Digital Imaging and Communications in Medicine</expanded-acronym>
+    <generic-icon name="image-x-generic"/>
+    <glob pattern="dicomdir"/>
+    <glob pattern="*.dcm"/>
+    <magic>
+      <match type="string" value="DICM" offset="128"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-docbook+xml">
+    <comment>DocBook document</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="90">
+      <match value="&lt;?xml" type="string" offset="0">
+        <match value="-//OASIS//DTD DocBook XML" type="string" offset="0:100"/>
+        <match value="-//KDE//DTD DocBook XML" type="string" offset="0:100"/>
+      </match>
+    </magic>
+    <glob pattern="*.dbk"/>
+    <glob pattern="*.docbook"/>
+    <alias type="application/docbook+xml"/>
+    <alias type="application/vnd.oasis.docbook+xml"/>
+  </mime-type>
+  <mime-type type="image/x-dib">
+    <comment>DIB image</comment>
+    <acronym>DIB</acronym>
+    <expanded-acronym>Device Independent Bitmap</expanded-acronym>
+    <magic>
+      <match type="string" value="\x28\00\00\00" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/vnd.djvu">
+    <comment>DjVu image</comment>
+    <alias type="image/x-djvu"/>
+    <alias type="image/x.djvu"/>
+    <magic priority="80">
+      <match type="string" offset="0" value="AT&amp;TFORM">
+        <match type="string" offset="12" value="DJVU"/>
+      </match>
+      <match type="string" offset="0" value="FORM">
+        <match type="string" offset="8" value="DJVU"/>
+      </match>
+    </magic>
+    <glob pattern="*.djvu"/>
+    <glob pattern="*.djv"/>
+  </mime-type>
+  <mime-type type="image/vnd.djvu+multipage">
+    <comment>DjVu document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic priority="80">
+      <match type="string" offset="0" value="AT&amp;TFORM">
+        <match type="string" offset="12" value="DJVM"/>
+      </match>
+      <match type="string" offset="0" value="FORM">
+        <match type="string" offset="8" value="DJVM"/>
+      </match>
+    </magic>
+    <sub-class-of type="image/vnd.djvu"/>
+    <glob pattern="*.djvu"/>
+    <glob pattern="*.djv"/>
+  </mime-type>
+  <mime-type type="image/dpx">
+    <comment>DPX image</comment>
+    <acronym>DPX</acronym>
+    <expanded-acronym>Digital Moving Picture Exchange</expanded-acronym>
+    <magic>
+      <match type="big32" value="0x53445058" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-eps">
+    <comment>EPS image</comment>
+    <acronym>EPS</acronym>
+    <expanded-acronym>Encapsulated PostScript</expanded-acronym>
+    <sub-class-of type="application/postscript"/>
+    <magic priority="90">
+      <match type="string" value="%!" offset="0">
+        <match type="string" value="EPS" offset="15"/>
+      </match>
+      <match type="string" value="\004%!" offset="0">
+        <match type="string" value="EPS" offset="16"/>
+      </match>
+      <match type="big32" value="0xC5D0D3C6" offset="0"/>
+    </magic>
+    <glob pattern="*.eps"/>
+    <glob pattern="*.epsi"/>
+    <glob pattern="*.epsf"/>
+  </mime-type>
+  <mime-type type="application/fits">
+    <comment>FITS document</comment>
+    <acronym>FITS</acronym>
+    <expanded-acronym>Flexible Image Transport System</expanded-acronym>
+    <magic>
+      <match type="string" value="SIMPLE  =" offset="0"/>
+    </magic>
+    <glob pattern="*.fits"/>
+    <glob pattern="*.fit"/>
+    <glob pattern="*.fts"/>
+    <alias type="image/x-fits"/>
+    <alias type="image/fits"/>
+  </mime-type>
+  <mime-type type="image/x-fpx">
+    <comment>FPX image</comment>
+    <acronym>FPX</acronym>
+    <expanded-acronym>FlashPiX</expanded-acronym>
+    <magic>
+      <match type="big32" value="0x46506978" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-gzeps">
+    <comment>EPS image (gzip-compressed)</comment>
+    <sub-class-of type="application/gzip"/>
+    <glob pattern="*.eps.gz"/>
+    <glob pattern="*.epsi.gz"/>
+    <glob pattern="*.epsf.gz"/>
+  </mime-type>
+  <mime-type type="image/vnd.microsoft.icon">
+    <comment>Windows icon</comment>
+    <magic>
+      <match type="string" value="\0\0\1\0" offset="0">
+        <match type="string" value="\0" offset="5"/>
+      </match>
+    </magic>
+    <glob pattern="*.ico"/>
+    <alias type="application/ico"/>
+    <alias type="image/ico"/>
+    <alias type="image/icon"/>
+    <alias type="image/x-ico"/>
+    <alias type="image/x-icon"/>
+    <alias type="text/ico"/>
+  </mime-type>
+  <mime-type type="image/x-icns">
+    <comment>MacOS X icon</comment>
+    <glob pattern="*.icns"/>
+    <magic>
+      <match type="string" value="icns" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-ilbm">
+    <comment>ILBM image</comment>
+    <acronym>ILBM</acronym>
+    <expanded-acronym>InterLeaved BitMap</expanded-acronym>
+    <sub-class-of type="application/x-iff"/>
+    <magic>
+      <match value="ILBM" type="string" offset="8"/>
+      <match value="PBM " type="string" offset="8"/>
+    </magic>
+    <glob pattern="*.iff"/>
+    <glob pattern="*.ilbm"/>
+    <glob pattern="*.lbm"/>
+    <alias type="image/x-iff"/>
+  </mime-type>
+  <mime-type type="image/x-jng">
+    <comment>JNG image</comment>
+    <acronym>JNG</acronym>
+    <expanded-acronym>JPEG Network Graphics</expanded-acronym>
+    <glob pattern="*.jng"/>
+  </mime-type>
+  <mime-type type="image/x-lwo">
+    <comment>LightWave object</comment>
+    <glob pattern="*.lwo"/>
+    <glob pattern="*.lwob"/>
+  </mime-type>
+  <mime-type type="image/x-lws">
+    <comment>LightWave scene</comment>
+    <glob pattern="*.lws"/>
+  </mime-type>
+  <mime-type type="image/x-macpaint">
+    <comment>MacPaint Bitmap image</comment>
+    <glob pattern="*.pntg"/>
+  </mime-type>
+  <mime-type type="image/x-msod">
+    <comment>Office drawing</comment>
+    <glob pattern="*.msod"/>
+  </mime-type>
+  <mime-type type="image/x-niff">
+    <comment>NIFF image</comment>
+    <acronym>NIFF</acronym>
+    <expanded-acronym>Navy Image File Format</expanded-acronym>
+    <magic priority="80">
+      <match type="string" value="IIN1" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/vnd.zbrush.pcx">
+    <comment>PCX image</comment>
+    <acronym>PCX</acronym>
+    <expanded-acronym>PiCture eXchange</expanded-acronym>
+    <magic>
+      <match type="byte" value="10" offset="0">
+        <match type="byte" value="0" offset="1"/>
+        <match type="byte" value="2" offset="1"/>
+        <match type="byte" value="3" offset="1"/>
+        <match type="byte" value="5" offset="1"/>
+      </match>
+    </magic>
+    <glob pattern="*.pcx"/>
+    <alias type="image/x-pcx"/>
+  </mime-type>
+  <mime-type type="image/x-photo-cd">
+    <comment>PCD image</comment>
+    <acronym>PCD</acronym>
+    <expanded-acronym>PhotoCD</expanded-acronym>
+    <glob pattern="*.pcd"/>
+  </mime-type>
+  <mime-type type="image/x-portable-anymap">
+    <comment>PNM image</comment>
+    <acronym>PNM</acronym>
+    <expanded-acronym>Portable Anymap</expanded-acronym>
+    <glob pattern="*.pnm"/>
+  </mime-type>
+  <mime-type type="image/x-portable-bitmap">
+    <comment>PBM image</comment>
+    <acronym>PBM</acronym>
+    <expanded-acronym>Portable BitMap</expanded-acronym>
+    <sub-class-of type="image/x-portable-anymap"/>
+    <magic>
+      <match type="string" value="P1" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+      <match type="string" value="P4" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+    </magic>
+    <glob pattern="*.pbm"/>
+  </mime-type>
+  <mime-type type="image/x-portable-graymap">
+    <comment>PGM image</comment>
+    <acronym>PGM</acronym>
+    <expanded-acronym>Portable GrayMap</expanded-acronym>
+    <sub-class-of type="image/x-portable-anymap"/>
+    <magic>
+      <match type="string" value="P2" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+      <match type="string" value="P5" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+    </magic>
+    <glob pattern="*.pgm"/>
+  </mime-type>
+  <mime-type type="image/x-portable-pixmap">
+    <comment>PPM image</comment>
+    <acronym>PPM</acronym>
+    <expanded-acronym>Portable PixMap</expanded-acronym>
+    <sub-class-of type="image/x-portable-anymap"/>
+    <magic>
+      <match type="string" value="P3" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+      <match type="string" value="P6" offset="0">
+        <match type="byte" value="0x0a" offset="2"/>
+        <match type="byte" value="0x20" offset="2"/>
+        <match type="byte" value="0x09" offset="2"/>
+        <match type="byte" value="0x0d" offset="2"/>
+      </match>
+    </magic>
+    <glob pattern="*.ppm"/>
+  </mime-type>
+  <mime-type type="image/vnd.adobe.photoshop">
+    <comment>Photoshop image</comment>
+    <magic>
+      <match type="string" mask="0xffffffff0000ffffffff" value="8BPS  \000\000\000\000" offset="0"/>
+    </magic>
+    <glob pattern="*.psd"/>
+    <alias type="image/psd"/>
+    <alias type="image/x-psd"/>
+    <alias type="image/photoshop"/>
+    <alias type="image/x-photoshop"/>
+    <alias type="application/photoshop"/>
+    <alias type="application/x-photoshop"/>
+  </mime-type>
+  <mime-type type="image/x-rgb">
+    <comment>RGB image</comment>
+    <glob pattern="*.rgb"/>
+  </mime-type>
+  <mime-type type="image/x-sgi">
+    <comment>SGI image</comment>
+    <glob pattern="*.sgi"/>
+  </mime-type>
+  <mime-type type="image/x-sun-raster">
+    <comment>Sun raster image</comment>
+    <magic>
+      <match type="big32" value="0x59a66a95" offset="0"/>
+    </magic>
+    <glob pattern="*.sun"/>
+  </mime-type>
+  <mime-type type="image/x-tga">
+    <comment>TGA image</comment>
+    <acronym>TGA</acronym>
+    <expanded-acronym>Truevision Graphics Adapter</expanded-acronym>
+    <magic priority="10">
+      <match type="string" value="\1\1" offset="1"/>
+      <match type="string" value="\1\11" offset="1"/>
+      <match type="string" value="\0\3" offset="1"/>
+      <match type="string" value="\0\xa" offset="1"/>
+      <match type="string" value="\0\xb" offset="1"/>
+    </magic>
+    <magic>
+      <match type="string" value="\0\2" offset="1">
+        <match type="byte" value="0x08" offset="16"/>
+        <match type="byte" value="0x10" offset="16"/>
+        <match type="byte" value="0x18" offset="16"/>
+        <match type="byte" value="0x20" offset="16"/>
+      </match>
+    </magic>
+    <glob pattern="*.tga"/>
+    <glob pattern="*.icb"/>
+    <glob pattern="*.tpic"/>
+    <glob pattern="*.vda"/>
+    <glob pattern="*.vst"/>
+    <alias type="application/tga"/>
+    <alias type="application/x-targa"/>
+    <alias type="application/x-tga"/>
+    <alias type="image/targa"/>
+    <alias type="image/tga"/>
+    <alias type="image/x-icb"/>
+    <alias type="image/x-targa"/>
+  </mime-type>
+  <mime-type type="image/x-win-bitmap">
+    <comment>Windows cursor</comment>
+    <magic>
+      <match type="string" value="\0\0\2\0" offset="0">
+        <match type="string" value="\0" offset="5"/>
+      </match>
+    </magic>
+    <glob pattern="*.cur"/>
+  </mime-type>
+  <mime-type type="application/x-navi-animation">
+    <comment>Windows animated cursor</comment>
+    <magic>
+      <match type="string" value="RIFF" offset="0">
+        <match type="string" value="ACON" offset="8"/>
+      </match>
+    </magic>
+    <glob pattern="*.ani"/>
+  </mime-type>
+  <mime-type type="image/emf">
+    <comment>EMF image</comment>
+    <acronym>EMF</acronym>
+    <expanded-acronym>Enhanced MetaFile</expanded-acronym>
+    <glob pattern="*.emf"/>
+    <alias type="image/x-emf"/>
+    <alias type="application/x-emf"/>
+    <alias type="application/emf"/>
+    <magic>
+      <match type="little32" offset="0" value="0x00000001">
+        <match type="little32" offset="40" value="0x464D4520">
+          <match type="little32" offset="44" value="0x00010000">
+            <match type="little16" offset="58" value="0x0000"/>
+          </match>
+        </match>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="image/wmf">
+    <comment>WMF image</comment>
+    <acronym>WMF</acronym>
+    <expanded-acronym>Windows Metafile</expanded-acronym>
+    <magic>
+      <!-- Placeable Metafile Header !-->
+      <match type="little32" offset="0" value="0x9AC6CDD7">
+        <!-- Followed by the standard Windows Metafile Header !-->
+        <match type="little16" offset="22" value="0x0001">
+          <match type="little16" offset="24" value="0x0009"/>
+        </match>
+      </match>
+      <!-- or just the standard Windows Metafile Header !-->
+      <match type="little16" offset="0" value="0x0001">
+        <match type="little16" offset="2" value="0x0009"/>
+      </match>
+    </magic>
+    <glob pattern="*.wmf"/>
+    <alias type="image/x-wmf"/>
+    <alias type="image/x-win-metafile"/>
+    <alias type="application/x-wmf"/>
+    <alias type="application/wmf"/>
+    <alias type="application/x-msmetafile"/>
+  </mime-type>
+  <mime-type type="image/x-xbitmap">
+    <comment>XBM image</comment>
+    <acronym>XBM</acronym>
+    <expanded-acronym>X BitMap</expanded-acronym>
+    <glob pattern="*.xbm"/>
+  </mime-type>
+  <mime-type type="image/x-xcf">
+    <comment>GIMP image</comment>
+    <glob pattern="*.xcf"/>
+    <magic>
+      <match type="string" value="gimp xcf file" offset="0"/>
+      <match type="string" value="gimp xcf v" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-gimp-gbr">
+    <comment>GIMP brush</comment>
+    <glob pattern="*.gbr"/>
+    <magic>
+      <match type="string" value="GIMP" offset="20"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-gimp-gih">
+    <comment>GIMP brush pipe</comment>
+    <glob pattern="*.gih"/>
+  </mime-type>
+  <mime-type type="image/x-gimp-pat">
+    <comment>GIMP pattern</comment>
+    <glob pattern="*.pat"/>
+    <magic>
+      <match type="string" value="GPAT" offset="20"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-xfig">
+    <comment>XFig image</comment>
+    <glob pattern="*.fig"/>
+    <magic>
+      <match type="string" value="#FIG" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="image/x-xpixmap">
+    <comment>XPM image</comment>
+    <acronym>XPM</acronym>
+    <expanded-acronym>X PixMap</expanded-acronym>
+    <magic>
+      <match type="string" value="/* XPM */" offset="0"/>
+      <match type="string" value="! XPM2\n" offset="0"/>
+    </magic>
+    <glob pattern="*.xpm"/>
+    <alias type="image/x-xpm"/>
+  </mime-type>
+  <mime-type type="image/x-xwindowdump">
+    <comment>X window image</comment>
+    <glob pattern="*.xwd"/>
+  </mime-type>
+  <mime-type type="inode/blockdevice">
+    <comment>block device</comment>
+  </mime-type>
+  <mime-type type="inode/chardevice">
+    <comment>character device</comment>
+  </mime-type>
+  <mime-type type="inode/directory">
+    <comment>folder</comment>
+    <generic-icon name="folder"/>
+    <alias type="x-directory/normal"/>
+  </mime-type>
+  <mime-type type="inode/fifo">
+    <comment>pipe</comment>
+  </mime-type>
+  <mime-type type="inode/mount-point">
+    <comment>mount point</comment>
+    <sub-class-of type="inode/directory"/>
+  </mime-type>
+  <mime-type type="inode/socket">
+    <comment>socket</comment>
+  </mime-type>
+  <mime-type type="inode/symlink">
+    <comment>symbolic link</comment>
+  </mime-type>
+  <mime-type type="message/delivery-status">
+    <comment>mail delivery report</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="message/disposition-notification">
+    <comment>mail disposition report</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="message/external-body">
+    <comment>reference to remote file</comment>
+    <generic-icon name="text-x-generic"/>
+  </mime-type>
+  <mime-type type="message/news">
+    <comment>Usenet news message</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="Article" offset="0"/>
+      <match type="string" value="Path:" offset="0"/>
+      <match type="string" value="Xref:" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="message/partial">
+    <comment>partial email message</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="message/rfc822">
+    <comment>email message</comment>
+    <generic-icon name="text-x-generic"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="#! rnews" offset="0"/>
+      <match type="string" value="Forward to" offset="0"/>
+      <match type="string" value="From:" offset="0"/>
+      <match type="string" value="N#! rnews" offset="0"/>
+      <match type="string" value="Pipe to" offset="0"/>
+      <match type="string" value="Received:" offset="0"/>
+      <match type="string" value="Relay-Version:" offset="0"/>
+      <match type="string" value="Return-Path:" offset="0"/>
+      <match type="string" value="Return-path:" offset="0"/>
+      <match type="string" value="Subject: " offset="0"/>
+    </magic>
+    <glob pattern="*.eml"/>
+  </mime-type>
+  <mime-type type="message/x-gnu-rmail">
+    <comment>GNU mail message</comment>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="RMAIL"/>
+  </mime-type>
+  <mime-type type="model/iges">
+    <comment>IGES document</comment>
+    <acronym>IGES</acronym>
+    <expanded-acronym>Initial Graphics Exchange Specification</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="S      1\x0a" offset="72"/>
+      <match type="string" value="S0000001\x0a" offset="72"/>
+    </magic>
+    <glob pattern="*.igs"/>
+    <glob pattern="*.iges"/>
+  </mime-type>
+  <mime-type type="model/gltf-binary">
+    <comment>glTF model</comment>
+    <acronym>glTF</acronym>
+    <expanded-acronym>GL Transmission Format</expanded-acronym>
+    <magic>
+      <match type="string" value="glTF" offset="0"/>
+    </magic>
+    <glob pattern="*.glb"/>
+  </mime-type>
+  <mime-type type="model/gltf+json">
+    <comment>glTF model</comment>
+    <acronym>glTF</acronym>
+    <expanded-acronym>GL Transmission Format</expanded-acronym>
+    <sub-class-of type="application/json"/>
+    <glob pattern="*.gltf"/>
+  </mime-type>
+  <mime-type type="model/vrml">
+    <comment>VRML document</comment>
+    <acronym>VRML</acronym>
+    <expanded-acronym>Virtual Reality Modeling Language</expanded-acronym>
+    <generic-icon name="x-office-document"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="#VRML " offset="0"/>
+    </magic>
+    <glob pattern="*.vrm"/>
+    <glob pattern="*.vrml"/>
+    <glob pattern="*.wrl"/>
+  </mime-type>
+  <mime-type type="model/obj">
+    <comment>OBJ 3D model</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value=" OBJ File: '" offset="0:64"/>
+      <match type="string" value="mtllib " offset="0:256"/>
+    </magic>
+    <glob pattern="*.obj"/>
+  </mime-type>
+  <mime-type type="model/mtl">
+    <comment>OBJ 3D model material library</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="# Blender MTL File: '" offset="0"/>
+      <match type="string" value="newmtl " offset="0:256"/>
+    </magic>
+    <glob pattern="*.mtl"/>
+  </mime-type>
+  <mime-type type="multipart/alternative">
+    <comment>message in several formats</comment>
+  </mime-type>
+  <mime-type type="multipart/appledouble">
+    <comment>Macintosh AppleDouble-encoded file</comment>
+  </mime-type>
+  <mime-type type="multipart/digest">
+    <comment>message digest</comment>
+  </mime-type>
+  <mime-type type="multipart/encrypted">
+    <comment>encrypted message</comment>
+  </mime-type>
+  <mime-type type="multipart/mixed">
+    <comment>compound documents</comment>
+  </mime-type>
+  <mime-type type="multipart/related">
+    <comment>compound document</comment>
+  </mime-type>
+  <mime-type type="multipart/report">
+    <comment>mail system report</comment>
+  </mime-type>
+  <mime-type type="multipart/signed">
+    <comment>signed message</comment>
+  </mime-type>
+  <mime-type type="multipart/x-mixed-replace">
+    <comment>stream of data (server push)</comment>
+  </mime-type>
+  <mime-type type="text/calendar">
+    <comment>VCS/ICS calendar</comment>
+    <acronym>VCS/ICS</acronym>
+    <expanded-acronym>vCalendar/iCalendar</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <alias type="text/x-vcalendar"/>
+    <alias type="application/ics"/>
+    <magic>
+      <match type="string" value="BEGIN:VCALENDAR" offset="0"/>
+      <match type="string" value="begin:vcalendar" offset="0"/>
+    </magic>
+    <glob pattern="*.vcs"/>
+    <glob pattern="*.ics"/>
+  </mime-type>
+  <mime-type type="text/css">
+    <comment>CSS stylesheet</comment>
+    <acronym>CSS</acronym>
+    <expanded-acronym>Cascading Style Sheets</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.css"/>
+  </mime-type>
+  <mime-type type="text/vcard">
+    <comment>electronic business card</comment>
+    <alias type="text/directory"/>
+    <alias type="text/x-vcard"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="BEGIN:VCARD" offset="0"/>
+      <match type="string" value="begin:vcard" offset="0"/>
+    </magic>
+    <glob pattern="*.vcard"/>
+    <glob pattern="*.vcf"/>
+    <glob pattern="*.vct"/>
+    <glob pattern="*.gcrd"/>
+  </mime-type>
+  <mime-type type="text/turtle">
+    <comment>Turtle document</comment>
+    <glob pattern="*.ttl"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/x-txt2tags">
+    <comment>txt2tags document</comment>
+    <sub-class-of type="text/plain"/>
+    <magic priority="60">
+      <match type="string" value="%!postproc" offset="0"/>
+      <match type="string" value="%!encoding" offset="0"/>
+    </magic>
+    <glob pattern="*.t2t"/>
+  </mime-type>
+  <mime-type type="text/x-verilog">
+    <comment>Verilog source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.v"/>
+  </mime-type>
+  <mime-type type="text/x-svhdr">
+    <comment>SystemVerilog header</comment>
+    <sub-class-of type="text/x-verilog"/>
+    <glob pattern="*.svh"/>
+  </mime-type>
+  <mime-type type="text/x-svsrc">
+    <comment>SystemVerilog source code</comment>
+    <sub-class-of type="text/x-verilog"/>
+    <glob pattern="*.sv"/>
+  </mime-type>
+  <mime-type type="text/x-vhdl">
+    <comment>VHDL source code</comment>
+    <acronym>VHDL</acronym>
+    <expanded-acronym>Very-High-Speed Integrated Circuit Hardware Description Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.vhd"/>
+    <glob pattern="*.vhdl"/>
+  </mime-type>
+  <mime-type type="text/enriched">
+    <comment>enriched text document</comment>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/htmlh">
+    <comment>help page</comment>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/plain">
+    <comment>plain text document</comment>
+    <magic>
+      <match type="string" value="This is TeX," offset="0"/>
+      <match type="string" value="This is METAFONT," offset="0"/>
+    </magic>
+    <glob pattern="*.txt"/>
+    <glob pattern="*.asc"/>
+    <glob pattern="*,v"/>
+  </mime-type>
+  <mime-type type="application/rdf+xml">
+    <comment>RDF file</comment>
+    <acronym>RDF</acronym>
+    <expanded-acronym>Resource Description Framework</expanded-acronym>
+    <alias type="text/rdf"/>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.rdf"/>
+    <glob pattern="*.rdfs"/>
+    <glob pattern="*.owl"/>
+    <root-XML namespaceURI="http://www.w3.org/1999/02/22-rdf-syntax-ns#" localName="RDF"/>
+  </mime-type>
+  <mime-type type="text/x-rst">
+    <comment>reStructuredText document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.rst"/>
+  </mime-type>
+  <mime-type type="application/owl+xml">
+    <comment>OWL XML file</comment>
+    <acronym>OWL</acronym>
+    <expanded-acronym>Web Ontology Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.owx"/>
+    <magic>
+      <match type="string" value="&lt;Ontology" offset="0:256"/>
+    </magic>
+    <root-XML namespaceURI="http://www.w3.org/2002/07/owl#" localName="Ontology"/>
+  </mime-type>
+  <mime-type type="text/rfc822-headers">
+    <comment>email headers</comment>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/richtext">
+    <comment>rich text document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.rtx"/>
+  </mime-type>
+  <mime-type type="application/rss+xml">
+    <comment>RSS summary</comment>
+    <acronym>RSS</acronym>
+    <expanded-acronym>RDF Site Summary</expanded-acronym>
+    <alias type="text/rss"/>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-html"/>
+    <glob pattern="*.rss"/>
+    <magic priority="70">
+      <match type="string" value="&lt;rss " offset="0:256"/>
+      <match type="string" value="&lt;RSS " offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/atom+xml">
+    <comment>Atom syndication feed</comment>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-html"/>
+    <glob pattern="*.atom"/>
+    <magic priority="70">
+      <match type="string" value="&lt;feed " offset="0:256"/>
+    </magic>
+    <root-XML namespaceURI="http://www.w3.org/2005/Atom" localName="feed"/>
+  </mime-type>
+  <mime-type type="text/x-opml+xml">
+    <comment>OPML syndication feed</comment>
+    <acronym>OPML</acronym>
+    <expanded-acronym>Outline Processor Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <alias type="text/x-opml"/>
+    <generic-icon name="text-html"/>
+    <glob pattern="*.opml"/>
+    <magic priority="70">
+      <match type="string" value="&lt;opml " offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/sgml">
+    <comment>SGML document</comment>
+    <acronym>SGML</acronym>
+    <expanded-acronym>Standard Generalized Markup Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.sgml"/>
+    <glob pattern="*.sgm"/>
+  </mime-type>
+  <mime-type type="text/spreadsheet">
+    <comment>spreadsheet interchange document</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="ID;" offset="0"/>
+    </magic>
+    <glob pattern="*.sylk"/>
+    <glob pattern="*.slk"/>
+  </mime-type>
+  <mime-type type="text/tab-separated-values">
+    <comment>TSV document</comment>
+    <acronym>TSV</acronym>
+    <expanded-acronym>Tab Separated Values</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.tsv"/>
+  </mime-type>
+  <mime-type type="text/vnd.graphviz">
+    <comment>Graphviz DOT graph</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="digraph " offset="0"/>
+      <match type="string" value="strict digraph " offset="0"/>
+      <match type="string" value="graph " offset="0"/>
+      <match type="string" value="strict graph " offset="0"/>
+    </magic>
+    <glob pattern="*.gv"/>
+    <glob pattern="*.dot"/>
+  </mime-type>
+  <mime-type type="text/vnd.sun.j2me.app-descriptor">
+    <comment>JAD document</comment>
+    <acronym>JAD</acronym>
+    <expanded-acronym>Java Application Descriptor</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="MIDlet-" offset="0"/>
+    </magic>
+    <glob pattern="*.jad"/>
+  </mime-type>
+  <mime-type type="text/vnd.wap.wml">
+    <comment>WML document</comment>
+    <acronym>WML</acronym>
+    <expanded-acronym>Wireless Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.wml"/>
+  </mime-type>
+  <mime-type type="text/vnd.wap.wmlscript">
+    <comment>WMLScript program</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.wmls"/>
+  </mime-type>
+  <mime-type type="text/vnd.senx.warpscript">
+    <comment>WarpScript source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.mc2"/>
+  </mime-type>
+  <mime-type type="application/x-ace">
+    <comment>ACE archive</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic priority="60">
+      <match type="string" value="**ACE**" offset="7"/>
+    </magic>
+    <glob pattern="*.ace"/>
+  </mime-type>
+  <mime-type type="text/x-adasrc">
+    <comment>Ada source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.adb"/>
+    <glob pattern="*.ads"/>
+  </mime-type>
+  <mime-type type="text/x-authors">
+    <comment>author list</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="AUTHORS"/>
+  </mime-type>
+  <mime-type type="text/x-bibtex">
+    <comment>BibTeX document</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="% This file was created with JabRef" offset="0"/>
+    </magic>
+    <glob pattern="*.bib"/>
+  </mime-type>
+  <mime-type type="text/x-c++hdr">
+    <comment>C++ header</comment>
+    <sub-class-of type="text/x-chdr"/>
+    <glob pattern="*.hh"/>
+    <glob pattern="*.hp"/>
+    <glob pattern="*.hpp"/>
+    <glob pattern="*.h++"/>
+    <glob pattern="*.hxx"/>
+  </mime-type>
+  <mime-type type="text/x-c++src">
+    <comment>C++ source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.cpp"/>
+    <glob pattern="*.cxx"/>
+    <glob pattern="*.cc"/>
+    <glob pattern="*.C" case-sensitive="true"/>
+    <glob pattern="*.c++"/>
+  </mime-type>
+  <mime-type type="text/x-changelog">
+    <comment>ChangeLog document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="ChangeLog"/>
+  </mime-type>
+  <mime-type type="text/x-chdr">
+    <comment>C header</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.h"/>
+  </mime-type>
+  <mime-type type="text/x-cmake">
+    <comment>CMake source code</comment>
+    <glob pattern="*.cmake"/>
+    <glob pattern="CMakeLists.txt"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/x-common-lisp">
+    <comment>Common Lisp source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.asd"/>
+    <glob pattern="*.fasl"/>
+    <glob pattern="*.lisp"/>
+    <glob pattern="*.ros"/>
+  </mime-type>
+  <mime-type type="text/csv">
+    <comment>CSV document</comment>
+    <acronym>CSV</acronym>
+    <expanded-acronym>Comma Separated Values</expanded-acronym>
+    <alias type="text/x-comma-separated-values"/>
+    <alias type="text/x-csv"/>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.csv"/>
+  </mime-type>
+  <mime-type type="text/csv-schema">
+    <comment>CSV Schema document</comment>
+    <acronym>CSV</acronym>
+    <expanded-acronym>Comma Separated Values</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.csvs"/>
+  </mime-type>
+  <mime-type type="text/x-copying">
+    <comment>license terms</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="COPYING"/>
+  </mime-type>
+  <mime-type type="text/x-credits">
+    <comment>author credits</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="CREDITS"/>
+  </mime-type>
+  <mime-type type="text/x-csrc">
+    <comment>C source code</comment>
+    <sub-class-of type="text/plain"/>
+    <alias type="text/x-c"/>
+    <glob pattern="*.c" case-sensitive="true"/>
+    <magic priority="30">
+      <match type="string" value="/*" offset="0"/>
+      <match type="string" value="//" offset="0"/>
+      <match type="string" value="#include" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/x-csharp">
+    <comment>C# source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.cs"/>
+  </mime-type>
+  <mime-type type="text/x-vala">
+    <comment>Vala source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.vala"/>
+    <glob pattern="*.vapi"/>
+  </mime-type>
+  <mime-type type="text/x-ooc">
+    <comment>OOC source code</comment>
+    <acronym>OOC</acronym>
+    <expanded-acronym>Out Of Class</expanded-acronym>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.ooc"/>
+  </mime-type>
+  <mime-type type="text/x-dcl">
+    <comment>DCL script</comment>
+    <acronym>DCL</acronym>
+    <expanded-acronym>Data Conversion Laboratory</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.dcl"/>
+  </mime-type>
+  <mime-type type="text/x-dsl">
+    <comment>DSSSL document</comment>
+    <acronym>DSSSL</acronym>
+    <expanded-acronym>Document Style Semantics and Specification Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.dsl"/>
+  </mime-type>
+  <mime-type type="text/x-dsrc">
+    <comment>D source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.d"/>
+    <glob pattern="*.di"/>
+  </mime-type>
+  <mime-type type="application/xml-dtd">
+    <comment>DTD file</comment>
+    <acronym>DTD</acronym>
+    <expanded-acronym>Document Type Definition</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.dtd"/>
+    <alias type="text/x-dtd"/>
+  </mime-type>
+  <mime-type type="text/x-eiffel">
+    <comment>Eiffel source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.e"/>
+    <glob pattern="*.eif"/>
+  </mime-type>
+  <mime-type type="text/x-emacs-lisp">
+    <comment>Emacs Lisp source code</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="\012(" offset="0"/>
+      <match type="string" value=";ELC\023\000\000\000" offset="0"/>
+    </magic>
+    <glob pattern="*.el"/>
+  </mime-type>
+    <mime-type type="text/x-elixir">
+    <comment>Elixir source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.ex"/>
+    <glob pattern="*.exs"/>
+  </mime-type>
+  <mime-type type="text/x-erlang">
+    <comment>Erlang source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.erl"/>
+  </mime-type>
+  <mime-type type="text/x-fortran">
+    <comment>Fortran source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.f"/>
+    <glob pattern="*.f90"/>
+    <glob pattern="*.f95"/>
+    <glob pattern="*.for"/>
+  </mime-type>
+  <mime-type type="text/x-genie">
+    <comment>Genie source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.gs" case-sensitive="true"/>
+    <generic-icon name="text-x-generic"/>
+  </mime-type>
+  <mime-type type="text/x-gettext-translation">
+    <comment>translation file</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.po"/>
+    <alias type="text/x-po"/>
+    <alias type="application/x-gettext"/>
+  </mime-type>
+  <mime-type type="text/x-gettext-translation-template">
+    <comment>translation template</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.pot"/>
+    <alias type="text/x-pot"/>
+    <magic>
+      <match type="string" value='#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version:' offset="0:256"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/x-gherkin">
+    <comment>Gherkin document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.feature"/>
+  </mime-type>
+  <mime-type type="text/html">
+    <comment>HTML document</comment>
+    <acronym>HTML</acronym>
+    <expanded-acronym>HyperText Markup Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="&lt;!DOCTYPE HTML" offset="0:256"/>
+      <match type="string" value="&lt;!doctype html" offset="0:256"/>
+      <match type="string" value="&lt;!DOCTYPE html" offset="0:256"/>
+      <match type="string" value="&lt;HEAD" offset="0:256"/>
+      <match type="string" value="&lt;head" offset="0:256"/>
+      <match type="string" value="&lt;HTML" offset="0:256"/>
+      <match type="string" value="&lt;html" offset="0:256"/>
+      <match type="string" value="&lt;SCRIPT" offset="0:256"/>
+      <match type="string" value="&lt;script" offset="0:256"/>
+      <match type="string" value="&lt;BODY" offset="0"/>
+      <match type="string" value="&lt;body" offset="0"/>
+      <match type="string" value="&lt;h1" offset="0"/>
+      <match type="string" value="&lt;H1" offset="0"/>
+      <match type="string" value="&lt;!doctype HTML" offset="0"/>
+    </magic>
+    <magic priority="40">
+      <match type="string" value="&lt;!--" offset="0"/>
+      <match type="string" value="&lt;TITLE" offset="0:256"/>
+      <match type="string" value="&lt;title" offset="0:256"/>
+    </magic>
+    <glob pattern="*.html" weight="80"/>
+    <glob pattern="*.htm" weight="80"/>
+  </mime-type>
+  <mime-type type="text/cache-manifest">
+    <comment>Web application cache file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="CACHE MANIFEST" offset="0">
+        <match type="string" value="\x20" offset="14"/>
+        <match type="string" value="\x09" offset="14"/>
+        <match type="string" value="\x0a" offset="14"/>
+        <match type="string" value="\x0d" offset="14"/>
+      </match>
+    </magic>
+    <glob pattern="*.manifest"/>
+  </mime-type>
+  <mime-type type="text/x-google-video-pointer">
+    <comment>Google Video Pointer shortcut</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="#.download.the.free.Google.Video.Player" offset="0"/>
+      <match type="string" value="# download the free Google Video Player" offset="0"/>
+    </magic>
+    <glob pattern="*.gvp"/>
+    <alias type="text/google-video-pointer"/>
+  </mime-type>
+  <mime-type type="text/x-haskell">
+    <comment>Haskell source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.hs"/>
+  </mime-type>
+  <mime-type type="text/x-idl">
+    <comment>IDL document</comment>
+    <acronym>IDL</acronym>
+    <expanded-acronym>Interface Definition Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.idl"/>
+  </mime-type>
+  <mime-type type="text/x-install">
+    <comment>installation instructions</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="INSTALL"/>
+  </mime-type>
+  <mime-type type="text/x-java">
+    <comment>Java source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.java"/>
+  </mime-type>
+  <mime-type type="text/x-ldif">
+    <comment>LDIF address book</comment>
+    <acronym>LDIF</acronym>
+    <expanded-acronym>LDAP Data Interchange Format</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="dn: cn=" offset="0"/>
+      <match type="string" value="dn: mail=" offset="0"/>
+    </magic>
+    <glob pattern="*.ldif"/>
+  </mime-type>
+  <mime-type type="text/x-lilypond">
+    <comment>Lilypond music sheet</comment>
+    <glob pattern="*.ly"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/x-literate-haskell">
+    <comment>LHS source code</comment>
+    <acronym>LHS</acronym>
+    <expanded-acronym>Literate Haskell source code</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.lhs"/>
+  </mime-type>
+  <mime-type type="text/x-log">
+    <comment>application log</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.log"/>
+  </mime-type>
+  <mime-type type="text/x-makefile">
+    <comment>Makefile build file</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="makefile"/>
+    <glob pattern="GNUmakefile"/>
+    <glob pattern="*.mk"/>
+    <glob pattern="*.mak"/>
+    <glob weight="10" pattern="Makefile.*"/>
+    <magic>
+      <match type="string" value="#!/usr/bin/make" offset="0"/>
+      <match type="string" value="#! /usr/bin/make" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/markdown">
+    <comment>Markdown document</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.md"/>
+    <glob pattern="*.mkd"/>
+    <glob pattern="*.markdown"/>
+    <alias type="text/x-markdown"/>
+  </mime-type>
+  <mime-type type="text/x-moc">
+    <comment>Qt MOC file</comment>
+    <acronym>Qt MOC</acronym>
+    <expanded-acronym>Qt Meta Object Compiler</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.moc"/>
+  </mime-type>
+  <mime-type type="text/x-ms-regedit">
+    <comment>Windows Registry extract</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="REGEDIT" offset="0"/>
+      <match type="string" value="Windows Registry Editor Version 5.00" offset="0"/>
+      <match type="string" value="\xff\xfeW\x00i\x00n\x00d\x00o\x00w\x00s\x00 \x00R\x00e\x00g\x00i\x00s\x00t\x00r\x00y\x00 \x00E\x00d\x00i\x00t\x00o\x00r\x00" offset="0"/>
+    </magic>
+    <glob pattern="*.reg"/>
+  </mime-type>
+  <mime-type type="text/x-mof">
+    <comment>MOF file</comment>
+    <acronym>MOF</acronym>
+    <expanded-acronym>Windows Managed Object File</expanded-acronym>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.mof"/>
+  </mime-type>
+  <mime-type type="text/x-mup">
+    <comment>Mup musical composition document</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="//!Mup" offset="0"/>
+    </magic>
+    <glob pattern="*.mup"/>
+    <glob pattern="*.not"/>
+  </mime-type>
+  <mime-type type="text/x-objcsrc">
+    <comment>Objective-C source code</comment>
+    <sub-class-of type="text/x-csrc"/>
+    <magic priority="30">
+      <match type="string" value="#import" offset="0"/>
+    </magic>
+    <glob pattern="*.m"/>
+  </mime-type>
+  <mime-type type="text/x-objc++src">
+    <comment>Objective-C++ source code</comment>
+    <sub-class-of type="text/x-c++src"/>
+    <sub-class-of type="text/x-objcsrc"/>
+    <glob pattern="*.mm"/>
+  </mime-type>
+  <mime-type type="text/x-ocaml">
+    <comment>OCaml source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.ml"/>
+    <glob pattern="*.mli"/>
+  </mime-type>
+  <mime-type type="text/x-opencl-src">
+    <comment>OpenCL source code</comment>
+    <acronym>OpenCL</acronym>
+    <expanded-acronym>Open Computing Language</expanded-acronym>
+    <sub-class-of type="text/x-csrc"/>
+    <glob pattern="*.cl"/>
+  </mime-type>
+  <mime-type type="text/x-matlab">
+    <comment>MATLAB file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic priority="10">
+      <match type="string" value="%" offset="0"/>
+    </magic>
+    <magic priority="10">
+      <match type="string" value="##" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="function" offset="0"/>
+    </magic>
+    <glob pattern="*.m"/>
+    <alias type="text/x-octave"/>
+  </mime-type>
+  <mime-type type="text/x-meson">
+    <comment>Meson source code</comment>
+    <glob pattern="meson.build"/>
+    <glob pattern="meson_options.txt"/>
+    <sub-class-of type="text/plain"/>
+  </mime-type>
+  <mime-type type="text/x-modelica">
+    <comment>Modelica model</comment>
+    <sub-class-of type="text/plain"/>
+    <magic priority="10">
+      <match type="string" value="//" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="function" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="class" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="model" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="record" offset="0"/>
+    </magic>
+    <glob pattern="*.mo"/>
+  </mime-type>
+  <mime-type type="text/x-pascal">
+    <comment>Pascal source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.p"/>
+    <glob pattern="*.pas"/>
+  </mime-type>
+  <mime-type type="text/x-patch">
+    <comment>differences between files</comment>
+    <alias type="text/x-diff"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="diff\t" offset="0"/>
+      <match type="string" value="diff " offset="0"/>
+      <match type="string" value="***\t" offset="0"/>
+      <match type="string" value="*** " offset="0"/>
+      <match type="string" value="=== " offset="0"/>
+      <match type="string" value="--- " offset="0"/>
+      <match type="string" value="Only in\t" offset="0"/>
+      <match type="string" value="Only in " offset="0"/>
+      <match type="string" value="Common subdirectories: " offset="0"/>
+      <match type="string" value="Index:" offset="0"/>
+    </magic>
+    <glob pattern="*.diff"/>
+    <glob pattern="*.patch"/>
+  </mime-type>
+  <mime-type type="text/x-dart">
+    <comment>Dart source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.dart"/>
+  </mime-type>
+  <mime-type type="text/x-go">
+    <comment>Go source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.go"/>
+  </mime-type>
+  <mime-type type="text/x-scons">
+    <comment>SCons configuration file</comment>
+    <sub-class-of type="text/x-python"/>
+    <glob pattern="SConstruct"/>
+    <glob pattern="SConscript"/>
+    <glob pattern="SConscript.*"/>
+  </mime-type>
+  <mime-type type="text/x-python3">
+    <comment>Python 3 script</comment>
+    <sub-class-of type='text/x-python'/>
+    <magic priority="60"><!-- higher priority than text/x-python -->
+      <match type="string" value="#!/bin/python3" offset="0"/>
+      <match type="string" value="#! /bin/python3" offset="0"/>
+      <match type="string" value='eval \"exec /bin/python3' offset="0"/>
+      <match type="string" value="#!/usr/bin/python3" offset="0"/>
+      <match type="string" value="#! /usr/bin/python3" offset="0"/>
+      <match type="string" value='eval \"exec /usr/bin/python3' offset="0"/>
+      <match type="string" value="#!/usr/local/bin/python3" offset="0"/>
+      <match type="string" value="#! /usr/local/bin/python3" offset="0"/>
+      <match type="string" value='eval \"exec /usr/local/bin/python3' offset="0"/>
+      <match type="string" value='/bin/env python3' offset="2:16"/>
+    </magic>
+    <glob pattern="*.py"/><!-- lower priority than in text/x-python -->
+    <glob pattern="*.py3" weight="60"/>
+    <glob pattern="*.py3x" weight="60"/>
+    <glob pattern="*.pyi" weight="60"/>
+  </mime-type>
+  <mime-type type="text/x-python">
+    <comment>Python script</comment>
+    <sub-class-of type='application/x-executable'/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="#!/bin/python" offset="0"/>
+      <match type="string" value="#! /bin/python" offset="0"/>
+      <match type="string" value='eval \"exec /bin/python' offset="0"/>
+      <match type="string" value="#!/usr/bin/python" offset="0"/>
+      <match type="string" value="#! /usr/bin/python" offset="0"/>
+      <match type="string" value='eval \"exec /usr/bin/python' offset="0"/>
+      <match type="string" value="#!/usr/local/bin/python" offset="0"/>
+      <match type="string" value="#! /usr/local/bin/python" offset="0"/>
+      <match type="string" value='eval \"exec /usr/local/bin/python' offset="0"/>
+      <match type="string" value='/bin/env python' offset="2:16"/>
+    </magic>
+    <glob pattern="*.py" weight="60"/>
+    <glob pattern="*.pyx" weight="60"/>
+    <glob pattern="*.wsgi" weight="60"/>
+  </mime-type>
+  <mime-type type="text/x-sagemath">
+    <comment>SageMath script</comment>
+    <sub-class-of type="text/x-python"/>
+    <glob pattern="*.sage" weight="60"/>
+  </mime-type>
+  <mime-type type="text/x-lua">
+    <comment>Lua script</comment>
+    <sub-class-of type='application/x-executable'/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="/bin/lua" offset="2:16"/>
+      <match type="string" value="/bin/luajit" offset="2:16"/>
+      <match type="string" value="/bin/env lua" offset="2:16"/>
+      <match type="string" value="/bin/env luajit" offset="2:16"/>
+    </magic>
+    <glob pattern="*.lua"/>
+  </mime-type>
+  <mime-type type="text/x-readme">
+    <comment>README document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob weight="10" pattern="README*"/>
+  </mime-type>
+  <mime-type type="text/x-nfo">
+    <comment>NFO document</comment>
+    <sub-class-of type="text/x-readme"/>
+    <glob pattern="*.nfo"/>
+  </mime-type>
+  <mime-type type="text/x-rpm-spec">
+    <comment>RPM spec file</comment>
+    <acronym>RPM</acronym>
+    <expanded-acronym>Red Hat Package Manager</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.spec"/>
+    <magic>
+      <match type="string" value="Summary: " offset="0"/>
+      <match type="string" value="%define " offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/x-sass">
+    <comment>Sass CSS pre-processor file</comment>
+    <acronym>Sass</acronym>
+    <expanded-acronym>Syntactically Awesome Style Sheets</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.sass"/>
+    <generic-icon name="text-x-generic"/>
+  </mime-type>
+  <mime-type type="text/x-scala">
+    <comment>Scala source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.scala"/>
+    <glob pattern="*.sc"/>
+  </mime-type>
+  <mime-type type="text/x-scheme">
+    <comment>Scheme source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.scm"/>
+    <glob pattern="*.ss"/>
+  </mime-type>
+  <mime-type type="text/x-scss">
+    <comment>SCSS pre-processor file</comment>
+    <acronym>SCSS</acronym>
+    <expanded-acronym>Sassy CSS</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.scss"/>
+    <generic-icon name="text-x-generic"/>
+  </mime-type>
+  <mime-type type="text/x-setext">
+    <comment>Setext document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.etx"/>
+  </mime-type>
+  <mime-type type="application/sql">
+    <comment>SQL code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.sql"/>
+    <alias type="text/x-sql"/>
+  </mime-type>
+  <mime-type type="text/tcl">
+    <comment>Tcl script</comment>
+    <alias type="text/x-tcl"/>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.tcl"/>
+    <glob pattern="*.tk"/>
+  </mime-type>
+  <mime-type type="text/x-tex">
+    <comment>TeX document</comment>
+    <sub-class-of type="text/plain"/>
+    <alias type="application/x-tex"/>
+    <glob pattern="*.tex"/>
+    <glob pattern="*.ltx"/>
+    <glob pattern="*.sty"/>
+    <glob pattern="*.cls"/>
+    <glob pattern="*.dtx"/>
+    <glob pattern="*.ins"/>
+    <glob pattern="*.latex"/>
+    <magic priority="10">
+      <match type="string" value="%" offset="0"/>
+    </magic>
+    <magic>
+      <match type="string" value="documentclass" offset="1"/>
+    </magic>
+  </mime-type>
+  <mime-type type="text/x-texinfo">
+    <comment>TeXInfo document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.texi"/>
+    <glob pattern="*.texinfo"/>
+  </mime-type>
+  <mime-type type="text/x-troff-me">
+    <comment>Troff ME input document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.me"/>
+  </mime-type>
+  <mime-type type="text/x-troff-mm">
+    <comment>Troff MM input document</comment>
+    <sub-class-of type="text/troff"/>
+    <glob pattern="*.mm"/>
+  </mime-type>
+  <mime-type type="text/x-troff-ms">
+    <comment>Troff MS input document</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.ms"/>
+  </mime-type>
+  <mime-type type="text/x-twig">
+    <comment>Twig template</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.twig"/>
+    <generic-icon name="text-x-generic-template"/>
+  </mime-type>
+  <mime-type type="text/x-uil">
+    <comment>X-Motif UIL table</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.uil"/>
+  </mime-type>
+  <mime-type type="text/x-uri">
+    <comment>resource location</comment>
+    <sub-class-of type="text/plain"/>
+    <!-- Note: text/uri-list is reserved by the XDND protocol! -->
+  </mime-type>
+  <mime-type type="text/x-uuencode">
+    <comment>uuencoded file</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.uue"/>
+    <magic>
+      <match type="string" value="begin " offset="0"/>
+    </magic>
+    <alias type="zz-application/zz-winassoc-uu"/>
+  </mime-type>
+  <mime-type type="text/vbscript">
+    <comment>VBScript program</comment>
+    <alias type="text/vbs"/>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-script"/>
+    <glob pattern="*.vbs"/>
+  </mime-type>
+  <mime-type type="text/x-xmi">
+    <comment>XMI file</comment>
+    <acronym>XMI</acronym>
+    <expanded-acronym>XML Metadata Interchange</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.xmi"/>
+    <root-XML namespaceURI="http://schema.omg.org/spec/XMI/2.0" localName="XMI"/>
+    <root-XML namespaceURI="http://schema.omg.org/spec/XMI/2.1" localName="XMI"/>
+  </mime-type>
+  <mime-type type="text/x-xslfo">
+    <comment>XSL FO file</comment>
+    <acronym>XSL FO</acronym>
+    <expanded-acronym>XSL Formatting Objects</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.fo"/>
+    <glob pattern="*.xslfo"/>
+    <root-XML namespaceURI="http://www.w3.org/1999/XSL/Format" localName="root"/>
+  </mime-type>
+  <mime-type type="text/x-iptables">
+    <comment>iptables configuration file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="/etc/sysconfig/iptables" offset="0:256"/>
+      <match type="string" value="*filter" offset="0:256">
+        <match type="string" value=":INPUT" offset="0:256">
+          <match type="string" value=":FORWARD" offset="0:256">
+            <match type="string" value=":OUTPUT" offset="0:256"/>
+          </match>
+        </match>
+      </match>
+      <match type="string" value="-A INPUT" offset="0:256">
+        <match type="string" value="-A FORWARD" offset="0:256">
+          <match type="string" value="-A OUTPUT" offset="0:256"/>
+        </match>
+      </match>
+      <match type="string" value="-P INPUT" offset="0:256">
+        <match type="string" value="-P FORWARD" offset="0:256">
+          <match type="string" value="-P OUTPUT" offset="0:256"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.iptables"/>
+  </mime-type>
+  <mime-type type="text/x-dbus-service">
+    <comment>D-Bus service file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="\n[D-BUS Service]\n" offset="0:256"/>
+      <match type="string" value="[D-BUS Service]\n" offset="0"/>
+    </magic>
+    <glob pattern="*.service"/>
+  </mime-type>
+  <mime-type type="text/x-systemd-unit">
+    <comment>systemd unit file</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <!-- Matches part-way through the file. -->
+      <match type="string" value="\n[Unit]\n" offset="0:256"/>
+      <match type="string" value="\n[Install]\n" offset="0:256"/>
+      <match type="string" value="\n[Automount]\n" offset="0:256"/>
+      <!-- Note no [Device] section exists (https://www.freedesktop.org/software/systemd/man/systemd.device.html) -->
+      <match type="string" value="\n[Mount]\n" offset="0:256"/>
+      <match type="string" value="\n[Path]\n" offset="0:256"/>
+      <match type="string" value="\n[Scope]\n" offset="0:256"/>
+      <match type="string" value="\n[Service]\n" offset="0:256"/>
+      <match type="string" value="\n[Slice]\n" offset="0:256"/>
+      <match type="string" value="\n[Socket]\n" offset="0:256"/>
+      <match type="string" value="\n[Swap]\n" offset="0:256"/>
+      <!-- Note no [Target] section exists (https://www.freedesktop.org/software/systemd/man/systemd.target.html) -->
+      <match type="string" value="\n[Timer]\n" offset="0:256"/>
+
+      <!-- Matches at the start of the file. -->
+      <match type="string" value="[Unit]\n" offset="0"/>
+      <match type="string" value="[Install]\n" offset="0"/>
+      <match type="string" value="[Automount]\n" offset="0"/>
+      <match type="string" value="[Mount]\n" offset="0"/>
+      <match type="string" value="[Path]\n" offset="0"/>
+      <match type="string" value="[Scope]\n" offset="0"/>
+      <match type="string" value="[Service]\n" offset="0"/>
+      <match type="string" value="[Slice]\n" offset="0"/>
+      <match type="string" value="[Socket]\n" offset="0"/>
+      <match type="string" value="[Swap]\n" offset="0"/>
+      <match type="string" value="[Timer]\n" offset="0"/>
+    </magic>
+    <glob pattern="*.automount"/>
+    <glob pattern="*.device"/>
+    <glob pattern="*.mount"/>
+    <glob pattern="*.path"/>
+    <glob pattern="*.scope"/>
+    <glob pattern="*.service"/>
+    <glob pattern="*.slice"/>
+    <glob pattern="*.socket"/>
+    <glob pattern="*.swap"/>
+    <glob pattern="*.target"/>
+    <glob pattern="*.timer"/>
+  </mime-type>
+  <mime-type type="application/xslt+xml">
+    <comment>XSLT stylesheet</comment>
+    <acronym>XSLT</acronym>
+    <expanded-acronym>eXtensible Stylesheet Language Transformation</expanded-acronym>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="&lt;xsl:stylesheet" offset="0:256"/>
+    </magic>
+    <glob pattern="*.xsl"/>
+    <glob pattern="*.xslt"/>
+    <root-XML namespaceURI="http://www.w3.org/1999/XSL/Transform" localName="stylesheet"/>
+    <sub-class-of type="application/xml"/>
+  </mime-type>
+  <mime-type type="text/x-maven+xml">
+    <comment>Maven description file</comment>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="pom.xml"/>
+    <glob pattern="settings.xml"/>
+    <sub-class-of type="application/xml"/>
+  </mime-type>
+  <mime-type type="text/xmcd">
+    <comment>XMCD CD database</comment>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="# xmcd" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/xml">
+    <comment>XML document</comment>
+    <acronym>XML</acronym>
+    <expanded-acronym>eXtensible Markup Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-html"/>
+    <magic priority="40">
+      <match type="string" value="&lt;?xml" offset="0"/>
+    </magic>
+    <glob pattern="*.xml"/>
+    <glob pattern="*.xbl"/>
+    <glob pattern="*.xsd"/>
+    <glob pattern="*.rng"/>
+    <alias type="text/xml"/>
+  </mime-type>
+  <mime-type type="application/xml-external-parsed-entity">
+    <comment>XML entities document</comment>
+    <acronym>XML</acronym>
+    <expanded-acronym>eXtensible Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="text-html"/>
+    <glob pattern="*.ent"/>
+    <alias type="text/xml-external-parsed-entity"/>
+  </mime-type>
+  <mime-type type="video/dv">
+    <comment>DV video</comment>
+    <acronym>DV</acronym>
+    <expanded-acronym>Digital Video</expanded-acronym>
+    <magic>
+      <match type="big32" value="0x1f070000" mask="0xffffff00" offset="0"/>
+    </magic>
+    <glob pattern="*.dv"/>
+  </mime-type>
+  <mime-type type="video/isivideo">
+    <comment>ISI video</comment>
+  </mime-type>
+  <mime-type type="video/mp2t">
+    <comment>MPEG-2 transport stream</comment>
+    <acronym>MPEG-2 TS</acronym>
+    <expanded-acronym>Moving Picture Experts Group 2 Transport Stream</expanded-acronym>
+    <magic>
+      <match type="byte" value="0x47" offset="0">
+        <match type="byte" value="0x47" offset="188">
+          <match type="byte" value="0x47" offset="376">
+            <match type="byte" value="0x47" offset="564">
+              <match type="byte" value="0x47" offset="752"/>
+            </match>
+          </match>
+        </match>
+      </match>
+      <match type="byte" value="0x47" offset="4">
+        <match type="byte" value="0x47" offset="196">
+          <match type="byte" value="0x47" offset="388">
+            <match type="byte" value="0x47" offset="580">
+              <match type="byte" value="0x47" offset="772"/>
+            </match>
+          </match>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.m2t"/>
+    <glob pattern="*.m2ts"/>
+    <glob pattern="*.ts"/>
+    <glob pattern="*.mts"/>
+    <glob pattern="*.cpi"/>
+    <glob pattern="*.clpi"/>
+    <glob pattern="*.mpl"/>
+    <glob pattern="*.mpls"/>
+    <glob pattern="*.bdm"/>
+    <glob pattern="*.bdmv"/>
+  </mime-type>
+  <mime-type type="video/mpeg">
+    <comment>MPEG video</comment>
+    <acronym>MPEG</acronym>
+    <expanded-acronym>Moving Picture Experts Group</expanded-acronym>
+    <alias type="video/x-mpeg"/>
+    <alias type="video/mpeg-system"/>
+    <alias type="video/x-mpeg-system"/>
+    <alias type="video/x-mpeg2"/>
+    <magic>
+      <match type="string" value="\x47\x3f\xff\x10" offset="0"/>
+      <match type="big32" value="0x000001b3" offset="0"/>
+      <match type="big32" value="0x000001ba" offset="0"/>
+    </magic>
+    <glob pattern="*.mpeg"/>
+    <glob pattern="*.mpg"/>
+    <glob pattern="*.mp2"/>
+    <glob pattern="*.mpe"/>
+    <glob pattern="*.vob"/>
+    <glob pattern="[0-9][0-9][0-9].vdr"/>
+  </mime-type>
+  <mime-type type="video/vnd.mpegurl">
+    <comment>Video playlist</comment>
+    <sub-class-of type="text/plain"/>
+    <alias type="video/x-mpegurl"/>
+    <magic>
+      <match type="string" value="#EXTM4U" offset="0"/>
+    </magic>
+    <glob pattern="*.m1u"/>
+    <glob pattern="*.m4u"/>
+    <glob pattern="*.mxu"/>
+  </mime-type>
+  <mime-type type="video/quicktime">
+    <comment>QuickTime video</comment>
+    <magic>
+      <match type="string" value="mdat" offset="12"/>
+      <match type="string" value="mdat" offset="4"/>
+      <match type="string" value="moov" offset="4"/>
+      <match type="string" value="ftypqt" offset="4"/>
+    </magic>
+    <glob pattern="*.qt"/>
+    <glob pattern="*.mov"/>
+    <glob pattern="*.moov"/>
+    <glob pattern="*.qtvr"/>
+  </mime-type>
+  <mime-type type="image/x-quicktime">
+    <comment>QuickTime image</comment>
+    <magic>
+      <match type="string" value="idat" offset="4"/>
+    </magic>
+    <glob pattern="*.qtif"/>
+    <glob pattern="*.qif"/>
+  </mime-type>
+  <mime-type type="image/ktx">
+    <comment>Khronos texture image</comment>
+    <magic priority="80">
+      <match type="big32" value="0xAB4B5458" offset="0">
+        <match type="big32" value="0x203131BB" offset="4">
+          <match type="big32" value="0x0D0A1A0A" offset="8"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ktx"/>
+  </mime-type>
+  <mime-type type="image/ktx2">
+    <comment>Khronos texture image</comment>
+    <magic priority="80">
+      <match type="big32" value="0xAB4B5458" offset="0">
+        <match type="big32" value="0x203230BB" offset="4">
+          <match type="big32" value="0x0D0A1A0A" offset="8"/>
+        </match>
+      </match>
+    </magic>
+    <glob pattern="*.ktx2"/>
+  </mime-type>
+  <mime-type type="image/astc">
+    <comment>ASTC texture</comment>
+    <acronym>ASTC</acronym>
+    <expanded-acronym>Advanced Scalable Texture Compression</expanded-acronym>
+    <glob pattern="*.astc"/>
+    <magic priority="80">
+      <match type="little32" value="0x5CA1AB13" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="video/vnd.vivo">
+    <comment>Vivo video</comment>
+    <alias type="video/vivo"/>
+    <glob pattern="*.viv"/>
+    <glob pattern="*.vivo"/>
+  </mime-type>
+  <mime-type type="video/wavelet">
+    <comment>Wavelet video</comment>
+  </mime-type>
+  <mime-type type="video/x-anim">
+    <comment>ANIM animation</comment>
+    <glob pattern="*.anim[1-9j]"/>
+  </mime-type>
+  <mime-type type="video/x-flic">
+    <comment>FLIC animation</comment>
+    <alias type="video/fli"/>
+    <alias type="video/x-fli"/>
+    <magic>
+      <match type="little16" value="0xAF11" offset="0"/>
+      <match type="little16" value="0xAF12" offset="0"/>
+    </magic>
+    <glob pattern="*.fli"/>
+    <glob pattern="*.flc"/>
+  </mime-type>
+  <mime-type type="application/x-hwp">
+    <comment>Haansoft Hangul document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match type="string" value="HWP Document File" offset="0"/>
+    </magic>
+    <glob pattern="*.hwp"/>
+    <alias type="application/vnd.haansoft-hwp"/>
+  </mime-type>
+  <mime-type type="application/x-hwt">
+    <comment>Haansoft Hangul document template</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.hwt"/>
+    <alias type="application/vnd.haansoft-hwt"/>
+  </mime-type>
+  <mime-type type="video/x-mng">
+    <comment>MNG animation</comment>
+    <acronym>MNG</acronym>
+    <expanded-acronym>Multiple-Image Network Graphics</expanded-acronym>
+    <magic>
+      <match type="string" value="\x8AMNG\x0D\x0A\x1A\x0A" offset="0"/>
+    </magic>
+    <glob pattern="*.mng"/>
+  </mime-type>
+  <mime-type type="application/vnd.ms-asf">
+    <comment>ASF video</comment>
+    <acronym>ASF</acronym>
+    <expanded-acronym>Advanced Streaming Format</expanded-acronym>
+    <alias type="video/x-ms-wm"/>
+    <alias type="video/x-ms-asf"/>
+    <alias type="video/x-ms-asf-plugin"/>
+    <glob pattern="*.asf"/>
+    <magic>
+      <match type="big32" value="0x3026b275" offset="0"/>
+      <match type="string" value="[Reference]" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-netshow-channel">
+    <comment>Windows Media Station file</comment>
+    <sub-class-of type="application/vnd.ms-asf"/>
+    <generic-icon name="video-x-generic"/>
+    <glob pattern="*.nsc"/>
+    <magic>
+      <match type="string" value="[Address]" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="video/x-ms-wmv">
+    <comment>Windows Media video</comment>
+    <sub-class-of type="application/vnd.ms-asf"/>
+    <glob pattern="*.wmv"/>
+  </mime-type>
+  <mime-type type="video/x-msvideo">
+    <comment>AVI video</comment>
+    <acronym>AVI</acronym>
+    <expanded-acronym>Audio Video Interleave</expanded-acronym>
+    <alias type="video/x-avi"/>
+    <alias type="video/avi"/>
+    <alias type="video/divx"/>
+    <alias type="video/msvideo"/>
+    <alias type="video/vnd.divx"/>
+    <magic>
+      <match type="string" value="RIFF" offset="0">
+        <match type="string" value="AVI " offset="8"/>
+      </match>
+      <match type="string" value="AVF0" offset="0">
+        <match type="string" value="AVI " offset="8"/>
+      </match>
+    </magic>
+    <glob pattern="*.avi"/>
+    <glob pattern="*.avf"/>
+    <glob pattern="*.divx"/>
+  </mime-type>
+  <mime-type type="video/x-nsv">
+    <comment>NullSoft video</comment>
+    <magic>
+      <match type="string" value="NSVf" offset="0"/>
+    </magic>
+    <glob pattern="*.nsv"/>
+  </mime-type>
+  <mime-type type="application/sdp">
+    <comment>SDP multicast stream file</comment>
+    <acronym>SDP</acronym>
+    <expanded-acronym>Session Description Protocol</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <alias type="application/x-sdp" />
+    <alias type="application/vnd.sdp" />
+    <generic-icon name="video-x-generic"/>
+    <magic>
+      <match type="string" value="v=" offset="0">
+        <match type="string" value="s=" offset="0:256" />
+      </match>
+    </magic>
+    <glob pattern="*.sdp"/>
+  </mime-type>
+  <mime-type type="video/x-sgi-movie">
+    <comment>SGI video</comment>
+    <magic>
+      <match type="string" value="MOVI" offset="0"/>
+    </magic>
+    <glob pattern="*.movie"/>
+  </mime-type>
+  <mime-type type="application/vnd.emusic-emusic_package">
+    <comment>eMusic download package</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="nF7YLao" offset="0"/>
+    </magic>
+    <glob pattern="*.emp"/>
+  </mime-type>
+  <mime-type type="application/vnd.google-earth.kml+xml">
+    <comment>KML geographic data</comment>
+    <acronym>KML</acronym>
+    <expanded-acronym>Keyhole Markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.kml"/>
+    <root-XML namespaceURI="http://www.opengis.net/kml/2.2" localName="kml"/>
+  </mime-type>
+  <mime-type type="application/vnd.google-earth.kmz">
+    <comment>KML geographic compressed data</comment>
+    <acronym>KML</acronym>
+    <expanded-acronym>Keyhole Markup Language</expanded-acronym>
+    <sub-class-of type="application/zip"/>
+    <glob pattern="*.kmz"/>
+  </mime-type>
+  <mime-type type="application/geo+json">
+    <comment>GeoJSON geospatial data</comment>
+    <sub-class-of type="application/json"/>
+    <glob pattern="*.geojson"/>
+    <glob pattern="*.geo.json"/>
+    <alias type="application/vnd.geo+json"/>
+  </mime-type>
+  <mime-type type="application/gpx+xml">
+    <comment>GPX geographic data</comment>
+    <acronym>GPX</acronym>
+    <expanded-acronym>GPS Exchange Format</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <alias type="application/gpx"/>
+    <alias type="application/x-gpx+xml"/>
+    <alias type="application/x-gpx"/>
+    <glob pattern="*.gpx"/>
+    <root-XML namespaceURI="http://www.topografix.com/GPX/1/0" localName="gpx"/>
+    <root-XML namespaceURI="http://www.topografix.com/GPX/1/1" localName="gpx"/>
+  </mime-type>
+  <mime-type type="application/x-ica">
+    <comment>Citrix ICA settings file</comment>
+    <acronym>ICA</acronym>
+    <expanded-acronym>Independent Computing Architecture</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.ica"/>
+  </mime-type>
+  <mime-type type="application/vnd.mozilla.xul+xml">
+    <comment>XUL interface document</comment>
+    <acronym>XUL</acronym>
+    <expanded-acronym>XML User interface markup Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <generic-icon name="x-office-document"/>
+    <root-XML namespaceURI="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" localName="window"/><!-- nocheck -->
+    <glob pattern="*.xul"/>
+  </mime-type>
+  <mime-type type="application/x-xpinstall">
+    <comment>XPInstall installer module</comment>
+    <sub-class-of type="application/zip"/>
+    <glob pattern="*.xpi"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.wordprocessingml.document">
+    <comment>Word 2007 document</comment>
+    <glob pattern="*.docx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.wordprocessingml.template">
+    <comment>Word 2007 document template</comment>
+    <glob pattern="*.dotx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.presentationml.presentation">
+    <comment>PowerPoint 2007 presentation</comment>
+    <glob pattern="*.pptx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.presentationml.slide">
+    <comment>PowerPoint 2007 slide</comment>
+    <glob pattern="*.sldx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.presentationml.slideshow">
+    <comment>PowerPoint 2007 show</comment>
+    <glob pattern="*.ppsx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.presentationml.template">
+    <comment>PowerPoint 2007 presentation template</comment>
+    <glob pattern="*.potx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
+    <comment>Excel 2007 spreadsheet</comment>
+    <glob pattern="*.xlsx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+  </mime-type>
+  <mime-type type="application/vnd.openxmlformats-officedocument.spreadsheetml.template">
+    <comment>Excel 2007 spreadsheet template</comment>
+    <glob pattern="*.xltx"/>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+  </mime-type>
+  <mime-type type="application/x-t602">
+    <comment>T602 document</comment>
+    <generic-icon name="x-office-document"/>
+    <magic>
+      <match offset="0" type="string" value="@CT 0" />
+      <match offset="0" type="string" value="@CT 1" />
+      <match offset="0" type="string" value="@CT 2" />
+    </magic>
+    <glob pattern="*.602" />
+  </mime-type>
+  <mime-type type="application/x-cisco-vpn-settings">
+    <comment>Cisco VPN settings</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <magic>
+      <match type="string" value="[main]" offset="0">
+        <match type="string" value="AuthType=" offset="0:256"/>
+      </match>
+    </magic>
+    <glob pattern="*.pcf"/>
+  </mime-type>
+  <mime-type type="application/vnd.iccprofile">
+    <comment>ICC profile</comment>
+    <acronym>ICC</acronym>
+    <expanded-acronym>International Color Consortium</expanded-acronym>
+    <magic>
+      <match type="string" value="acsp" offset="36"/>
+    </magic>
+    <glob pattern="*.icc"/>
+    <glob pattern="*.icm"/>
+  </mime-type>
+  <mime-type type="application/x-it87">
+    <comment>IT 8.7 color calibration file</comment>
+    <magic>
+      <match type="string" value="IT8.7" offset="0"/>
+    </magic>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.it87"/>
+  </mime-type>
+  <mime-type type="application/x-ccmx">
+    <comment>CCMX color correction file</comment>
+    <magic>
+      <match type="string" value="CCMX" offset="0"/>
+    </magic>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.ccmx"/>
+  </mime-type>
+  <mime-type type="application/winhlp">
+    <comment>WinHelp help file</comment>
+    <magic>
+      <match type="little32" value="0x00035f3f" offset="0"/>
+    </magic>
+    <glob pattern="*.hlp"/>
+    <alias type="zz-application/zz-winassoc-hlp" />
+  </mime-type>
+  <mime-type type="application/x-bsdiff">
+    <comment>binary differences between files</comment>
+    <magic>
+      <match type="string" value="BSDIFF40" offset="0"/>
+      <match type="string" value="BSDIFN40" offset="0"/>
+    </magic>
+    <glob pattern="*.bsdiff"/>
+  </mime-type>
+
+  <!-- Tree content-types -->
+  <mime-type type="x-content/image-dcf">
+    <!-- http://en.wikipedia.org/wiki/Design_rule_for_Camera_File_system -->
+    <comment>digital photos</comment>
+    <treemagic>
+      <treematch path="dcim" type="directory" non-empty="true"/>
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/video-vcd">
+    <!-- TRANSLATORS: This is a brand-name, not a generic term. Please see
+         http://en.wikipedia.org/wiki/Video_CD
+         http://www.herongyang.com/CD-DVD/VCD-Movie-File-Directory-Structure.html -->
+    <comment>Video CD</comment>
+    <treemagic>
+      <treematch path="mpegav/AVSEQ01.DAT" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/video-svcd">
+    <!-- TRANSLATORS: This is a brand-name, not a generic term. Please see
+         http://en.wikipedia.org/wiki/Super_Video_CD
+         http://everything2.com/index.pl?node_id=1009222 -->
+    <comment>Super Video CD</comment>
+    <treemagic>
+      <treematch path="MPEG2/AVSEQ01.MPG" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/video-dvd">
+    <!-- http://en.wikipedia.org/wiki/DVD-Video -->
+    <comment>video DVD</comment>
+    <treemagic>
+      <treematch path="VIDEO_TS/VIDEO_TS.IFO" type="file" />
+      <treematch path="VIDEO_TS/VIDEO_TS.IFO;1" type="file" />
+      <treematch path="VIDEO_TS.IFO" type="file" />
+      <treematch path="VIDEO_TS.IFO;1" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/audio-cdda">
+    <!-- http://en.wikipedia.org/wiki/Red_Book_(audio_CD_standard) -->
+    <comment>audio CD</comment>
+  </mime-type>
+
+  <mime-type type="x-content/blank-cd">
+    <!-- http://en.wikipedia.org/wiki/Compact_Disc -->
+    <comment>blank CD disc</comment>
+  </mime-type>
+
+  <mime-type type="x-content/blank-dvd">
+    <!-- http://en.wikipedia.org/wiki/DVD -->
+    <comment>blank DVD disc</comment>
+  </mime-type>
+
+  <mime-type type="x-content/blank-bd">
+    <!-- http://en.wikipedia.org/wiki/Blu-ray_Disc -->
+    <comment>blank Blu-ray disc</comment>
+  </mime-type>
+
+  <mime-type type="x-content/blank-hddvd">
+    <!-- http://en.wikipedia.org/wiki/HD_DVD -->
+    <comment>blank HD DVD disc</comment>
+  </mime-type>
+
+  <mime-type type="x-content/audio-dvd">
+    <!-- http://en.wikipedia.org/wiki/DVD-Audio -->
+    <comment>audio DVD</comment>
+    <treemagic>
+      <treematch path="AUDIO_TS/AUDIO_TS.IFO" type="file" />
+      <treematch path="AUDIO_TS/AUDIO_TS.IFO;1" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/video-bluray">
+    <!-- http://en.wikipedia.org/wiki/Blu-ray_Disc
+         http://www.blu-raydisc.com/Section-13470/Section-13890/Index.html -->
+    <comment>Blu-ray video disc</comment>
+    <treemagic>
+      <treematch path="BDAV" type="directory" non-empty="true"/>
+      <treematch path="BDMV" type="directory" non-empty="true"/>
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/video-hddvd">
+    <!-- http://en.wikipedia.org/wiki/HD_DVD
+         http://www.dvdafteredit.com/wiki/The_HVDVD_TS_Folder -->
+    <comment>HD DVD video disc</comment>
+    <treemagic>
+      <treematch path="HVDVD_TS/HV000I01.IFO" type="file" />
+      <treematch path="HVDVD_TS/HV001I01.IFO" type="file" />
+      <treematch path="HVDVD_TS/HVA00001.VTI" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/ebook-reader">
+    <!-- see fd.o hal spec -->
+    <comment>e-book reader</comment>
+    <treemagic>
+      <treematch path=".kobo" type="directory" non-empty="true"/>
+      <treematch path="system/com.amazon.ebook.booklet.reader" non-empty="false"/>
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/image-picturecd">
+    <!-- TRANSLATORS: This is a brand-name, not a generic term. Please see
+         http://en.wikipedia.org/wiki/Picture_CD
+         http://www.re.org/kristin/picturecd.html  -->
+    <comment>Picture CD</comment>
+    <treemagic>
+      <treematch path="PICTURES" type="directory" non-empty="true" match-case="true"/>
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/audio-player">
+    <!-- see fd.o hal spec -->
+    <comment>portable audio player</comment>
+  </mime-type>
+
+  <mime-type type="x-content/ostree-repository">
+    <!-- https://github.com/ostreedev/ostree/blob/master/man/ostree-create-usb.xml --><!-- nocheck -->
+    <comment>OSTree software updates</comment>
+    <treemagic>
+      <treematch path=".ostree" type="directory" non-empty="true" match-case="true" />
+      <treematch path="ostree/repo" type="directory" non-empty="true" match-case="true" />
+      <treematch path="var/lib/flatpak/repo" type="directory" non-empty="true" match-case="true" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/software">
+    <!-- http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+         http://bugzilla.gnome.org/show_bug.cgi?id=509823#c3 -->
+    <comment>software</comment>
+  </mime-type>
+
+  <mime-type type="x-content/unix-software">
+    <!-- http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+         http://bugzilla.gnome.org/show_bug.cgi?id=509823#c3 -->
+    <comment>UNIX software</comment>
+    <sub-class-of type="x-content/software"/>
+    <treemagic>
+      <treematch path=".autorun" type="file" match-case="true" />
+      <treematch path="autorun" type="file" match-case="true" />
+      <treematch path="autorun.sh" type="file" match-case="true" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="x-content/win32-software">
+    <!-- http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+         http://bugzilla.gnome.org/show_bug.cgi?id=509823#c3 -->
+    <comment>Windows software</comment>
+    <sub-class-of type="x-content/software"/>
+    <treemagic>
+      <treematch path="autorun.exe" type="file" executable="true" />
+      <treematch path="autorun.inf" type="file" />
+    </treemagic>
+  </mime-type>
+
+  <mime-type type="application/trig">
+    <comment>TriG RDF document</comment>
+    <acronym>TriG</acronym>
+    <expanded-acronym>TriG RDF Graph Triple Language</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.trig" />
+    <alias type="application/x-trig"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.apple.keynote">
+    <comment>Apple Keynote 5 presentation</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-presentation"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="index.apxl" offset="30"/>
+      </match>
+    </magic>
+    <glob pattern="*.key" weight="80"/>
+    <alias type="application/x-iwork-keynote-sffkey"/>
+  </mime-type>
+  <mime-type type="application/vnd.apple.numbers">
+    <comment>Apple Numbers spreadsheet</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-spreadsheet"/>
+    <magic priority="65">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="index.xml" offset="30"/>
+        <match type="string" value="Index/Document.iwa" offset="30"/>
+      </match>
+    </magic>
+    <glob pattern="*.numbers"/>
+    <alias type="application/x-iwork-numbers-sffnumbers"/>
+  </mime-type>
+  <mime-type type="application/vnd.apple.pages">
+    <comment>Apple Pages document</comment>
+    <sub-class-of type="application/zip"/>
+    <generic-icon name="x-office-document"/>
+    <magic priority="70">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="index.xml" offset="30"/>
+        <match type="string" value="Index/Document.iwa" offset="30"/>
+      </match>
+    </magic>
+    <glob pattern="*.pages"/>
+    <alias type="application/x-iwork-pages-sffpages"/>
+  </mime-type>
+  <mime-type type="application/vnd.apple.pkpass">
+    <comment>Apple Wallet pass</comment>
+    <sub-class-of type="application/zip"/>
+    <magic priority="65">
+      <match type="string" value="PK\003\004" offset="0">
+        <match type="string" value="pass.json" offset="30"/>
+      </match>
+    </magic>
+    <glob pattern="*.pkpass"/>
+  </mime-type>
+
+  <mime-type type="application/x-pagemaker">
+    <comment>Adobe PageMaker document</comment>
+    <sub-class-of type="application/x-ole-storage"/>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.p65"/>
+    <glob pattern="*.pm"/>
+    <glob pattern="*.pm6"/>
+    <glob pattern="*.pmd"/>
+  </mime-type>
+
+  <mime-type type="application/x-doom-wad">
+    <comment>Doom WAD file</comment>
+    <acronym>WAD</acronym>
+    <expanded-acronym>Where's All the Data</expanded-acronym>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="IWAD" offset="0"/>
+      <match type="string" value="PWAD" offset="0"/>
+    </magic>
+    <glob pattern="*.wad" weight="80"/>
+  </mime-type>
+
+  <mime-type type="application/x-amiga-disk-format">
+    <comment>Amiga disk image</comment>
+    <magic>
+      <match type="string" value="DOS\x00" offset="0"/>
+    </magic>
+    <glob pattern="*.adf"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.flatpak">
+    <comment>Flatpak application bundle</comment>
+    <generic-icon name="package-x-generic"/>
+    <magic>
+      <match type="string" value="xdg-app\x00\x01\x00\x89\xe5" offset="0"/>
+      <match type="string" value="flatpak\x00\x01\x00\x89\xe5" offset="0"/>
+    </magic>
+    <glob pattern="*.flatpak"/>
+    <glob pattern="*.xdgapp"/>
+    <alias type="application/vnd.xdgapp"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.flatpak.repo">
+    <comment>Flatpak repository description</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[Flatpak Repo]" offset="0:256"/>
+    </magic>
+    <glob pattern="*.flatpakrepo"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.flatpak.ref">
+    <comment>Flatpak repository reference</comment>
+    <generic-icon name="package-x-generic"/>
+    <sub-class-of type="text/plain"/>
+    <magic>
+      <match type="string" value="[Flatpak Ref]" offset="0:256"/>
+    </magic>
+    <glob pattern="*.flatpakref"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.squashfs">
+    <comment>Squashfs filesystem image</comment>
+    <magic>
+      <match type="string" value="sqsh" offset="0"/>
+      <match type="string" value="hsqs" offset="0"/>
+    </magic>
+    <glob pattern="*.sqsh"/>
+  </mime-type>
+
+  <!-- AppImage application bundle (Type 2) -->
+  <mime-type type="application/vnd.appimage">
+    <comment>AppImage application bundle</comment>
+    <sub-class-of type="application/x-executable"/>
+    <sub-class-of type="application/vnd.squashfs"/>
+    <generic-icon name="application-x-executable"/>
+    <magic>
+      <match value="ELF" type="string" offset="1" >
+        <match value="0x41" type="byte" offset="8">
+          <match value="0x49" type="byte" offset="9">
+            <match value="0x02" type="byte" offset="10"/>
+          </match>
+        </match>
+      </match>
+    </magic>
+    <glob weight="60" pattern="*.appimage"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.snap">
+    <comment>Snap package</comment>
+    <glob pattern="*.snap"/>
+    <sub-class-of type="application/vnd.squashfs"/>
+  </mime-type>
+
+  <!-- 3D models and GCODEs -->
+  <mime-type type="model/3mf">
+    <comment>3MF document</comment>
+    <acronym>3MF</acronym>
+    <expanded-acronym>3D Manufacturing Format</expanded-acronym>
+    <glob pattern="*.3mf"/>
+    <alias type="application/vnd.ms-3mfdocument"/>
+    <sub-class-of type="application/zip"/>
+  </mime-type>
+
+  <mime-type type="model/stl">
+    <comment>STL 3D model</comment>
+    <acronym>STL</acronym>
+    <expanded-acronym>StereoLithography</expanded-acronym>
+    <magic>
+      <match type="string" value="solid" offset="0"/>
+      <match type="string" value="SOLID" offset="0"/>
+    </magic>
+    <glob pattern="*.stl"/>
+    <alias type="model/x.stl-ascii"/>
+    <alias type="model/x.stl-binary"/>
+  </mime-type>
+
+  <mime-type type="text/x.gcode">
+    <comment>G-code file</comment>
+    <sub-class-of type="text/plain"/>
+    <generic-icon name="text-x-generic"/>
+    <glob pattern="*.gcode"/>
+  </mime-type>
+
+  <mime-type type="text/x-gcode-gx">
+    <comment>G-code Extended file</comment>
+    <magic>
+      <match type="string" value="xgcode 1.0" offset="0"/>
+    </magic>
+    <glob pattern="*.gx"/>
+  </mime-type>
+
+  <mime-type type="application/x-fds-disk">
+    <comment>Nintendo FDS disk image</comment>
+    <acronym>FDS</acronym>
+    <expanded-acronym>Famicom Disk System</expanded-acronym>
+    <glob pattern="*.fds"/>
+    <magic>
+      <match type="string" value="*NINTENDO-HVC*" offset="1"/>
+    </magic>
+  </mime-type>
+
+  <mime-type type="application/ovf">
+    <comment>OVF disk image</comment>
+    <acronym>OVF</acronym>
+    <expanded-acronym>Open Virtualization Format</expanded-acronym>
+    <glob pattern="*.ova"/>
+    <magic priority="60">
+      <match type="string" value=".ovf" offset="1:256">
+        <match type="string" value="ustar\0" offset="257"/>
+        <match type="string" value="ustar\040\040\0" offset="257"/>
+      </match>
+    </magic>
+    <alias type="application/x-virtualbox-ova"/>
+    <sub-class-of type="application/x-tar"/>
+  </mime-type>
+  <mime-type type="application/x-qed-disk">
+    <comment>QEMU QED disk image</comment>
+    <acronym>QED</acronym>
+    <expanded-acronym>QEMU Enhanced Disk</expanded-acronym>
+    <glob pattern="*.qed"/>
+    <magic>
+      <match type="string" value="QED\0" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-qemu-disk">
+    <comment>QEMU QCOW disk image</comment>
+    <acronym>QCOW</acronym>
+    <expanded-acronym>QEMU Copy On Write</expanded-acronym>
+    <glob pattern="*.qcow2"/>
+    <glob pattern="*.qcow"/>
+    <magic>
+      <match type="string" value="QFI" offset="0">
+        <match value="0xfb" type="byte" offset="3"/>
+      </match>
+    </magic>
+  </mime-type>
+  <mime-type type="application/x-vhd-disk">
+    <comment>VHD disk image</comment>
+    <acronym>VHD</acronym>
+    <expanded-acronym>Virtual Hard Disk</expanded-acronym>
+    <glob pattern="*.vhd"/>
+    <glob pattern="*.vpc"/>
+    <magic>
+      <match type="string" value="conectix" offset="0"/>
+    </magic>
+    <alias type="application/x-virtualbox-vhd"/>
+  </mime-type>
+  <mime-type type="application/x-vhdx-disk">
+    <comment>VHDX disk image</comment>
+    <acronym>VHDX</acronym>
+    <expanded-acronym>Virtual Hard Disk v2</expanded-acronym>
+    <glob pattern="*.vhdx"/>
+    <magic>
+      <match type="string" value="vhdxfile" offset="0"/>
+    </magic>
+    <alias type="application/x-virtualbox-vhdx"/>
+  </mime-type>
+  <mime-type type="application/x-vmdk-disk">
+    <comment>VMDK disk image</comment>
+    <acronym>VMDK</acronym>
+    <expanded-acronym>Virtual Machine Disk</expanded-acronym>
+    <glob pattern="*.vmdk"/>
+    <magic>
+      <match type="string" value="KDMV\x01\x00\x00\x00" offset="0"/>
+      <match type="string" value="KDMV\x02\x00\x00\x00" offset="0"/>
+    </magic>
+    <alias type="application/x-virtualbox-vmdk"/>
+  </mime-type>
+  <mime-type type="application/x-vdi-disk">
+    <comment>VDI disk image</comment>
+    <acronym>VDI</acronym>
+    <expanded-acronym>Virtual Disk Image</expanded-acronym>
+    <glob pattern="*.vdi"/>
+    <magic>
+      <match type="string" value="&lt;&lt;&lt; QEMU VM Virtual Disk Image >>>\n" offset="0"/>
+      <match type="string" value="&lt;&lt;&lt; Oracle VM VirtualBox Disk Image >>>\n" offset="0"/>
+      <match type="string" value="&lt;&lt;&lt; Sun VirtualBox Disk Image >>>\n" offset="0"/>
+      <match type="string" value="&lt;&lt;&lt; Sun xVM VirtualBox Disk Image >>>\n" offset="0"/>
+      <match type="string" value="&lt;&lt;&lt; innotek VirtualBox Disk Image >>>" offset="0"/>
+      <match type="string" value="&lt;&lt;&lt; CloneVDI VirtualBox Disk Image >>>\n" offset="0"/>
+    </magic>
+    <alias type="application/x-virtualbox-vdi"/>
+  </mime-type>
+
+  <mime-type type="application/x-appleworks-document">
+    <comment>AppleWorks document</comment>
+    <generic-icon name="x-office-document"/>
+    <glob pattern="*.cwk"/>
+  </mime-type>
+
+  <mime-type type="application/x-bps-patch">
+    <comment>BPS patch</comment>
+    <acronym>BPS</acronym>
+    <expanded-acronym>Binary Patching System</expanded-acronym>
+    <glob pattern="*.bps"/>
+    <magic>
+      <match type="string" value="BPS1" offset="0"/>
+    </magic>
+  </mime-type>
+
+  <mime-type type="application/x-ips-patch">
+    <comment>IPS patch</comment>
+    <acronym>IPS</acronym>
+    <expanded-acronym>International Patching System</expanded-acronym>
+    <glob pattern="*.ips"/>
+    <magic>
+      <match type="string" value="PATCH" offset="0"/>
+    </magic>
+  </mime-type>
+
+  <mime-type type="application/x-pyspread-spreadsheet">
+    <comment>Pyspread spreadsheet</comment>
+    <glob pattern="*.pysu"/>
+    <magic>
+      <match type="string" value="[Pyspread save file version]" offset="0"/>
+    </magic>
+    <generic-icon name="x-office-spreadsheet"/>
+  </mime-type>
+  <mime-type type="application/x-pyspread-bz-spreadsheet">
+    <comment>Pyspread spreadsheet (bzip-compressed)</comment>
+    <sub-class-of type="application/x-bzip"/>
+    <glob pattern="*.pys"/>
+    <generic-icon name="x-office-spreadsheet"/>
+  </mime-type>
+
+  <mime-type type="text/x-kotlin">
+    <comment>Kotlin source code</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.kt"/>
+  </mime-type>
+
+  <mime-type type="text/x-devicetree-source">
+    <comment>Devicetree source code</comment>
+    <acronym>DTS</acronym>
+    <expanded-acronym>Device Tree Source</expanded-acronym>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.dts"/>
+    <glob pattern="*.dtsi"/>
+    <magic>
+      <match type="string" mask="0x8080" value="\000\000" offset="0">
+        <match type="string" value="/dts-v1/" offset="0:4080"/>
+      </match>
+    </magic>
+    <magic priority="40">
+      <match type="string" mask="0x8080" value="\000\000" offset="0">
+        <match type="string" value="/ {" offset="0:4090"/>
+        <match type="string" value="include " offset="0:4080">
+          <match type="string" value=".dts" offset="10:4090"/>
+        </match>
+      </match>
+    </magic>
+  </mime-type>
+
+  <mime-type type="text/x-devicetree-binary">
+    <comment>Flattened Devicetree</comment>
+    <acronym>DTB</acronym>
+    <expanded-acronym>Device Tree Binary</expanded-acronym>
+    <glob pattern="*.dtb"/>
+    <magic>
+      <match type="big32" value="0xd00dfeed" offset="0"/>
+    </magic>
+  </mime-type>
+
+  <mime-type type="image/avif">
+    <comment>AVIF image</comment>
+    <acronym>AVIF</acronym>
+    <expanded-acronym>AV1 Image File Format</expanded-acronym>
+    <magic>
+      <match type="string" value="ftypavif" offset="4"/>
+      <match type="string" value="ftypavis" offset="4"/>
+      <match type="string" value="ftypmif1" offset="4">
+        <match type="string" value="avif" offset="16"/>
+        <match type="string" value="avif" offset="20"/>
+        <match type="string" value="avif" offset="24"/>
+      </match>
+    </magic>
+    <glob pattern="*.avif"/>
+    <glob pattern="*.avifs"/>
+    <alias type="image/avif-sequence"/>
+  </mime-type>
+
+  <mime-type type="video/vnd.radgamettools.bink">
+    <comment>Bink Video</comment>
+    <magic>
+      <match type="string" value="BIK" offset="0">
+        <match type="string" value="b" offset="3"/>
+        <match type="string" value="f" offset="3"/>
+        <match type="string" value="g" offset="3"/>
+        <match type="string" value="h" offset="3"/>
+        <match type="string" value="i" offset="3"/>
+      </match>
+      <match type="string" value="KB2" offset="0">
+        <match type="string" value="a" offset="3"/>
+        <match type="string" value="d" offset="3"/>
+        <match type="string" value="f" offset="3"/>
+        <match type="string" value="g" offset="3"/>
+        <match type="string" value="h" offset="3"/>
+        <match type="string" value="i" offset="3"/>
+        <match type="string" value="j" offset="3"/>
+        <match type="string" value="k" offset="3"/>
+      </match>
+    </magic>
+    <glob pattern="*.bik"/>
+    <glob pattern="*.bk2"/>
+  </mime-type>
+  <mime-type type="video/vnd.radgamettools.smacker">
+    <comment>Smacker Video</comment>
+    <magic>
+      <match type="string" value="SMK" offset="0">
+        <match type="string" value="2" offset="3"/>
+        <match type="string" value="4" offset="3"/>
+      </match>
+    </magic>
+    <glob pattern="*.smk"/>
+  </mime-type>
+  <mime-type type="text/org">
+    <comment>Org-mode file</comment>
+    <sub-class-of type="text/plain"/>
+    <glob pattern="*.org"/>
+  </mime-type>
+  <mime-type type="application/x-openzim">
+    <comment>OpenZIM file</comment>
+    <acronym>ZIM</acronym>
+    <expanded-acronym>Zeno IMproved</expanded-acronym>
+    <glob pattern="*.zim"/>
+    <magic>
+      <match type="string" value="\x5a\x49\x4d\x04" offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/sparql-query">
+    <comment>SPARQL query</comment>
+    <acronym>SPARQL</acronym>
+    <expanded-acronym>SPARQL Protocol and RDF Query Language</expanded-acronym>
+    <glob pattern="*.qs"/>
+    <magic priority="40">
+      <match type="string" value="PREFIX" offset="0"/>
+    </magic>
+  </mime-type>
+    <mime-type type="application/sparql-results+xml">
+    <comment>SPARQL query results</comment>
+    <acronym>SPARQL</acronym>
+    <expanded-acronym>SPARQL Protocol and RDF Query Language</expanded-acronym>
+    <sub-class-of type="application/xml"/>
+    <root-XML namespaceURI="http://www.w3.org/2005/sparql-results#" localName="sparql"/>
+    <glob pattern="*.srx"/>
+  </mime-type>
+</mime-info>
diff --git a/third_party/xdg_shared_mime_info/generate.py b/third_party/xdg_shared_mime_info/generate.py
new file mode 100755
index 0000000..0c726171
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/generate.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+# 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.
+
+"""Fetches, saves, and parses freedesktop.org.xml.in to generate mime_cache.cc.
+"""
+
+
+import os
+import re
+import sys
+import urllib.request
+import xml.etree.ElementTree as ET
+
+# Import jinja2 from //third_party/jinja2
+current_dir = os.path.dirname(__file__)
+src_dir = os.path.join(current_dir, *([os.pardir] * 2))
+sys.path.insert(1, os.path.join(src_dir, 'third_party'))
+import jinja2
+
+assert __name__ == '__main__'
+
+# A static extension has form such as '*.txt' where it starts with '*.'
+# followed by a static string without any of the 5 chars *?[]!
+# which are used by fnmatch for globbing.
+static_ext = re.compile(r'^\*\.[^*?\[\]!]+$')
+ns = ''
+mime_types = {}
+
+# Fetch and save local copy of xml.
+filename = 'freedesktop.org.xml.in'
+url = ('https://raw.githubusercontent.com/freedesktop/xdg-shared-mime-info/'
+       'HEAD/data/%s' % filename)
+xml = urllib.request.urlopen(url).read()
+with open(os.path.join(current_dir, filename), 'wb') as f:
+  f.write(xml)
+
+# Parse xml.
+root = ET.fromstring(xml)
+for mtype in root:
+  mglobs = mtype.findall(
+      '{http://www.freedesktop.org/standards/shared-mime-info}glob')
+  if mglobs is None:
+    continue
+  for mglob in mglobs:
+    if not static_ext.match(mglob.attrib['pattern']):
+      continue
+    ext = mglob.attrib['pattern'][2:]
+    if not mglob.attrib.get('case-sensitive', False):
+      ext = ext.lower()
+    weight = int(mglob.attrib['weight'])
+    if ext not in mime_types or weight > mime_types[ext]['weight']:
+      mime_types[ext] = {
+        'ext': ext,
+        'mime': mtype.attrib['type'],
+        'weight': weight,
+      }
+
+# Update mime_cache.cc.
+values = list(mime_types.values())
+values.sort(key=lambda x: x['ext'])
+env = jinja2.Environment(
+    loader=jinja2.FileSystemLoader(current_dir),
+    lstrip_blocks=True,
+    trim_blocks=True)
+template = env.get_template('mime_cache.cc.tmpl')
+with open(os.path.join(current_dir, 'mime_cache.gen.cc'), 'w') as f:
+  f.write(template.render({'mime_types': values}))
+
diff --git a/third_party/xdg_shared_mime_info/mime_cache.cc.tmpl b/third_party/xdg_shared_mime_info/mime_cache.cc.tmpl
new file mode 100644
index 0000000..904489d
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/mime_cache.cc.tmpl
@@ -0,0 +1,36 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/xdg_shared_mime_info/mime_cache.h"
+
+#include "base/containers/flat_map.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
+
+// File generated by //third_party/xdg_mime_shared_info/generate.py.
+namespace xdg_shared_mime_info {
+
+bool GetMimeCacheTypeFromExtension(std::string ext, std::string* result) {
+  static const base::NoDestructor<base::flat_map<std::string, std::string>>
+      kMap({
+{% for mime_type in mime_types %}
+          {"{{mime_type.ext}}", "{{mime_type.mime}}"},
+{% endfor %}
+      });
+
+  // If first match fails, try matching lower case.
+  auto it = kMap->find(ext);
+  if (it != kMap->end()) {
+    *result = it->second;
+    return true;
+  }
+  it = kMap->find(base::ToLowerASCII(ext));
+  if (it != kMap->end()) {
+    *result = it->second;
+    return true;
+  }
+  return false;
+}
+
+}  // namespace xdg_shared_mime_info
diff --git a/third_party/xdg_shared_mime_info/mime_cache.gen.cc b/third_party/xdg_shared_mime_info/mime_cache.gen.cc
new file mode 100644
index 0000000..9a13a57
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/mime_cache.gen.cc
@@ -0,0 +1,1087 @@
+// 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 "third_party/xdg_shared_mime_info/mime_cache.h"
+
+#include "base/containers/flat_map.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
+
+// File generated by //third_party/xdg_mime_shared_info/generate.py.
+namespace xdg_shared_mime_info {
+
+bool GetMimeCacheTypeFromExtension(std::string ext, std::string* result) {
+  static const base::NoDestructor<base::flat_map<std::string, std::string>>
+      kMap({
+          {"123", "application/vnd.lotus-1-2-3"},
+          {"32x", "application/x-genesis-32x-rom"},
+          {"3ds", "application/x-nintendo-3ds-rom"},
+          {"3dsx", "application/x-nintendo-3ds-executable"},
+          {"3g2", "video/3gpp2"},
+          {"3ga", "video/3gpp"},
+          {"3gp", "video/3gpp"},
+          {"3gp2", "video/3gpp2"},
+          {"3gpp", "video/3gpp"},
+          {"3gpp2", "video/3gpp2"},
+          {"3mf", "model/3mf"},
+          {"602", "application/x-t602"},
+          {"669", "audio/x-mod"},
+          {"7z", "application/x-7z-compressed"},
+          {"7z.001", "application/x-7z-compressed"},
+          {"C", "text/x-c++src"},
+          {"a", "application/x-archive"},
+          {"a26", "application/x-atari-2600-rom"},
+          {"a78", "application/x-atari-7800-rom"},
+          {"aa", "audio/x-pn-audibleaudio"},
+          {"aac", "audio/aac"},
+          {"aax", "audio/vnd.audible.aax"},
+          {"abw", "application/x-abiword"},
+          {"abw.crashed", "application/x-abiword"},
+          {"abw.gz", "application/x-abiword"},
+          {"ac3", "audio/ac3"},
+          {"ace", "application/x-ace"},
+          {"adb", "text/x-adasrc"},
+          {"adf", "application/x-amiga-disk-format"},
+          {"ads", "text/x-adasrc"},
+          {"adts", "audio/aac"},
+          {"afm", "application/x-font-afm"},
+          {"ag", "image/x-applix-graphics"},
+          {"agb", "application/x-gba-rom"},
+          {"ai", "application/illustrator"},
+          {"aif", "audio/x-aiff"},
+          {"aifc", "audio/x-aifc"},
+          {"aiff", "audio/x-aiff"},
+          {"aiffc", "audio/x-aifc"},
+          {"al", "application/x-perl"},
+          {"alz", "application/x-alz"},
+          {"amr", "audio/AMR"},
+          {"amz", "audio/x-amzxml"},
+          {"ani", "application/x-navi-animation"},
+          {"anx", "application/annodex"},
+          {"ape", "audio/x-ape"},
+          {"apk", "application/vnd.android.package-archive"},
+          {"appimage", "application/vnd.appimage"},
+          {"ar", "application/x-archive"},
+          {"arj", "application/x-arj"},
+          {"arw", "image/x-sony-arw"},
+          {"as", "application/x-applix-spreadsheet"},
+          {"asar", "application/x-asar"},
+          {"asc", "text/plain"},
+          {"asd", "text/x-common-lisp"},
+          {"asf", "application/vnd.ms-asf"},
+          {"asp", "application/x-asp"},
+          {"ass", "text/x-ssa"},
+          {"astc", "image/astc"},
+          {"asx", "audio/x-ms-asx"},
+          {"atom", "application/atom+xml"},
+          {"au", "audio/basic"},
+          {"automount", "text/x-systemd-unit"},
+          {"avf", "video/x-msvideo"},
+          {"avi", "video/x-msvideo"},
+          {"avif", "image/avif"},
+          {"avifs", "image/avif"},
+          {"aw", "application/x-applix-word"},
+          {"awb", "audio/AMR-WB"},
+          {"awk", "application/x-awk"},
+          {"axa", "audio/annodex"},
+          {"axv", "video/annodex"},
+          {"azw3", "application/vnd.amazon.mobi8-ebook"},
+          {"bak", "application/x-trash"},
+          {"bcpio", "application/x-bcpio"},
+          {"bdf", "application/x-font-bdf"},
+          {"bdm", "video/mp2t"},
+          {"bdmv", "video/mp2t"},
+          {"bib", "text/x-bibtex"},
+          {"bik", "video/vnd.radgamettools.bink"},
+          {"bk2", "video/vnd.radgamettools.bink"},
+          {"blend", "application/x-blender"},
+          {"blender", "application/x-blender"},
+          {"bmp", "image/bmp"},
+          {"bps", "application/x-bps-patch"},
+          {"bsdiff", "application/x-bsdiff"},
+          {"bz", "application/x-bzip"},
+          {"bz2", "application/x-bzip"},
+          {"c", "text/x-csrc"},
+          {"c++", "text/x-c++src"},
+          {"cab", "application/vnd.ms-cab-compressed"},
+          {"cap", "application/vnd.tcpdump.pcap"},
+          {"cb7", "application/x-cb7"},
+          {"cbl", "text/x-cobol"},
+          {"cbr", "application/vnd.comicbook-rar"},
+          {"cbt", "application/x-cbt"},
+          {"cbz", "application/vnd.comicbook+zip"},
+          {"cc", "text/x-c++src"},
+          {"cci", "application/x-nintendo-3ds-rom"},
+          {"ccmx", "application/x-ccmx"},
+          {"cdf", "application/x-netcdf"},
+          {"cdi", "application/x-discjuggler-cd-image"},
+          {"cdr", "application/vnd.corel-draw"},
+          {"cer", "application/pkix-cert"},
+          {"cert", "application/x-x509-ca-cert"},
+          {"cgb", "application/x-gameboy-color-rom"},
+          {"cgm", "image/cgm"},
+          {"chd", "application/x-mame-chd"},
+          {"chm", "application/vnd.ms-htmlhelp"},
+          {"chrt", "application/x-kchart"},
+          {"cl", "text/x-opencl-src"},
+          {"class", "application/x-java"},
+          {"clpi", "video/mp2t"},
+          {"cls", "text/x-tex"},
+          {"cmake", "text/x-cmake"},
+          {"cob", "text/x-cobol"},
+          {"coffee", "application/vnd.coffeescript"},
+          {"cpi", "video/mp2t"},
+          {"cpio", "application/x-cpio"},
+          {"cpio.gz", "application/x-cpio-compressed"},
+          {"cpp", "text/x-c++src"},
+          {"cr", "text/x-crystal"},
+          {"cr2", "image/x-canon-cr2"},
+          {"cr3", "image/x-canon-cr3"},
+          {"crdownload", "application/x-partial-download"},
+          {"crl", "application/pkix-crl"},
+          {"crt", "application/x-x509-ca-cert"},
+          {"crw", "image/x-canon-crw"},
+          {"cs", "text/x-csharp"},
+          {"csh", "application/x-csh"},
+          {"cso", "application/x-compressed-iso"},
+          {"css", "text/css"},
+          {"csv", "text/csv"},
+          {"csvs", "text/csv-schema"},
+          {"cue", "application/x-cue"},
+          {"cur", "image/x-win-bitmap"},
+          {"cwk", "application/x-appleworks-document"},
+          {"cxx", "text/x-c++src"},
+          {"d", "text/x-dsrc"},
+          {"dar", "application/x-dar"},
+          {"dart", "text/x-dart"},
+          {"dbf", "application/x-dbf"},
+          {"dbk", "application/x-docbook+xml"},
+          {"dcl", "text/x-dcl"},
+          {"dcm", "application/dicom"},
+          {"dcr", "image/x-kodak-dcr"},
+          {"dds", "image/x-dds"},
+          {"deb", "application/vnd.debian.binary-package"},
+          {"der", "application/x-x509-ca-cert"},
+          {"desktop", "application/x-desktop"},
+          {"device", "text/x-systemd-unit"},
+          {"dff", "audio/x-dff"},
+          {"di", "text/x-dsrc"},
+          {"dia", "application/x-dia-diagram"},
+          {"dib", "image/bmp"},
+          {"diff", "text/x-patch"},
+          {"divx", "video/x-msvideo"},
+          {"djv", "image/vnd.djvu"},
+          {"djvu", "image/vnd.djvu"},
+          {"dmg", "application/x-apple-diskimage"},
+          {"dmp", "application/vnd.tcpdump.pcap"},
+          {"dng", "image/x-adobe-dng"},
+          {"doc", "application/msword"},
+          {"docbook", "application/x-docbook+xml"},
+          {"docm", "application/vnd.ms-word.document.macroEnabled.12"},
+          {"docx",
+           "application/"
+           "vnd.openxmlformats-officedocument.wordprocessingml.document"},
+          {"dot", "application/msword-template"},
+          {"dotm", "application/vnd.ms-word.template.macroEnabled.12"},
+          {"dotx",
+           "application/"
+           "vnd.openxmlformats-officedocument.wordprocessingml.template"},
+          {"dsf", "audio/x-dsf"},
+          {"dsl", "text/x-dsl"},
+          {"dtb", "text/x-devicetree-binary"},
+          {"dtd", "application/xml-dtd"},
+          {"dts", "audio/vnd.dts"},
+          {"dtshd", "audio/vnd.dts.hd"},
+          {"dtsi", "text/x-devicetree-source"},
+          {"dtx", "text/x-tex"},
+          {"dv", "video/dv"},
+          {"dvi", "application/x-dvi"},
+          {"dvi.bz2", "application/x-bzdvi"},
+          {"dvi.gz", "application/x-gzdvi"},
+          {"dwg", "image/vnd.dwg"},
+          {"dxf", "image/vnd.dxf"},
+          {"e", "text/x-eiffel"},
+          {"egon", "application/x-egon"},
+          {"eif", "text/x-eiffel"},
+          {"el", "text/x-emacs-lisp"},
+          {"emf", "image/emf"},
+          {"eml", "message/rfc822"},
+          {"emp", "application/vnd.emusic-emusic_package"},
+          {"ent", "application/xml-external-parsed-entity"},
+          {"eps", "image/x-eps"},
+          {"eps.bz2", "image/x-bzeps"},
+          {"eps.gz", "image/x-gzeps"},
+          {"epsf", "image/x-eps"},
+          {"epsf.bz2", "image/x-bzeps"},
+          {"epsf.gz", "image/x-gzeps"},
+          {"epsi", "image/x-eps"},
+          {"epsi.bz2", "image/x-bzeps"},
+          {"epsi.gz", "image/x-gzeps"},
+          {"epub", "application/epub+zip"},
+          {"erl", "text/x-erlang"},
+          {"es", "application/ecmascript"},
+          {"escn", "application/x-godot-scene"},
+          {"etheme", "application/x-e-theme"},
+          {"etx", "text/x-setext"},
+          {"ex", "text/x-elixir"},
+          {"exe", "application/x-ms-dos-executable"},
+          {"exr", "image/x-exr"},
+          {"exs", "text/x-elixir"},
+          {"ez", "application/andrew-inset"},
+          {"f", "text/x-fortran"},
+          {"f4a", "audio/mp4"},
+          {"f4b", "audio/x-m4b"},
+          {"f4v", "video/mp4"},
+          {"f90", "text/x-fortran"},
+          {"f95", "text/x-fortran"},
+          {"fasl", "text/x-common-lisp"},
+          {"fb2", "application/x-fictionbook+xml"},
+          {"fb2.zip", "application/x-zip-compressed-fb2"},
+          {"fd", "application/x-raw-floppy-disk-image"},
+          {"fds", "application/x-fds-disk"},
+          {"feature", "text/x-gherkin"},
+          {"fig", "image/x-xfig"},
+          {"fit", "application/fits"},
+          {"fits", "application/fits"},
+          {"fl", "application/x-fluid"},
+          {"flac", "audio/flac"},
+          {"flatpak", "application/vnd.flatpak"},
+          {"flatpakref", "application/vnd.flatpak.ref"},
+          {"flatpakrepo", "application/vnd.flatpak.repo"},
+          {"flc", "video/x-flic"},
+          {"fli", "video/x-flic"},
+          {"flv", "video/x-flv"},
+          {"flw", "application/x-kivio"},
+          {"fm", "application/vnd.framemaker"},
+          {"fo", "text/x-xslfo"},
+          {"fodg", "application/vnd.oasis.opendocument.graphics-flat-xml"},
+          {"fodp", "application/vnd.oasis.opendocument.presentation-flat-xml"},
+          {"fods", "application/vnd.oasis.opendocument.spreadsheet-flat-xml"},
+          {"fodt", "application/vnd.oasis.opendocument.text-flat-xml"},
+          {"for", "text/x-fortran"},
+          {"fts", "application/fits"},
+          {"fxm", "video/x-javafx"},
+          {"g3", "image/g3fax"},
+          {"gb", "application/x-gameboy-rom"},
+          {"gba", "application/x-gba-rom"},
+          {"gbc", "application/x-gameboy-color-rom"},
+          {"gbr", "image/x-gimp-gbr"},
+          {"gcode", "text/x.gcode"},
+          {"gcrd", "text/vcard"},
+          {"gd", "application/x-gdscript"},
+          {"gdi", "application/x-gd-rom-cue"},
+          {"gdshader", "application/x-godot-shader"},
+          {"ged", "application/x-gedcom"},
+          {"gedcom", "application/x-gedcom"},
+          {"gem", "application/x-tar"},
+          {"gen", "application/x-genesis-rom"},
+          {"geo.json", "application/geo+json"},
+          {"geojson", "application/geo+json"},
+          {"gf", "application/x-tex-gf"},
+          {"gg", "application/x-gamegear-rom"},
+          {"gif", "image/gif"},
+          {"gih", "image/x-gimp-gih"},
+          {"glade", "application/x-glade"},
+          {"glb", "model/gltf-binary"},
+          {"gltf", "model/gltf+json"},
+          {"gml", "application/gml+xml"},
+          {"gmo", "application/x-gettext-translation"},
+          {"gnc", "application/x-gnucash"},
+          {"gnd", "application/gnunet-directory"},
+          {"gnucash", "application/x-gnucash"},
+          {"gnumeric", "application/x-gnumeric"},
+          {"gnuplot", "application/x-gnuplot"},
+          {"go", "text/x-go"},
+          {"gp", "application/x-gnuplot"},
+          {"gpg", "application/pgp-encrypted"},
+          {"gplt", "application/x-gnuplot"},
+          {"gpx", "application/gpx+xml"},
+          {"gra", "application/x-graphite"},
+          {"gradle", "text/x-gradle"},
+          {"groovy", "text/x-groovy"},
+          {"gs", "text/x-genie"},
+          {"gsf", "application/x-font-type1"},
+          {"gsh", "text/x-groovy"},
+          {"gsm", "audio/x-gsm"},
+          {"gtar", "application/x-tar"},
+          {"gv", "text/vnd.graphviz"},
+          {"gvp", "text/x-google-video-pointer"},
+          {"gvy", "text/x-groovy"},
+          {"gx", "text/x-gcode-gx"},
+          {"gy", "text/x-groovy"},
+          {"gz", "application/gzip"},
+          {"h", "text/x-chdr"},
+          {"h++", "text/x-c++hdr"},
+          {"h4", "application/x-hdf"},
+          {"h5", "application/x-hdf"},
+          {"hdf", "application/x-hdf"},
+          {"hdf4", "application/x-hdf"},
+          {"hdf5", "application/x-hdf"},
+          {"heic", "image/heif"},
+          {"heif", "image/heif"},
+          {"hfe", "application/x-hfe-floppy-image"},
+          {"hh", "text/x-c++hdr"},
+          {"hif", "image/heif"},
+          {"hlp", "application/winhlp"},
+          {"hp", "text/x-c++hdr"},
+          {"hpgl", "application/vnd.hp-hpgl"},
+          {"hpp", "text/x-c++hdr"},
+          {"hs", "text/x-haskell"},
+          {"htm", "text/html"},
+          {"html", "text/html"},
+          {"hwp", "application/x-hwp"},
+          {"hwt", "application/x-hwt"},
+          {"hxx", "text/x-c++hdr"},
+          {"ica", "application/x-ica"},
+          {"icb", "image/x-tga"},
+          {"icc", "application/vnd.iccprofile"},
+          {"icm", "application/vnd.iccprofile"},
+          {"icns", "image/x-icns"},
+          {"ico", "image/vnd.microsoft.icon"},
+          {"ics", "text/calendar"},
+          {"idl", "text/x-idl"},
+          {"ief", "image/ief"},
+          {"iff", "image/x-ilbm"},
+          {"iges", "model/iges"},
+          {"igs", "model/iges"},
+          {"ilbm", "image/x-ilbm"},
+          {"ime", "text/x-iMelody"},
+          {"img", "application/x-raw-disk-image"},
+          {"img.xz", "application/x-raw-disk-image-xz-compressed"},
+          {"imy", "text/x-iMelody"},
+          {"ins", "text/x-tex"},
+          {"ips", "application/x-ips-patch"},
+          {"iptables", "text/x-iptables"},
+          {"ipynb", "application/x-ipynb+json"},
+          {"iso", "application/x-cd-image"},
+          {"iso9660", "application/x-cd-image"},
+          {"it", "audio/x-it"},
+          {"it87", "application/x-it87"},
+          {"j2c", "image/x-jp2-codestream"},
+          {"j2k", "image/x-jp2-codestream"},
+          {"jad", "text/vnd.sun.j2me.app-descriptor"},
+          {"jar", "application/x-java-archive"},
+          {"java", "text/x-java"},
+          {"jceks", "application/x-java-jce-keystore"},
+          {"jks", "application/x-java-keystore"},
+          {"jng", "image/x-jng"},
+          {"jnlp", "application/x-java-jnlp-file"},
+          {"jp2", "image/jp2"},
+          {"jpc", "image/x-jp2-codestream"},
+          {"jpe", "image/jpeg"},
+          {"jpeg", "image/jpeg"},
+          {"jpf", "image/jpx"},
+          {"jpg", "image/jpeg"},
+          {"jpg2", "image/jp2"},
+          {"jpgm", "image/jpm"},
+          {"jpm", "image/jpm"},
+          {"jpr", "application/x-jbuilder-project"},
+          {"jpx", "application/x-jbuilder-project"},
+          {"jrd", "application/jrd+json"},
+          {"js", "text/javascript"},
+          {"jsm", "text/javascript"},
+          {"json", "application/json"},
+          {"json-patch", "application/json-patch+json"},
+          {"jsonld", "application/ld+json"},
+          {"jxl", "image/jxl"},
+          {"k25", "image/x-kodak-k25"},
+          {"k7", "application/x-thomson-cassette"},
+          {"kar", "audio/midi"},
+          {"karbon", "application/x-karbon"},
+          {"kdc", "image/x-kodak-kdc"},
+          {"kdelnk", "application/x-desktop"},
+          {"kexi", "application/x-kexiproject-sqlite2"},
+          {"kexic", "application/x-kexi-connectiondata"},
+          {"kexis", "application/x-kexiproject-shortcut"},
+          {"key", "application/vnd.apple.keynote"},
+          {"kfo", "application/x-kformula"},
+          {"kfx", "application/vnd.amazon.mobi8-ebook"},
+          {"kil", "application/x-killustrator"},
+          {"kino", "application/smil+xml"},
+          {"kml", "application/vnd.google-earth.kml+xml"},
+          {"kmz", "application/vnd.google-earth.kmz"},
+          {"kon", "application/x-kontour"},
+          {"kpm", "application/x-kpovmodeler"},
+          {"kpr", "application/x-kpresenter"},
+          {"kpt", "application/x-kpresenter"},
+          {"kra", "application/x-krita"},
+          {"krz", "application/x-krita"},
+          {"ks", "application/x-java-keystore"},
+          {"ksp", "application/x-kspread"},
+          {"ksy", "text/x-kaitai-struct"},
+          {"kt", "text/x-kotlin"},
+          {"ktx", "image/ktx"},
+          {"ktx2", "image/ktx2"},
+          {"kud", "application/x-kugar"},
+          {"kwd", "application/x-kword"},
+          {"kwt", "application/x-kword"},
+          {"la", "application/x-shared-library-la"},
+          {"latex", "text/x-tex"},
+          {"lbm", "image/x-ilbm"},
+          {"ldif", "text/x-ldif"},
+          {"lha", "application/x-lha"},
+          {"lhs", "text/x-literate-haskell"},
+          {"lhz", "application/x-lhz"},
+          {"lisp", "text/x-common-lisp"},
+          {"lnx", "application/x-atari-lynx-rom"},
+          {"loas", "audio/usac"},
+          {"log", "text/x-log"},
+          {"lrv", "video/mp4"},
+          {"lrz", "application/x-lrzip"},
+          {"ltx", "text/x-tex"},
+          {"lua", "text/x-lua"},
+          {"lwo", "image/x-lwo"},
+          {"lwob", "image/x-lwo"},
+          {"lwp", "application/vnd.lotus-wordpro"},
+          {"lws", "image/x-lws"},
+          {"ly", "text/x-lilypond"},
+          {"lyx", "application/x-lyx"},
+          {"lz", "application/x-lzip"},
+          {"lz4", "application/x-lz4"},
+          {"lzh", "application/x-lha"},
+          {"lzma", "application/x-lzma"},
+          {"lzo", "application/x-lzop"},
+          {"m", "text/x-objcsrc"},
+          {"m15", "audio/x-mod"},
+          {"m1u", "video/vnd.mpegurl"},
+          {"m2t", "video/mp2t"},
+          {"m2ts", "video/mp2t"},
+          {"m3u", "audio/x-mpegurl"},
+          {"m3u8", "audio/x-mpegurl"},
+          {"m4", "application/x-m4"},
+          {"m4a", "audio/mp4"},
+          {"m4b", "audio/x-m4b"},
+          {"m4r", "audio/x-m4r"},
+          {"m4u", "video/vnd.mpegurl"},
+          {"m4v", "video/mp4"},
+          {"m7", "application/x-thomson-cartridge-memo7"},
+          {"mab", "application/x-markaby"},
+          {"mak", "text/x-makefile"},
+          {"man", "application/x-troff-man"},
+          {"manifest", "text/cache-manifest"},
+          {"markdown", "text/markdown"},
+          {"mbox", "application/mbox"},
+          {"mc2", "text/vnd.senx.warpscript"},
+          {"md", "text/markdown"},
+          {"mdb", "application/vnd.ms-access"},
+          {"mdi", "image/vnd.ms-modi"},
+          {"mdx", "application/x-genesis-32x-rom"},
+          {"me", "text/x-troff-me"},
+          {"med", "audio/x-mod"},
+          {"meta4", "application/metalink4+xml"},
+          {"metalink", "application/metalink+xml"},
+          {"mgp", "application/x-magicpoint"},
+          {"mht", "application/x-mimearchive"},
+          {"mhtml", "application/x-mimearchive"},
+          {"mid", "audio/midi"},
+          {"midi", "audio/midi"},
+          {"mif", "application/x-mif"},
+          {"minipsf", "audio/x-minipsf"},
+          {"mj2", "video/mj2"},
+          {"mjp2", "video/mj2"},
+          {"mjpeg", "video/x-mjpeg"},
+          {"mjpg", "video/x-mjpeg"},
+          {"mjs", "text/javascript"},
+          {"mk", "text/x-makefile"},
+          {"mk3d", "video/x-matroska-3d"},
+          {"mka", "audio/x-matroska"},
+          {"mkd", "text/markdown"},
+          {"mkv", "video/x-matroska"},
+          {"ml", "text/x-ocaml"},
+          {"mli", "text/x-ocaml"},
+          {"mm", "text/x-objc++src"},
+          {"mmf", "application/vnd.smaf"},
+          {"mml", "application/mathml+xml"},
+          {"mng", "video/x-mng"},
+          {"mo", "application/x-gettext-translation"},
+          {"mo3", "audio/x-mo3"},
+          {"mobi", "application/x-mobipocket-ebook"},
+          {"moc", "text/x-moc"},
+          {"mod", "audio/x-mod"},
+          {"mof", "text/x-mof"},
+          {"moov", "video/quicktime"},
+          {"mount", "text/x-systemd-unit"},
+          {"mov", "video/quicktime"},
+          {"movie", "video/x-sgi-movie"},
+          {"mp+", "audio/x-musepack"},
+          {"mp2", "audio/mp2"},
+          {"mp3", "audio/mpeg"},
+          {"mp4", "video/mp4"},
+          {"mpc", "audio/x-musepack"},
+          {"mpe", "video/mpeg"},
+          {"mpeg", "video/mpeg"},
+          {"mpg", "video/mpeg"},
+          {"mpga", "audio/mpeg"},
+          {"mpl", "text/x-mpl2"},
+          {"mpls", "video/mp2t"},
+          {"mpp", "audio/x-musepack"},
+          {"mrl", "text/x-mrml"},
+          {"mrml", "text/x-mrml"},
+          {"mrw", "image/x-minolta-mrw"},
+          {"ms", "text/x-troff-ms"},
+          {"msi", "application/x-msi"},
+          {"msod", "image/x-msod"},
+          {"msx", "application/x-msx-rom"},
+          {"mtl", "model/mtl"},
+          {"mtm", "audio/x-mod"},
+          {"mts", "video/mp2t"},
+          {"mup", "text/x-mup"},
+          {"mxf", "application/mxf"},
+          {"mxmf", "audio/mobile-xmf"},
+          {"mxu", "video/vnd.mpegurl"},
+          {"n64", "application/x-n64-rom"},
+          {"nb", "application/mathematica"},
+          {"nc", "application/x-netcdf"},
+          {"nds", "application/x-nintendo-ds-rom"},
+          {"nef", "image/x-nikon-nef"},
+          {"nes", "application/x-nes-rom"},
+          {"nez", "application/x-nes-rom"},
+          {"nfo", "text/x-nfo"},
+          {"ngc", "application/x-neo-geo-pocket-color-rom"},
+          {"ngp", "application/x-neo-geo-pocket-rom"},
+          {"not", "text/x-mup"},
+          {"nrw", "image/x-nikon-nrw"},
+          {"nsc", "application/x-netshow-channel"},
+          {"nsv", "video/x-nsv"},
+          {"numbers", "application/vnd.apple.numbers"},
+          {"nzb", "application/x-nzb"},
+          {"o", "application/x-object"},
+          {"obj", "application/x-tgif"},
+          {"ocl", "text/x-ocl"},
+          {"oda", "application/oda"},
+          {"odb", "application/vnd.oasis.opendocument.database"},
+          {"odc", "application/vnd.oasis.opendocument.chart"},
+          {"odf", "application/vnd.oasis.opendocument.formula"},
+          {"odg", "application/vnd.oasis.opendocument.graphics"},
+          {"odi", "application/vnd.oasis.opendocument.image"},
+          {"odm", "application/vnd.oasis.opendocument.text-master"},  // nocheck
+          {"odp", "application/vnd.oasis.opendocument.presentation"},
+          {"ods", "application/vnd.oasis.opendocument.spreadsheet"},
+          {"odt", "application/vnd.oasis.opendocument.text"},
+          {"oga", "audio/ogg"},
+          {"ogg", "audio/ogg"},
+          {"ogm", "video/x-ogm+ogg"},
+          {"ogv", "video/ogg"},
+          {"ogx", "application/ogg"},
+          {"old", "application/x-trash"},
+          {"oleo", "application/x-oleo"},
+          {"ooc", "text/x-ooc"},
+          {"opml", "text/x-opml+xml"},
+          {"oprc", "application/vnd.palm"},
+          {"opus", "audio/ogg"},
+          {"ora", "image/openraster"},
+          {"orf", "image/x-olympus-orf"},
+          {"org", "text/org"},
+          {"otc", "application/vnd.oasis.opendocument.chart-template"},
+          {"otf", "application/vnd.oasis.opendocument.formula-template"},
+          {"otg", "application/vnd.oasis.opendocument.graphics-template"},
+          {"oth", "application/vnd.oasis.opendocument.text-web"},
+          {"otp", "application/vnd.oasis.opendocument.presentation-template"},
+          {"ots", "application/vnd.oasis.opendocument.spreadsheet-template"},
+          {"ott", "application/vnd.oasis.opendocument.text-template"},
+          {"ova", "application/ovf"},
+          {"owl", "application/rdf+xml"},
+          {"owx", "application/owl+xml"},
+          {"oxps", "application/oxps"},
+          {"oxt", "application/vnd.openofficeorg.extension"},
+          {"p", "text/x-pascal"},
+          {"p10", "application/pkcs10"},
+          {"p12", "application/pkcs12"},
+          {"p65", "application/x-pagemaker"},
+          {"p7b", "application/x-pkcs7-certificates"},
+          {"p7c", "application/pkcs7-mime"},
+          {"p7m", "application/pkcs7-mime"},
+          {"p7s", "application/pkcs7-signature"},
+          {"p8", "application/pkcs8"},
+          {"p8e", "application/pkcs8-encrypted"},
+          {"pack", "application/x-java-pack200"},
+          {"pages", "application/vnd.apple.pages"},
+          {"pak", "application/x-pak"},
+          {"par2", "application/x-par2"},
+          {"part", "application/x-partial-download"},
+          {"pas", "text/x-pascal"},
+          {"pat", "image/x-gimp-pat"},
+          {"patch", "text/x-patch"},
+          {"path", "text/x-systemd-unit"},
+          {"pbm", "image/x-portable-bitmap"},
+          {"pcap", "application/vnd.tcpdump.pcap"},
+          {"pcd", "image/x-photo-cd"},
+          {"pce", "application/x-pc-engine-rom"},
+          {"pcf", "application/x-font-pcf"},
+          {"pcf.gz", "application/x-font-pcf"},
+          {"pcf.z", "application/x-font-pcf"},
+          {"pcl", "application/vnd.hp-pcl"},
+          {"pct", "image/x-pict"},
+          {"pcx", "image/vnd.zbrush.pcx"},
+          {"pdb", "application/x-aportisdoc"},
+          {"pdc", "application/x-aportisdoc"},
+          {"pdf", "application/pdf"},
+          {"pdf.bz2", "application/x-bzpdf"},
+          {"pdf.gz", "application/x-gzpdf"},
+          {"pdf.lz", "application/x-lzpdf"},
+          {"pdf.xz", "application/x-xzpdf"},
+          {"pef", "image/x-pentax-pef"},
+          {"pem", "application/x-x509-ca-cert"},
+          {"perl", "application/x-perl"},
+          {"pfa", "application/x-font-type1"},
+          {"pfb", "application/x-font-type1"},
+          {"pfx", "application/pkcs12"},
+          {"pgm", "image/x-portable-graymap"},
+          {"pgn", "application/vnd.chess-pgn"},
+          {"pgp", "application/pgp-encrypted"},
+          {"php", "application/x-php"},
+          {"php3", "application/x-php"},
+          {"php4", "application/x-php"},
+          {"php5", "application/x-php"},
+          {"phps", "application/x-php"},
+          {"pict", "image/x-pict"},
+          {"pict1", "image/x-pict"},
+          {"pict2", "image/x-pict"},
+          {"pk", "application/x-tex-pk"},
+          {"pkg", "application/x-xar"},
+          {"pkipath", "application/pkix-pkipath"},
+          {"pkpass", "application/vnd.apple.pkpass"},
+          {"pkr", "application/pgp-keys"},
+          {"pl", "application/x-perl"},
+          {"pla", "audio/x-iriver-pla"},
+          {"pln", "application/x-planperfect"},
+          {"pls", "audio/x-scpls"},
+          {"pm", "application/x-perl"},
+          {"pm6", "application/x-pagemaker"},
+          {"pmd", "application/x-pagemaker"},
+          {"png", "image/png"},
+          {"pnm", "image/x-portable-anymap"},
+          {"pntg", "image/x-macpaint"},
+          {"po", "text/x-gettext-translation"},
+          {"pod", "application/x-perl"},
+          {"por", "application/x-spss-por"},
+          {"pot", "application/vnd.ms-powerpoint"},
+          {"potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},
+          {"potx",
+           "application/"
+           "vnd.openxmlformats-officedocument.presentationml.template"},
+          {"ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},
+          {"ppm", "image/x-portable-pixmap"},
+          {"pps", "application/vnd.ms-powerpoint"},
+          {"ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
+          {"ppsx",
+           "application/"
+           "vnd.openxmlformats-officedocument.presentationml.slideshow"},
+          {"ppt", "application/vnd.ms-powerpoint"},
+          {"pptm",
+           "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
+          {"pptx",
+           "application/"
+           "vnd.openxmlformats-officedocument.presentationml.presentation"},
+          {"ppz", "application/vnd.ms-powerpoint"},
+          {"pqa", "application/vnd.palm"},
+          {"prc", "application/x-mobipocket-ebook"},
+          {"ps", "application/postscript"},
+          {"ps.bz2", "application/x-bzpostscript"},
+          {"ps.gz", "application/x-gzpostscript"},
+          {"psd", "image/vnd.adobe.photoshop"},
+          {"psf", "application/x-font-linux-psf"},
+          {"psf.gz", "application/x-gz-font-linux-psf"},
+          {"psflib", "audio/x-psflib"},
+          {"psid", "audio/prs.sid"},
+          {"psw", "application/x-pocket-word"},
+          {"pub", "application/vnd.ms-publisher"},
+          {"pw", "application/x-pw"},
+          {"py", "text/x-python"},
+          {"py3", "text/x-python3"},
+          {"py3x", "text/x-python3"},
+          {"pyc", "application/x-python-bytecode"},
+          {"pyi", "text/x-python3"},
+          {"pyo", "application/x-python-bytecode"},
+          {"pys", "application/x-pyspread-bz-spreadsheet"},
+          {"pysu", "application/x-pyspread-spreadsheet"},
+          {"pyx", "text/x-python"},
+          {"qcow", "application/x-qemu-disk"},
+          {"qcow2", "application/x-qemu-disk"},
+          {"qd", "application/x-raw-floppy-disk-image"},
+          {"qed", "application/x-qed-disk"},
+          {"qif", "application/x-qw"},
+          {"qml", "text/x-qml"},
+          {"qmlproject", "text/x-qml"},
+          {"qmltypes", "text/x-qml"},
+          {"qp", "application/x-qpress"},
+          {"qs", "application/sparql-query"},
+          {"qt", "video/quicktime"},
+          {"qti", "application/x-qtiplot"},
+          {"qti.gz", "application/x-qtiplot"},
+          {"qtif", "image/x-quicktime"},
+          {"qtl", "application/x-quicktime-media-link"},
+          {"qtvr", "video/quicktime"},
+          {"ra", "audio/vnd.rn-realaudio"},
+          {"raf", "image/x-fuji-raf"},
+          {"ram", "application/ram"},
+          {"raml", "application/raml+yaml"},
+          {"rar", "application/vnd.rar"},
+          {"ras", "image/x-cmu-raster"},
+          {"raw", "image/x-panasonic-rw"},
+          {"raw-disk-image", "application/x-raw-disk-image"},
+          {"raw-disk-image.xz", "application/x-raw-disk-image-xz-compressed"},
+          {"rax", "audio/vnd.rn-realaudio"},
+          {"rb", "application/x-ruby"},
+          {"rdf", "application/rdf+xml"},
+          {"rdfs", "application/rdf+xml"},
+          {"reg", "text/x-ms-regedit"},
+          {"rej", "text/x-reject"},
+          {"res", "application/x-godot-resource"},
+          {"rgb", "image/x-rgb"},
+          {"rle", "image/rle"},
+          {"rm", "application/vnd.rn-realmedia"},
+          {"rmj", "application/vnd.rn-realmedia"},
+          {"rmm", "application/vnd.rn-realmedia"},
+          {"rms", "application/vnd.rn-realmedia"},
+          {"rmvb", "application/vnd.rn-realmedia"},
+          {"rmx", "application/vnd.rn-realmedia"},
+          {"rnc", "application/relax-ng-compact-syntax"},
+          {"rng", "application/xml"},
+          {"roff", "text/troff"},
+          {"ros", "text/x-common-lisp"},
+          {"rp", "image/vnd.rn-realpix"},
+          {"rpm", "application/x-rpm"},
+          {"rs", "text/rust"},
+          {"rss", "application/rss+xml"},
+          {"rst", "text/x-rst"},
+          {"rt", "text/vnd.rn-realtext"},
+          {"rtf", "application/rtf"},
+          {"rtx", "text/richtext"},
+          {"rv", "video/vnd.rn-realvideo"},
+          {"rvx", "video/vnd.rn-realvideo"},
+          {"rw2", "image/x-panasonic-rw2"},
+          {"s3m", "audio/x-s3m"},
+          {"sage", "text/x-sagemath"},
+          {"sam", "application/x-amipro"},
+          {"sami", "application/x-sami"},
+          {"sap", "application/x-thomson-sap-image"},
+          {"sass", "text/x-sass"},
+          {"sav", "application/x-spss-sav"},
+          {"sc", "text/x-scala"},
+          {"scala", "text/x-scala"},
+          {"scm", "text/x-scheme"},
+          {"scn", "application/x-godot-scene"},
+          {"scope", "text/x-systemd-unit"},
+          {"scss", "text/x-scss"},
+          {"sda", "application/vnd.stardivision.draw"},
+          {"sdc", "application/vnd.stardivision.calc"},
+          {"sdd", "application/vnd.stardivision.impress"},
+          {"sdp", "application/vnd.stardivision.impress"},
+          {"sds", "application/vnd.stardivision.chart"},
+          {"sdw", "application/vnd.stardivision.writer"},
+          {"service", "text/x-dbus-service"},
+          {"sfc", "application/vnd.nintendo.snes.rom"},
+          {"sg", "application/x-sg1000-rom"},
+          {"sgb", "application/x-gameboy-rom"},
+          {"sgd", "application/x-genesis-rom"},
+          {"sgf", "application/x-go-sgf"},
+          {"sgi", "image/x-sgi"},
+          {"sgl", "application/vnd.stardivision.writer"},
+          {"sgm", "text/sgml"},
+          {"sgml", "text/sgml"},
+          {"sh", "application/x-shellscript"},
+          {"shape", "application/x-dia-shape"},
+          {"shar", "application/x-shar"},
+          {"shn", "application/x-shorten"},
+          {"siag", "application/x-siag"},
+          {"sid", "audio/prs.sid"},
+          {"sig", "application/pgp-signature"},
+          {"sik", "application/x-trash"},
+          {"sis", "application/vnd.symbian.install"},
+          {"sisx", "x-epoc/x-sisx-app"},
+          {"sit", "application/x-stuffit"},
+          {"siv", "application/sieve"},
+          {"sk", "image/x-skencil"},
+          {"sk1", "image/x-skencil"},
+          {"skr", "application/pgp-keys"},
+          {"sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"},
+          {"sldx",
+           "application/"
+           "vnd.openxmlformats-officedocument.presentationml.slide"},
+          {"slice", "text/x-systemd-unit"},
+          {"slk", "text/spreadsheet"},
+          {"smaf", "application/vnd.smaf"},
+          {"smc", "application/vnd.nintendo.snes.rom"},
+          {"smd", "application/vnd.stardivision.mail"},
+          {"smf", "application/vnd.stardivision.math"},
+          {"smi", "application/smil+xml"},
+          {"smil", "application/smil+xml"},
+          {"smk", "video/vnd.radgamettools.smacker"},
+          {"sml", "application/smil+xml"},
+          {"sms", "application/x-sms-rom"},
+          {"snap", "application/vnd.snap"},
+          {"snd", "audio/basic"},
+          {"so", "application/x-sharedlib"},
+          {"socket", "text/x-systemd-unit"},
+          {"spc", "application/x-pkcs7-certificates"},
+          {"spd", "application/x-font-speedo"},
+          {"spec", "text/x-rpm-spec"},
+          {"spl", "application/vnd.adobe.flash.movie"},
+          {"spm", "application/x-source-rpm"},
+          {"spx", "audio/x-speex+ogg"},
+          {"sql", "application/sql"},
+          {"sqlite2", "application/x-sqlite2"},
+          {"sqlite3", "application/vnd.sqlite3"},
+          {"sqsh", "application/vnd.squashfs"},
+          {"sr2", "image/x-sony-sr2"},
+          {"src", "application/x-wais-source"},
+          {"src.rpm", "application/x-source-rpm"},
+          {"srf", "image/x-sony-srf"},
+          {"srt", "application/x-subrip"},
+          {"srx", "application/sparql-results+xml"},
+          {"ss", "text/x-scheme"},
+          {"ssa", "text/x-ssa"},
+          {"stc", "application/vnd.sun.xml.calc.template"},
+          {"std", "application/vnd.sun.xml.draw.template"},
+          {"sti", "application/vnd.sun.xml.impress.template"},
+          {"stl", "model/stl"},
+          {"stm", "audio/x-stm"},
+          {"stw", "application/vnd.sun.xml.writer.template"},
+          {"sty", "text/x-tex"},
+          {"sub", "text/x-microdvd"},
+          {"sun", "image/x-sun-raster"},
+          {"sv", "text/x-svsrc"},
+          {"sv4cpio", "application/x-sv4cpio"},
+          {"sv4crc", "application/x-sv4crc"},
+          {"svg", "image/svg+xml"},
+          {"svg.gz", "image/svg+xml-compressed"},
+          {"svgz", "image/svg+xml-compressed"},
+          {"svh", "text/x-svhdr"},
+          {"swap", "text/x-systemd-unit"},
+          {"swf", "application/vnd.adobe.flash.movie"},
+          {"swm", "application/x-ms-wim"},
+          {"sxc", "application/vnd.sun.xml.calc"},
+          {"sxd", "application/vnd.sun.xml.draw"},
+          {"sxg", "application/vnd.sun.xml.writer.global"},
+          {"sxi", "application/vnd.sun.xml.impress"},
+          {"sxm", "application/vnd.sun.xml.math"},
+          {"sxw", "application/vnd.sun.xml.writer"},
+          {"sylk", "text/spreadsheet"},
+          {"t", "application/x-perl"},
+          {"t2t", "text/x-txt2tags"},
+          {"tak", "audio/x-tak"},
+          {"tar", "application/x-tar"},
+          {"tar.bz", "application/x-bzip-compressed-tar"},
+          {"tar.bz2", "application/x-bzip-compressed-tar"},
+          {"tar.gz", "application/x-compressed-tar"},
+          {"tar.lrz", "application/x-lrzip-compressed-tar"},
+          {"tar.lz", "application/x-lzip-compressed-tar"},
+          {"tar.lz4", "application/x-lz4-compressed-tar"},
+          {"tar.lzma", "application/x-lzma-compressed-tar"},
+          {"tar.lzo", "application/x-tzo"},
+          {"tar.xz", "application/x-xz-compressed-tar"},
+          {"tar.z", "application/x-tarz"},
+          {"tar.zst", "application/x-zstd-compressed-tar"},
+          {"target", "text/x-systemd-unit"},
+          {"taz", "application/x-tarz"},
+          {"tb2", "application/x-bzip-compressed-tar"},
+          {"tbz", "application/x-bzip-compressed-tar"},
+          {"tbz2", "application/x-bzip-compressed-tar"},
+          {"tcl", "text/tcl"},
+          {"tex", "text/x-tex"},
+          {"texi", "text/x-texinfo"},
+          {"texinfo", "text/x-texinfo"},
+          {"tga", "image/x-tga"},
+          {"tgz", "application/x-compressed-tar"},
+          {"theme", "application/x-theme"},
+          {"themepack", "application/x-windows-themepack"},
+          {"tif", "image/tiff"},
+          {"tiff", "image/tiff"},
+          {"timer", "text/x-systemd-unit"},
+          {"tk", "text/tcl"},
+          {"tlrz", "application/x-lrzip-compressed-tar"},
+          {"tlz", "application/x-lzma-compressed-tar"},
+          {"tnef", "application/vnd.ms-tnef"},
+          {"tnf", "application/vnd.ms-tnef"},
+          {"toc", "application/x-cdrdao-toc"},
+          {"toml", "application/toml"},
+          {"torrent", "application/x-bittorrent"},
+          {"tpic", "image/x-tga"},
+          {"tr", "text/troff"},
+          {"tres", "application/x-godot-resource"},
+          {"trig", "application/trig"},
+          {"ts", "text/vnd.trolltech.linguist"},
+          {"tscn", "application/x-godot-scene"},
+          {"tsv", "text/tab-separated-values"},
+          {"tta", "audio/x-tta"},
+          {"ttc", "font/collection"},
+          {"ttf", "font/ttf"},
+          {"ttl", "text/turtle"},
+          {"ttx", "application/x-font-ttx"},
+          {"twig", "text/x-twig"},
+          {"txt", "text/plain"},
+          {"txz", "application/x-xz-compressed-tar"},
+          {"tzo", "application/x-tzo"},
+          {"tzst", "application/x-zstd-compressed-tar"},
+          {"udeb", "application/vnd.debian.binary-package"},
+          {"ufraw", "application/x-ufraw"},
+          {"ui", "application/x-designer"},
+          {"uil", "text/x-uil"},
+          {"ult", "audio/x-mod"},
+          {"unf", "application/x-nes-rom"},
+          {"uni", "audio/x-mod"},
+          {"unif", "application/x-nes-rom"},
+          {"url", "application/x-mswinurl"},
+          {"ustar", "application/x-ustar"},
+          {"uue", "text/x-uuencode"},
+          {"v", "text/x-verilog"},
+          {"v64", "application/x-n64-rom"},
+          {"vala", "text/x-vala"},
+          {"vapi", "text/x-vala"},
+          {"vb", "application/x-virtual-boy-rom"},
+          {"vbs", "text/vbscript"},
+          {"vcard", "text/vcard"},
+          {"vcf", "text/vcard"},
+          {"vcs", "text/calendar"},
+          {"vct", "text/vcard"},
+          {"vda", "image/x-tga"},
+          {"vdi", "application/x-vdi-disk"},
+          {"vhd", "text/x-vhdl"},
+          {"vhdl", "text/x-vhdl"},
+          {"vhdx", "application/x-vhdx-disk"},
+          {"viv", "video/vnd.vivo"},
+          {"vivo", "video/vnd.vivo"},
+          {"vlc", "audio/x-mpegurl"},
+          {"vmdk", "application/x-vmdk-disk"},
+          {"vob", "video/mpeg"},
+          {"voc", "audio/x-voc"},
+          {"vor", "application/vnd.stardivision.writer"},
+          {"vpc", "application/x-vhd-disk"},
+          {"vrm", "model/vrml"},
+          {"vrml", "model/vrml"},
+          {"vsd", "application/vnd.visio"},
+          {"vsdm", "application/vnd.ms-visio.drawing.macroEnabled.main+xml"},
+          {"vsdx", "application/vnd.ms-visio.drawing.main+xml"},
+          {"vss", "application/vnd.visio"},
+          {"vssm", "application/vnd.ms-visio.stencil.macroEnabled.main+xml"},
+          {"vssx", "application/vnd.ms-visio.stencil.main+xml"},
+          {"vst", "application/vnd.visio"},
+          {"vstm", "application/vnd.ms-visio.template.macroEnabled.main+xml"},
+          {"vstx", "application/vnd.ms-visio.template.main+xml"},
+          {"vsw", "application/vnd.visio"},
+          {"vtt", "text/vtt"},
+          {"wad", "application/x-doom-wad"},
+          {"wav", "audio/x-wav"},
+          {"wax", "audio/x-ms-asx"},
+          {"wb1", "application/x-quattropro"},
+          {"wb2", "application/x-quattropro"},
+          {"wb3", "application/x-quattropro"},
+          {"wbmp", "image/vnd.wap.wbmp"},
+          {"wcm", "application/vnd.ms-works"},
+          {"wdb", "application/vnd.ms-works"},
+          {"webm", "video/webm"},
+          {"webp", "image/webp"},
+          {"wim", "application/x-ms-wim"},
+          {"wk1", "application/vnd.lotus-1-2-3"},
+          {"wk3", "application/vnd.lotus-1-2-3"},
+          {"wk4", "application/vnd.lotus-1-2-3"},
+          {"wkdownload", "application/x-partial-download"},
+          {"wks", "application/vnd.lotus-1-2-3"},
+          {"wma", "audio/x-ms-wma"},
+          {"wmf", "image/wmf"},
+          {"wml", "text/vnd.wap.wml"},
+          {"wmls", "text/vnd.wap.wmlscript"},
+          {"wmv", "video/x-ms-wmv"},
+          {"wmx", "audio/x-ms-asx"},
+          {"woff", "font/woff"},
+          {"woff2", "font/woff2"},
+          {"wp", "application/vnd.wordperfect"},
+          {"wp4", "application/vnd.wordperfect"},
+          {"wp5", "application/vnd.wordperfect"},
+          {"wp6", "application/vnd.wordperfect"},
+          {"wpd", "application/vnd.wordperfect"},
+          {"wpg", "application/x-wpg"},
+          {"wpl", "application/vnd.ms-wpl"},
+          {"wpp", "application/vnd.wordperfect"},
+          {"wps", "application/vnd.ms-works"},
+          {"wri", "application/x-mswrite"},
+          {"wrl", "model/vrml"},
+          {"ws", "application/x-wonderswan-rom"},
+          {"wsc", "application/x-wonderswan-color-rom"},
+          {"wsgi", "text/x-python"},
+          {"wv", "audio/x-wavpack"},
+          {"wvc", "audio/x-wavpack-correction"},
+          {"wvp", "audio/x-wavpack"},
+          {"wvx", "audio/x-ms-asx"},
+          {"wwf", "application/x-wwf"},
+          {"x3f", "image/x-sigma-x3f"},
+          {"xac", "application/x-gnucash"},
+          {"xar", "application/x-xar"},
+          {"xbel", "application/x-xbel"},
+          {"xbl", "application/xml"},
+          {"xbm", "image/x-xbitmap"},
+          {"xcf", "image/x-xcf"},
+          {"xcf.bz2", "image/x-compressed-xcf"},
+          {"xcf.gz", "image/x-compressed-xcf"},
+          {"xdgapp", "application/vnd.flatpak"},
+          {"xhe", "audio/usac"},
+          {"xht", "application/xhtml+xml"},
+          {"xhtml", "application/xhtml+xml"},
+          {"xi", "audio/x-xi"},
+          {"xla", "application/vnd.ms-excel"},
+          {"xlam", "application/vnd.ms-excel.addin.macroEnabled.12"},
+          {"xlc", "application/vnd.ms-excel"},
+          {"xld", "application/vnd.ms-excel"},
+          {"xlf", "application/xliff+xml"},
+          {"xliff", "application/xliff+xml"},
+          {"xll", "application/vnd.ms-excel"},
+          {"xlm", "application/vnd.ms-excel"},
+          {"xlr", "application/vnd.ms-works"},
+          {"xls", "application/vnd.ms-excel"},
+          {"xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
+          {"xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},
+          {"xlsx",
+           "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
+          {"xlt", "application/vnd.ms-excel"},
+          {"xltm", "application/vnd.ms-excel.template.macroEnabled.12"},
+          {"xltx",
+           "application/"
+           "vnd.openxmlformats-officedocument.spreadsheetml.template"},
+          {"xlw", "application/vnd.ms-excel"},
+          {"xm", "audio/x-xm"},
+          {"xmf", "audio/x-xmf"},
+          {"xmi", "text/x-xmi"},
+          {"xml", "application/xml"},
+          {"xpi", "application/x-xpinstall"},
+          {"xpm", "image/x-xpixmap"},
+          {"xps", "application/vnd.ms-xpsdocument"},
+          {"xsd", "application/xml"},
+          {"xsl", "application/xslt+xml"},
+          {"xslfo", "text/x-xslfo"},
+          {"xslt", "application/xslt+xml"},
+          {"xspf", "application/xspf+xml"},
+          {"xul", "application/vnd.mozilla.xul+xml"},
+          {"xwd", "image/x-xwindowdump"},
+          {"xz", "application/x-xz"},
+          {"yaml", "application/x-yaml"},
+          {"yml", "application/x-yaml"},
+          {"yt", "video/vnd.youtube.yt"},
+          {"z", "application/x-compress"},
+          {"z64", "application/x-n64-rom"},
+          {"zabw", "application/x-abiword"},
+          {"zim", "application/x-openzim"},
+          {"zip", "application/zip"},
+          {"zipx", "application/zip"},
+          {"zoo", "application/x-zoo"},
+          {"zsav", "application/x-spss-sav"},
+          {"zst", "application/zstd"},
+          {"zz", "application/zlib"},
+      });
+
+  // If first match fails, try matching lower case.
+  auto it = kMap->find(ext);
+  if (it != kMap->end()) {
+    *result = it->second;
+    return true;
+  }
+  it = kMap->find(base::ToLowerASCII(ext));
+  if (it != kMap->end()) {
+    *result = it->second;
+    return true;
+  }
+  return false;
+}
+
+}  // namespace xdg_shared_mime_info
diff --git a/third_party/xdg_shared_mime_info/mime_cache.h b/third_party/xdg_shared_mime_info/mime_cache.h
new file mode 100644
index 0000000..a86c3879
--- /dev/null
+++ b/third_party/xdg_shared_mime_info/mime_cache.h
@@ -0,0 +1,18 @@
+// 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 THIRD_PARTY_XDG_SHARED_MIME_INFO_MIME_CACHE_H_
+#define THIRD_PARTY_XDG_SHARED_MIME_INFO_MIME_CACHE_H_
+
+#include <string>
+
+namespace xdg_shared_mime_info {
+
+// Gets the mime type (if any) that is associated with the file extension.
+// Returns true if a corresponding mime type exists.
+bool GetMimeCacheTypeFromExtension(std::string ext, std::string* result);
+
+}  // namespace xdg_shared_mime_info
+
+#endif  // THIRD_PARTY_XDG_SHARED_MIME_INFO_MIME_CACHE_H_
diff --git a/tools/binary_size/libsupersize/viewer/caspian/diff.cc b/tools/binary_size/libsupersize/viewer/caspian/diff.cc
index e4339ef..2c0228d1 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/diff.cc
+++ b/tools/binary_size/libsupersize/viewer/caspian/diff.cc
@@ -4,6 +4,7 @@
 
 #include "tools/binary_size/libsupersize/viewer/caspian/diff.h"
 
+#include <cmath>
 #include <deque>
 #include <functional>
 #include <iostream>
@@ -245,15 +246,20 @@
     SectionId section_id = pair.first;
     float padding = pair.second;
     if (padding != 0.0f) {
+      float abs_padding = std::abs(padding);
       ret.owned_symbols.emplace_back();
-      Symbol& after_sym = ret.owned_symbols.back();
-      after_sym.section_id_ = section_id;
-      after_sym.size_ = padding;
-      after_sym.padding_ = padding;
-      after_sym.full_name_ = "Overhead: aggregate padding of diff'ed symbols";
-      after_sym.template_name_ = after_sym.full_name_;
-      after_sym.name_ = after_sym.full_name_;
-      ret.delta_symbols.push_back(DeltaSymbol(nullptr, &after_sym));
+      Symbol& abs_sym = ret.owned_symbols.back();
+      abs_sym.section_id_ = section_id;
+      abs_sym.size_ = abs_padding;
+      abs_sym.padding_ = abs_padding;
+      abs_sym.full_name_ = "Overhead: aggregate padding of diff'ed symbols";
+      abs_sym.template_name_ = abs_sym.full_name_;
+      abs_sym.name_ = abs_sym.full_name_;
+      if (padding < 0.0f) {
+        ret.delta_symbols.emplace_back(&abs_sym, nullptr);
+      } else {
+        ret.delta_symbols.emplace_back(nullptr, &abs_sym);
+      }
     }
   }
   return ret;
diff --git a/tools/binary_size/libsupersize/viewer/caspian/model.cc b/tools/binary_size/libsupersize/viewer/caspian/model.cc
index c35f56af..fc4f4dda 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/model.cc
+++ b/tools/binary_size/libsupersize/viewer/caspian/model.cc
@@ -5,6 +5,7 @@
 #include "tools/binary_size/libsupersize/viewer/caspian/model.h"
 
 #include <algorithm>
+#include <cassert>
 #include <iostream>
 #include <list>
 #include <sstream>
@@ -132,6 +133,12 @@
   return static_cast<float>(Padding()) / NumAliases();
 }
 
+float Symbol::BeforePss() const {
+  // This function should only used for diff mode.
+  assert(false);
+  return 0.0f;
+}
+
 DiffStatus Symbol::GetDiffStatus() const {
   return DiffStatus::kUnchanged;
 }
@@ -267,6 +274,10 @@
   return 0;
 }
 
+float DeltaSymbol::BeforePss() const {
+  return before_ ? before_->Pss() : 0.0f;
+}
+
 DiffStatus DeltaSymbol::GetDiffStatus() const {
   if (!before_) {
     return DiffStatus::kAdded;
@@ -354,11 +365,10 @@
 }
 
 void TreeNode::WriteIntoJson(
-    int depth,
+    const JsonWriteOptions& opts,
     std::function<bool(const TreeNode* const& l, const TreeNode* const& r)>
         compare_func,
-    bool is_sparse,
-    bool method_count_mode,
+    int depth,
     Json::Value* out) {
   if (symbol) {
     (*out)["container"] = std::string(symbol->ContainerName());
@@ -382,7 +392,7 @@
     }
   } else {
     (*out)["idPath"] = id_path.ToString();
-    if (!is_sparse && !children.empty()) {
+    if (!opts.is_sparse && !children.empty()) {
       // Add tag to containers in which all child symbols were added/removed.
       DiffStatus diff_status = node_stats.GetGlobalDiffStatus();
       if (diff_status != DiffStatus::kUnchanged) {
@@ -399,6 +409,9 @@
   type += static_cast<char>(biggest_section);
   (*out)["type"] = type;
   (*out)["size"] = size;
+  if (opts.diff_mode) {
+    (*out)["beforeSize"] = before_size;
+  }
   if (padding) {
     (*out)["padding"] = padding;
   }
@@ -406,7 +419,7 @@
     (*out)["address"] = address;
   }
   (*out)["flags"] = flags;
-  node_stats.WriteIntoJson(method_count_mode, &(*out)["childStats"]);
+  node_stats.WriteIntoJson(opts, &(*out)["childStats"]);
 
   const size_t kMaxChildNodesToExpand = 1000;
   if (children.size() > kMaxChildNodesToExpand) {
@@ -422,8 +435,8 @@
     // TODO: Support additional compare functions.
     std::sort(children.begin(), children.end(), compare_func);
     for (unsigned int i = 0; i < children.size(); i++) {
-      children[i]->WriteIntoJson(depth - 1, compare_func, is_sparse,
-                                 method_count_mode, &(*out)["children"][i]);
+      children[i]->WriteIntoJson(opts, compare_func, depth - 1,
+                                 &(*out)["children"][i]);
     }
   }
 }
@@ -450,8 +463,10 @@
   }
 }
 
-void NodeStats::WriteIntoJson(bool method_count_mode, Json::Value* out) const {
+void NodeStats::WriteIntoJson(const JsonWriteOptions& opts,
+                              Json::Value* out) const {
   (*out) = Json::Value(Json::objectValue);
+  bool is_diff_count = opts.diff_mode && opts.method_count_mode;
   for (const auto kv : child_stats) {
     const std::string sectionId = std::string(1, static_cast<char>(kv.first));
     const Stat stats = kv.second;
@@ -463,11 +478,7 @@
     // Count is used to store value for "method count" mode.
     // Why? Because that's how it was implemented in the (now removed) .ndjson
     // worker.
-    int count = stats.count;
-    bool is_diff = stats.added > 0 || stats.removed > 0 || stats.changed > 0;
-    if (method_count_mode && is_diff) {
-      count = stats.added - stats.removed;
-    }
+    int count = is_diff_count ? stats.added - stats.removed : stats.count;
     (*out)[sectionId]["count"] = count;
   }
 }
diff --git a/tools/binary_size/libsupersize/viewer/caspian/model.h b/tools/binary_size/libsupersize/viewer/caspian/model.h
index faa1fbb..5520c3b2 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/model.h
+++ b/tools/binary_size/libsupersize/viewer/caspian/model.h
@@ -110,6 +110,7 @@
   virtual float Pss() const = 0;
   virtual float PssWithoutPadding() const = 0;
   virtual float PaddingPss() const = 0;
+  virtual float BeforePss() const = 0;
 
   virtual DiffStatus GetDiffStatus() const = 0;
 
@@ -197,10 +198,9 @@
   std::string* Disassembly() const override;
 
   float Pss() const override;
-
   float PssWithoutPadding() const override;
-
   float PaddingPss() const override;
+  float BeforePss() const override;
 
   DiffStatus GetDiffStatus() const override;
 
@@ -258,6 +258,7 @@
   float Pss() const override;
   float PssWithoutPadding() const override;
   float PaddingPss() const override;
+  float BeforePss() const override;
 
   DiffStatus GetDiffStatus() const override;
 
@@ -325,6 +326,12 @@
   std::deque<Symbol> owned_symbols;
 };
 
+struct JsonWriteOptions {
+  bool is_sparse;
+  bool diff_mode;
+  bool method_count_mode;
+};
+
 struct Stat {
   int32_t count = 0;
   int32_t added = 0;
@@ -345,7 +352,7 @@
   NodeStats();
   ~NodeStats();
   explicit NodeStats(const BaseSymbol& symbol);
-  void WriteIntoJson(bool method_count_mode, Json::Value* out) const;
+  void WriteIntoJson(const JsonWriteOptions& opts, Json::Value* out) const;
   NodeStats& operator+=(const NodeStats& other);
   SectionId ComputeBiggestSection() const;
   int32_t SumCount() const;
@@ -362,16 +369,16 @@
 
   using CompareFunc =
       std::function<bool(const TreeNode* const& l, const TreeNode* const& r)>;
-  void WriteIntoJson(int depth,
+  void WriteIntoJson(const JsonWriteOptions& opts,
                      CompareFunc compare_func,
-                     bool is_sparse,
-                     bool method_count_mode,
+                     int depth,
                      Json::Value* out);
 
   GroupedPath id_path;
   const char* src_path = nullptr;
   const char* component = nullptr;
   float size = 0.0f;
+  float before_size = 0.0f;
   float padding = 0.0f;
   int32_t address = 0;
   int32_t flags = 0;
diff --git a/tools/binary_size/libsupersize/viewer/caspian/tree_builder.cc b/tools/binary_size/libsupersize/viewer/caspian/tree_builder.cc
index 45a9d36..23f943e 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/tree_builder.cc
+++ b/tools/binary_size/libsupersize/viewer/caspian/tree_builder.cc
@@ -18,7 +18,7 @@
 constexpr const char kNoPath[] = "(No path)";
 }  // namespace
 
-TreeBuilder::TreeBuilder(SizeInfo* size_info) {
+TreeBuilder::TreeBuilder(SizeInfo* size_info) : diff_mode_(false) {
   symbols_.reserve(size_info->raw_symbols.size());
   for (const Symbol& sym : size_info->raw_symbols) {
     symbols_.push_back(&sym);
@@ -26,7 +26,7 @@
   size_info_ = size_info;
 }
 
-TreeBuilder::TreeBuilder(DeltaSizeInfo* size_info) {
+TreeBuilder::TreeBuilder(DeltaSizeInfo* size_info) : diff_mode_(true) {
   symbols_.reserve(size_info->delta_symbols.size());
   for (const DeltaSymbol& sym : size_info->delta_symbols) {
     symbols_.push_back(&sym);
@@ -129,9 +129,14 @@
               << std::endl;
     exit(1);
   }
+
+  JsonWriteOptions opts = {
+      .is_sparse = size_info_->IsSparse(),
+      .diff_mode = diff_mode_,
+      .method_count_mode = method_count_mode_,
+  };
   Json::Value v;
-  node->WriteIntoJson(1, node_sort_func, size_info_->IsSparse(),
-                      method_count_mode_, &v);
+  node->WriteIntoJson(opts, node_sort_func, 1, &v);
   return v;
 }
 
@@ -166,6 +171,9 @@
     symbol_node->address = sym->Address();
     symbol_node->node_stats = NodeStats(*sym);
     symbol_node->symbol = sym;
+    if (diff_mode_) {
+      symbol_node->before_size = sym->BeforePss();
+    }
     symbol_nodes.push_back(symbol_node);
   }
 
@@ -229,6 +237,9 @@
   TreeNode* node = child;
   while (node->parent) {
     node->parent->size += child->size;
+    if (diff_mode_) {
+      node->parent->before_size += child->before_size;
+    }
     node->parent->padding += child->padding;
     node->parent->node_stats += child->node_stats;
     node = node->parent;
diff --git a/tools/binary_size/libsupersize/viewer/caspian/tree_builder.h b/tools/binary_size/libsupersize/viewer/caspian/tree_builder.h
index c4ea9e7..26d25406 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/tree_builder.h
+++ b/tools/binary_size/libsupersize/viewer/caspian/tree_builder.h
@@ -49,6 +49,7 @@
   void JoinDexMethodClasses(TreeNode* node);
 
   BaseSizeInfo* size_info_;
+  bool diff_mode_;
   TreeNode root_;
   std::unordered_map<GroupedPath, TreeNode*> _parents;
 
diff --git a/tools/binary_size/libsupersize/viewer/static/index.html b/tools/binary_size/libsupersize/viewer/static/index.html
index 1da1a9a..d3b4e15 100644
--- a/tools/binary_size/libsupersize/viewer/static/index.html
+++ b/tools/binary_size/libsupersize/viewer/static/index.html
@@ -7,6 +7,7 @@
 -->
 
 <head>
+  <meta charset="utf-8">
   <title>Super Size Tiger View</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta name="theme-color" content="#4285f4">
diff --git a/tools/binary_size/libsupersize/viewer/static/shared.js b/tools/binary_size/libsupersize/viewer/static/shared.js
index 9c27479..24fe02b 100644
--- a/tools/binary_size/libsupersize/viewer/static/shared.js
+++ b/tools/binary_size/libsupersize/viewer/static/shared.js
@@ -29,6 +29,8 @@
  *     read the name.
  * @property {number} size - Byte size of this node and its children.
  * @property {number|undefined} padding - Padding bytes used by this node.
+ * @property {number|undefined} beforeSize - Diff mode only: Byte size of the
+ *     node and its children in the "before" binary.
  * @property {number|undefined} address - Start address of this node.
  * @property {number} flags - A bit field to store symbol properties.
  * @property {number} numAliases - Number of aliases for the symbol.
diff --git a/tools/binary_size/libsupersize/viewer/static/state.js b/tools/binary_size/libsupersize/viewer/static/state.js
index 399e1fd..86caad5 100644
--- a/tools/binary_size/libsupersize/viewer/static/state.js
+++ b/tools/binary_size/libsupersize/viewer/static/state.js
@@ -394,10 +394,15 @@
 
     } else {
       const bytes = node.size;
-
-      let description = `${formatNumber(bytes)} bytes`;
+      const descriptionToks = [];
+      if ('beforeSize' in node) {
+        const before = formatNumber(node.beforeSize);
+        const after = formatNumber(node.beforeSize + bytes);
+        descriptionToks.push(`(${before} → ${after})`);  // '→' is '\u2192'.
+      }
+      descriptionToks.push(`${formatNumber(bytes)} bytes`);
       if (node.numAliases && node.numAliases > 1) {
-        description += ` for 1 of ${node.numAliases} aliases`;
+        descriptionToks.push(`for 1 of ${node.numAliases} aliases`);
       }
 
       const unit = state.get('byteunit') || 'KiB';
@@ -409,7 +414,7 @@
       const suffixElement = dom.textElement('small', unit);
 
       return {
-        description,
+        description: descriptionToks.join(' '),
         element: dom.createFragment([textNode, suffixElement]),
         value: bytes,
       };
diff --git a/tools/binary_size/libsupersize/viewer/static/viewer.html b/tools/binary_size/libsupersize/viewer/static/viewer.html
index 18963cb..98e47d9 100644
--- a/tools/binary_size/libsupersize/viewer/static/viewer.html
+++ b/tools/binary_size/libsupersize/viewer/static/viewer.html
@@ -7,6 +7,7 @@
 -->
 
 <head>
+  <meta charset="utf-8">
   <title>Super Size Tiger View</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta name="theme-color" content="#4285f4">
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
index 6662dd8..00294fb 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
@@ -307,8 +307,11 @@
   }
 
   // Don't check if the class can't construct.
-  if (info->record()->isAbstract() || info->IsConsideredAbstract())
+  if (info->record()->isAbstract() ||
+      (info->IsConsideredAbstract() &&
+       !info->record()->needsImplicitDefaultConstructor())) {
     return;
+  }
 
   if (info->IsGCDerived() || info->DeclaresNewOperator())
     return;
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
index 5be5d09..897de517 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -380,11 +380,9 @@
   return is_declaring_local_trace_;
 }
 
-// A (non-virtual) class is considered abstract in Blink if it has no implicit
-// default constructor, no public constructors and no public create methods.
+// A (non-virtual) class is considered abstract in Blink if it has
+// no public constructors and no create methods.
 bool RecordInfo::IsConsideredAbstract() {
-  if (record()->needsImplicitDefaultConstructor())
-    return false;
   for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin();
        it != record_->ctor_end();
        ++it) {
@@ -394,7 +392,7 @@
   for (CXXRecordDecl::method_iterator it = record_->method_begin();
        it != record_->method_end();
        ++it) {
-    if (it->getNameAsString() == kCreateName && it->getAccess() == AS_public)
+    if (it->getNameAsString() == kCreateName)
       return false;
   }
   return true;
diff --git a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h
index a7721be..9cbdc9c 100644
--- a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h
+++ b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h
@@ -13,20 +13,14 @@
  public:
   void Trace(Visitor*) const;
   // Needs a TraceAfterDispatch method.
-  void FinalizeGarbageCollectedObject() {}
-
- protected:
-  NeedsDispatch() = default;
+  void FinalizeGarbageCollectedObject(){};
 };
 
 class NeedsFinalizedBase : public GarbageCollected<NeedsFinalizedBase> {
- public:
-  void Trace(Visitor*) const {}
-  void TraceAfterDispatch(Visitor*) const {}
-  void FinalizeGarbageCollectedObject() {}
-
- protected:
-  NeedsFinalizedBase() = default;
+public:
+ void Trace(Visitor*) const {};
+ void TraceAfterDispatch(Visitor*) const {};
+ void FinalizeGarbageCollectedObject(){};
 };
 
 class A : GarbageCollected<A> {
diff --git a/tools/clang/blink_gc_plugin/tests/heap/stubs.h b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
index 82f7349..4a48ef18 100644
--- a/tools/clang/blink_gc_plugin/tests/heap/stubs.h
+++ b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
@@ -5,9 +5,7 @@
 #ifndef HEAP_STUBS_H_
 #define HEAP_STUBS_H_
 
-#include <cstddef>
-#include <new>
-#include <utility>
+#include <stddef.h>
 
 namespace WTF {
 
@@ -216,14 +214,17 @@
 
 template <typename T>
 class GarbageCollected {
+ public:
+  void* operator new(size_t, void* location) { return location; }
+
+ private:
   void* operator new(size_t) = delete;
   void* operator new[](size_t) = delete;
 };
 
 template <typename T, typename... Args>
 T* MakeGarbageCollected(int, Args&&... args) {
-  void* memory = reinterpret_cast<void*>(0x87654321);
-  return ::new (memory) T(std::forward<Args>(args)...);
+  return new (reinterpret_cast<void*>(0x87654321)) T(args...);
 }
 
 class GarbageCollectedMixin {
@@ -266,7 +267,7 @@
 using GarbageCollected = cppgc::GarbageCollected<T>;
 template <typename T, typename... Args>
 T* MakeGarbageCollected(Args&&... args) {
-  return cppgc::MakeGarbageCollected<T>(0, std::forward<Args>(args)...);
+  return cppgc::MakeGarbageCollected<T>(0, args...);
 }
 
 using GarbageCollectedMixin = cppgc::GarbageCollectedMixin;
@@ -299,14 +300,17 @@
 
 template <typename T>
 class GarbageCollected {
+ public:
+  void* operator new(size_t, void* location) { return location; }
+
+ private:
   void* operator new(size_t) = delete;
   void* operator new[](size_t) = delete;
 };
 
 template <typename T, typename... Args>
 T* MakeGarbageCollected(Args&&... args) {
-  void* memory = reinterpret_cast<void*>(0x87654321);
-  return ::new (memory) T(std::forward<Args>(args)...);
+  return new (reinterpret_cast<void*>(0x87654321)) T(args...);
 }
 
 class GarbageCollectedMixin {
diff --git a/tools/clang/blink_gc_plugin/tests/trace_wrapper.h b/tools/clang/blink_gc_plugin/tests/trace_wrapper.h
index 12df72b..12345aa 100644
--- a/tools/clang/blink_gc_plugin/tests/trace_wrapper.h
+++ b/tools/clang/blink_gc_plugin/tests/trace_wrapper.h
@@ -27,9 +27,6 @@
  public:
   void Trace(Visitor* visitor) const;
   void TraceAfterDispatch(Visitor*) const {}
-
- protected:
-  B() = default;
 };
 
 class C : public B {
diff --git a/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt b/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt
index d73a8068..a6e9d3ef 100644
--- a/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt
+++ b/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt
@@ -5,11 +5,11 @@
 ./trace_wrapper.h:23:3: note: [blink-gc] Untraced field 'str_' declared here:
   TraceWrapperV8Reference<v8::String> str_;
   ^
-./trace_wrapper.h:37:3: warning: [blink-gc] Base class 'B' of derived class 'C' requires tracing.
+./trace_wrapper.h:34:3: warning: [blink-gc] Base class 'B' of derived class 'C' requires tracing.
   void TraceAfterDispatch(Visitor*) const {
   ^
-./trace_wrapper.h:37:3: warning: [blink-gc] Class 'C' has untraced fields that require tracing.
-./trace_wrapper.h:42:3: note: [blink-gc] Untraced field 'str_' declared here:
+./trace_wrapper.h:34:3: warning: [blink-gc] Class 'C' has untraced fields that require tracing.
+./trace_wrapper.h:39:3: note: [blink-gc] Untraced field 'str_' declared here:
   TraceWrapperV8Reference<v8::String> str_;
   ^
 3 warnings generated.
diff --git a/tools/grit/grit/util.py b/tools/grit/grit/util.py
index 98433d1..98e770b8 100644
--- a/tools/grit/grit/util.py
+++ b/tools/grit/grit/util.py
@@ -209,7 +209,7 @@
     mode = 'rb'
     encoding = None
   else:
-    mode = 'rU'
+    mode = 'r'
 
   with io.open(filename, mode, encoding=encoding) as f:
     return f.read()
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index c12fdf4e..5d87051 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -380,9 +380,13 @@
     "META": {"sizes": {"includes": [10]}},
     "includes": [2330],
   },
+  "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/app_home/resources.grd": {
+    "META": {"sizes": {"includes": [10]}},
+    "includes": [2340],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/gaia_auth_host/resources.grd": {
     "META": {"sizes": {"includes": [10],}},
-    "includes": [2340],
+    "includes": [2350],
   },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/invalidations/resources.grd": {
     "META": {"sizes": {"includes": [10],}},
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 1269303..8de18856 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -94,7 +94,6 @@
       'android-10-arm64-rel': 'android_release_bot_minimal_symbols_arm64_fastbuild_webview_trichrome_reclient',
       'android-11-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_reclient',
       'android-12-x64-rel': 'android_release_bot_minimal_symbols_x64_fastbuild_webview_trichrome_reclient',
-      'android-12l-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_reclient',
       'android-arm64-proguard-rel': 'android_release_bot_minimal_symbols_arm64_webview_google',
       'android-bfcache-rel': 'android_release_bot_minimal_symbols_reclient',
       'android-binary-size-generator': 'android_binary_size_reclient',
@@ -951,7 +950,7 @@
       'android-11-x86-rel': 'android_release_trybot_x86_fastbuild_webview_trichrome',
       'android-12-x64-dbg': 'android_debug_trybot_x64_webview_trichrome_webview_shell',
       'android-12-x64-rel': 'android_release_trybot_x64_fastbuild_webview_trichrome',
-      'android-12l-x86-rel': 'android_release_trybot_x86_fastbuild_webview_trichrome',
+      'android-12l-x64-dbg': 'android_debug_trybot_x64_webview_trichrome_webview_shell',
       'android-arm64-all-targets-dbg': 'android_debug_trybot_compile_only_arm64_fastbuild',
       'android-asan': 'android_clang_asan_release_trybot',
       'android-bfcache-rel': 'android_release_trybot',
@@ -3230,7 +3229,7 @@
     ],
 
     'official_goma_linux_pgo': [
-      'official', 'goma', 'static', 'no_symbols', 'pgo_phase_1',
+      'official', 'goma', 'no_symbols', 'pgo_phase_1', 'release'
     ],
 
     'official_goma_mac': [
@@ -3250,7 +3249,7 @@
     ],
 
     'official_goma_mac_arm_pgo': [
-      'official', 'goma', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'arm64', 'disable_widevine_signing', 'static', 'no_symbols', 'pgo_phase_1'
+      'official', 'goma', 'no_widevine_cdm_host_verification', 'arm64', 'disable_widevine_signing', 'no_symbols', 'pgo_phase_1', 'release'
     ],
 
     'official_goma_mac_perf': [
@@ -3262,7 +3261,7 @@
     ],
 
     'official_goma_mac_pgo': [
-      'official', 'goma', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'disable_widevine_signing', 'static', 'no_symbols', 'pgo_phase_1'
+      'official', 'goma', 'no_widevine_cdm_host_verification', 'disable_widevine_signing', 'no_symbols', 'pgo_phase_1', 'release'
     ],
 
     'official_goma_minimal_symbols_android': [
@@ -3302,7 +3301,7 @@
     ],
 
     'official_goma_x64_pgo': [
-      'official', 'goma', 'x64', 'static', 'no_symbols', 'pgo_phase_1', 'no_resource_allowlisting',
+      'official', 'goma', 'x64', 'no_symbols', 'pgo_phase_1', 'release'
     ],
 
     'official_goma_x86': [
@@ -3310,7 +3309,7 @@
     ],
 
     'official_goma_x86_pgo': [
-      'official', 'goma', 'x86', 'static', 'no_symbols', 'pgo_phase_1', 'no_resource_allowlisting',
+      'official', 'goma', 'x86', 'no_symbols', 'pgo_phase_1', 'release'
     ],
 
     'official_optimize_goma': [
@@ -4455,7 +4454,6 @@
     },
 
     'pgo_phase_1': {
-      'mixins': ['strip_absolute_paths_from_debug_symbols'],
       'gn_args': 'chrome_pgo_phase=1'
     },
 
diff --git a/tools/mb/mb_config_expectations/chrome.pgo.json b/tools/mb/mb_config_expectations/chrome.pgo.json
index 80ae786..2e97311 100644
--- a/tools/mb/mb_config_expectations/chrome.pgo.json
+++ b/tools/mb/mb_config_expectations/chrome.pgo.json
@@ -7,7 +7,6 @@
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 1,
       "target_cpu": "arm",
       "target_os": "android",
@@ -22,7 +21,6 @@
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 1,
       "target_cpu": "arm64",
       "target_os": "android",
@@ -32,10 +30,10 @@
   "linux-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "use_goma": true
     }
@@ -43,13 +41,12 @@
   "mac-arm-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_keystone_registration_framework": false,
+      "dcheck_always_on": false,
       "enable_widevine_cdm_host_verification": false,
       "ignore_missing_widevine_signing_cert": true,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "arm64",
       "use_goma": true
@@ -58,13 +55,12 @@
   "mac-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_keystone_registration_framework": false,
+      "dcheck_always_on": false,
       "enable_widevine_cdm_host_verification": false,
       "ignore_missing_widevine_signing_cert": true,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "use_goma": true
     }
@@ -72,11 +68,10 @@
   "win32-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_resource_allowlist_generation": false,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "x86",
       "use_goma": true
@@ -85,11 +80,10 @@
   "win64-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_resource_allowlist_generation": false,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "x64",
       "use_goma": true
diff --git a/tools/mb/mb_config_expectations/chromium.android.json b/tools/mb/mb_config_expectations/chromium.android.json
index 9145859..296e7eaf 100644
--- a/tools/mb/mb_config_expectations/chromium.android.json
+++ b/tools/mb/mb_config_expectations/chromium.android.json
@@ -161,22 +161,6 @@
       "use_remoteexec": true
     }
   },
-  "android-12l-x86-rel": {
-    "gn_args": {
-      "android_static_analysis": "off",
-      "dcheck_always_on": false,
-      "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.webview.debug",
-      "target_cpu": "x86",
-      "target_os": "android",
-      "use_remoteexec": true
-    }
-  },
   "android-arm64-proguard-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/chromium.clang.json b/tools/mb/mb_config_expectations/chromium.clang.json
index 1bf35a3..96be7dc 100644
--- a/tools/mb/mb_config_expectations/chromium.clang.json
+++ b/tools/mb/mb_config_expectations/chromium.clang.json
@@ -268,7 +268,6 @@
       "is_clang": true,
       "is_official_build": true,
       "llvm_force_head_revision": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0
     }
   },
@@ -405,7 +404,6 @@
       "is_clang": true,
       "is_official_build": true,
       "llvm_force_head_revision": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0
     }
   },
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
index 80ae786..2e97311 100644
--- a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
+++ b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
@@ -7,7 +7,6 @@
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 1,
       "target_cpu": "arm",
       "target_os": "android",
@@ -22,7 +21,6 @@
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 1,
       "target_cpu": "arm64",
       "target_os": "android",
@@ -32,10 +30,10 @@
   "linux-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "use_goma": true
     }
@@ -43,13 +41,12 @@
   "mac-arm-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_keystone_registration_framework": false,
+      "dcheck_always_on": false,
       "enable_widevine_cdm_host_verification": false,
       "ignore_missing_widevine_signing_cert": true,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "arm64",
       "use_goma": true
@@ -58,13 +55,12 @@
   "mac-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_keystone_registration_framework": false,
+      "dcheck_always_on": false,
       "enable_widevine_cdm_host_verification": false,
       "ignore_missing_widevine_signing_cert": true,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "use_goma": true
     }
@@ -72,11 +68,10 @@
   "win32-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_resource_allowlist_generation": false,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "x86",
       "use_goma": true
@@ -85,11 +80,10 @@
   "win64-pgo": {
     "gn_args": {
       "chrome_pgo_phase": 1,
-      "enable_resource_allowlist_generation": false,
+      "dcheck_always_on": false,
       "is_chrome_branded": true,
-      "is_component_build": false,
+      "is_debug": false,
       "is_official_build": true,
-      "strip_absolute_paths_from_debug_symbols": true,
       "symbol_level": 0,
       "target_cpu": "x64",
       "use_goma": true
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index ba23b6bc..62042ff6 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -62,18 +62,16 @@
       "use_goma": true
     }
   },
-  "android-12l-x86-rel": {
+  "android-12l-x64-dbg": {
     "gn_args": {
-      "android_static_analysis": "off",
-      "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
+      "is_component_build": true,
+      "is_debug": true,
       "proprietary_codecs": true,
-      "strip_debug_info": true,
-      "symbol_level": 0,
+      "symbol_level": 1,
       "system_webview_package_name": "com.google.android.webview.debug",
-      "target_cpu": "x86",
+      "system_webview_shell_package_name": "org.chromium.my_webview_shell",
+      "target_cpu": "x64",
       "target_os": "android",
       "use_goma": true
     }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ff4c9d39d..ad5b25f 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -41214,6 +41214,7 @@
   <int value="4343" label="DeferredShaping2ReshapedByPrinting"/>
   <int value="4344" label="DeferredShaping2ReshapedByScrolling"/>
   <int value="4345" label="LCPCandidateImageFromOriginDirtyStyle"/>
+  <int value="4346" label="V8TurboFanOsrCompileStarted"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -59410,6 +59411,7 @@
   <int value="-43650386" label="WindowsFollowCursor:enabled"/>
   <int value="-43428597" label="ClickToCallDetectionV2:enabled"/>
   <int value="-42175674" label="ShareUsageRankingFixedMore:disabled"/>
+  <int value="-41460305" label="InfobarScrollOptimization:disabled"/>
   <int value="-41254374" label="WebRtcMetronomeTaskQueue:enabled"/>
   <int value="-40935502" label="ContextualSuggestionsSlimPeekUI:enabled"/>
   <int value="-37966026" label="PermissionPredictions:enabled"/>
@@ -61066,6 +61068,7 @@
   <int value="989740984" label="BorealisStorageBallooning:enabled"/>
   <int value="990380525"
       label="AutofillRationalizeStreetAddressAndAddressLine:enabled"/>
+  <int value="991192182" label="InfobarScrollOptimization:enabled"/>
   <int value="991462028"
       label="WebViewSynthesizePageLoadOnlyOnInitialMainDocumentAccess:enabled"/>
   <int value="993486662" label="BorealisForceBetaClient:enabled"/>
@@ -73949,6 +73952,7 @@
   <int value="1115" label="Privacy: Lock On Leave"/>
   <int value="1116" label="Privacy: Camera Software Switch"/>
   <int value="1117" label="Privacy: Microphone Software Switch"/>
+  <int value="1118" label="Privacy: Geolocation Software Switch"/>
   <int value="1200" label="Add Language"/>
   <int value="1201" label="Show Input Options In Shelf"/>
   <int value="1202" label="Show Personal Information Suggestions"/>
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
index 4c54f0fc..ca903ea9 100644
--- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
+++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -83,7 +83,7 @@
 reillyg@chromium.org
 rkgibson@google.com
 rouslan@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 rushans@google.com
 schenney@chromium.org
 sebsg@chromium.org
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml
index 11d8710b..f9f88cfc 100644
--- a/tools/metrics/histograms/metadata/accessibility/histograms.xml
+++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -149,7 +149,7 @@
 </variants>
 
 <histogram name="Accessibility.ActiveTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>aleventhal@chromium.org</owner>
   <owner>janewman@microsoft.com</owner>
   <summary>
@@ -328,7 +328,7 @@
 </histogram>
 
 <histogram name="Accessibility.AutoDisabled.DisabledTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>abigailbklein@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -338,7 +338,7 @@
 </histogram>
 
 <histogram name="Accessibility.AutoDisabled.EnabledTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>abigailbklein@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -348,7 +348,7 @@
 </histogram>
 
 <histogram name="Accessibility.AutoDisabled.EventCount" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>abigailbklein@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -466,7 +466,7 @@
 </histogram>
 
 <histogram name="Accessibility.CrosDictation.Language" enum="LocaleCodeISO639"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>katie@chromium.org</owner>
   <owner>dtseng@chromium.org</owner>
   <owner>chrome-a11y-core@google.com</owner>
@@ -481,7 +481,7 @@
 
 <histogram
     name="Accessibility.CrosDictation.ListeningDuration.NetworkRecognition"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>katie@chromium.org</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -533,7 +533,7 @@
 </histogram>
 
 <histogram name="Accessibility.CrosDictation.UsedOnDeviceSpeech"
-    enum="BooleanUsage" expires_after="2022-12-25">
+    enum="BooleanUsage" expires_after="2023-02-26">
   <owner>katie@chromium.org</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -1336,7 +1336,7 @@
 </histogram>
 
 <histogram name="Accessibility.PDF.HasAccessibleText" enum="BooleanExists"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>dtseng@chromium.org</owner>
   <owner>nektar@chromium.org</owner>
   <owner>chrome-a11y-core@google.com</owner>
@@ -1915,7 +1915,7 @@
 </histogram>
 
 <histogram name="DomDistiller.Time.ViewingReaderModePage" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mdjones@chromium.org</owner>
   <summary>
     Records the amount of time a user spent on a Reader Mode Page.
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 8a8b5dde..8f9ea84 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -201,7 +201,7 @@
 </histogram>
 
 <histogram name="Android.AdaptiveToolbarButton.Clicked"
-    enum="AdaptiveToolbarButtonVariant" expires_after="2022-12-25">
+    enum="AdaptiveToolbarButtonVariant" expires_after="2023-02-26">
   <owner>bttk@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -211,7 +211,7 @@
 </histogram>
 
 <histogram name="Android.AdaptiveToolbarButton.SessionVariant"
-    enum="AdaptiveToolbarButtonVariant" expires_after="2022-12-25">
+    enum="AdaptiveToolbarButtonVariant" expires_after="2023-02-26">
   <owner>bttk@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -255,7 +255,7 @@
 </histogram>
 
 <histogram name="Android.AdaptiveToolbarButton.SettingsToggle.Startup"
-    enum="BooleanEnabled" expires_after="2022-12-25">
+    enum="BooleanEnabled" expires_after="2023-02-26">
   <owner>shaktisahu@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -427,7 +427,7 @@
 
 <histogram name="Android.AutofillAssistant.OnboardingFetcher.ResultStatus"
     enum="AutofillAssistantOnboardingFetcherResultStatus"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sandromaggi@google.com</owner>
   <owner>mcarlen@google.com</owner>
   <summary>
@@ -538,7 +538,7 @@
 </histogram>
 
 <histogram name="Android.BackgroundRestrictions.IsBackgroundRestricted"
-    enum="Boolean" expires_after="2022-12-25">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>shaktisahu@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -548,7 +548,7 @@
 </histogram>
 
 <histogram name="Android.BackgroundRestrictions.StandbyBucket"
-    enum="StandbyBucket" expires_after="2022-12-25">
+    enum="StandbyBucket" expires_after="2023-02-26">
   <owner>shaktisahu@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -573,7 +573,7 @@
 
 <histogram
     name="Android.BackgroundRestrictions.StandbyBucket.WithUserRestriction"
-    enum="StandbyBucket" expires_after="2022-12-25">
+    enum="StandbyBucket" expires_after="2023-02-26">
   <owner>shaktisahu@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -997,7 +997,7 @@
 </histogram>
 
 <histogram name="Android.DarkTheme.EnabledReason" enum="DarkThemeEnabledReason"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
   <summary>
@@ -1007,7 +1007,7 @@
 </histogram>
 
 <histogram name="Android.DarkTheme.EnabledState" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
   <summary>
@@ -1017,7 +1017,7 @@
 </histogram>
 
 <histogram name="Android.DarkTheme.Preference.State"
-    enum="DarkThemePreferences" expires_after="2022-12-25">
+    enum="DarkThemePreferences" expires_after="2023-02-26">
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
   <summary>
@@ -2361,7 +2361,7 @@
 </histogram>
 
 <histogram name="Android.MultiInstance.NumActivities" units="activities"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jinsukkim@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
@@ -2376,7 +2376,7 @@
 </histogram>
 
 <histogram name="Android.MultiInstance.NumInstances" units="instances"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jinsukkim@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
@@ -3173,7 +3173,7 @@
 </histogram>
 
 <histogram name="Android.PlayServices.Version" units="versioncode"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>twellington@chromium.org</owner>
   <owner>tedchoc@chromium.org</owner>
   <summary>
@@ -3247,7 +3247,7 @@
 </histogram>
 
 <histogram name="Android.Rotation.BeginToRendererFrameActivation" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jonross@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -4271,7 +4271,7 @@
 </histogram>
 
 <histogram name="Android.WebView.MixedContent.Mode"
-    enum="WebViewMixedContentMode" expires_after="2022-10-06">
+    enum="WebViewMixedContentMode" expires_after="2023-08-25">
   <owner>ntfschr@chromium.org</owner>
   <owner>carlosil@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
@@ -4742,7 +4742,7 @@
 
 <histogram
     name="Android.WebView.UniversalAccess.OriginUrlMismatchInRenderFrame"
-    enum="BooleanAllowed" expires_after="2022-09-01">
+    enum="BooleanAllowed" expires_after="2023-01-15">
   <owner>torne@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index 44b55ee3..ed1026f 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -628,7 +628,7 @@
 </histogram>
 
 <histogram name="Apps.AppList.ItemSuggestCache.ResponseSize" units="bytes"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tby@chromium.org</owner>
   <owner>thanhdng@chromium.org</owner>
   <owner>wrong@chromium.org</owner>
@@ -651,7 +651,7 @@
 </histogram>
 
 <histogram name="Apps.AppList.ItemSuggestCache.UpdateCacheLatency" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tby@chromium.org</owner>
   <owner>thanhdng@chromium.org</owner>
   <owner>wrong@chromium.org</owner>
@@ -1010,7 +1010,7 @@
 </histogram>
 
 <histogram name="Apps.AppList.SortDiscoveryDurationAfterEducationNudge"
-    units="ms" expires_after="2023-02-19">
+    units="ms" expires_after="2023-02-26">
   <owner>andrewxu@chromium.org</owner>
   <owner>tbarzic@chromium.org</owner>
   <summary>
@@ -2075,7 +2075,7 @@
 </histogram>
 
 <histogram name="Apps.FileHandler.Registration.Win.Result"
-    enum="FileHandlerRegistrationWinResult" expires_after="M110">
+    enum="FileHandlerRegistrationWinResult" expires_after="2023-02-26">
   <owner>estade@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -2351,7 +2351,7 @@
 </histogram>
 
 <histogram name="Apps.LockScreen.NoteTakingApp.AvailabilityOnScreenLock"
-    enum="LockScreenActionAvailability" expires_after="2022-12-01">
+    enum="LockScreenActionAvailability" expires_after="2023-02-26">
   <owner>glenrob@chromium.org</owner>
   <owner>tbuckley@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index 3d52997..2627716 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -735,7 +735,7 @@
 </histogram>
 
 <histogram name="Arc.ClipboardDragDrop" enum="ArcClipboardDragDropEvent"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yhanada@google.com</owner>
   <owner>arc-framework@google.com</owner>
   <summary>The number of clipboard and drag-and-drop events.</summary>
@@ -2001,7 +2001,7 @@
 </histogram>
 
 <histogram name="Arc.SystemHealth.Upgrade.PackagesDeleted"
-    enum="BooleanDeletedOrNot" expires_after="2022-12-27">
+    enum="BooleanDeletedOrNot" expires_after="2023-08-29">
   <owner>mhasank@chromium.org</owner>
   <owner>arc-core@google.com</owner>
   <summary>
@@ -2010,7 +2010,7 @@
 </histogram>
 
 <histogram name="Arc.SystemHealth.Upgrade.TimeDelta" units="ms"
-    expires_after="2022-10-09">
+    expires_after="2023-08-29">
   <owner>mhasank@chromium.org</owner>
   <owner>arc-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index c03fcd6..5b2acbf 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -1476,7 +1476,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.ConsecutiveDailyVisits" units="days"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>afakhry@chromium.org</owner>
   <owner>janetmac@chromium.org</owner>
   <summary>
@@ -1564,7 +1564,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.NumberOfDeskTraversals" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>afakhry@chromium.org</owner>
   <owner>sammiequon@chromium.org</owner>
   <owner>tclaiborne@chromium.org</owner>
@@ -2439,7 +2439,7 @@
 </histogram>
 
 <histogram name="Ash.Login.Login.AuthMethod.Used.TabletMode" enum="AuthMethod"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>emaamari@google.com</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -4691,9 +4691,15 @@
 </histogram>
 
 <histogram name="Ash.Wallpaper.Type" enum="WallpaperType"
-    expires_after="2022-04-24">
+    expires_after="2023-08-29">
   <owner>kuscher@google.com</owner>
-  <summary>The wallpaper type. Recorded at user login.</summary>
+  <owner>assistive-eng@google.com</owner>
+  <summary>
+    The wallpaper type. Recorded at user login.
+
+    This metric expired in April 2022 and was revived in August 2022. Data
+    between these times is incomplete.
+  </summary>
 </histogram>
 
 <histogram name="Ash.Window.AnimationSmoothness.CrossFade" units="%"
diff --git a/tools/metrics/histograms/metadata/ash_clipboard/histograms.xml b/tools/metrics/histograms/metadata/ash_clipboard/histograms.xml
index 27205c81..c42051a8 100644
--- a/tools/metrics/histograms/metadata/ash_clipboard/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash_clipboard/histograms.xml
@@ -34,7 +34,7 @@
 </histogram>
 
 <histogram name="Ash.Clipboard.ConsecutivePastes" units="times"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -44,7 +44,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ConsecutivePastes" units="times"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -57,7 +57,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatDeleted"
-    enum="ClipboardHistoryDisplayFormat" expires_after="2022-12-25">
+    enum="ClipboardHistoryDisplayFormat" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -67,7 +67,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatPasted"
-    enum="ClipboardHistoryDisplayFormat" expires_after="2022-12-25">
+    enum="ClipboardHistoryDisplayFormat" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -77,7 +77,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatShown"
-    enum="ClipboardHistoryDisplayFormat" expires_after="2022-12-25">
+    enum="ClipboardHistoryDisplayFormat" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -87,7 +87,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.MenuOptionSelected"
-    units="index" expires_after="2022-12-25">
+    units="index" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -97,7 +97,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.NumberOfItemsShown"
-    units="Items Shown" expires_after="2022-12-25">
+    units="Items Shown" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -108,7 +108,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.ShowMenu"
-    enum="ClipboardHistoryTriggerType" expires_after="2022-12-25">
+    enum="ClipboardHistoryTriggerType" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -118,7 +118,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.ShowPlaceholderString"
-    enum="ClipboardHistoryPlaceholderStringType" expires_after="2022-12-25">
+    enum="ClipboardHistoryPlaceholderStringType" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -129,7 +129,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ContextMenu.UserJourneyTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -141,7 +141,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ControlToVDelay" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -156,7 +156,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ImageModelRequest.Lifetime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -166,7 +166,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ImageModelRequest.Runtime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -176,7 +176,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.ImageModelRequest.StopReason"
-    enum="RequestStopReason" expires_after="2022-12-25">
+    enum="RequestStopReason" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -227,7 +227,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.Operation"
-    enum="ClipboardHistoryOperation" expires_after="2022-12-25">
+    enum="ClipboardHistoryOperation" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
@@ -240,7 +240,7 @@
 </histogram>
 
 <histogram name="Ash.ClipboardHistory.PasteType"
-    enum="ClipboardHistoryPasteType" expires_after="2022-12-25">
+    enum="ClipboardHistoryPasteType" expires_after="2023-02-26">
   <owner>ckincaid@chromium.org</owner>
   <owner>multipaste@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index 8b94899..2eee22a1 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -2615,7 +2615,7 @@
 </histogram>
 
 <histogram name="Autofill.ProfileImport.NewProfileDecision"
-    enum="AutofillProfileImportDecision" expires_after="2022-12-25">
+    enum="AutofillProfileImportDecision" expires_after="2023-02-26">
   <owner>koerber@google.com</owner>
   <owner>src/components/autofill/OWNERS</owner>
   <summary>
@@ -2701,7 +2701,7 @@
 </histogram>
 
 <histogram name="Autofill.ProfileImport.ProfileImportType"
-    enum="AutofillProfileImportType" expires_after="2022-12-25">
+    enum="AutofillProfileImportType" expires_after="2023-02-26">
   <owner>koerber@google.com</owner>
   <owner>src/components/autofill/OWNERS</owner>
   <summary>
@@ -2724,7 +2724,7 @@
 
 <histogram
     name="Autofill.ProfileImport.SilentUpdatesWithRemovedPhoneNumberProfileImportType"
-    enum="AutofillSilentUpdatesProfileImportType" expires_after="2022-12-25">
+    enum="AutofillSilentUpdatesProfileImportType" expires_after="2023-02-26">
   <owner>fleimgruber@google.com</owner>
   <owner>chrome-autofill-team@google.com</owner>
   <summary>
@@ -2781,7 +2781,7 @@
 </histogram>
 
 <histogram name="Autofill.ProfileImport.UpdateProfileDecision"
-    enum="AutofillProfileImportDecision" expires_after="2022-12-25">
+    enum="AutofillProfileImportDecision" expires_after="2023-02-26">
   <owner>koerber@google.com</owner>
   <owner>src/components/autofill/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/background/histograms.xml b/tools/metrics/histograms/metadata/background/histograms.xml
index 793a038..b7619e5 100644
--- a/tools/metrics/histograms/metadata/background/histograms.xml
+++ b/tools/metrics/histograms/metadata/background/histograms.xml
@@ -270,7 +270,7 @@
 </histogram>
 
 <histogram name="BackgroundSync.Event.FromWakeupTask"
-    enum="BackgroundSyncWakeupTask" expires_after="2022-12-25">
+    enum="BackgroundSyncWakeupTask" expires_after="2023-02-26">
   <owner>nator@chromium.org</owner>
   <owner>rayankans@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 1db519a..92edcc2 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -2769,7 +2769,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.FencedFrames.AnimatedCSSProperties"
-    enum="MappedCSSProperties" expires_after="2022-12-25">
+    enum="MappedCSSProperties" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparc-dev@chromium.org</owner>
   <summary>
@@ -2786,7 +2786,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.FencedFrames.CSSProperties"
-    enum="MappedCSSProperties" expires_after="2022-12-25">
+    enum="MappedCSSProperties" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparc-dev@chromium.org</owner>
   <summary>
@@ -2815,7 +2815,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.FencedFrames.Features" enum="FeatureObserver"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparc-dev@chromium.org</owner>
   <summary>
@@ -2831,7 +2831,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.FencedFrames.MainFrame.Features"
-    enum="FeatureObserver" expires_after="2022-12-25">
+    enum="FeatureObserver" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparc-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index 7d16d3b..e3463b6 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -222,7 +222,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.ConnectDevice.Result"
-    enum="BooleanSuccess" expires_after="2022-12-25">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -737,7 +737,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.PairRetry.Count" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -1236,7 +1236,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ConnectedDeviceCount" units="devices"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>adlr@chromium.org</owner>
   <summary>
     Counts the number of simulataneously connected Bluetooth devices. Used to
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
index 95c05ec..dc633fbd 100644
--- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml
+++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -141,7 +141,7 @@
 </histogram>
 
 <histogram name="Bookmarks.Count.OnProfileLoad" units="bookmarks"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>supertri@chromium.org</owner>
   <owner>isherman@chromium.org</owner>
   <owner>aidanday@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index 7d64d94..95554e2 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -27,6 +27,7 @@
   <variant name="Assistant"/>
   <variant name="Bookmarks"/>
   <variant name="CustomizeChrome"/>
+  <variant name="Extension"/>
   <variant name="Feed"/>
   <variant name="HistoryClusters"/>
   <variant name="Lens"/>
@@ -52,7 +53,7 @@
 </variants>
 
 <histogram name="Browser.AnyWindowHasName" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ellyjones@chromium.org</owner>
   <owner>lgrey@chromium.org</owner>
   <summary>
@@ -385,7 +386,7 @@
 </histogram>
 
 <histogram name="Browser.Responsiveness.IOJanksTotalPerMinute" units="janks"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>gab@chromium.org</owner>
   <owner>olivierli@chromium.org</owner>
   <summary>
@@ -683,7 +684,7 @@
 </histogram>
 
 <histogram name="Browser.WindowCount.Guest" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-privacy-core@google.com</owner>
   <summary>
@@ -695,7 +696,7 @@
 </histogram>
 
 <histogram name="Browser.WindowCount.Incognito" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-privacy-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index f408975..45b809f 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -417,7 +417,7 @@
 </histogram>
 
 <histogram base="true" name="ChromeOS.Camera.Jpeg.Latency" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes
      name="ChromeOS.Camera.JpegProcessMethod" and
      name="ChromeOS.Camera.JpegProcessType" -->
@@ -1037,7 +1037,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Intents.LinkCapturingEvent2"
-    enum="LinkCapturingEvent" expires_after="2023-02-19">
+    enum="LinkCapturingEvent" expires_after="2023-02-26">
   <owner>vpao@google.com</owner>
   <owner>chromeos-apps-foundation-team@google.com</owner>
   <summary>
@@ -1162,7 +1162,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.GetPackState.LanguageCode"
-    enum="LanguagePackLanguageCodes" expires_after="2023-01-01">
+    enum="LanguagePackLanguageCodes" expires_after="2023-01-30">
   <owner>claudiomagni@chromium.org</owner>
   <owner>mlcui@google.com</owner>
   <owner>dvallet@chromium.org</owner>
@@ -1173,7 +1173,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.InstallComplete.Success"
-    enum="BooleanSuccess" expires_after="2022-12-11">
+    enum="BooleanSuccess" expires_after="2023-01-30">
   <owner>claudiomagni@chromium.org</owner>
   <owner>mlcui@google.com</owner>
   <owner>dvallet@chromium.org</owner>
@@ -1184,7 +1184,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.Mojo.BasePackStateResponse"
-    enum="LanguagePackMojoPackState" expires_after="2022-12-11">
+    enum="LanguagePackMojoPackState" expires_after="2023-01-30">
   <owner>mlcui@google.com</owner>
   <owner>cros-borders-eng@google.com</owner>
   <summary>
@@ -1194,7 +1194,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.Mojo.GetPackInfo.Feature"
-    enum="LanguagePackMojoFeatureId" expires_after="2022-12-04">
+    enum="LanguagePackMojoFeatureId" expires_after="2023-01-30">
   <owner>mlcui@google.com</owner>
   <owner>cros-borders-eng@google.com</owner>
   <summary>
@@ -1204,7 +1204,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.Mojo.InstallBasePack.Feature"
-    enum="LanguagePackMojoFeatureId" expires_after="2022-12-11">
+    enum="LanguagePackMojoFeatureId" expires_after="2023-01-30">
   <owner>mlcui@google.com</owner>
   <owner>cros-borders-eng@google.com</owner>
   <summary>
@@ -1214,7 +1214,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.Mojo.InstallPack.Feature"
-    enum="LanguagePackMojoFeatureId" expires_after="2022-12-11">
+    enum="LanguagePackMojoFeatureId" expires_after="2023-01-30">
   <owner>mlcui@google.com</owner>
   <owner>cros-borders-eng@google.com</owner>
   <summary>
@@ -1224,7 +1224,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.Mojo.PackStateResponse"
-    enum="LanguagePackMojoPackState" expires_after="2022-10-01">
+    enum="LanguagePackMojoPackState" expires_after="2023-01-30">
   <owner>mlcui@google.com</owner>
   <owner>cros-borders-eng@google.com</owner>
   <summary>
@@ -1234,7 +1234,7 @@
 </histogram>
 
 <histogram name="ChromeOS.LanguagePacks.UninstallComplete.Success"
-    enum="BooleanSuccess" expires_after="2022-10-01">
+    enum="BooleanSuccess" expires_after="2023-01-30">
   <owner>claudiomagni@chromium.org</owner>
   <owner>mlcui@google.com</owner>
   <owner>dvallet@chromium.org</owner>
@@ -1513,7 +1513,7 @@
 </histogram>
 
 <histogram name="ChromeOS.SAML.Provider" enum="ChromeOSSamlProvider"
-    expires_after="2022-10-17">
+    expires_after="2023-02-26">
   <owner>mslus@chromium.org</owner>
   <owner>mohammedabdon@chromium.org</owner>
   <summary>Records SAML provider when SAML login flow is used.</summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 9e547806..8e469d2 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -200,7 +200,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.RootDamage" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
@@ -212,7 +212,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.TotalDamage" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
@@ -700,7 +700,7 @@
 </histogram>
 
 <histogram name="Compositing.SurfaceAggregator.AggregateUs"
-    units="microseconds" expires_after="2022-12-25">
+    units="microseconds" expires_after="2023-02-26">
   <owner>kylechar@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -726,7 +726,7 @@
 </histogram>
 
 <histogram name="Compositing.SurfaceAggregator.CopyUs" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kylechar@chromium.org</owner>
   <owner>jonross@chromium.org</owner>
   <summary>
@@ -931,7 +931,7 @@
 </histogram>
 
 <histogram name="Graphics.Smoothness.95pctPercentDroppedFrames_1sWindow"
-    units="%" expires_after="2022-12-25">
+    units="%" expires_after="2023-02-26">
   <owner>jonross@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index 0e8967d..a5e536b 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -191,14 +191,14 @@
 </histogram>
 
 <histogram name="ContentSettings.DefaultAutoplaySetting" enum="ContentSetting"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>The default autoplay setting at profile open.</summary>
 </histogram>
 
 <histogram name="ContentSettings.DefaultCookiesSetting" enum="ContentSetting"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>The default cookies setting at profile open.</summary>
@@ -228,7 +228,7 @@
 </histogram>
 
 <histogram name="ContentSettings.DefaultLocationSetting" enum="ContentSetting"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>The default location setting at profile open.</summary>
@@ -259,7 +259,7 @@
 </histogram>
 
 <histogram name="ContentSettings.DefaultNotificationsSetting"
-    enum="ContentSetting" expires_after="2022-12-25">
+    enum="ContentSetting" expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>The default notification setting at profile open.</summary>
@@ -273,7 +273,7 @@
 </histogram>
 
 <histogram name="ContentSettings.DefaultRequestDesktopSiteSetting"
-    enum="ContentSetting" expires_after="2022-12-25">
+    enum="ContentSetting" expires_after="2023-02-26">
   <owner>shuyng@google.com</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/content_creation/histograms.xml b/tools/metrics/histograms/metadata/content_creation/histograms.xml
index c6f99c54..2fac002 100644
--- a/tools/metrics/histograms/metadata/content_creation/histograms.xml
+++ b/tools/metrics/histograms/metadata/content_creation/histograms.xml
@@ -144,7 +144,7 @@
 </histogram>
 
 <histogram name="LightweightReactions.GifGenerationDuration" units="ms"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>gujen@google.com</owner>
   <owner>chrome-creation@google.com</owner>
   <summary>
@@ -153,7 +153,7 @@
 </histogram>
 
 <histogram name="LightweightReactions.GifGenerationSuccess"
-    enum="BooleanSuccess" expires_after="2022-12-04">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>gujen@google.com</owner>
   <owner>chrome-creation@google.com</owner>
   <summary>
@@ -162,7 +162,7 @@
 </histogram>
 
 <histogram name="LightweightReactions.GifShared" enum="BooleanShared"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>gujen@google.com</owner>
   <owner>chrome-creation@google.com</owner>
   <summary>Records whether the GIF was shared in the Share Sheet.</summary>
@@ -179,7 +179,7 @@
 </histogram>
 
 <histogram name="LightweightReactions.ReactionsUsed" enum="ReactionType"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>gujen@google.com</owner>
   <owner>chrome-creation@google.com</owner>
   <summary>
@@ -497,7 +497,7 @@
 </histogram>
 
 <histogram name="SharedHighlights.LinkToTextDiagnoseStatus"
-    enum="LinkToTextDiagnoseStatus" expires_after="2022-12-25">
+    enum="LinkToTextDiagnoseStatus" expires_after="2023-02-26">
   <owner>jeffreycohen@chromium.org</owner>
   <owner>chrome-shared-highlighting@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index 30b2ac5..4fff4a12 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -132,7 +132,7 @@
 </histogram>
 
 <histogram name="Cookie.CookieSourceSchemeName" enum="CookieSourceSchemeName"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -216,7 +216,7 @@
   </summary>
 </histogram>
 
-<histogram name="Cookie.DomainSet" enum="Boolean" expires_after="2022-12-25">
+<histogram name="Cookie.DomainSet" enum="Boolean" expires_after="2023-02-26">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -497,7 +497,7 @@
   </summary>
 </histogram>
 
-<histogram name="Cookie.NumKeys" units="keys" expires_after="2022-12-25">
+<histogram name="Cookie.NumKeys" units="keys" expires_after="2023-02-26">
   <owner>cfredric@chromium.org</owner>
   <owner>kaustubhag@chromium.org</owner>
   <summary>
@@ -552,7 +552,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.Localhost"
-    enum="InterestingCookiePorts" expires_after="2022-09-11">
+    enum="InterestingCookiePorts" expires_after="2023-03-11">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -573,7 +573,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.RemoteHost"
-    enum="InterestingCookiePorts" expires_after="2022-09-11">
+    enum="InterestingCookiePorts" expires_after="2023-03-11">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -670,7 +670,7 @@
 </histogram>
 
 <histogram name="Cookie.RequestSameSiteContext" enum="SameSiteCookieContext"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bingler@chromium.org</owner>
   <owner>morlovich@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml
index d1ff551..eceeefc 100644
--- a/tools/metrics/histograms/metadata/cras/histograms.xml
+++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="Cras.A2dp100msFailureOverStream" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cros_ml/histograms.xml b/tools/metrics/histograms/metadata/cros_ml/histograms.xml
index 74c8511..f50b27bbc 100644
--- a/tools/metrics/histograms/metadata/cros_ml/histograms.xml
+++ b/tools/metrics/histograms/metadata/cros_ml/histograms.xml
@@ -326,7 +326,7 @@
 </histogram>
 
 <histogram name="MachineLearningService.WorkerProcessExitStatus"
-    units="exit status" expires_after="2022-12-25">
+    units="exit status" expires_after="2023-02-26">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>honglinyu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index bef76d7..10dbfbb 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -208,7 +208,7 @@
 </histogram>
 
 <histogram name="CustomTabs.DetachedResourceRequest.FinalStatus"
-    enum="NetErrorCodes" expires_after="2022-12-25">
+    enum="NetErrorCodes" expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>cct-team@google.com</owner>
   <summary>
@@ -308,7 +308,7 @@
 </histogram>
 
 <histogram name="CustomTabs.PostMessage.OnMessage" enum="Boolean"
-    expires_after="M108">
+    expires_after="2023-02-26">
   <owner>sinansahin@google.com</owner>
   <owner>jinsukkim@chromium.org</owner>
   <owner>chrome-connective-tissue@google.com</owner>
@@ -319,7 +319,7 @@
 </histogram>
 
 <histogram name="CustomTabs.PostMessage.PostMessageFromClientApp"
-    enum="Boolean" expires_after="M108">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>sinansahin@google.com</owner>
   <owner>jinsukkim@chromium.org</owner>
   <owner>chrome-connective-tissue@google.com</owner>
@@ -330,7 +330,7 @@
 </histogram>
 
 <histogram name="CustomTabs.PostMessage.RequestPostMessageChannel"
-    enum="Boolean" expires_after="M108">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>sinansahin@google.com</owner>
   <owner>jinsukkim@chromium.org</owner>
   <owner>chrome-connective-tissue@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml
index d2d4ce01..aa3f8b6 100644
--- a/tools/metrics/histograms/metadata/download/histograms.xml
+++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -94,7 +94,7 @@
 </histogram>
 
 <histogram name="Download.Bubble.DragInfo" enum="Download.DragInfo"
-    expires_after="2022-12-22">
+    expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -243,7 +243,7 @@
 </histogram>
 
 <histogram name="Download.DangerousDialog.Events"
-    enum="DangerousDownloadDialogEvent" expires_after="2022-12-25">
+    enum="DangerousDownloadDialogEvent" expires_after="2023-02-26">
   <owner>qinmin@chromium.org</owner>
   <summary>
     Records user interactions with the dangerous download dialog on Android.
@@ -896,7 +896,7 @@
 </histogram>
 
 <histogram name="Download.Retry.InterruptReason" enum="InterruptReason"
-    expires_after="2022-12-28">
+    expires_after="2023-02-26">
   <owner>thefrog@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index da1ed841..cdc828b 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -429,7 +429,7 @@
 </histogram>
 
 <histogram name="Enterprise.CloudReportingBasicRequestSize" units="KB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>zmin@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
@@ -460,7 +460,7 @@
 </histogram>
 
 <histogram name="Enterprise.CloudReportingResponse"
-    enum="EnterpriseCloudReportingResponse" expires_after="2022-12-25">
+    enum="EnterpriseCloudReportingResponse" expires_after="2023-02-26">
   <owner>zmin@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
@@ -1865,7 +1865,7 @@
 </histogram>
 
 <histogram name="Enterprise.MultipartDataPipe.WriteRate"
-    units="kilobytes per second" expires_after="2022-12-25">
+    units="kilobytes per second" expires_after="2023-02-26">
   <owner>domfc@chromium.org</owner>
   <owner>anthonyvd@chromium.org</owner>
   <summary>
@@ -2391,7 +2391,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsDomainJoined" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>pastarmovj@chromium.org</owner>
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
@@ -2402,7 +2402,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsEnterpriseUser" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>pastarmovj@chromium.org</owner>
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
@@ -2414,7 +2414,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsFullyManaged2" enum="IsFullyManagedBoolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>twellington@google.com</owner>
   <owner>tedchcoc@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 230479f..e9d62607 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -134,7 +134,7 @@
 </histogram>
 
 <histogram name="Extensions.ActiveScriptController.PermittedExtensions"
-    units="Extension Count" expires_after="2022-12-25">
+    units="Extension Count" expires_after="2023-02-26">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -870,7 +870,7 @@
 </histogram>
 
 <histogram name="Extensions.DevTools.UserIsInDeveloperMode"
-    enum="InDeveloperMode" expires_after="2022-11-13">
+    enum="InDeveloperMode" expires_after="2023-02-26">
   <owner>ghazale@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1215,7 +1215,7 @@
 </histogram>
 
 <histogram name="Extensions.ExtensionCacheCount" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vkovalova@google.com</owner>
   <owner>burunduk@chromium.org</owner>
   <owner>managed-devices@google.com</owner>
@@ -1226,7 +1226,7 @@
 </histogram>
 
 <histogram name="Extensions.ExtensionCacheSize" units="MB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vkovalova@google.com</owner>
   <owner>burunduk@chromium.org</owner>
   <owner>managed-devices@google.com</owner>
@@ -1953,7 +1953,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.SucceededTotalExecutionTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1966,7 +1966,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.SynchronousExecutionTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
index d5b3399e..499d14b 100644
--- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
+++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -281,7 +281,7 @@
 </histogram>
 
 <histogram name="InProductHelp.Db.TotalEvents" units="events"
-    expires_after="2022-12-26">
+    expires_after="2023-02-26">
   <owner>nyquist@chromium.org</owner>
   <summary>
     Records the total number of event records in the database for in-product
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml
index a162832..a1c4997 100644
--- a/tools/metrics/histograms/metadata/file/histograms.xml
+++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -356,7 +356,7 @@
 </histogram>
 
 <histogram name="FileBrowser.Glitch" enum="FileManagerGlitch"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>majewski@chromium.org</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index 7b04b71..ca034f1 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1230,7 +1230,7 @@
 </histogram>
 
 <histogram name="GPU.ProcessLifetimeEvents.HardwareAccelerated"
-    enum="GPUProcessLifetimeEvent" expires_after="2022-12-25">
+    enum="GPUProcessLifetimeEvent" expires_after="2023-02-26">
   <owner>vmiura@chromium.org</owner>
   <summary>
     Recorded once for every GPU process launch and crash when GPU process is
@@ -1241,7 +1241,7 @@
 </histogram>
 
 <histogram name="GPU.ProcessLifetimeEvents.SwiftShader"
-    enum="GPUProcessLifetimeEvent" expires_after="2022-12-25">
+    enum="GPUProcessLifetimeEvent" expires_after="2023-02-26">
   <owner>vmiura@chromium.org</owner>
   <summary>
     Recorded once for every GPU process launch and crash when GPU process is
@@ -1689,7 +1689,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayNumProposedCandidates"
-    units="units" expires_after="2022-12-25">
+    units="units" expires_after="2023-02-26">
   <owner>petermcneeley@chromium.org</owner>
   <owner>dcastagna@chromium.org</owner>
   <summary>
@@ -1700,7 +1700,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayQuadMaterial"
-    enum="OverlayQuadMaterial" expires_after="2022-12-25">
+    enum="OverlayQuadMaterial" expires_after="2023-02-26">
   <owner>petermcneeley@chromium.org</owner>
   <owner>dcastagna@chromium.org</owner>
   <summary>
@@ -1731,7 +1731,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.RootDamageRect.Overlay"
-    enum="BooleanOverlayDamageRect" expires_after="2022-12-25">
+    enum="BooleanOverlayDamageRect" expires_after="2023-02-26">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml
index ce73d2c..8417085 100644
--- a/tools/metrics/histograms/metadata/history/histograms.xml
+++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -472,7 +472,7 @@
 </histogram>
 
 <histogram name="History.ClearBrowsingData.UserDeletedFromTab"
-    enum="ClearBrowsingDataTab" expires_after="2022-12-25">
+    enum="ClearBrowsingDataTab" expires_after="2023-02-26">
   <owner>dullweber@chromium.org</owner>
   <owner>msramek@chromium.org</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -815,7 +815,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.NumKeywordsPerCluster"
-    units="number keywords" expires_after="2023-02-19">
+    units="number keywords" expires_after="2023-02-26">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;Journeys</component>
@@ -1237,7 +1237,7 @@
 </histogram>
 
 <histogram name="History.DatabaseSqliteError" enum="SqliteLoggedResultCode"
-    expires_after="2022-12-23">
+    expires_after="2023-02-26">
   <owner>sophiechang@chromium.org</owner>
   <owner>asully@chromium.org</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -1259,7 +1259,7 @@
 </histogram>
 
 <histogram name="History.DomainCount1Day_V2" units="domains"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -1296,7 +1296,7 @@
 </histogram>
 
 <histogram name="History.DomainCount28Day_V2" units="domains"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -1334,7 +1334,7 @@
 </histogram>
 
 <histogram name="History.DomainCount7Day_V2" units="domains"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -1372,7 +1372,7 @@
 </histogram>
 
 <histogram name="History.DomainCountQueryTime_V2" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -1865,7 +1865,7 @@
 </histogram>
 
 <histogram name="History.WeeklyHostCount" units="hosts"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>sky@chromium.org</owner>
   <component>UI&gt;Browser&gt;History</component>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml
index 993296e..ccd56f1 100644
--- a/tools/metrics/histograms/metadata/input/histograms.xml
+++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -219,7 +219,7 @@
 </histogram>
 
 <histogram name="InputMethod.Assistive.MultiWord.CandidatesGenerated"
-    enum="IMEAssistiveMultiWordSuggestionType" expires_after="2022-12-04">
+    enum="IMEAssistiveMultiWordSuggestionType" expires_after="2023-02-26">
   <owner>curtismcmullan@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -266,7 +266,7 @@
 </histogram>
 
 <histogram name="InputMethod.Assistive.MultiWord.RequestCandidates"
-    enum="IMEAssistiveMultiWordSuggestionType" expires_after="2022-12-04">
+    enum="IMEAssistiveMultiWordSuggestionType" expires_after="2023-02-26">
   <owner>curtismcmullan@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -643,7 +643,7 @@
 </histogram>
 
 <histogram name="InputMethod.KeyEventLatency" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>shend@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>Time taken by the engine to handle a key event.</summary>
@@ -846,7 +846,7 @@
 </histogram>
 
 <histogram name="InputMethod.SystemEmojiPicker.Delay" units="ms"
-    expires_after="M110">
+    expires_after="2023-02-26">
   <owner>jopalmer@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -855,7 +855,7 @@
 </histogram>
 
 <histogram name="InputMethod.SystemEmojiPicker.SearchLength" units="characters"
-    expires_after="M110">
+    expires_after="2023-02-26">
   <owner>jopalmer@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -864,7 +864,7 @@
 </histogram>
 
 <histogram name="InputMethod.SystemEmojiPicker.TriggerType"
-    enum="VirtualKeyboardEmojiTriggerType" expires_after="M110">
+    enum="VirtualKeyboardEmojiTriggerType" expires_after="2023-02-26">
   <owner>jopalmer@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>How emojis were inserted.</summary>
@@ -965,7 +965,7 @@
 </histogram>
 
 <histogram name="InputMethod.VirtualKeyboard.ContainerBehavior"
-    enum="VirtualKeyboardContainerType" expires_after="2022-12-25">
+    enum="VirtualKeyboardContainerType" expires_after="2023-02-26">
   <owner>shend@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -1002,7 +1002,7 @@
 </histogram>
 
 <histogram name="InputMethod.VirtualKeyboard.Emoji.TriggerType"
-    enum="VirtualKeyboardEmojiTriggerType" expires_after="2022-12-25">
+    enum="VirtualKeyboardEmojiTriggerType" expires_after="2023-02-26">
   <owner>shend@chromium.org</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>How emojis were inserted.</summary>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 7bc356ec2..eac4d8e 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="IOS.Allocator.ShimInstalled" enum="Boolean"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>rohitrao@chromium.org</owner>
   <owner>justincohen@chromium.org</owner>
   <summary>
@@ -115,7 +115,7 @@
 </histogram>
 
 <histogram name="IOS.ContentExtension.DisplayCount" units="count"
-    expires_after="2022-11-02">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>
@@ -474,7 +474,7 @@
 </histogram>
 
 <histogram name="IOS.DefaultBrowserPromo.NonModal.OnScreenTime" units="ms"
-    expires_after="2022-12-01">
+    expires_after="2023-02-26">
   <owner>rkgibson@chromium.org</owner>
   <owner>djean@chromium.org</owner>
   <summary>
@@ -556,7 +556,7 @@
 </histogram>
 
 <histogram name="IOS.ExperienceKitCalendar.TextClassifierModelAvailable"
-    enum="BooleanAvailable" expires_after="2022-09-08">
+    enum="BooleanAvailable" expires_after="2022-12-31">
   <owner>rajendrant@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -594,7 +594,7 @@
 </histogram>
 
 <histogram name="IOS.FinishedURLMatchesCurrentItem" enum="Boolean"
-    expires_after="2022-10-26">
+    expires_after="2023-02-26">
   <owner>ajuma@chromium.org</owner>
   <owner>gambard@chromium.org</owner>
   <summary>
@@ -670,7 +670,7 @@
 </histogram>
 
 <histogram name="IOS.Frame.FirstContentfulPaint.MainFrame" units="ms"
-    expires_after="2022-11-30">
+    expires_after="2023-02-26">
   <owner>danieltwhite@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -686,7 +686,7 @@
 </histogram>
 
 <histogram name="IOS.Frame.FirstContentfulPaint.SubFrame" units="ms"
-    expires_after="2022-11-30">
+    expires_after="2023-02-26">
   <owner>danieltwhite@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -880,7 +880,7 @@
 </histogram>
 
 <histogram name="IOS.IsEligibleDefaultBrowserPromoUser" enum="BooleanEligible"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
@@ -913,7 +913,7 @@
 </histogram>
 
 <histogram name="IOS.MainThreadFreezeDetection.HangWithCleanExit"
-    enum="Boolean" expires_after="2022-09-12">
+    enum="Boolean" expires_after="2023-09-12">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -926,7 +926,7 @@
 
 <histogram name="IOS.MainThreadFreezeDetection.NotRunningAfterReport"
     enum="IOSMainThreadFreezeDetectionNotRunningAfterReportBlock"
-    expires_after="2022-09-12">
+    expires_after="2023-09-12">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -936,7 +936,7 @@
 </histogram>
 
 <histogram name="IOS.MainThreadFreezeDetection.RecordGenerationTime" units="ms"
-    expires_after="2022-09-12">
+    expires_after="2023-09-12">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -946,7 +946,7 @@
 </histogram>
 
 <histogram name="IOS.MainThreadFreezeDetection.RecoveredAfter" units="ms"
-    expires_after="2022-09-12">
+    expires_after="2023-09-12">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -1045,7 +1045,7 @@
 </histogram>
 
 <histogram name="IOS.MetricKit.BackgroundTimePerDay" units="ms"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -1088,7 +1088,7 @@
 </histogram>
 
 <histogram name="IOS.MetricKit.ForegroundTimePerDay" units="s"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -1172,7 +1172,7 @@
 </histogram>
 
 <histogram name="IOS.NTP.Impression" enum="IOSNTPImpression"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>gambard@chromium.org</owner>
   <summary>
     The type of NTP impressions on iOS, split by type of suggestions shown
@@ -1192,7 +1192,7 @@
 </histogram>
 
 <histogram name="IOS.OpenIn.MimeType" enum="IOSOpenInMimeType"
-    expires_after="2022-11-21">
+    expires_after="2023-02-26">
   <owner>ewannpv@chromium.org</owner>
   <owner>gambard@chromium.org</owner>
   <owner>bling-team@google.com</owner>
@@ -1227,7 +1227,7 @@
 </histogram>
 
 <histogram name="IOS.PageLoadCount.Counts"
-    enum="IOSPageLoadCountNavigationType" expires_after="2022-12-18">
+    enum="IOSPageLoadCountNavigationType" expires_after="2023-02-26">
   <owner>gambard@chromium.org</owner>
   <owner>bling-team@google.com</owner>
   <summary>The number of navigation started events by navigation type.</summary>
@@ -1369,7 +1369,7 @@
 </histogram>
 
 <histogram name="IOS.Process.ActivePrewarm" enum="Boolean"
-    expires_after="2022-11-27">
+    expires_after="2023-02-26">
   <owner>justincohen@google.com</owner>
   <owner>olivierrobin@google.com</owner>
   <summary>
@@ -1507,7 +1507,7 @@
 </histogram>
 
 <histogram name="IOS.SafeBrowsing.RedirectedRequestResponseHostsMatch"
-    enum="BooleanMatched" expires_after="2022-11-06">
+    enum="BooleanMatched" expires_after="2023-02-26">
   <owner>ajuma@chromium.org</owner>
   <owner>gambard@chromium.org</owner>
   <summary>
@@ -1521,14 +1521,14 @@
 </histogram>
 
 <histogram name="IOS.SearchExtension.Action" enum="IOSSearchExtensionAction"
-    expires_after="2022-11-02">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>The action selected by the user in the Search Extension.</summary>
 </histogram>
 
 <histogram name="IOS.SearchExtension.DisplayCount" units="count"
-    expires_after="2022-11-02">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>
@@ -1738,7 +1738,7 @@
 </histogram>
 
 <histogram name="IOS.TabSwitcher.PageChangeInteraction"
-    enum="IOSTabSwitcherPageChangeInteraction" expires_after="2022-11-06">
+    enum="IOSTabSwitcherPageChangeInteraction" expires_after="2023-02-26">
   <owner>marq@chromium.org</owner>
   <owner>bling-team@google.com</owner>
   <summary>
@@ -1748,7 +1748,7 @@
 </histogram>
 
 <histogram name="IOS.TabSwitcher.TimeSpent" units="ms"
-    expires_after="2022-11-01">
+    expires_after="2023-02-26">
   <owner>mrefaat@chromium.org</owner>
   <owner>marq@chromium.org</owner>
   <summary>
@@ -1758,7 +1758,7 @@
 </histogram>
 
 <histogram name="IOS.TextSelection.EntityDetection.DetectedEntityType"
-    enum="TextSelectionDetectedEntityType" expires_after="2022-09-08">
+    enum="TextSelectionDetectedEntityType" expires_after="2022-12-31">
   <owner>rajendrant@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -1771,7 +1771,7 @@
 
 <histogram
     name="IOS.TextSelection.EntityDetection.TFLiteModelEvaluationDuration"
-    units="ms" expires_after="2022-09-08">
+    units="ms" expires_after="2022-12-31">
   <owner>rajendrant@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -1782,7 +1782,7 @@
 </histogram>
 
 <histogram name="IOS.Thumbstrip.CancelBy" enum="ThumbstripOpenByIOS"
-    expires_after="2022-12-01">
+    expires_after="2023-02-26">
   <owner>djean@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>
@@ -1792,14 +1792,14 @@
 </histogram>
 
 <histogram name="IOS.Thumbstrip.CloseBy" enum="ThumbstripCloseByIOS"
-    expires_after="2022-12-01">
+    expires_after="2023-02-26">
   <owner>djean@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>[iOS] Reports how the thumbstrip was closed.</summary>
 </histogram>
 
 <histogram name="IOS.Thumbstrip.OpenBy" enum="ThumbstripOpenByIOS"
-    expires_after="2022-12-01">
+    expires_after="2023-02-26">
   <owner>djean@chromium.org</owner>
   <owner>rkgibson@chromium.org</owner>
   <summary>[iOS] Reports how the thumbstrip was opened.</summary>
@@ -1852,7 +1852,7 @@
 </histogram>
 
 <histogram name="IOS.WidgetKit.Action" enum="IOSWidgetKitAction"
-    expires_after="2022-10-16">
+    expires_after="2023-02-26">
   <owner>rkgibson@google.com</owner>
   <owner>muradyan@google.com</owner>
   <summary>
@@ -1881,7 +1881,7 @@
 </histogram>
 
 <histogram name="IOS.WindowIDInjection.ElapsedTime" units="ms"
-    expires_after="2022-11-06">
+    expires_after="2023-02-26">
   <owner>michaeldo@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml
index bb09f93a..1d37f4a61 100644
--- a/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml
+++ b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml
@@ -184,7 +184,7 @@
 </histogram>
 
 <histogram name="ProtoDB.SharedDbInitStatus" enum="ProtoDatabaseInitState"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ssid@chromium.org</owner>
   <owner>salg@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/login/OWNERS b/tools/metrics/histograms/metadata/login/OWNERS
index 88594879..1edd1298 100644
--- a/tools/metrics/histograms/metadata/login/OWNERS
+++ b/tools/metrics/histograms/metadata/login/OWNERS
@@ -3,5 +3,5 @@
 # Prefer sending CLs to the owners listed below.
 # Use chromium-metrics-reviews@google.com as a backup.
 jorgelo@chromium.org
-rsorokin@chromium.org
+rsorokin@google.com
 alemate@chromium.org
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 094701d6..06f777f6 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -60,8 +60,19 @@
   <variant name="RendererImpl"/>
 </variants>
 
+<!-- The names should match media::GetCodecNameForUMA(). -->
+
+<variants name="VideoCodec">
+  <variant name="AV1"/>
+  <variant name="DolbyVision"/>
+  <variant name="H264"/>
+  <variant name="HEVC"/>
+  <variant name="VP8"/>
+  <variant name="VP9"/>
+</variants>
+
 <histogram name="Media.AImageReaderGLOwner.AcquireImageResult"
-    enum="MediaStatus" expires_after="2022-12-25">
+    enum="MediaStatus" expires_after="2023-02-26">
   <owner>vikassoni@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -106,7 +117,7 @@
 </histogram>
 
 <histogram name="Media.Android.MediaPlayerSuccess" enum="MediaPlayerExitStatus"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tguilbert@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>Android: Whether MediaPlayer exited without errors.</summary>
@@ -298,7 +309,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.LowLatencyCallbackError"
-    enum="BooleanError" expires_after="2022-12-25">
+    enum="BooleanError" expires_after="2023-02-26">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -707,7 +718,7 @@
 </histogram>
 
 <histogram name="Media.Audio.OutputDeviceAuthorizationTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>armax@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
@@ -920,7 +931,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Processing.TotalDelayMs" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>armax@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <summary>
@@ -985,7 +996,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.GetSourceDataTimeMax.WebRTC"
-    units="microseconds" expires_after="2022-12-25">
+    units="microseconds" expires_after="2023-02-26">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -1082,7 +1093,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.OutputDeviceStatus"
-    enum="OutputDeviceStatus" expires_after="2022-12-25">
+    enum="OutputDeviceStatus" expires_after="2023-02-26">
   <owner>dalecurtis@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
@@ -1419,7 +1430,7 @@
 </histogram>
 
 <histogram name="Media.AudioInputControllerSessionSilenceReport"
-    enum="AudioInputSilenceReport" expires_after="2022-12-25">
+    enum="AudioInputSilenceReport" expires_after="2023-02-26">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -2381,7 +2392,7 @@
 
 <histogram
     name="Media.EME.MediaFoundationCdm.Widevine.HardwareSecure.Initialize"
-    enum="Hresult" expires_after="2022-12-25">
+    enum="Hresult" expires_after="2023-02-26">
   <owner>xhwang@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -2535,6 +2546,31 @@
   </summary>
 </histogram>
 
+<histogram name="Media.EME.Widevine.HardwareSecure.Support"
+    enum="BooleanSupported" expires_after="2023-05-07">
+  <owner>xhwang@chromium.org</owner>
+  <owner>media-dev@chromium.org</owner>
+  <summary>
+    When hardware secure decryption is enabled, whether Widevine hardware secure
+    decryption is actually supported by the platform (device). Reported at most
+    once per browser session when EME query is triggered by a website, and when
+    Widevine hardware secure CDM was registered.
+  </summary>
+</histogram>
+
+<histogram name="Media.EME.Widevine.HardwareSecure.Support.{VideoCodec}"
+    enum="BooleanSupported" expires_after="2023-05-07">
+  <owner>xhwang@chromium.org</owner>
+  <owner>media-dev@chromium.org</owner>
+  <summary>
+    When hardware secure decryption is enabled and supported by Widevine,
+    whether {VideoCodec} video codec is supported by the platform (device).
+    Reported at most once per browser session when EME query is triggered by a
+    website, and when Widevine hardware secure CDM was registered.
+  </summary>
+  <token key="VideoCodec" variants="VideoCodec"/>
+</histogram>
+
 <histogram name="Media.EME.Widevine.VideoCapability.HasEmptyRobustness"
     enum="BooleanEmpty" expires_after="2023-01-15">
   <owner>xhwang@chromium.org</owner>
@@ -3466,7 +3502,7 @@
 </histogram>
 
 <histogram name="Media.MojoVideoDecoder.ActiveInstances" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sandersd@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -3528,7 +3564,7 @@
 </histogram>
 
 <histogram base="true" name="Media.MSE.CodecChangeTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wolenetz@chromium.org</owner>
   <owner>sandersd@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
@@ -3574,7 +3610,7 @@
 </histogram>
 
 <histogram name="Media.MSE.Mp4ConsecutiveEmptySamples" units="samples"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wolenetz@chromium.org</owner>
   <owner>sandersd@chromium.org</owner>
   <summary>
@@ -3598,7 +3634,7 @@
 </histogram>
 
 <histogram name="Media.MSE.Mp4SampleSize" units="bytes"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wolenetz@chromium.org</owner>
   <owner>sandersd@chromium.org</owner>
   <summary>
@@ -3609,7 +3645,7 @@
 </histogram>
 
 <histogram name="Media.MSE.Mp4TrunSampleCount" units="samples"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wolenetz@chromium.org</owner>
   <owner>sandersd@chromium.org</owner>
   <summary>
@@ -3790,7 +3826,7 @@
 </histogram>
 
 <histogram name="Media.OutputStreamDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -3857,7 +3893,7 @@
   </summary>
 </histogram>
 
-<histogram name="Media.PipelineStatus.AudioVideo.{Codec}.{Pipeline}"
+<histogram name="Media.PipelineStatus.AudioVideo.{VideoCodec}.{Pipeline}"
     enum="PipelineStatus" expires_after="never">
 <!-- expires-never: Media pipeline health metric. -->
 
@@ -3865,17 +3901,9 @@
   <owner>media-dev@chromium.org</owner>
   <summary>
     Status of the media pipeline at the end of its lifecycle for audio-video
-    streams with {Codec} video codec using {Pipeline}.
+    streams with {VideoCodec} video codec using {Pipeline}.
   </summary>
-  <token key="Codec">
-    <variant name="AV1"/>
-    <variant name="DolbyVision"/>
-    <variant name="H264"/>
-    <variant name="HEVC"/>
-    <variant name="Other" summary="other"/>
-    <variant name="VP8"/>
-    <variant name="VP9"/>
-  </token>
+  <token key="VideoCodec" variants="VideoCodec"/>
   <token key="Pipeline">
     <variant name="DDS.HW"
         summary="RendererImpl with hardware decoder and
@@ -4086,7 +4114,7 @@
 </histogram>
 
 <histogram name="Media.Remoting.SessionDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Measures the duration of each remoting session.</summary>
@@ -4100,14 +4128,14 @@
 </histogram>
 
 <histogram name="Media.Remoting.SessionStartTrigger"
-    enum="RemotingStartTrigger" expires_after="2022-12-25">
+    enum="RemotingStartTrigger" expires_after="2023-02-26">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Tracks the trigger for starting a remoting session.</summary>
 </histogram>
 
 <histogram name="Media.Remoting.SessionStopTrigger" enum="RemotingStopTrigger"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Tracks the trigger for stopping a remoting session.</summary>
@@ -4173,7 +4201,7 @@
 </histogram>
 
 <histogram name="Media.Remoting.VideoCodecProfile" enum="VideoCodecProfile"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Video codec profile used while remoting content.</summary>
@@ -4610,7 +4638,7 @@
 </histogram>
 
 <histogram name="Media.Ui.GetDisplayMedia.DisplayCapturePolicyResult"
-    enum="DisplayCapturePolicyResult" expires_after="2022-12-25">
+    enum="DisplayCapturePolicyResult" expires_after="2023-02-26">
   <owner>eladalon@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <summary>
@@ -4924,7 +4952,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.Error" enum="VideoCaptureError"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mcasas@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
@@ -5087,7 +5115,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.Start" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>toprice@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <summary>
@@ -5097,7 +5125,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.StartOutcome"
-    enum="VideoCaptureStartOutcome" expires_after="2022-12-25">
+    enum="VideoCaptureStartOutcome" expires_after="2023-02-26">
   <owner>toprice@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <summary>
@@ -5156,7 +5184,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.Win.ErrorEvent" enum="Hresult"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>toprice@chromium.org</owner>
   <owner>hta@chromium.org</owner>
   <summary>
@@ -5805,7 +5833,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Cast.Channel.ConnectResult" enum="BooleanSuccess"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mfoltz@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
@@ -6061,7 +6089,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Dial.AvailableDevicesCount" units="devices"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mfoltz@chromium.org</owner>
   <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
@@ -6129,7 +6157,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Icon.Click.Location"
-    enum="MediaRouterDialogActivationLocation" expires_after="2022-12-25">
+    enum="MediaRouterDialogActivationLocation" expires_after="2023-02-26">
   <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Location the user clicked to open the Media Router dialog.</summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml
index 297ece44..bccf2be 100644
--- a/tools/metrics/histograms/metadata/memory/histograms.xml
+++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -281,7 +281,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Active" units="MB"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -308,7 +308,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Background" units="MB"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -352,7 +352,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.NumOpenTabs" units="tabs"
-    expires_after="2022-11-14">
+    expires_after="2023-02-26">
   <owner>ajuma@chromium.org</owner>
   <owner>rkgibson@google.com</owner>
   <summary>
@@ -1376,7 +1376,7 @@
 </histogram>
 
 <histogram base="true" name="Memory.GPU.PeakMemoryAllocationSource2" units="MB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
 <!-- Name completed by a combination of the following two histogram_suffixes: -->
 
 <!-- histogram_suffixes name="GPU.PeakMemoryAllocationSourceBase" -->
@@ -1393,7 +1393,7 @@
 </histogram>
 
 <histogram base="true" name="Memory.GPU.PeakMemoryUsage2" units="MB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="GPU_PeakMemoryUsage" -->
 
   <owner>jonross@chromium.org</owner>
@@ -1880,7 +1880,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.OnDiskSize.5min" units="KiB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1890,7 +1890,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.Read.Latency" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1913,7 +1913,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.Read.Throughput" units="MiBps"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1933,7 +1933,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.TotalReadTime.5min" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1963,7 +1963,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.UnparkedSize.5min" units="KiB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1973,7 +1973,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.Write.Latency" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -1986,7 +1986,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableImage.Write.Size" units="KiB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thiabaud@google.com</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -2015,7 +2015,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.Compression.Latency"
-    units="microseconds" expires_after="2022-12-25">
+    units="microseconds" expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>thiabaud@google.com</owner>
   <summary>
@@ -2045,7 +2045,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.CompressionRatio.5min" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
   <summary>
@@ -2056,7 +2056,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.Decompression.Latency"
-    units="microseconds" expires_after="2022-12-25">
+    units="microseconds" expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>thiabaud@google.com</owner>
   <summary>
@@ -2078,7 +2078,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.Decompression.ThroughputMBps"
-    units="MBps" expires_after="2022-12-25">
+    units="MBps" expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>thiabaud@google.com</owner>
   <summary>
@@ -2179,7 +2179,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.Read.Latency" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>lizeb@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
   <summary>
@@ -2364,7 +2364,7 @@
 </histogram>
 
 <histogram base="true" name="Memory.PressureWindowDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="Memory.Pressure.TransitionType" -->
 
   <owner>fdoray@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml
index 1668ef8..0fa203e 100644
--- a/tools/metrics/histograms/metadata/mobile/histograms.xml
+++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -213,7 +213,7 @@
 </histogram>
 
 <histogram name="Mobile.Messages.Banner.OnScreenTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sczs@chromium.org</owner>
   <owner>thegreenfrog@google.com</owner>
   <summary>
@@ -246,7 +246,7 @@
 </histogram>
 
 <histogram base="true" name="Mobile.Messages.Confirm.Event"
-    enum="MobileMessagesConfirmInfobarEvents" expires_after="2022-12-25">
+    enum="MobileMessagesConfirmInfobarEvents" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="Mobile.Messages.Confirm.Type" -->
 
   <owner>sczs@chromium.org</owner>
@@ -1165,7 +1165,7 @@
 </histogram>
 
 <histogram name="MobileStartup.DailyLaunchCount" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tedchoc@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index 9c8f8429..13f7d24 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -81,7 +81,7 @@
 
 <histogram
     name="BackForwardCache.AllSites.HistoryNavigationOutcome.BlocklistedFeature"
-    enum="WebSchedulerTrackedFeature" expires_after="2022-12-25">
+    enum="WebSchedulerTrackedFeature" expires_after="2023-02-26">
   <owner>hajimehoshi@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -134,7 +134,7 @@
 
 <histogram
     name="BackForwardCache.AllSites.HistoryNavigationOutcome.NotRestoredReason"
-    enum="BackForwardCacheNotRestoredReason" expires_after="2022-12-25">
+    enum="BackForwardCacheNotRestoredReason" expires_after="2023-02-26">
   <owner>hajimehoshi@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -417,7 +417,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.Restore.NavigationToFirstPaint" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sreejakshetty@chromium.org</owner>
   <owner>altimin@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
@@ -1876,7 +1876,7 @@
 </histogram>
 
 <histogram name="Prerender.PrerenderLoadComplete" enum="BooleanSuccess"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>gambard@chromium.org</owner>
   <owner>justincohen@chromium.org</owner>
   <summary>
@@ -1913,7 +1913,7 @@
 </histogram>
 
 <histogram name="Prerender.PrerenderTimeSaved" units="ms"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>gambard@chromium.org</owner>
   <owner>justincohen@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 47da44a4..b1f37055 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -770,7 +770,7 @@
 </histogram>
 
 <histogram name="Net.DNS.DnsTask.HttpUpgrade" enum="DNS.HttpUpgradeResult"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ericorth@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -1066,7 +1066,7 @@
 </histogram>
 
 <histogram name="Net.DNS.InsecureDnsTask.FailureTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ericorth@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -1298,7 +1298,7 @@
 </histogram>
 
 <histogram base="true" name="Net.DNS.UI.DropdownSelectionEvent"
-    enum="DohProviderId" expires_after="2022-12-18">
+    enum="DohProviderId" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes
    name="DnsDropdownSelectionEvent" -->
 
@@ -1675,7 +1675,7 @@
 </histogram>
 
 <histogram name="Net.HttpJob.TotalTime.TLS13.Google" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>davidben@chromium.org</owner>
   <owner>trusty-transport@chromium.org</owner>
   <summary>
@@ -1854,7 +1854,7 @@
 </histogram>
 
 <histogram name="Net.NetworkChangeNotifier.NewConnectionCost"
-    enum="NetworkConnectionCost" expires_after="2022-12-25">
+    enum="NetworkConnectionCost" expires_after="2023-02-26">
   <owner>fbeaufort@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -1864,7 +1864,7 @@
 </histogram>
 
 <histogram name="Net.NetworkChangeNotifier.NewConnectionType"
-    enum="NetworkConnectionType" expires_after="2022-12-25">
+    enum="NetworkConnectionType" expires_after="2023-02-26">
   <owner>dschinazi@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -4907,7 +4907,7 @@
 </histogram>
 
 <histogram base="true" name="Net.TrustTokens.NetErrorForFetchFailure"
-    enum="NetErrorCodes" expires_after="2022-11-06">
+    enum="NetErrorCodes" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="TrustTokenOperationType" -->
 
   <owner>davidvc@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 9165a8f..078bcf4 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -2676,7 +2676,7 @@
 </histogram>
 
 <histogram name="Network.Shill.WiFi.TimeFromRekeyToFailureSeconds"
-    units="seconds" expires_after="2022-12-01">
+    units="seconds" expires_after="2023-02-26">
   <owner>billyzhao@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -3003,7 +3003,7 @@
 </histogram>
 
 <histogram name="NetworkService.ClearStaleDataDirectoryResult"
-    enum="DeleteStaleCookiesResult" expires_after="2022-12-25">
+    enum="DeleteStaleCookiesResult" expires_after="2023-02-26">
   <owner>wfh@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
   <summary>
@@ -3108,7 +3108,7 @@
 </histogram>
 
 <histogram name="NetworkService.GrantSandboxResult"
-    enum="NetworkServiceSandboxGrantResult" expires_after="2022-12-25">
+    enum="NetworkServiceSandboxGrantResult" expires_after="2023-02-26">
   <owner>wfh@chromium.org</owner>
   <owner>mmenke@chromium.org</owner>
   <summary>
@@ -3279,7 +3279,7 @@
 </histogram>
 
 <histogram name="NetworkService.TimeToMigrateData" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wfh@chromium.org</owner>
   <owner>mmenke@chromium.org</owner>
   <summary>
@@ -3328,7 +3328,7 @@
 </histogram>
 
 <histogram name="NetworkService.URLLoaderFactory.UpdateLoadInfo" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jam@chromium.org</owner>
   <owner>cduvall@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
index fd58011c..48771c9 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -105,7 +105,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.CartImageCount" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <summary>
@@ -257,7 +257,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.DiscountCountAtLoad" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>meiliang@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -271,7 +271,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.NonDiscountCountAtLoad" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>meiliang@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -1020,7 +1020,7 @@
 </histogram>
 
 <histogram name="NewTabPage.MainUi.ShownTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tiborg@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
   <summary>
@@ -1919,7 +1919,7 @@
 </histogram>
 
 <histogram name="NewTabPage.TimeSinceLastNTP" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/notifications/histograms.xml b/tools/metrics/histograms/metadata/notifications/histograms.xml
index f8bac0f6..7371651 100644
--- a/tools/metrics/histograms/metadata/notifications/histograms.xml
+++ b/tools/metrics/histograms/metadata/notifications/histograms.xml
@@ -594,7 +594,7 @@
 </histogram>
 
 <histogram name="Notifications.NotifierType" enum="NotifierType"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tbarzic@chromium.org</owner>
   <owner>tengs@chromium.org</owner>
   <owner>gzadina@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/offline/histograms.xml b/tools/metrics/histograms/metadata/offline/histograms.xml
index a077bdd4..3f8fa50 100644
--- a/tools/metrics/histograms/metadata/offline/histograms.xml
+++ b/tools/metrics/histograms/metadata/offline/histograms.xml
@@ -617,7 +617,7 @@
 </histogram>
 
 <histogram name="OfflinePages.DidNavigationThrottleCancelNavigation"
-    enum="Boolean" expires_after="2022-12-25">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml
index 5fd51471..e35a7ee 100644
--- a/tools/metrics/histograms/metadata/omnibox/histograms.xml
+++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -491,7 +491,7 @@
 </histogram>
 
 <histogram name="Omnibox.CutOrCopyAllText" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jdonnelly@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
@@ -1213,7 +1213,7 @@
 </histogram>
 
 <histogram name="Omnibox.ResumeJourneyShown" units="position"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tommycli@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
   <summary>
@@ -1434,7 +1434,7 @@
 </histogram>
 
 <histogram name="Omnibox.SuggestionUsed.AnswerInSuggest"
-    enum="SuggestionAnswerOptionalType" expires_after="2022-12-25">
+    enum="SuggestionAnswerOptionalType" expires_after="2023-02-26">
   <owner>jdonnelly@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
@@ -1487,7 +1487,7 @@
 </histogram>
 
 <histogram name="Omnibox.SuggestionUsed.ResumeJourney" units="position"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tommycli@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
   <summary>
@@ -1529,7 +1529,7 @@
 </histogram>
 
 <histogram name="Omnibox.SuggestionUsed.ResumeJourney.ClusterKeywordType"
-    enum="HistoryClusterKeywordType" expires_after="2023-02-19">
+    enum="HistoryClusterKeywordType" expires_after="2023-02-26">
   <owner>junzou@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -1582,7 +1582,7 @@
 </histogram>
 
 <histogram name="Omnibox.SuggestionUsed.ResumeJourney.PageEntityCollection"
-    enum="OptimizationGuidePageEntityCollection" expires_after="2023-02-19">
+    enum="OptimizationGuidePageEntityCollection" expires_after="2023-02-26">
   <owner>junzou@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -2012,7 +2012,7 @@
 </histogram>
 
 <histogram name="Omnibox.TabMatchTime" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>gangwu@chromium.org</owner>
   <owner>jdonnelly@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/oobe/OWNERS b/tools/metrics/histograms/metadata/oobe/OWNERS
index f0e7010..f80af19 100644
--- a/tools/metrics/histograms/metadata/oobe/OWNERS
+++ b/tools/metrics/histograms/metadata/oobe/OWNERS
@@ -2,5 +2,5 @@
 
 # Prefer sending CLs to the owners listed below.
 # Use chromium-metrics-reviews@google.com as a backup.
-rsorokin@chromium.org
+rsorokin@google.com
 alemate@chromium.org
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index 23c6d4af..60c55dd 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -357,7 +357,7 @@
 
 <histogram
     name="OptimizationGuide.HintsManager.ConcurrentPageNavigationFetches"
-    units="counts" expires_after="M109">
+    units="counts" expires_after="2023-02-26">
   <owner>sophiechang@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -739,7 +739,7 @@
 <histogram
     name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageStatus"
     enum="OptimizationGuidePageContentAnnotationsStorageStatus"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>sophiechang@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -1151,7 +1151,7 @@
 
 <histogram
     name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.NetErrorCode"
-    enum="NetErrorCodes" expires_after="2023-02-19">
+    enum="NetErrorCodes" expires_after="2023-02-26">
   <owner>mcrouse@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -1181,7 +1181,7 @@
 
 <histogram
     name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.Status"
-    enum="HttpResponseCode" expires_after="2023-02-19">
+    enum="HttpResponseCode" expires_after="2023-02-26">
   <owner>mcrouse@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 1ca9441..abc19b4 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -2813,7 +2813,7 @@
 </histogram>
 
 <histogram name="ClientHints.UpdateEventCount" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yoavweiss@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <owner>mkwst@chromium.org</owner>
@@ -2825,7 +2825,7 @@
 </histogram>
 
 <histogram name="ClientHints.UpdateSize" units="count"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yoavweiss@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <owner>mkwst@chromium.org</owner>
@@ -3066,7 +3066,7 @@
 </histogram>
 
 <histogram name="ContextMenu.iOS.LensSupportStatus" enum="IOSLensSupportStatus"
-    expires_after="2022-10-16">
+    expires_after="2023-02-26">
   <owner>hujasonx@google.com</owner>
   <owner>lens-in-bling-team@google.com</owner>
   <summary>
@@ -4147,7 +4147,7 @@
 </histogram>
 
 <histogram name="Crashpad.AnrUpload.Skipped" enum="AnrSkippedReason"
-    expires_after="2022-12-15">
+    expires_after="2023-02-26">
   <owner>smaier@chromium.org</owner>
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The reason that an ANR upload was skipped.</summary>
@@ -4938,7 +4938,7 @@
 </histogram>
 
 <histogram name="DocumentScan.ScanFailed" enum="DocumentScanSaneBackend"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>project-bolton@google.com</owner>
   <summary>
@@ -4958,7 +4958,7 @@
 </histogram>
 
 <histogram name="DocumentScan.ScanSucceeded" enum="DocumentScanSaneBackend"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>project-bolton@google.com</owner>
   <summary>
@@ -5602,7 +5602,7 @@
 </histogram>
 
 <histogram name="ExploreSites.MonthlyHostCount" units="hosts"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>dimich@chromium.org</owner>
   <summary>
     Number of unique hosts visited by the user during the last 30 days. Reported
@@ -5981,7 +5981,7 @@
 </histogram>
 
 <histogram name="Feedback.Duration.FormSubmitToSendQueue" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>xiangdongkong@google.com</owner>
   <owner>cros-feedback-app@google.com</owner>
   <summary>
@@ -6042,7 +6042,7 @@
 </histogram>
 
 <histogram name="Feedback.TrustSafetySentiment.SurveyRequested"
-    enum="TrustSafetySentimentFeatureArea" expires_after="2022-12-25">
+    enum="TrustSafetySentimentFeatureArea" expires_after="2023-02-26">
   <owner>sauski@google.com</owner>
   <owner>chrome-hats-eng@google.com</owner>
   <summary>
@@ -6052,7 +6052,7 @@
 </histogram>
 
 <histogram name="Feedback.TrustSafetySentiment.TriggerOccurred"
-    enum="TrustSafetySentimentFeatureArea" expires_after="2022-12-25">
+    enum="TrustSafetySentimentFeatureArea" expires_after="2023-02-26">
   <owner>sauski@google.com</owner>
   <owner>chrome-hats-eng@google.com</owner>
   <summary>
@@ -6182,7 +6182,7 @@
 </histogram>
 
 <histogram name="FirstRun.Sentinel.Created" enum="FirstRunSentinelResult"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>jlebel@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>Result of sentinel file has been written.</summary>
@@ -6207,7 +6207,7 @@
 </histogram>
 
 <histogram name="FirstRun.Stage" enum="FirstRunStageResult"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>tinazwang@chromium.org</owner>
   <owner>bling-get-started@google.com</owner>
   <summary>
@@ -6702,7 +6702,7 @@
   </summary>
 </histogram>
 
-<histogram name="Hardware.TotalDiskSpace" units="GB" expires_after="2022-12-25">
+<histogram name="Hardware.TotalDiskSpace" units="GB" expires_after="2023-02-26">
   <owner>zmo@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -8230,7 +8230,7 @@
 </histogram>
 
 <histogram name="Mojo.Channel.WriteMessageSize" units="bytes"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>amistry@chromium.org</owner>
   <owner>bgeffon@chromium.org</owner>
   <owner>rockot@google.com</owner>
@@ -9559,7 +9559,7 @@
 </histogram>
 
 <histogram name="PeriodicBackgroundSync.Event.FromWakeupTask"
-    enum="BackgroundSyncWakeupTask" expires_after="2022-12-25">
+    enum="BackgroundSyncWakeupTask" expires_after="2023-02-26">
   <owner>nator@chromium.org</owner>
   <owner>rayankans@chromium.org</owner>
   <summary>
@@ -9569,7 +9569,7 @@
 </histogram>
 
 <histogram name="PeriodicBackgroundSync.Event.Time" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>nator@chromium.org</owner>
   <owner>rayankans@chromium.org</owner>
   <summary>
@@ -10645,7 +10645,7 @@
 </histogram>
 
 <histogram name="ReadingList.WebUI.LoadCompletedTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -11572,7 +11572,7 @@
 </histogram>
 
 <histogram base="true" name="SB2.RequestDestination" enum="RequestDestination"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -12305,7 +12305,7 @@
 </histogram>
 
 <histogram name="SignedExchange.Prefetch.LoadResult2"
-    enum="SignedExchangeLoadResult" expires_after="2022-12-25">
+    enum="SignedExchangeLoadResult" expires_after="2023-02-26">
   <owner>ksakamoto@chromium.org</owner>
   <owner>webpackage-dev@chromium.org</owner>
   <summary>
@@ -12693,7 +12693,7 @@
 </histogram>
 
 <histogram name="SpellCheck.SuggestionHitRatio" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>gujen@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14394,7 +14394,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.DismissedEventSource"
-    enum="VoiceInteractionEventSource" expires_after="2022-12-25">
+    enum="VoiceInteractionEventSource" expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14404,7 +14404,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.DismissedEventTarget"
-    enum="VoiceIntentTarget" expires_after="2022-12-25">
+    enum="VoiceIntentTarget" expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14415,7 +14415,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.FailureEventSource"
-    enum="VoiceInteractionEventSource" expires_after="2022-10-23">
+    enum="VoiceInteractionEventSource" expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14427,7 +14427,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.FailureEventTarget" enum="VoiceIntentTarget"
-    expires_after="2022-10-23">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14439,7 +14439,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.FinishEventSource"
-    enum="VoiceInteractionEventSource" expires_after="2022-12-25">
+    enum="VoiceInteractionEventSource" expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14449,7 +14449,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.FinishEventTarget" enum="VoiceIntentTarget"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14469,7 +14469,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.QueryDuration.Android" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14516,7 +14516,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.StartEventSource"
-    enum="VoiceInteractionEventSource" expires_after="2022-12-25">
+    enum="VoiceInteractionEventSource" expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14526,7 +14526,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.StartEventTarget" enum="VoiceIntentTarget"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14567,7 +14567,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.VoiceResultConfidenceValue" units="%"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -14589,7 +14589,7 @@
 </histogram>
 
 <histogram name="VoiceInteraction.VoiceSearchResult" enum="BooleanSuccess"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jds@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -15039,7 +15039,7 @@
 </histogram>
 
 <histogram name="WebUITabStrip.OpenDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>collinbaker@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index 81a061ef6..10e6b22 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -318,7 +318,7 @@
 
 <histogram
     name="PageLoad.Clients.AMP.Experimental.PageTiming.InputToNavigation.Subframe"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>bmcquade@chromium.org</owner>
   <owner>sullivan@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
@@ -631,7 +631,7 @@
 
 <histogram
     name="PageLoad.Clients.FencedFrames.LayoutInstability.CumulativeShiftScore"
-    units="scorex10" expires_after="2022-12-25">
+    units="scorex10" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparch-dev@chromium.org</owner>
   <summary>
@@ -658,7 +658,7 @@
 
 <histogram
     name="PageLoad.Clients.FencedFrames.PaintTiming.NavigationToFirstContentfulPaint"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparch-dev@chromium.org</owner>
   <summary>
@@ -696,7 +696,7 @@
 
 <histogram
     name="PageLoad.Clients.FencedFrames.PaintTiming.NavigationToFirstPaint"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparch-dev@chromium.org</owner>
   <summary>
@@ -708,7 +708,7 @@
 
 <histogram
     name="PageLoad.Clients.FencedFrames.PaintTiming.NavigationToLargestContentfulPaint2"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparch-dev@chromium.org</owner>
   <summary>
@@ -803,7 +803,7 @@
 
 <histogram
     name="PageLoad.Clients.GoogleSearch.PaintTiming.NavigationToFirstContentfulPaint"
-    units="ms" expires_after="2022-12-23">
+    units="ms" expires_after="2023-02-26">
   <owner>spelchat@chromium.org</owner>
   <owner>chrome-brapp-loading@google.com</owner>
   <summary>
@@ -817,7 +817,7 @@
 
 <histogram
     name="PageLoad.Clients.GoogleSearch.PaintTiming.NavigationToLargestContentfulPaint"
-    units="ms" expires_after="2022-12-23">
+    units="ms" expires_after="2023-02-26">
   <owner>spelchat@chromium.org</owner>
   <owner>chrome-brapp-loading@google.com</owner>
   <summary>
@@ -1168,7 +1168,7 @@
 
 <histogram
     name="PageLoad.Clients.ThirdParty.Frames.NavigationToFirstContentfulPaint3"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>jkarlin@chromium.org</owner>
   <owner>johnidel@chromium.org</owner>
   <summary>
@@ -1271,7 +1271,7 @@
 
 <histogram
     name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>bmcquade@chromium.org</owner>
   <owner>csharrison@chromium.org</owner>
   <summary>
@@ -1281,7 +1281,7 @@
 </histogram>
 
 <histogram name="PageLoad.DocumentTiming.NavigationToLoadEventFired" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmcquade@chromium.org</owner>
   <owner>csharrison@chromium.org</owner>
   <summary>
@@ -1704,7 +1704,7 @@
 
 <histogram
     name="PageLoad.Experimental.NavigationTiming.NavigationStartToFirstResponseStart"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>nhiroki@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
   <summary>
@@ -1715,7 +1715,7 @@
 
 <histogram
     name="PageLoad.Experimental.NavigationTiming.NavigationStartToNavigationCommitSent"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>nhiroki@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
   <summary>
@@ -1874,7 +1874,7 @@
 
 <histogram
     name="PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>ksakamoto@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <summary>
@@ -2633,7 +2633,7 @@
 </histogram>
 
 <histogram name="PageLoad.PaintTiming.ForegroundToFirstContentfulPaint"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>sullivan@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <summary>
@@ -2688,7 +2688,7 @@
 </histogram>
 
 <histogram name="PageLoad.PaintTiming.NavigationToFirstPaint" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ksakamoto@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <summary>
@@ -2793,6 +2793,30 @@
   </summary>
 </histogram>
 
+<histogram
+    name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint2AtFirstOnHidden"
+    units="ms" expires_after="2023-08-08">
+  <owner>lanwei@chromium.org</owner>
+  <owner>speed-metrics-dev@chromium.org</owner>
+  <summary>
+    Measures the time from navigation timing's navigation start to the time the
+    largest content (text or image) is first painted, across all frames.
+    Recorded at the point when a page which has been opened in the foreground is
+    moved to the background for the first time. Excludes any content painted
+    after user input. Includes content that has been removed from the page. See
+    web.dev/lcp for more details.
+
+    This metric is trying to record the LCP values which are not able to be
+    recorded in PageLoad.PaintTiming.NavigationToLargestContentfulPaint2 for
+    some reasons.
+
+    Do not modify this metric in any way without contacting
+    speed-metrics-dev@chromium.org AND chrome-analysis-team@google.com.
+
+    Log of major changes: http://bit.ly/chrome-speed-metrics-changelog
+  </summary>
+</histogram>
+
 <histogram name="PageLoad.PaintTiming.ParseStartToFirstContentfulPaint"
     units="ms" expires_after="2023-02-12">
   <owner>bmcquade@chromium.org</owner>
@@ -2805,7 +2829,7 @@
 </histogram>
 
 <histogram name="PageLoad.ParseTiming.NavigationToParseStart" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmcquade@chromium.org</owner>
   <owner>csharrison@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index e1ebe05a..6e7e5c5 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -78,7 +78,7 @@
 </variants>
 
 <histogram name="KeyboardAccessory.AccessoryActionImpression"
-    enum="AccessoryAction" expires_after="2022-12-25">
+    enum="AccessoryAction" expires_after="2023-02-26">
   <owner>fhorschig@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -88,7 +88,7 @@
 </histogram>
 
 <histogram name="KeyboardAccessory.AccessoryActionSelected"
-    enum="AccessoryAction" expires_after="2022-12-25">
+    enum="AccessoryAction" expires_after="2023-02-26">
   <owner>fhorschig@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -98,7 +98,7 @@
 </histogram>
 
 <histogram name="KeyboardAccessory.AccessoryBarShown"
-    enum="AccessoryBarContents" expires_after="2022-12-25">
+    enum="AccessoryBarContents" expires_after="2023-02-26">
   <owner>fhorschig@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -129,7 +129,7 @@
 </histogram>
 
 <histogram name="KeyboardAccessory.AccessorySheetTriggered"
-    enum="AccessorySheetTrigger" expires_after="2022-12-25">
+    enum="AccessorySheetTrigger" expires_after="2023-02-26">
   <owner>fhorschig@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -151,7 +151,7 @@
 </histogram>
 
 <histogram name="KeyboardAccessory.AccessoryToggleImpression"
-    enum="AccessoryToggleType" expires_after="2022-12-25">
+    enum="AccessoryToggleType" expires_after="2023-02-26">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
@@ -217,7 +217,7 @@
 </histogram>
 
 <histogram name="PasswordGeneration.Event" enum="PasswordGenerationEvent"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>kolos@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
@@ -640,7 +640,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationFetcher.FailedToParseResponse"
-    enum="Boolean" expires_after="2022-12-11">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -672,7 +672,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationFetcher.FetchResult"
-    enum="AffiliationFetchResult" expires_after="2022-12-25">
+    enum="AffiliationFetchResult" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -874,7 +874,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AutomaticChange.AcceptanceWithoutAutoButton"
-    enum="PasswordCheckResolutionAction" expires_after="2022-12-25">
+    enum="PasswordCheckResolutionAction" expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -999,7 +999,7 @@
 </histogram>
 
 <histogram name="PasswordManager.BulkCheck.Error"
-    enum="PasswordLeakDetectionError" expires_after="2022-12-25">
+    enum="PasswordLeakDetectionError" expires_after="2023-02-26">
   <owner>vasilii@chromium.org</owner>
   <owner>vsemeniuk@google.com</owner>
   <summary>Error encountered during the password bulk check.</summary>
@@ -1033,7 +1033,7 @@
 </histogram>
 
 <histogram name="PasswordManager.BulkCheck.PasswordCheckReferrer"
-    enum="PasswordCheckReferrer" expires_after="2022-12-25">
+    enum="PasswordCheckReferrer" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1089,7 +1089,7 @@
 </histogram>
 
 <histogram name="PasswordManager.BulkCheck.TimePerCredential" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vasilii@chromium.org</owner>
   <owner>vsemeniuk@google.com</owner>
   <summary>
@@ -1409,7 +1409,7 @@
 </histogram>
 
 <histogram name="PasswordManager.EditsInSaveBubble"
-    enum="PasswordManagerEditsInSaveBubbleEnum" expires_after="2022-12-25">
+    enum="PasswordManagerEditsInSaveBubbleEnum" expires_after="2023-02-26">
   <owner>vasilii@chromium.org</owner>
   <owner>kazinova@google.com</owner>
   <summary>
@@ -1444,7 +1444,7 @@
 </histogram>
 
 <histogram name="PasswordManager.FieldNameCollisionInVotes" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>khamutov@google.com</owner>
   <summary>
@@ -1463,7 +1463,7 @@
 </histogram>
 
 <histogram name="PasswordManager.FillingAssistance"
-    enum="PasswordManagerFillingAssistance" expires_after="2022-12-25">
+    enum="PasswordManagerFillingAssistance" expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -1676,7 +1676,7 @@
 </histogram>
 
 <histogram name="PasswordManager.iOS.InfoBar.PasswordSave" enum="Boolean"
-    expires_after="2022-10-16">
+    expires_after="2023-02-26">
   <owner>djean@chromium.org</owner>
   <owner>sczs@google.com</owner>
   <summary>
@@ -1744,7 +1744,7 @@
 
 <histogram name="PasswordManager.LeakDetection.DialogDismissalReason"
     enum="PasswordLeakDetectionDialogDismissalReason"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1754,7 +1754,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.Error"
-    enum="PasswordLeakDetectionError" expires_after="2022-12-25">
+    enum="PasswordLeakDetectionError" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1763,7 +1763,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.HttpResponseCode"
-    enum="HttpResponseCode" expires_after="2022-12-25">
+    enum="HttpResponseCode" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1834,7 +1834,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1864,14 +1864,14 @@
 </histogram>
 
 <histogram name="PasswordManager.LoginDatabaseInit"
-    enum="LoginDatabaseInitError" expires_after="2022-12-25">
+    enum="LoginDatabaseInitError" expires_after="2023-02-26">
   <owner>vasilii@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
   <summary>An error on LoginDatabase initialization.</summary>
 </histogram>
 
 <histogram name="PasswordManager.ManagePasswordsReferrer"
-    enum="ManagePasswordsReferrer" expires_after="2022-12-25">
+    enum="ManagePasswordsReferrer" expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2000,7 +2000,7 @@
 </histogram>
 
 <histogram name="PasswordManager.NewlySavedPasswordIsGenerated"
-    enum="BooleanNewlySavedPasswordIsGenerated" expires_after="2022-12-25">
+    enum="BooleanNewlySavedPasswordIsGenerated" expires_after="2023-02-26">
   <owner>nepper@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
@@ -2233,7 +2233,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordScriptsFetcher.CacheState"
-    enum="PasswordScriptsFetcherCacheState" expires_after="2022-12-25">
+    enum="PasswordScriptsFetcherCacheState" expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -2244,7 +2244,7 @@
 
 <histogram
     name="PasswordManager.PasswordScriptsFetcher.HttpResponseAndNetErrorCode"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2022-12-25">
+    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -2254,7 +2254,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordScriptsFetcher.ParsingResult"
-    enum="PasswordScriptsFetcherParsingResult" expires_after="2022-12-25">
+    enum="PasswordScriptsFetcherParsingResult" expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>Result of parsing of a list of available password scripts.</summary>
@@ -2748,7 +2748,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordSyncState2" enum="PasswordSyncState"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2781,7 +2781,7 @@
 </histogram>
 
 <histogram name="PasswordManager.ProvisionalSaveFailure"
-    enum="ProvisionalSaveFailure" expires_after="2022-12-25">
+    enum="ProvisionalSaveFailure" expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2893,7 +2893,7 @@
 </histogram>
 
 <histogram name="PasswordManager.SaveUIDismissalReason"
-    enum="PasswordManagerUIDismissalReason" expires_after="2022-12-25">
+    enum="PasswordManagerUIDismissalReason" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="PasswordAccountStorageUserState" -->
 
   <owner>vasilii@chromium.org</owner>
@@ -3112,7 +3112,7 @@
 </histogram>
 
 <histogram name="PasswordManager.SyncingAccountState2"
-    enum="PasswordManagerSyncingAccountState" expires_after="2022-12-25">
+    enum="PasswordManagerSyncingAccountState" expires_after="2023-02-26">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <owner>chrome-password-manager-metrics-alerts@google.com</owner>
@@ -3155,7 +3155,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TouchToFill.CredentialIndex" units="index"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
@@ -3166,7 +3166,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TouchToFill.DismissalReason"
-    enum="BottomSheet.StateChangeReason" expires_after="2022-12-25">
+    enum="BottomSheet.StateChangeReason" expires_after="2023-02-26">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
@@ -3184,7 +3184,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TouchToFill.Outcome"
-    enum="TouchToFill.Outcome" expires_after="2022-12-25">
+    enum="TouchToFill.Outcome" expires_after="2023-02-26">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
@@ -3196,7 +3196,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TouchToFill.SubmissionReadiness"
-    enum="TouchToFill.SubmissionReadiness" expires_after="2022-12-25">
+    enum="TouchToFill.SubmissionReadiness" expires_after="2023-02-26">
   <owner>kolos@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
@@ -3253,7 +3253,7 @@
 </histogram>
 
 <histogram name="PasswordManager.UIDismissalReason"
-    enum="PasswordManagerUIDismissalReason" expires_after="2022-12-25">
+    enum="PasswordManagerUIDismissalReason" expires_after="2023-02-26">
   <owner>vasilii@chromium.org</owner>
   <summary>
     Why was the password manager's UI (bubble or infobar) closed? Save and
@@ -3658,7 +3658,7 @@
 </histogram>
 
 <histogram name="PasswordProtection.InterstitialAction"
-    enum="PasswordProtectionWarningAction" expires_after="2022-12-25">
+    enum="PasswordProtectionWarningAction" expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -3763,7 +3763,7 @@
 </histogram>
 
 <histogram base="true" name="PasswordProtection.RequestOutcome"
-    enum="PasswordProtectionRequestOutcome" expires_after="2022-12-25">
+    enum="PasswordProtectionRequestOutcome" expires_after="2023-02-26">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -3808,7 +3808,7 @@
 </histogram>
 
 <histogram name="PasswordProtection.Verdict" enum="PasswordProtectionVerdict"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/payment/histograms.xml b/tools/metrics/histograms/metadata/payment/histograms.xml
index 0d916c54..4070a38 100644
--- a/tools/metrics/histograms/metadata/payment/histograms.xml
+++ b/tools/metrics/histograms/metadata/payment/histograms.xml
@@ -119,7 +119,7 @@
 </histogram>
 
 <histogram name="PaymentRequest.JourneyLoggerHasRecorded" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rouslan@chromium.org</owner>
   <owner>web-payments-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/pdf/histograms.xml b/tools/metrics/histograms/metadata/pdf/histograms.xml
index f21445a..4d73eb9 100644
--- a/tools/metrics/histograms/metadata/pdf/histograms.xml
+++ b/tools/metrics/histograms/metadata/pdf/histograms.xml
@@ -86,7 +86,7 @@
 </histogram>
 
 <histogram name="PDF.LoadStatus" enum="ChromePDFViewerLoadStatus"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kmoon@chromium.org</owner>
   <owner>thestig@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml
index b23cba5f..ef1839e 100644
--- a/tools/metrics/histograms/metadata/permissions/histograms.xml
+++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -443,7 +443,7 @@
 </histogram>
 
 <histogram name="Permissions.Engagement.Ignored" units="%"
-    expires_after="2022-10-30">
+    expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>
@@ -994,7 +994,7 @@
 </histogram>
 
 <histogram base="true" name="Permissions.Usage.ElapsedTimeSinceGrant"
-    units="seconds" expires_after="2022-12-25">
+    units="seconds" expires_after="2023-02-26">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml
index 89841bd4..ce3277e 100644
--- a/tools/metrics/histograms/metadata/platform/histograms.xml
+++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -1143,7 +1143,7 @@
 </histogram>
 
 <histogram name="Platform.SATA.PercentageUsed" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>gwendal@chromium.org</owner>
   <summary>
@@ -1183,7 +1183,7 @@
 </histogram>
 
 <histogram name="Platform.StatefulFormat" enum="StatefulFormat"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sarthakkukreti@chromium.org</owner>
   <owner>gwendal@chromium.org</owner>
   <summary>Chrome OS stateful partition format. Sampled once per boot.</summary>
@@ -1199,7 +1199,7 @@
 </histogram>
 
 <histogram name="Platform.StatefulLifetimeWrites" units="GiB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>gwendal@chromium.org</owner>
   <summary>
@@ -1249,7 +1249,7 @@
 </histogram>
 
 <histogram name="Platform.StatefulWritesDaily" units="KiB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>gwendal@chromium.org</owner>
   <summary>
@@ -1269,7 +1269,7 @@
 </histogram>
 
 <histogram name="Platform.Storage.Nvme.PercentageUsed" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>gwendal@chromium.org</owner>
   <summary>
@@ -1292,7 +1292,7 @@
   </summary>
 </histogram>
 
-<histogram name="Platform.SwapInDaily" units="pages" expires_after="2022-12-25">
+<histogram name="Platform.SwapInDaily" units="pages" expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>chromeos-storage@google.com</owner>
   <summary>Number of pages swapped IN over a day, sampled daily.</summary>
@@ -1317,7 +1317,7 @@
 </histogram>
 
 <histogram name="Platform.SwapOutDaily" units="pages"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asavery@chromium.org</owner>
   <owner>chromeos-storage@google.com</owner>
   <summary>Number of pages swapped OUT over a day, sampled daily.</summary>
@@ -1473,7 +1473,7 @@
 </histogram>
 
 <histogram name="Platform.TPM.VersionFingerprint" enum="TPMVersionFingerprint"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mnissler@chromium.org</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index 778b9466..13c17b4 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -713,7 +713,7 @@
 </histogram>
 
 <histogram name="Power.BatteryDischargeRate" units="mW"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>puthik@chromium.org</owner>
   <owner>chromeos-platform-power@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/print/histograms.xml b/tools/metrics/histograms/metadata/print/histograms.xml
index 2601691..28b7fe30 100644
--- a/tools/metrics/histograms/metadata/print/histograms.xml
+++ b/tools/metrics/histograms/metadata/print/histograms.xml
@@ -75,7 +75,7 @@
 </histogram>
 
 <histogram name="PrintPreview.PrintDocumentType"
-    enum="PrintPreviewPrintDocumentTypeBuckets" expires_after="2022-12-25">
+    enum="PrintPreviewPrintDocumentTypeBuckets" expires_after="2023-02-26">
   <owner>rbpotter@chromium.org</owner>
   <owner>awscreen@chromium.org</owner>
   <summary>
@@ -220,7 +220,7 @@
 </histogram>
 
 <histogram name="PrintPreview.UserAction" enum="PrintPreviewUserActionType"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>thestig@chromium.org</owner>
   <owner>awscreen@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml
index 3399352..acb3bc2a 100644
--- a/tools/metrics/histograms/metadata/printing/histograms.xml
+++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -118,7 +118,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.IppDeviceReachable" enum="BooleanSuccess"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>cros-printing-dev@chromium.org</owner>
   <summary>
@@ -194,7 +194,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.PrinterAdded" enum="PrinterProtocol"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>src/chromeos/printing/OWNERS</owner>
   <summary>
@@ -204,7 +204,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.PrinterRemoved" enum="PrinterProtocol"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>src/chromeos/printing/OWNERS</owner>
   <summary>
@@ -238,7 +238,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.PrinterSetupResult.PrintPreview"
-    enum="PrinterSetupResult" expires_after="2022-12-25">
+    enum="PrinterSetupResult" expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>cros-printing-dev@chromium.org</owner>
   <summary>
@@ -342,7 +342,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.ZeroconfPrinterSetupResult.PrintPreview"
-    enum="PrinterSetupResult" expires_after="2022-12-25">
+    enum="PrinterSetupResult" expires_after="2023-02-26">
   <owner>bmgordon@chromium.org</owner>
   <owner>cros-printing-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml
index 681222db..d86e6c6 100644
--- a/tools/metrics/histograms/metadata/privacy/histograms.xml
+++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -400,6 +400,18 @@
   </summary>
 </histogram>
 
+<histogram
+    name="PrivacySandbox.AggregationService.Storage.Sql.StoreRequestHasCapacity"
+    enum="Boolean" expires_after="2023-02-24">
+  <owner>alexmt@chromium.org</owner>
+  <owner>linnan@chromium.org</owner>
+  <summary>
+    Records whether there was sufficient capacity to store the request, i.e.
+    that the per-reporting origin limit had not been reached. Recorded for each
+    StoreRequest attempt.
+  </summary>
+</histogram>
+
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml
index 5e3a6a5e..bbc225c9 100644
--- a/tools/metrics/histograms/metadata/profile/histograms.xml
+++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -39,7 +39,7 @@
 </histogram>
 
 <histogram name="Profile.AllAccounts.Categories"
-    enum="ProfileAllAccountsCategories" expires_after="2022-12-25">
+    enum="ProfileAllAccountsCategories" expires_after="2023-02-26">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
@@ -98,7 +98,7 @@
 </histogram>
 
 <histogram name="Profile.BrowserActive.PerProfile" enum="Profile"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>msarda@chromium.org</owner>
   <owner>tangltom@chromium.org</owner>
   <summary>
@@ -211,7 +211,7 @@
 </histogram>
 
 <histogram name="Profile.Guest.OTR.Lifetime" units="minutes"
-    expires_after="2022-10-23">
+    expires_after="2023-02-26">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-incognito@google.com</owner>
   <summary>
@@ -387,7 +387,7 @@
 </histogram>
 
 <histogram name="Profile.NukeFromDisk.Result" enum="NukeProfileResult"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>nicolaso@chromium.org</owner>
   <owner>cbe-eng@google.com</owner>
   <summary>
@@ -562,7 +562,7 @@
 </histogram>
 
 <histogram base="true" name="Profile.State.UnconsentedPrimaryAccountType"
-    enum="ProfileUnconsentedPrimaryAccountType" expires_after="2022-12-25">
+    enum="ProfileUnconsentedPrimaryAccountType" expires_after="2023-02-26">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
@@ -671,7 +671,7 @@
 </histogram>
 
 <histogram name="Profile.ZombieProfileCount" units="profiles"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>nicolaso@chromium.org</owner>
   <owner>cbe-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/quick_answers/histograms.xml b/tools/metrics/histograms/metadata/quick_answers/histograms.xml
index 82b0751..0fef11f 100644
--- a/tools/metrics/histograms/metadata/quick_answers/histograms.xml
+++ b/tools/metrics/histograms/metadata/quick_answers/histograms.xml
@@ -64,7 +64,7 @@
 </histogram>
 
 <histogram name="QuickAnswers.Click" enum="QuickAnswersResultType"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>updowndota@chromium.org</owner>
   <owner>llin@google.com</owner>
   <owner>croissant-eng@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/quota/histograms.xml b/tools/metrics/histograms/metadata/quota/histograms.xml
index 33a325e7..397b5c4 100644
--- a/tools/metrics/histograms/metadata/quota/histograms.xml
+++ b/tools/metrics/histograms/metadata/quota/histograms.xml
@@ -43,7 +43,7 @@
 </histogram>
 
 <histogram name="Quota.AvailableDiskSpace" units="MB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ayui@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -62,7 +62,7 @@
   </summary>
 </histogram>
 
-<histogram name="Quota.DiskspaceShortage" units="MB" expires_after="2022-12-25">
+<histogram name="Quota.DiskspaceShortage" units="MB" expires_after="2023-02-26">
   <owner>ayui@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -165,7 +165,7 @@
 </histogram>
 
 <histogram name="Quota.PercentDiskAvailable2" units="%"
-    expires_after="2022-10-30">
+    expires_after="2023-02-26">
   <owner>ayui@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/renderer/histograms.xml b/tools/metrics/histograms/metadata/renderer/histograms.xml
index f8d2385..217f868 100644
--- a/tools/metrics/histograms/metadata/renderer/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer/histograms.xml
@@ -428,7 +428,7 @@
 </histogram>
 
 <histogram name="RendererScheduler.RendererMainThreadLoad5" units="%"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>altimin@chromium.org</owner>
   <summary>
     Renderer main thread load (percentage of time spent in tasks), reported in
diff --git a/tools/metrics/histograms/metadata/renderer4/histograms.xml b/tools/metrics/histograms/metadata/renderer4/histograms.xml
index c5476a6..a7b1b99 100644
--- a/tools/metrics/histograms/metadata/renderer4/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer4/histograms.xml
@@ -134,7 +134,7 @@
 </histogram>
 
 <histogram name="Renderer4.GpuRasterizationEnabled" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>jonross@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -292,7 +292,7 @@
 </histogram>
 
 <histogram name="Renderer4.ScrollingThread" enum="ScrollingThreadStatus"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="ScrollSourceDevice" -->
 
   <owner>bokan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index c397197..fd4b8a11 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1090,7 +1090,7 @@
 
 <histogram
     name="SafeBrowsing.EsbDisabled.TimesDisabledLast28Days.{EnabledDuration}"
-    units="times" expires_after="2022-10-11">
+    units="times" expires_after="2023-02-28">
   <owner>thefrog@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1105,7 +1105,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.ExtensionPersister.AgedFileFound"
-    enum="BooleanFound" expires_after="2022-12-25">
+    enum="BooleanFound" expires_after="2023-02-26">
   <owner>psarouthakis@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1136,7 +1136,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.ExtensionPersister.ReadResult"
-    enum="BooleanSuccess" expires_after="2022-12-25">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>psarouthakis@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1148,7 +1148,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.ExtensionPersister.WriteResult"
-    enum="BooleanSuccess" expires_after="2022-12-25">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>psarouthakis@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1485,7 +1485,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.Pref.Daily.Extended" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1724,7 +1724,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.HasTokenFromFetcher" enum="BooleanHasToken"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1912,7 +1912,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.Response.VerdictType"
-    enum="SafeBrowsingRTLookupResponseVerdictType" expires_after="2023-02-19">
+    enum="SafeBrowsingRTLookupResponseVerdictType" expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2214,7 +2214,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4GetHash.CacheHit.Result"
-    enum="SafeBrowsingV4FullHashCacheResult" expires_after="2022-12-25">
+    enum="SafeBrowsingV4FullHashCacheResult" expires_after="2023-02-26">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>Track cache hits for V4 full hashes.</summary>
@@ -2323,7 +2323,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4ProcessFullUpdate.AdditionsHashesCount2"
-    units="entries" expires_after="2022-12-25">
+    units="entries" expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2384,7 +2384,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4ProcessPartialUpdate.AdditionsHashesCount"
-    units="entries" expires_after="2022-12-25">
+    units="entries" expires_after="2023-02-26">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2394,7 +2394,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4ProcessPartialUpdate.ApplyUpdate.Result"
-    enum="SafeBrowsingV4ApplyUpdateResult" expires_after="2022-12-25">
+    enum="SafeBrowsingV4ApplyUpdateResult" expires_after="2023-02-26">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml
index c1ecd33..3d9f2650 100644
--- a/tools/metrics/histograms/metadata/sb_client/histograms.xml
+++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -183,7 +183,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.DownloadRequestDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <owner>mattm@chromium.org</owner>
@@ -329,7 +329,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.FileFeatureExtractionDuration" units="ms"
-    expires_after="2022-12-15">
+    expires_after="2023-02-26">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -339,7 +339,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.GetTabRedirectsDuration" units="ms"
-    expires_after="2022-12-15">
+    expires_after="2023-02-26">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -371,7 +371,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.MemoryMapFileDuration" units="ms"
-    expires_after="2022-12-15">
+    expires_after="2023-02-26">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/scanning/histograms.xml b/tools/metrics/histograms/metadata/scanning/histograms.xml
index 5a60ee44..d5f9840 100644
--- a/tools/metrics/histograms/metadata/scanning/histograms.xml
+++ b/tools/metrics/histograms/metadata/scanning/histograms.xml
@@ -105,7 +105,7 @@
 </histogram>
 
 <histogram name="Scanning.NumDetectedScanners" units="scanners"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/scheduler/histograms.xml b/tools/metrics/histograms/metadata/scheduler/histograms.xml
index 4da5971..0f8fa795 100644
--- a/tools/metrics/histograms/metadata/scheduler/histograms.xml
+++ b/tools/metrics/histograms/metadata/scheduler/histograms.xml
@@ -199,7 +199,7 @@
 </histogram>
 
 <histogram name="Scheduling.Renderer.DeadlineMode"
-    enum="RendererSchedulerDeadlineMode" expires_after="2022-12-25">
+    enum="RendererSchedulerDeadlineMode" expires_after="2023-02-26">
   <owner>weiliangc@chromium.org</owner>
   <owner>chrome-gpu-metrics@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index 215216f..5649b22 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -63,7 +63,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.ActivateEvent.Time" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wanderview@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
@@ -1001,7 +1001,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Status"
-    enum="ServiceWorkerStatusCode" expires_after="2022-12-25">
+    enum="ServiceWorkerStatusCode" expires_after="2023-02-26">
   <owner>wanderview@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
@@ -1027,7 +1027,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Time" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wanderview@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
@@ -1041,7 +1041,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Timeout.StartPurpose"
-    enum="ServiceWorkerMetrics.EventType" expires_after="2022-12-25">
+    enum="ServiceWorkerMetrics.EventType" expires_after="2023-02-26">
   <owner>wanderview@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
@@ -1054,7 +1054,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.TimeoutPhase"
-    enum="EmbeddedWorkerStartingPhase" expires_after="2022-12-25">
+    enum="EmbeddedWorkerStartingPhase" expires_after="2023-02-26">
   <owner>wanderview@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/session/histograms.xml b/tools/metrics/histograms/metadata/session/histograms.xml
index 9daf2639..0c4d0c9a 100644
--- a/tools/metrics/histograms/metadata/session/histograms.xml
+++ b/tools/metrics/histograms/metadata/session/histograms.xml
@@ -49,7 +49,7 @@
 </histogram>
 
 <histogram name="Session.IsActive" enum="BooleanActive"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>rogerm@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -80,7 +80,7 @@
 </histogram>
 
 <histogram name="Session.OpenedTabCounts" units="operations"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>rohitrao@chromium.org</owner>
   <owner>marq@chromium.org</owner>
   <summary>
@@ -806,7 +806,7 @@
 </histogram>
 
 <histogram name="Session.WebState.CustomWebViewSerializedSize" units="KB"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -828,7 +828,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.ArchivedDataWithRootObjectTime" units="ms"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -851,7 +851,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.NativeRestoreSessionFromCache"
-    enum="BooleanSuccess" expires_after="2022-12-18">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -873,7 +873,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.ReadFromFileTime" units="ms"
-    expires_after="2022-09-15">
+    expires_after="2023-09-15">
   <owner>justincohen@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
@@ -894,7 +894,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.SerializedSize" units="KB"
-    expires_after="2022-11-20">
+    expires_after="2023-02-26">
   <owner>justincohen@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
@@ -905,7 +905,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.WriteToFileTime" units="ms"
-    expires_after="2022-09-15">
+    expires_after="2023-09-15">
   <owner>justincohen@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml
index 15bed53..ee732c1d 100644
--- a/tools/metrics/histograms/metadata/settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -51,7 +51,7 @@
 </histogram>
 
 <histogram name="Settings.ClearBrowsingData.OpenMyActivity"
-    enum="ClearBrowsingDataMyActivityNavigation" expires_after="2022-12-25">
+    enum="ClearBrowsingDataMyActivityNavigation" expires_after="2023-02-26">
   <owner>andzaytsev@google.com</owner>
   <owner>chrome-friendly-settings@google.com</owner>
   <summary>
@@ -89,7 +89,7 @@
 </histogram>
 
 <histogram name="Settings.GivenShowHomeButton_HomePageIsNewTabPage"
-    enum="Boolean" expires_after="2022-12-25">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -182,7 +182,7 @@
 </histogram>
 
 <histogram name="Settings.PreloadStatus.OnStartup" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>harrisonsean@chromium.org</owner>
   <owner>chrome-friendly-settings@google.com</owner>
   <summary>
@@ -424,7 +424,7 @@
 </histogram>
 
 <histogram name="Settings.ShowHomeButton" enum="BooleanEnabled"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mpearson@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -485,7 +485,7 @@
 </histogram>
 
 <histogram name="Settings.TrackedPreferenceChanged" enum="TrackedPreference"
-    expires_after="2022-12-22">
+    expires_after="2023-02-26">
   <owner>proberge@chromium.org</owner>
   <owner>junhao.huang@microsoft.com</owner>
   <summary>
@@ -544,7 +544,7 @@
 </histogram>
 
 <histogram name="Settings.TrackedPreferenceReset" enum="TrackedPreference"
-    expires_after="2022-12-22">
+    expires_after="2023-02-26">
   <owner>proberge@chromium.org</owner>
   <owner>junhao.huang@microsoft.com</owner>
   <summary>The id of a tracked preference which was reset by Chrome.</summary>
@@ -584,7 +584,7 @@
 </histogram>
 
 <histogram name="Settings.TrackedPreferenceWantedReset"
-    enum="TrackedPreference" expires_after="2022-12-22">
+    enum="TrackedPreference" expires_after="2023-02-26">
   <owner>proberge@chromium.org</owner>
   <owner>junhao.huang@microsoft.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml
index 4b2bf42d..9ad4142b 100644
--- a/tools/metrics/histograms/metadata/sharing/histograms.xml
+++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="Sharing.DefaultSharesheetAndroid.Opened" enum="ShareOrigin"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sophey@chromium.org</owner>
   <owner>src/chrome/browser/share/OWNERS</owner>
   <summary>
@@ -369,7 +369,7 @@
 
 <histogram name="Sharing.ScrollCapture.BitmapGeneratorStatus"
     enum="SharingScrollCaptureBitmapGenerationStatus"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckitagawa@chromium.org</owner>
   <owner>src/components/paint_preview/OWNERS</owner>
   <summary>
@@ -381,7 +381,7 @@
 </histogram>
 
 <histogram name="Sharing.ScrollCapture.SuccessfulCaptureDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>ckitagawa@chromium.org</owner>
   <owner>src/components/paint_preview/OWNERS</owner>
   <summary>
@@ -419,7 +419,7 @@
 </histogram>
 
 <histogram name="Sharing.SendTabToSelf.NotificationStatus"
-    enum="SendTabToSelfNotificationStatus" expires_after="2022-12-25">
+    enum="SendTabToSelfNotificationStatus" expires_after="2023-02-26">
   <owner>ellyjones@chromium.org</owner>
   <owner>src/chrome/browser/share/OWNERS</owner>
   <summary>
@@ -511,7 +511,7 @@
 </histogram>
 
 <histogram name="Sharing.SharingHubAndroid.Opened" enum="ShareOrigin"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sophey@chromium.org</owner>
   <owner>src/chrome/browser/share/OWNERS</owner>
   <summary>
@@ -543,7 +543,7 @@
 </histogram>
 
 <histogram name="Sharing.SharingHubAndroid.TimeToShare" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sophey@chromium.org</owner>
   <owner>src/chrome/browser/share/OWNERS</owner>
   <summary>
@@ -633,7 +633,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherAvailableDeviceCount" units="devices"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
@@ -655,7 +655,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherScreenOnAndUnlocked" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
@@ -666,7 +666,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherTapWithChromeDestroyed" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index 3682fdc..4afa51e5 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -105,7 +105,7 @@
 </histogram>
 
 <histogram name="Signin.AccountFetcher.AccountAvatarFetchTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>triploblastic@chromium.org</owner>
   <owner>aliceywang@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -256,7 +256,7 @@
 </histogram>
 
 <histogram name="Signin.AuthError" enum="GoogleServiceAuthError"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>msarda@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
@@ -546,7 +546,7 @@
 </histogram>
 
 <histogram name="Signin.IOSDeviceRestoreSentinelError"
-    enum="SigninIOSDeviceRestoreSentinelError" expires_after="2022-12-18">
+    enum="SigninIOSDeviceRestoreSentinelError" expires_after="2023-02-26">
   <owner>jlebel@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>
@@ -556,7 +556,7 @@
 </histogram>
 
 <histogram name="Signin.IOSDeviceRestoreSentinelPathGenerated"
-    enum="BooleanSuccess" expires_after="2022-12-18">
+    enum="BooleanSuccess" expires_after="2023-02-26">
   <owner>jlebel@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>
@@ -609,7 +609,7 @@
 </histogram>
 
 <histogram name="Signin.IOSNumberOfDeviceAccounts" units="accounts"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>jlebel@chromium.org</owner>
   <owner>msarda@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -662,7 +662,7 @@
 </histogram>
 
 <histogram name="Signin.LoadedIdentities.Count" units="identities"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>jlebel@chromium.org</owner>
   <owner>msarda@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -1215,7 +1215,7 @@
 </histogram>
 
 <histogram name="Signin.TransactionalReauthUserAction"
-    enum="SigninReauthUserAction" expires_after="2022-12-25">
+    enum="SigninReauthUserAction" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes
 name="TransactionalReauthEntryPoint" -->
 
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml
index 0e56b55..51e6c35 100644
--- a/tools/metrics/histograms/metadata/stability/histograms.xml
+++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -364,7 +364,7 @@
 </histogram>
 
 <histogram name="Stability.Internals.SystemCrashCount" units="crashes"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>davidbienvenu@chromium.org</owner>
   <owner>jessemckenna@google.com</owner>
   <summary>
@@ -471,7 +471,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.HasPossibleExplanation"
-    enum="BooleanHasPossibleExplanation" expires_after="2022-10-16">
+    enum="BooleanHasPossibleExplanation" expires_after="2023-02-26">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -552,7 +552,7 @@
 </histogram>
 
 <histogram name="Stability.MobileSessionShutdownType"
-    enum="MobileSessionShutdownType" expires_after="2022-12-18">
+    enum="MobileSessionShutdownType" expires_after="2023-02-26">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 4ffc84ac..96f5ff08 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -217,7 +217,7 @@
 </histogram>
 
 <histogram base="true" name="Startup.Android.FeedContentFirstLoadedTime"
-    units="ms" expires_after="2022-12-25">
+    units="ms" expires_after="2023-02-26">
 <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
 
   <owner>hanxi@chromium.org</owner>
@@ -319,7 +319,7 @@
 
 <histogram name="Startup.Android.ShowChromeStartSegmentationResultComparison"
     enum="ShowChromeStartSegmentationResultComparison"
-    expires_after="2022-12-11">
+    expires_after="2023-02-26">
   <owner>hanxi@chromium.org</owner>
   <owner>ssid@chromium.org</owner>
   <summary>
@@ -626,7 +626,7 @@
 </histogram>
 
 <histogram name="Startup.ConsecutiveLoadsWithoutLaunch" units="count"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -799,7 +799,7 @@
 </histogram>
 
 <histogram name="Startup.MobileSessionStartFromApps"
-    enum="MobileSessionCallerApp" expires_after="2022-10-16">
+    enum="MobileSessionCallerApp" expires_after="2023-02-26">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>The calling application (if any).</summary>
@@ -924,7 +924,7 @@
 </histogram>
 
 <histogram name="Startup.TimeFromProcessCreationToDidFinishLaunchingCall"
-    units="ms" expires_after="2022-12-04">
+    units="ms" expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -935,7 +935,7 @@
 </histogram>
 
 <histogram name="Startup.TimeFromProcessCreationToLoad" units="ms"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -945,7 +945,7 @@
 </histogram>
 
 <histogram name="Startup.TimeFromProcessCreationToMainCall" units="ms"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -955,7 +955,7 @@
 </histogram>
 
 <histogram name="Startup.TimeFromProcessCreationToSceneConnection" units="ms"
-    expires_after="2022-12-04">
+    expires_after="2023-02-26">
   <owner>olivierrobin@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml
index 8a4afdb..117a0d8 100644
--- a/tools/metrics/histograms/metadata/storage/histograms.xml
+++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -450,7 +450,7 @@
 </histogram>
 
 <histogram name="Storage.InterestGroup.DBMaintenanceTime" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <summary>
@@ -463,7 +463,7 @@
 </histogram>
 
 <histogram name="Storage.InterestGroup.DBSize" units="KB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <summary>
@@ -473,7 +473,7 @@
 </histogram>
 
 <histogram name="Storage.InterestGroup.PerSiteCount" units="groups"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <summary>
@@ -987,6 +987,20 @@
   </summary>
 </histogram>
 
+<histogram name="Storage.SharedStorage.Worklet.Timing.UsefulResourceDuration"
+    units="%" expires_after="2023-07-31">
+  <owner>cammie@chromium.org</owner>
+  <owner>yaoxia@chromium.org</owner>
+  <owner>chrome-ads-histograms@google.com</owner>
+  <summary>
+    Measures the percentage of the time duration between a
+    `SharedStorageWorkletHost`'s creation and destruction that occurs before the
+    time of its last finished operation. For worklets that are destroyed before
+    completing their outstanding operations, we record 100. Recorded in the
+    destructor of `SharedStorageWorkletHost`.
+  </summary>
+</histogram>
+
 <histogram name="Storage.StoragePressure.Bubble"
     enum="StoragePressureBubbleUserAction" expires_after="2023-03-09">
   <owner>ayui@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/subresource/histograms.xml b/tools/metrics/histograms/metadata/subresource/histograms.xml
index 775778b6..8ded35bc 100644
--- a/tools/metrics/histograms/metadata/subresource/histograms.xml
+++ b/tools/metrics/histograms/metadata/subresource/histograms.xml
@@ -579,7 +579,7 @@
 </histogram>
 
 <histogram name="SubresourceFilter.SafeBrowsing.TotalCheckTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>alexmt@chromium.org</owner>
   <owner>chrome-ads-histograms@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml
index 705a88c..cef9824 100644
--- a/tools/metrics/histograms/metadata/sync/histograms.xml
+++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -904,7 +904,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessage"
-    enum="SyncClientToServerMessageContents" expires_after="2022-12-25">
+    enum="SyncClientToServerMessageContents" expires_after="2023-02-26">
   <owner>mastiz@chromium.org</owner>
   <component>Services&gt;Sync</component>
   <summary>
@@ -914,7 +914,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessageError2" enum="SyncErrorType"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>mastiz@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <component>Services&gt;Sync</component>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index ea94082..495bdaa 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -339,7 +339,7 @@
   </token>
 </histogram>
 
-<histogram name="Tab.Count.Guest" units="units" expires_after="2022-12-25">
+<histogram name="Tab.Count.Guest" units="units" expires_after="2023-02-26">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-incognito@google.com</owner>
   <summary>
@@ -421,7 +421,8 @@
   </summary>
 </histogram>
 
-<histogram name="Tab.PerceivedRestoreTime" units="ms" expires_after="M108">
+<histogram name="Tab.PerceivedRestoreTime" units="ms"
+    expires_after="2023-02-26">
   <owner>ckitagawa@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
@@ -530,7 +531,7 @@
 </histogram>
 
 <histogram name="Tab.RendererTermination.AliveRenderersCount" units="renderers"
-    expires_after="2022-11-06">
+    expires_after="2023-02-26">
   <owner>ajuma@chromium.org</owner>
   <owner>bling-fundamentals@google.com</owner>
   <summary>
@@ -558,7 +559,7 @@
 </histogram>
 
 <histogram name="Tab.RendererTermination.TotalTabCount" units="tabs"
-    expires_after="2022-11-06">
+    expires_after="2023-02-26">
   <owner>ajuma@chromium.org</owner>
   <owner>thegreenfrog@chromium.org</owner>
   <summary>
@@ -615,7 +616,7 @@
 </histogram>
 
 <histogram name="Tab.StateAtRendererTermination" enum="TabForegroundState"
-    expires_after="2022-10-16">
+    expires_after="2023-02-26">
   <owner>gambard@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -624,7 +625,7 @@
 </histogram>
 
 <histogram name="Tab.StatusWhenSwitchedBackToForeground" enum="TabStatus"
-    expires_after="M108">
+    expires_after="2023-02-26">
   <owner>ckitagawa@chromium.org</owner>
   <owner>marq@chromium.org</owner>
   <summary>
@@ -782,7 +783,7 @@
 </histogram>
 
 <histogram name="TabGroups.UserCustomizedGroupCountPerLoad" units="groups"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>connily@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -1083,7 +1084,7 @@
 </histogram>
 
 <histogram name="TabManager.Discarding.DiscardCount" units="Discards"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>chrisha@chromium.org</owner>
   <owner>catan-team@chromium.org</owner>
   <summary>
@@ -1142,7 +1143,7 @@
 </histogram>
 
 <histogram name="TabManager.Discarding.ReloadCount" units="Reloads"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>chrisha@chromium.org</owner>
   <owner>catan-team@chromium.org</owner>
   <summary>
@@ -1619,7 +1620,7 @@
 </histogram>
 
 <histogram name="Tabs.LiveNTPCountAtResume" units="tabs"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>bling-team@google.com</owner>
   <summary>
@@ -1684,7 +1685,7 @@
   <token key="BatteryState" variants="BatteryState"/>
 </histogram>
 
-<histogram name="Tabs.NTPCountAtResume" units="tabs" expires_after="2022-12-18">
+<histogram name="Tabs.NTPCountAtResume" units="tabs" expires_after="2023-02-26">
   <owner>gogerald@chromium.org</owner>
   <owner>nasims@google.com</owner>
   <summary>
@@ -1693,7 +1694,7 @@
 </histogram>
 
 <histogram name="Tabs.NTPCountAtStartup" units="tabs"
-    expires_after="2022-12-18">
+    expires_after="2023-02-26">
   <owner>gogerald@chromium.org</owner>
   <owner>nasims@google.com</owner>
   <summary>[iOS] The number of NTP tabs open at cold launch.</summary>
@@ -1955,7 +1956,7 @@
 </histogram>
 
 <histogram name="Tabs.SadTab.Reload.Event" enum="SadTabEvent"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>sonnyrao@chromium.org</owner>
   <owner>jamescook@chromium.org</owner>
   <summary>
@@ -2023,7 +2024,7 @@
   </summary>
 </histogram>
 
-<histogram name="Tabs.ScrubDistance" units="tabs" expires_after="2022-12-25">
+<histogram name="Tabs.ScrubDistance" units="tabs" expires_after="2023-02-26">
   <owner>afakhry@chromium.org</owner>
   <owner>tclaiborne@chromium.org</owner>
   <summary>
@@ -2341,7 +2342,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.CloseAction" enum="TabSearchCloseActions"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2357,7 +2358,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.Mojo.SwitchToTab" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>romanarora@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2370,7 +2371,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.Mojo.SwitchToTab.IsOverlap" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>romanarora@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2383,7 +2384,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.Mojo.TabUpdated" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>romanarora@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2397,7 +2398,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.Mojo.TabUpdated.IsOverlap" enum="Boolean"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>romanarora@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2410,7 +2411,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.NumTabsClosedPerInstance" units="tabs"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2423,7 +2424,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.NumTabsOnOpen" units="tabs"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2461,7 +2462,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.PageHandlerConstructionDelay" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2480,7 +2481,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.RecentlyClosedSectionToggleAction"
-    enum="TabSearchRecentlyClosedToggleActions" expires_after="2022-12-25">
+    enum="TabSearchRecentlyClosedToggleActions" expires_after="2023-02-26">
   <owner>romanarora@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
@@ -2538,7 +2539,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.LoadCompletedTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2549,7 +2550,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.LoadDocumentTime" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2575,7 +2576,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.SearchAlgorithmDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>yuhengh@chromium.org</owner>
   <owner>chrome-cros@chromium.org</owner>
   <summary>
@@ -2586,7 +2587,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.TabListDataReceived" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2599,7 +2600,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.TabListDataReceived2" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
@@ -2616,7 +2617,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WebUI.TabListDataReceived2.IsOverlap"
-    enum="Boolean" expires_after="2022-12-25">
+    enum="Boolean" expires_after="2023-02-26">
   <owner>kerenzhu@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
@@ -2660,7 +2661,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WindowDisplayedDuration3" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
@@ -2683,7 +2684,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WindowTimeToShowCachedWebView" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2702,7 +2703,7 @@
 </histogram>
 
 <histogram name="Tabs.TabSearch.WindowTimeToShowUncachedWebView" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
@@ -2977,7 +2978,7 @@
   <token key="BatteryState" variants="BatteryState"/>
 </histogram>
 
-<histogram name="Tabs.WindowWidth" units="DIPs" expires_after="2022-12-25">
+<histogram name="Tabs.WindowWidth" units="DIPs" expires_after="2023-02-26">
   <owner>collinbaker@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/translate/histograms.xml b/tools/metrics/histograms/metadata/translate/histograms.xml
index ebb859a..9dc9f4e 100644
--- a/tools/metrics/histograms/metadata/translate/histograms.xml
+++ b/tools/metrics/histograms/metadata/translate/histograms.xml
@@ -59,7 +59,7 @@
 </histogram>
 
 <histogram name="Translate.ApplicationStart.NeverTranslateLanguage"
-    enum="LocaleCodeISO639" expires_after="2022-12-25">
+    enum="LocaleCodeISO639" expires_after="2023-02-26">
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -332,7 +332,7 @@
 </histogram>
 
 <histogram name="Translate.LanguageDetection.TFLiteModelEvaluationDuration"
-    units="ms" expires_after="2022-11-13">
+    units="ms" expires_after="2023-02-26">
   <owner>rajendrant@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
@@ -380,7 +380,7 @@
 </histogram>
 
 <histogram name="Translate.MenuTranslation.UnavailableReasons"
-    enum="MenuTranslationUnavailableReason" expires_after="2022-12-25">
+    enum="MenuTranslationUnavailableReason" expires_after="2023-02-26">
   <owner>cuianthony@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index d0e59b9..a08499fe 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -343,7 +343,7 @@
 </histogram>
 
 <histogram name="UMA.JavaCachingRecorder.DroppedHistogramSampleCount"
-    units="samples" expires_after="2022-12-25">
+    units="samples" expires_after="2023-02-26">
   <owner>bttk@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -354,7 +354,7 @@
 </histogram>
 
 <histogram name="UMA.JavaCachingRecorder.DroppedUserActionCount"
-    units="samples" expires_after="2022-12-25">
+    units="samples" expires_after="2023-02-26">
   <owner>bttk@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -511,7 +511,7 @@
 </histogram>
 
 <histogram name="UMA.MetricsReporting.Toggle" enum="MetricsReportingChange"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -859,7 +859,7 @@
 </histogram>
 
 <histogram name="UMA.TruncatedEvents.UserAction" units="events"
-    expires_after="2023-02-19">
+    expires_after="2023-02-26">
   <owner>rkaplow@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml
index eeff3f0..22afedd 100644
--- a/tools/metrics/histograms/metadata/v8/histograms.xml
+++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -151,7 +151,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -183,7 +183,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds.ConsumeCache"
-    units="microseconds" expires_after="2022-12-25">
+    units="microseconds" expires_after="2023-02-26">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_apk/histograms.xml b/tools/metrics/histograms/metadata/web_apk/histograms.xml
index 0996a7f7..4a7a0e0a 100644
--- a/tools/metrics/histograms/metadata/web_apk/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_apk/histograms.xml
@@ -64,7 +64,7 @@
 </histogram>
 
 <histogram name="WebApk.Install.GooglePlayErrorCode"
-    enum="WebApkInstallGooglePlayErrorCode" expires_after="2022-12-25">
+    enum="WebApkInstallGooglePlayErrorCode" expires_after="2023-02-26">
   <owner>hartmanng@chromium.org</owner>
   <owner>
     src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
@@ -88,7 +88,7 @@
 </histogram>
 
 <histogram name="WebApk.Install.InstallDuration" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>hartmanng@chromium.org</owner>
   <owner>
     src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
diff --git a/tools/metrics/histograms/metadata/web_audio/histograms.xml b/tools/metrics/histograms/metadata/web_audio/histograms.xml
index 9cb0da8a..1aa691f 100644
--- a/tools/metrics/histograms/metadata/web_audio/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_audio/histograms.xml
@@ -79,7 +79,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContext.HardwareSampleRate" units="Hz"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <summary>
@@ -113,7 +113,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContext.MaxChannelsAvailable" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
@@ -137,7 +137,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContextOptions.sampleRateRatio" units="units"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/web_core/histograms.xml b/tools/metrics/histograms/metadata/web_core/histograms.xml
index 73609f74..1f7dc14 100644
--- a/tools/metrics/histograms/metadata/web_core/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_core/histograms.xml
@@ -31,7 +31,7 @@
 </variants>
 
 <histogram name="WebCore.DistillabilityUs" units="microseconds"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>wychen@chromium.org</owner>
   <owner>gilmanmh@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index 5e09c04..9a271574 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -180,7 +180,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc.DigitalGainApplied" units="dB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>alessiob@chromium.org</owner>
   <summary>
     Logs adaptive digital compression gain that is applied by AgcManagerDirect.
@@ -212,7 +212,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc2.DigitalGainApplied" units="dB"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>alessiob@chromium.org</owner>
   <summary>
     Logs adaptive digital compression gain that is applied by
@@ -381,7 +381,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.ApmCaptureInputLevelPeakRms"
-    units="dBFS (negated)" expires_after="2022-12-25">
+    units="dBFS (negated)" expires_after="2023-02-26">
   <owner>hlundin@chromium.org</owner>
   <summary>
     This histogram reports the peak RMS of the signal coming in to WebRTC's
@@ -875,7 +875,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.TargetJitterBufferDelayMs" units="ms"
-    expires_after="2022-12-26">
+    expires_after="2023-02-26">
   <owner>hlundin@chromium.org</owner>
   <summary>
     The target jitter buffer delay for the receiving side. Sampled once every 10
@@ -951,7 +951,7 @@
 </histogram>
 
 <histogram name="WebRTC.BWE.InitialVsConvergedDiff" units="kbps"
-    expires_after="2022-12-27">
+    expires_after="2023-02-26">
   <owner>holmer@chromium.org</owner>
   <summary>
     The difference between the bandwidth estimate at 2 seconds and 20 seconds
@@ -1039,7 +1039,7 @@
 </histogram>
 
 <histogram name="WebRTC.BWE.RampUpTimeTo1000kbpsInMs" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>holmer@chromium.org</owner>
   <summary>
     The time it takes the estimated bandwidth to reach 1000 kbps from the first
@@ -1057,7 +1057,7 @@
 </histogram>
 
 <histogram name="WebRTC.BWE.RampUpTimeTo500kbpsInMs" units="ms"
-    expires_after="2022-12-27">
+    expires_after="2023-02-26">
   <owner>holmer@chromium.org</owner>
   <summary>
     The time it takes the estimated bandwidth to reach 500 kbps from the first
@@ -1146,7 +1146,7 @@
 </histogram>
 
 <histogram name="WebRTC.Call.TimeReceivingVideoRtpPacketsInSeconds" units="s"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>saza@chromium.org</owner>
   <summary>
     The amount of time between the arrival of the first and last video RTP
@@ -1422,7 +1422,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.Duration.Network" units="microseconds"
-    expires_after="2022-11-27">
+    expires_after="2023-02-26">
   <owner>handellm@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1454,7 +1454,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.Duration.Worker" units="microseconds"
-    expires_after="2022-11-27">
+    expires_after="2023-02-26">
   <owner>handellm@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1784,16 +1784,6 @@
   </summary>
 </histogram>
 
-<histogram name="WebRTC.PeerConnection.SdpSemanticRequested"
-    enum="PeerConnectionSdpSemanticRequested" expires_after="2022-09-11">
-  <owner>hta@chromium.org</owner>
-  <owner>webrtc-dev@chromium.org</owner>
-  <summary>
-    What SDP semantic (Unified Plan, Plan B or &quot;use default&quot;) has been
-    asked for by the creator of a PeerConnection.
-  </summary>
-</histogram>
-
 <histogram name="WebRTC.PeerConnection.Simulcast.ApplyLocalDescription"
     enum="SimulcastApiVersion" expires_after="2020-08-23">
   <owner>amithi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index 674d8222e..cb2f7fb9 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -147,7 +147,7 @@
 </histogram>
 
 <histogram name="Launch.WebAppDisplayMode" enum="WebAppDisplayMode"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>peter@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -252,7 +252,7 @@
 </histogram>
 
 <histogram name="Webapp.CheckServiceWorker.Time" units="ms"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -646,7 +646,7 @@
 </histogram>
 
 <histogram name="WebApp.Preinstalled.AppToReplaceStillInstalledCount"
-    units="apps" expires_after="2022-12-25">
+    units="apps" expires_after="2023-02-26">
   <owner>alancutter@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -663,7 +663,7 @@
 </histogram>
 
 <histogram name="WebApp.Preinstalled.AppToReplaceStillInstalledInShelfCount"
-    units="apps" expires_after="2022-12-25">
+    units="apps" expires_after="2023-02-26">
   <owner>alancutter@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -690,7 +690,7 @@
 </histogram>
 
 <histogram name="WebApp.Preinstalled.DisabledCount" units="apps"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>alancutter@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -765,7 +765,7 @@
 </histogram>
 
 <histogram name="WebApp.Preinstalled.UninstallAndReplaceCount" units="apps"
-    expires_after="2022-12-25">
+    expires_after="2023-02-26">
   <owner>alancutter@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 996eaa0..789990e 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -12912,7 +12912,7 @@
   </metric>
 </event>
 
-<event name="NavigationThrottleDeferredTime" singular="False">
+<event name="NavigationThrottleDeferredTime">
   <owner>ryansturm@chromium.org</owner>
   <owner>chrome-brapp-loading@google.com</owner>
   <summary>
@@ -15213,6 +15213,31 @@
       removed from the page. See http://bit.ly/fcp_plus_plus for more details.
     </summary>
   </metric>
+  <metric name="PaintTiming.NavigationToLargestContentfulPaint2AtFirstOnHidden">
+    <summary>
+      Measures the time in milliseconds from navigation timing's navigation
+      start to the time when the page first paints the largest content (text or
+      image) within viewport, across all frames. Recorded at the point when a
+      page which has been opened in the foreground is moved to the background
+      for the first time. See http://bit.ly/fcp_plus_plus for more details. Log
+      of major changes: http://bit.ly/chrome-speed-metrics-changelog. This
+      metric is trying to record the LCP values which are not able to be
+      recorded in PaintTiming.NavigationToLargestContentfulPaint2 for some
+      reasons.
+    </summary>
+    <aggregation>
+      <history>
+        <index fields="profile.country"/>
+        <index fields="profile.country,profile.system_ram"/>
+        <index fields="profile.is_dominant_version"/>
+        <index fields="profile.is_latest_version"/>
+        <index fields="profile.system_ram"/>
+        <statistics>
+          <quantiles type="std-percentiles"/>
+        </statistics>
+      </history>
+    </aggregation>
+  </metric>
   <metric name="ParseTiming.NavigationToParseStart">
     <summary>
       Measures the time in milliseconds from navigation timing's navigation
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 6c112fb..17cb2dc 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -37,6 +37,11 @@
 crbug.com/859979 [ android-webview ] blink_perf.paint/paint-offset-changes.html [ Skip ]
 crbug.com/901493 [ android-nexus-6 android-webview ] blink_perf.paint/* [ Skip ]
 crbug.com/1000460 [ android-pixel-2 ] blink_perf.paint/color-changes.html [ Skip ]
+crbug.com/1354792 blink_perf.paint/custom-highlights-baseline.html [ Skip ]
+crbug.com/1354792 blink_perf.paint/custom-highlights.html [ Skip ]
+crbug.com/1354792 blink_perf.paint/wavy-decorations-long.html [ Skip ]
+crbug.com/1354792 blink_perf.paint/wavy-decorations-many.html [ Skip ]
+crbug.com/1354792 blink_perf.paint/custom-highlights-heavy.html [ Skip ]
 
 # Benchmark: blink_perf.parser
 crbug.com/966613 [ android-pixel-2 ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ]
diff --git a/tools/perf/page_sets/rendering/top_real_world_mobile.py b/tools/perf/page_sets/rendering/top_real_world_mobile.py
index d36d0ad..ecdf53f 100644
--- a/tools/perf/page_sets/rendering/top_real_world_mobile.py
+++ b/tools/perf/page_sets/rendering/top_real_world_mobile.py
@@ -401,6 +401,13 @@
   YEAR = '2018'
   URL = 'http://gsp.ro'
 
+  def RunNavigateSteps(self, action_runner):
+    super(GSPMobile2018Page, self).RunNavigateSteps(action_runner)
+
+    # Close a pop-up dialog that occludes a large area of the page.
+    action_runner.WaitForElement(selector='.close-btn')
+    action_runner.TapElement(selector='.close-btn')
+
 
 class TheVergeMobile2018Page(TopRealWorldMobilePage):
   """Why: Top tech blog"""
diff --git a/tools/typescript/ts_definitions.gni b/tools/typescript/ts_definitions.gni
index eb9f6a87..a165206d 100644
--- a/tools/typescript/ts_definitions.gni
+++ b/tools/typescript/ts_definitions.gni
@@ -11,6 +11,7 @@
 
     forward_variables_from(invoker,
                            [
+                             "deps",
                              "extra_deps",
                              "js_files",
                            ])
@@ -45,6 +46,16 @@
              "--js_files",
            ] + js_files
 
+    if (defined(deps)) {
+      args += [ "--deps" ]
+
+      foreach(dep, deps) {
+        name = get_label_info(dep, "name")
+        args += [ rebase_path(get_label_info(dep, "dir"), ".") +
+                  "/tsconfig_$name.json" ]
+      }
+    }
+
     if (defined(extra_deps)) {
       if (!defined(deps)) {
         deps = []
diff --git a/tools/typescript/ts_definitions.py b/tools/typescript/ts_definitions.py
index eb104f3..3931a37 100644
--- a/tools/typescript/ts_definitions.py
+++ b/tools/typescript/ts_definitions.py
@@ -33,6 +33,7 @@
 
 def main(argv):
   parser = argparse.ArgumentParser()
+  parser.add_argument('--deps', nargs='*')
   parser.add_argument('--gen_dir', required=True)
   parser.add_argument('--out_dir', required=True)
   parser.add_argument('--root_dir', required=True)
@@ -62,6 +63,9 @@
       path_mappings[mapping[0]].append(os.path.join('./', mapping[1]))
     tsconfig['compilerOptions']['paths'] = path_mappings
 
+  if args.deps is not None:
+    tsconfig['references'] = [{'path': dep} for dep in args.deps]
+
   _write_tsconfig_json(args.gen_dir, tsconfig)
 
   if (args.root_dir == args.out_dir):
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc
index aee128d71..b4ccebab 100644
--- a/ui/accessibility/ax_enum_util.cc
+++ b/ui/accessibility/ax_enum_util.cc
@@ -790,6 +790,8 @@
       return "description";
     case ax::mojom::StringAttribute::kDisplay:
       return "display";
+    case ax::mojom::StringAttribute::kDoDefaultLabel:
+      return "doDefaultLabel";
     case ax::mojom::StringAttribute::kFontFamily:
       return "fontFamily";
     case ax::mojom::StringAttribute::kHtmlTag:
@@ -820,6 +822,8 @@
       return "role";
     case ax::mojom::StringAttribute::kRoleDescription:
       return "roleDescription";
+    case ax::mojom::StringAttribute::kLongClickLabel:
+      return "longClickLabel";
     case ax::mojom::StringAttribute::kTooltip:
       return "tooltip";
     case ax::mojom::StringAttribute::kUrl:
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom
index 34fcbe2..52772ff7 100644
--- a/ui/accessibility/ax_enums.mojom
+++ b/ui/accessibility/ax_enums.mojom
@@ -542,7 +542,8 @@
   kNodeRemoved,
 };
 
-// Next value: 31
+// Next version: 2
+// Next value: 33
 [Extensible, Stable, Uuid="e5a4cd0c-3152-4427-93d5-35ff7d0f1ae8"]
 enum StringAttribute {
   [Default]kNone = 0,
@@ -560,6 +561,7 @@
   kContainerLiveStatus = 10,
   kDescription = 11,  // Any description = 11, from any description source.
   kDisplay = 12,
+  [MinVersion=1] kDoDefaultLabel = 31, // Only for ARC
   // Only present when different from parent.
   kFontFamily = 13,
   kHtmlTag = 14,
@@ -572,6 +574,7 @@
   kKeyShortcuts = 19,
   // Only present when different from parent.
   kLanguage = 20,
+  [MinVersion=1] kLongClickLabel = 32, // Only for ARC
   kName = 21,
   kLiveRelevant = 22,
   kLiveStatus = 23,
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index 42039ec..1bebc3e1 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -633,6 +633,23 @@
   return !IsChildOfLeaf();
 }
 
+AXNode* AXNode::GetLowestCommonAncestor(const AXNode& other) {
+  if (this == &other)
+    return this;
+
+  AXNode* common_ancestor = nullptr;
+  base::stack<AXNode*> our_ancestors = GetAncestorsCrossingTreeBoundary();
+  base::stack<AXNode*> other_ancestors =
+      other.GetAncestorsCrossingTreeBoundary();
+  while (!our_ancestors.empty() && !other_ancestors.empty() &&
+         our_ancestors.top() == other_ancestors.top()) {
+    common_ancestor = our_ancestors.top();
+    our_ancestors.pop();
+    other_ancestors.pop();
+  }
+  return common_ancestor;
+}
+
 absl::optional<int> AXNode::CompareTo(const AXNode& other) const {
   if (this == &other)
     return 0;
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h
index deeb6213..b17d839 100644
--- a/ui/accessibility/ax_node.h
+++ b/ui/accessibility/ax_node.h
@@ -244,6 +244,8 @@
   // software to handle the event on the other end.
   bool CanFireEvents() const;
 
+  AXNode* GetLowestCommonAncestor(const AXNode& other);
+
   // Returns an optional integer indicating the logical order of this node
   // compared to another node, or returns an empty optional if the nodes are not
   // comparable. Nodes are not comparable if they do not share a common
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
index 6179db7..6a55fb99 100644
--- a/ui/accessibility/ax_node_data.cc
+++ b/ui/accessibility/ax_node_data.cc
@@ -1526,6 +1526,9 @@
       case ax::mojom::StringAttribute::kDisplay:
         result += " display=" + value;
         break;
+      case ax::mojom::StringAttribute::kDoDefaultLabel:
+        result += " doDefaultLabel=" + value;
+        break;
       case ax::mojom::StringAttribute::kFontFamily:
         result += " font-family=" + value;
         break;
@@ -1576,6 +1579,9 @@
       case ax::mojom::StringAttribute::kRoleDescription:
         result += " role_description=" + value;
         break;
+      case ax::mojom::StringAttribute::kLongClickLabel:
+        result += " longClickLabel=" + value;
+        break;
       case ax::mojom::StringAttribute::kTooltip:
         result += " tooltip=" + value;
         break;
diff --git a/ui/accessibility/ax_node_position_fuzzer.cc b/ui/accessibility/ax_node_position_fuzzer.cc
index 38ed017..9e8dfffc 100644
--- a/ui/accessibility/ax_node_position_fuzzer.cc
+++ b/ui/accessibility/ax_node_position_fuzzer.cc
@@ -376,7 +376,6 @@
 
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
-  size = kMaxFuzzDataSize;
   if (size < kMinFuzzDataSize || size > kMaxFuzzDataSize)
     return 0;
   static Environment env;
diff --git a/ui/accessibility/ax_node_unittest.cc b/ui/accessibility/ax_node_unittest.cc
index 7355369..9dd6024 100644
--- a/ui/accessibility/ax_node_unittest.cc
+++ b/ui/accessibility/ax_node_unittest.cc
@@ -820,4 +820,94 @@
   EXPECT_TRUE(gridcell_3_node->IsReadOnlyOrDisabled());
 }
 
+TEST(AXNodeTest, GetLowestCommonAncestor) {
+  // ++kRootWebArea
+  // ++++kParagraph
+  // ++++++kStaticText
+  // ++++kParagraph
+  // ++++++kLink
+  // ++++++++kStaticText
+  // ++++++kButton
+
+  // Numbers at the end of variable names indicate their position under the
+  // root.
+  AXNodeData root;
+  AXNodeData paragraph_0;
+  AXNodeData static_text_0_0;
+  AXNodeData paragraph_1;
+  AXNodeData link_1_0;
+  AXNodeData static_text_1_0_0;
+  AXNodeData button_1_1;
+
+  root.id = 1;
+  paragraph_0.id = 2;
+  static_text_0_0.id = 3;
+  paragraph_1.id = 4;
+  link_1_0.id = 5;
+  static_text_1_0_0.id = 6;
+  button_1_1.id = 7;
+
+  root.role = ax::mojom::Role::kRootWebArea;
+  root.child_ids = {paragraph_0.id, paragraph_1.id};
+
+  paragraph_0.role = ax::mojom::Role::kParagraph;
+  paragraph_0.child_ids = {static_text_0_0.id};
+
+  static_text_0_0.role = ax::mojom::Role::kStaticText;
+  static_text_0_0.SetName("static_text_0_0");
+
+  paragraph_1.role = ax::mojom::Role::kParagraph;
+  paragraph_1.child_ids = {link_1_0.id, button_1_1.id};
+
+  link_1_0.role = ax::mojom::Role::kLink;
+  link_1_0.AddState(ax::mojom::State::kLinked);
+  link_1_0.child_ids = {static_text_1_0_0.id};
+
+  static_text_1_0_0.role = ax::mojom::Role::kStaticText;
+  static_text_1_0_0.SetName("static_text_1_0_0");
+
+  button_1_1.role = ax::mojom::Role::kButton;
+  button_1_1.SetName("button_1_1");
+
+  AXTreeUpdate initial_state;
+  initial_state.root_id = root.id;
+  initial_state.nodes = {root,        paragraph_0, static_text_0_0,
+                         paragraph_1, link_1_0,    static_text_1_0_0,
+                         button_1_1};
+  initial_state.has_tree_data = true;
+
+  AXTreeData tree_data;
+  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
+  tree_data.title = "Application";
+  initial_state.tree_data = tree_data;
+
+  AXTree tree;
+  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();
+
+  AXNode* root_node = tree.GetFromId(root.id);
+  AXNode* paragraph_0_node = tree.GetFromId(paragraph_0.id);
+  AXNode* static_text_0_0_node = tree.GetFromId(static_text_0_0.id);
+  AXNode* paragraph_1_node = tree.GetFromId(paragraph_1.id);
+  AXNode* link_1_0_node = tree.GetFromId(link_1_0.id);
+  AXNode* static_text_1_0_0_node = tree.GetFromId(static_text_1_0_0.id);
+  AXNode* button_1_1_node = tree.GetFromId(button_1_1.id);
+
+  // The lowest common ancestor of a node and itself is itself.
+  ASSERT_EQ(root_node, root_node->GetLowestCommonAncestor(*root_node));
+  ASSERT_EQ(paragraph_0_node,
+            paragraph_0_node->GetLowestCommonAncestor(*paragraph_0_node));
+
+  // Lowest common ancestor is reflexive.
+  ASSERT_EQ(paragraph_1_node,
+            link_1_0_node->GetLowestCommonAncestor(*button_1_1_node));
+  ASSERT_EQ(paragraph_1_node,
+            button_1_1_node->GetLowestCommonAncestor(*link_1_0_node));
+
+  // Finds the lowest common ancestor for two nodes not on the same level.
+  ASSERT_EQ(root_node, static_text_1_0_0_node->GetLowestCommonAncestor(
+                           *static_text_0_0_node));
+  ASSERT_EQ(link_1_0_node,
+            static_text_1_0_0_node->GetLowestCommonAncestor(*link_1_0_node));
+}
+
 }  // namespace ui
diff --git a/ui/accessibility/ax_selection.h b/ui/accessibility/ax_selection.h
index 9c6f2ce..bcb82b2 100644
--- a/ui/accessibility/ax_selection.h
+++ b/ui/accessibility/ax_selection.h
@@ -5,6 +5,8 @@
 #ifndef UI_ACCESSIBILITY_AX_SELECTION_H_
 #define UI_ACCESSIBILITY_AX_SELECTION_H_
 
+#include "ui/accessibility/ax_export.h"
+
 namespace ui {
 
 // A data structure that can store either the selected range of nodes in the
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
index 19c7e08..25e8dfc 100644
--- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -547,11 +547,6 @@
   WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETATTRIBUTEVALUE);
   WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETATTRIBUTEVALUE);
   UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(value);
-  // Use a cloned range so that GetAttributeValue does not introduce
-  // side-effects while normalizing the original range.
-  AXPositionInstance normalized_start = start()->Clone();
-  AXPositionInstance normalized_end = end()->Clone();
-  NormalizeTextRange(normalized_start, normalized_end);
 
   base::win::VariantVector attribute_value;
 
@@ -567,12 +562,12 @@
   // attributes, but it appears to be reasonable enough for the readonly one.
   //
   // To determine if the range encompasses *only* a generated newline, we need
-  // to validate that both the start and end endpoints are around a paragraph
-  // boundary and that, when normalized, the range would be a degenerate range.
+  // to validate that both the start and end endpoints are around the same
+  // paragraph boundary.
   if (attribute_id == UIA_IsReadOnlyAttributeId &&
       start()->anchor_id() != end()->anchor_id() &&
       start()->AtEndOfParagraph() && end()->AtStartOfParagraph() &&
-      *normalized_start == *normalized_end) {
+      *start()->AsLeafTextPositionBeforeCharacter() == *end()) {
     AXPlatformNodeWin* common_anchor = GetLowestAccessibleCommonPlatformNode();
     DCHECK(common_anchor);
 
@@ -586,6 +581,12 @@
     return S_OK;
   }
 
+  // Use a cloned range so that GetAttributeValue does not introduce
+  // side-effects while normalizing the original range.
+  AXPositionInstance normalized_start = start()->Clone();
+  AXPositionInstance normalized_end = end()->Clone();
+  NormalizeTextRange(normalized_start, normalized_end);
+
   // The range is inclusive, so advance our endpoint to the next position
   const auto end_leaf_text_position = normalized_end->AsLeafTextPosition();
   auto end = end_leaf_text_position->CreateNextAnchorPosition();
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
index 2ec4a34..11f5d349 100644
--- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -7385,6 +7385,9 @@
   // ++++5 kGenericContainer editable
   // ++++++6 kImage
   // ++++++7 kTextField editable
+  // ++++8 kGenericContainer
+  // ++++++9 kTextField editable
+  // ++++++10 kTextField editable
   AXNodeData root_1;
   AXNodeData generic_container_2;
   AXNodeData image_3;
@@ -7392,6 +7395,9 @@
   AXNodeData generic_container_5;
   AXNodeData image_6;
   AXNodeData text_field_7;
+  AXNodeData generic_container_8;
+  AXNodeData text_field_9;
+  AXNodeData text_field_10;
 
   root_1.id = 1;
   generic_container_2.id = 2;
@@ -7400,9 +7406,13 @@
   generic_container_5.id = 5;
   image_6.id = 6;
   text_field_7.id = 7;
+  generic_container_8.id = 8;
+  text_field_9.id = 9;
+  text_field_10.id = 10;
 
   root_1.role = ax::mojom::Role::kRootWebArea;
-  root_1.child_ids = {generic_container_2.id, generic_container_5.id};
+  root_1.child_ids = {generic_container_2.id, generic_container_5.id,
+                      generic_container_8.id};
 
   generic_container_2.role = ax::mojom::Role::kGenericContainer;
   generic_container_2.child_ids = {image_3.id, text_field_4.id};
@@ -7425,6 +7435,17 @@
   text_field_7.role = ax::mojom::Role::kTextField;
   text_field_7.AddState(ax::mojom::State::kEditable);
 
+  generic_container_8.role = ax::mojom::Role::kGenericContainer;
+  generic_container_8.child_ids = {text_field_9.id, text_field_10.id};
+
+  text_field_9.role = ax::mojom::Role::kTextField;
+  text_field_9.AddState(ax::mojom::State::kEditable);
+  text_field_9.AddBoolAttribute(ax::mojom::BoolAttribute::kIsLineBreakingObject,
+                                true);
+
+  text_field_10.role = ax::mojom::Role::kTextField;
+  text_field_10.AddState(ax::mojom::State::kEditable);
+
   ui::AXTreeUpdate update;
   ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
   update.root_id = root_1.id;
@@ -7432,7 +7453,8 @@
   update.has_tree_data = true;
   update.nodes = {root_1,       generic_container_2, image_3,
                   text_field_4, generic_container_5, image_6,
-                  text_field_7};
+                  text_field_7, generic_container_8, text_field_9,
+                  text_field_10};
   Init(update);
 
   // Making |owner| AXID:1 so that |TestAXNodeWrapper::BuildAllWrappers|
@@ -7471,6 +7493,25 @@
   EXPECT_UIA_TEXTATTRIBUTE_EQ(range_2, UIA_IsReadOnlyAttributeId,
                               expected_variant);
   expected_variant.Reset();
+
+  // This is testing a corner case when the range spans two text fields
+  // separated by a paragraph boundary. This case used to not work because we
+  // were relying on NormalizeTextRange to handle generated newlines and
+  // normalization doesn't work when the range spans text fields.
+  ComPtr<AXPlatformNodeTextRangeProviderWin> range_3;
+  CreateTextRangeProviderWin(
+      range_3, owner, tree_id,
+      /*start_anchor_id*/ text_field_9.id, /*start_offset*/ 1,
+      /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
+      /*end_anchor_id*/ text_field_10.id, /*end_offset*/ 0,
+      /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
+
+  EXPECT_UIA_TEXTRANGE_EQ(range_3, /*expected_text*/ L"\n");
+
+  expected_variant.Set(true);
+  EXPECT_UIA_TEXTATTRIBUTE_EQ(range_3, UIA_IsReadOnlyAttributeId,
+                              expected_variant);
+  expected_variant.Reset();
 }
 
 }  // namespace ui
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc
index 0d973359..eb4d39a 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -355,7 +355,7 @@
         GetInternetShortcutFileContents(url);
     SetFileContents(base::FilePath(valid_file_name),
                     shortcut_url_file_contents);
-    STGMEDIUM storage = CreateStorageForString(std::string());
+    storage = CreateStorageForString(std::string());
     data_->contents_.push_back(
         DataObjectImpl::StoredDataInfo::TakeStorageMedium(
             GetIgnoreFileContentsFormatType().ToFormatEtc(), storage));
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc
index d1ff912..19136eb 100644
--- a/ui/base/ime/win/tsf_text_store_unittest.cc
+++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -1562,7 +1562,6 @@
     SCOPED_TRACE("Verify URL and InputScope support");
     TS_ATTRVAL buffer[2] = {};
     num_copied = 0xfffffff;
-    base::win::ScopedVariant variant;
     const TS_ATTRID inputScopeAndUrlAttributes[] = {GUID_PROP_INPUTSCOPE,
                                                     GUID_PROP_URL};
 
diff --git a/ui/chromeos/file_manager_strings.grdp b/ui/chromeos/file_manager_strings.grdp
index 2938c58..adf9e9f9 100644
--- a/ui/chromeos/file_manager_strings.grdp
+++ b/ui/chromeos/file_manager_strings.grdp
@@ -470,7 +470,7 @@
     Restore from trash
   </message>
   <message name="IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL" desc="Context menu item that empties (permanently deletes all items in) the trash / recycle bin.">
-    Empty Trash
+    Empty trash now
   </message>
   <message name="IDS_FILE_BROWSER_PASTE_BUTTON_LABEL" desc="Context menu item that pastes the file(s) in the clipboard.">
     Paste
@@ -808,7 +808,7 @@
     Restoring <ph name="COUNT">$1<ex>10</ex></ph> items...
   </message>
   <message name="IDS_FILE_BROWSER_TRASH_DELETED_FOREVER" desc="Message informing that items in the trash / recycle bin are deleted forever after 30 days.">
-    Items in the trash are deleted forever after 30 days.
+    Files in the trash for more than 30 days will be automatically deleted.
   </message>
   <message name="IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR" desc="Message informing about error while restoring an item or items from the trash / recycle bin.">
     An error occurred. Some items may not have been restored.
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL.png.sha1
index 151e591..0aff3ba0 100644
--- a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL.png.sha1
+++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_EMPTY_TRASH_BUTTON_LABEL.png.sha1
@@ -1 +1 @@
-f163fae3de47a09d68bb0dd5ce6728f86169a2aa
\ No newline at end of file
+a9b53257cbd17fb41b76ea0b32f8d066f9971f2d
\ No newline at end of file
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_TRASH_DELETED_FOREVER.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_TRASH_DELETED_FOREVER.png.sha1
index 886d736e..0aff3ba0 100644
--- a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_TRASH_DELETED_FOREVER.png.sha1
+++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_TRASH_DELETED_FOREVER.png.sha1
@@ -1 +1 @@
-164a56cf2a713112b07c044ef83fcb9e40bd4528
\ No newline at end of file
+a9b53257cbd17fb41b76ea0b32f8d066f9971f2d
\ No newline at end of file
diff --git a/ui/chromeos/styles/cros_colors.json5 b/ui/chromeos/styles/cros_colors.json5
index 59e8e93..20bb183 100644
--- a/ui/chromeos/styles/cros_colors.json5
+++ b/ui/chromeos/styles/cros_colors.json5
@@ -60,7 +60,7 @@
       generate_inverted: true,
     },
     color_positive: {
-      light: "$google_green_600",
+      light: "$google_green_700",
       dark: "$google_green_300",
     },
     color_selection: {
diff --git a/ui/chromeos/translations/ui_chromeos_strings_af.xtb b/ui/chromeos/translations/ui_chromeos_strings_af.xtb
index e85653b9..ea18fc68 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_af.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_af.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Kanselleer <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Netwerk <ph name="NETWORK_INDEX" /> van <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />; nie geaktiveer nie; <ph name="CONNECTION_STATUS" />; seinsterkte <ph name="SIGNAL_STRENGTH" />%; besonderhede</translation>
 <translation id="3691184985318546178">Singalees</translation>
+<translation id="3722341589402358578">’n Fout het voorgekom. Sommige items is dalk nie na die asblik toe geskuif nie.</translation>
 <translation id="3726463242007121105">Hierdie toestel kan nie oopgemaak word nie want sy lêerstelsel word nie gesteun nie.</translation>
 <translation id="3727148787322499904">As hierdie instelling verander word, sal dit alle gedeelde netwerke raak</translation>
 <translation id="3737576078404241332">Verwyder uit kantbalk</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ar.xtb b/ui/chromeos/translations/ui_chromeos_strings_ar.xtb
index 36e0165..df3dcc5c 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_ar.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_ar.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">إلغاء <ph name="ACTIVITY_DESCRIPTION" /></translation>
 <translation id="3690128548376345212">الشبكة <ph name="NETWORK_INDEX" /> من إجمالي <ph name="NETWORK_COUNT" />، <ph name="NETWORK_NAME" />، غير مفعّلة، <ph name="CONNECTION_STATUS" />، قوة الإشارة <ph name="SIGNAL_STRENGTH" />%، التفاصيل</translation>
 <translation id="3691184985318546178">السنهالية</translation>
+<translation id="3722341589402358578">حدث خطأ. ومن المحتمّل أنّ بعض الملفات لم يتم إرسالها إلى المهملات.</translation>
 <translation id="3726463242007121105">لا يمكن فتح الجهاز لأن نظام الملفات غير متوافق.</translation>
 <translation id="3727148787322499904">سيؤثر تغيير هذا الإعداد في جميع الشبكات المشتركة</translation>
 <translation id="3737576078404241332">الإزالة من الشريط الجانبي</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_az.xtb b/ui/chromeos/translations/ui_chromeos_strings_az.xtb
index acfb6693..91a864f8 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_az.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_az.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Ləğv edin: <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Şəbəkə <ph name="NETWORK_INDEX" />/<ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, Deaktivdir, <ph name="CONNECTION_STATUS" />, Siqnal Gücü <ph name="SIGNAL_STRENGTH" />%, Detallar</translation>
 <translation id="3691184985318546178">Sinhala</translation>
+<translation id="3722341589402358578">Xəta baş verdi. Bəzi elementlər zibil qutusuna atılmamış ola bilər.</translation>
 <translation id="3726463242007121105">Bu fayl açıla bilməz, çünki onun fayl sistemi dəstəklənmir.</translation>
 <translation id="3727148787322499904">Bu ayarın dəyişdirilməsi bütün paylaşılan şəbəkələrə təsir edəcək</translation>
 <translation id="3737576078404241332">Yan paneldən silin</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bg.xtb b/ui/chromeos/translations/ui_chromeos_strings_bg.xtb
index f701ebb..669fde5 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_bg.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_bg.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Грамофонна плоча</translation>
 <translation id="3290356915286466215">незащитена</translation>
 <translation id="3291218047831493686">Свържете се с тази мрежа, за да промените настройките за заключване на SIM картата</translation>
+<translation id="3293023191599135697">WEP мрежите не се поддържат</translation>
 <translation id="3295357220137379386">Устройството е заето</translation>
 <translation id="3296763833017966289">грузински</translation>
 <translation id="3307875152560779385">Украински</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb
index 4556c64..ee7b26e6 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Gramofonska ploča</translation>
 <translation id="3290356915286466215">Nije osigurano</translation>
 <translation id="3291218047831493686">Povežite se s ovom mrežom da promijenite postavke zaključavanja SIM-a</translation>
+<translation id="3293023191599135697">WEP mreže nisu podržane</translation>
 <translation id="3295357220137379386">Uređaj je zauzet</translation>
 <translation id="3296763833017966289">Gruzijska</translation>
 <translation id="3307875152560779385">ukrajinski</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_cy.xtb b/ui/chromeos/translations/ui_chromeos_strings_cy.xtb
index 059769a0..4d91611 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_cy.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_cy.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Canslo <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Rhwydwaith <ph name="NETWORK_INDEX" /> o <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, Heb ei weithredu <ph name="CONNECTION_STATUS" />, Cryfer Signal <ph name="SIGNAL_STRENGTH" />%, Manylion</translation>
 <translation id="3691184985318546178">Sinhala</translation>
+<translation id="3722341589402358578">Bu gwall. Mae'n bosib na fydd rhai eitemau wedi'u rhoi yn y bin sbwriel.</translation>
 <translation id="3726463242007121105">Ni ellir agor y ddyfais hon oherwydd na chefnogir ei system ffeiliau.</translation>
 <translation id="3727148787322499904">Bydd newid y gosodiad hwn yn effeithio ar yr holl rwydweithiau cyffredin</translation>
 <translation id="3737576078404241332">Tynnu o'r bar ochr</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb b/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb
index b2a8a368..884bcb2 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Cancelar <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Red <ph name="NETWORK_INDEX" /> de <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, no activada, <ph name="CONNECTION_STATUS" />, intensidad de la señal: <ph name="SIGNAL_STRENGTH" />%, detalles</translation>
 <translation id="3691184985318546178">Cingalés</translation>
+<translation id="3722341589402358578">Se produjo un error. Es posible que algunos elementos no se hayan enviado a la papelera.</translation>
 <translation id="3726463242007121105">Este dispositivo no puede abrirse porque su sistema de archivos no es compatible.</translation>
 <translation id="3727148787322499904">Si cambias esta configuración, las redes compartidas se verán afectadas</translation>
 <translation id="3737576078404241332">Quitar de la barra lateral</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fa.xtb b/ui/chromeos/translations/ui_chromeos_strings_fa.xtb
index 86e6407..5612cf1 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_fa.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_fa.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">لغو <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">شبکه <ph name="NETWORK_INDEX" /> از <ph name="NETWORK_COUNT" />،‏ <ph name="NETWORK_NAME" />،‏ غیرفعال، <ph name="CONNECTION_STATUS" />، قدرت سیگنال <ph name="SIGNAL_STRENGTH" />٪، جزئیات</translation>
 <translation id="3691184985318546178">سینهالی</translation>
+<translation id="3722341589402358578">خطایی رخ داد. ممکن است برخی‌از موارد به «حذف‌شده‌ها» منتقل نشده باشد.</translation>
 <translation id="3726463242007121105">این دستگاه باز نمی‌شود زیرا سیستم فایل آن پشتیبانی نمی‌شود.</translation>
 <translation id="3727148787322499904">تغییر این تنظیم همه شبکه‌های به اشتراک‌گذاشته‌شده را تحت تأثیر قرار می‌دهد</translation>
 <translation id="3737576078404241332">حذف از نوار کناری</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hr.xtb b/ui/chromeos/translations/ui_chromeos_strings_hr.xtb
index 2c343c61..efd9db0 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_hr.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_hr.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Gramofonska ploča</translation>
 <translation id="3290356915286466215">Nije osigurano</translation>
 <translation id="3291218047831493686">Povežite se s ovom mrežom da biste promijenili postavku zaključavanja SIM kartice</translation>
+<translation id="3293023191599135697">WEP mreže nisu podržane</translation>
 <translation id="3295357220137379386">Uređaj je zauzet</translation>
 <translation id="3296763833017966289">Gruzijski</translation>
 <translation id="3307875152560779385">ukrajinski</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_id.xtb b/ui/chromeos/translations/ui_chromeos_strings_id.xtb
index 9beb8675..a485278 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_id.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_id.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Batalkan <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Jaringan <ph name="NETWORK_INDEX" /> dari <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, Tidak Diaktifkan, <ph name="CONNECTION_STATUS" />, Kekuatan Sinyal <ph name="SIGNAL_STRENGTH" />%, Detail</translation>
 <translation id="3691184985318546178">Sinhala</translation>
+<translation id="3722341589402358578">Terjadi error. Beberapa item mungkin belum dibuang.</translation>
 <translation id="3726463242007121105">Perangkat ini tidak dapat dibuka karena sistem berkasnya tidak didukung.</translation>
 <translation id="3727148787322499904">Perubahan pada setelan ini akan berpengaruh pada semua jaringan bersama</translation>
 <translation id="3737576078404241332">Hapus dari sidebar</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_it.xtb b/ui/chromeos/translations/ui_chromeos_strings_it.xtb
index 5ea04156..91e05d7 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_it.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_it.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Annulla <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Rete <ph name="NETWORK_INDEX" /> di <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, Non attivato, <ph name="CONNECTION_STATUS" />, Intensità del segnale <ph name="SIGNAL_STRENGTH" />%, Dettagli</translation>
 <translation id="3691184985318546178">Singalese</translation>
+<translation id="3722341589402358578">Si è verificato un errore. Alcuni elementi potrebbero non essere stati messi nel cestino.</translation>
 <translation id="3726463242007121105">Impossibile aprire il dispositivo perché il suo filesystem non è supportato.</translation>
 <translation id="3727148787322499904">La modifica di questa impostazione avrà effetto su tutte le reti condivise</translation>
 <translation id="3737576078404241332">Rimuovi dalla barra laterale</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_iw.xtb b/ui/chromeos/translations/ui_chromeos_strings_iw.xtb
index 2410b6f..a63832e 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_iw.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_iw.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">ביטול <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">רשת <ph name="NETWORK_INDEX" /> מתוך <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, לא פעילה, <ph name="CONNECTION_STATUS" />, חוזק האות <ph name="SIGNAL_STRENGTH" />%, פרטים</translation>
 <translation id="3691184985318546178">סינהאלה</translation>
+<translation id="3722341589402358578">אירעה שגיאה. ייתכן שפריטים מסוימים לא הועברו לאשפה.</translation>
 <translation id="3726463242007121105">לא ניתן לפתוח מכשיר זה מאחר שמערכת הקבצים שלו אינה נתמכת.</translation>
 <translation id="3727148787322499904">שינוי של הגדרה זו ישפיע על כל הרשתות המשותפות</translation>
 <translation id="3737576078404241332">הסרה מסרגל הצד</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ko.xtb b/ui/chromeos/translations/ui_chromeos_strings_ko.xtb
index 7b2792fb..1699e39 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_ko.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_ko.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551"><ph name="ACTIVITY_DESCRIPTION" /> 작업을 취소합니다.</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_COUNT" />개 중 <ph name="NETWORK_INDEX" />번째 네트워크, <ph name="NETWORK_NAME" />, 비활성화됨, <ph name="CONNECTION_STATUS" />, 신호 강도 <ph name="SIGNAL_STRENGTH" />%, 세부정보</translation>
 <translation id="3691184985318546178">싱할라어</translation>
+<translation id="3722341589402358578">오류가 발생했습니다. 일부 항목이 휴지통으로 이동되지 않았을 수도 있습니다.</translation>
 <translation id="3726463242007121105">파일 시스템이 지원되지 않아 이 기기를 열 수 없습니다.</translation>
 <translation id="3727148787322499904">이 설정을 변경하면 모든 공유 네트워크에 영향을 줍니다.</translation>
 <translation id="3737576078404241332">사이드바에서 삭제</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_lo.xtb b/ui/chromeos/translations/ui_chromeos_strings_lo.xtb
index 77b73f2..58990f4 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_lo.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_lo.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">ຍົກເລີກ <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">ເຄືອຂ່າຍທີ <ph name="NETWORK_INDEX" /> ຈາກທັງໝົດ <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, ບໍ່ໄດ້ເປີດໃຊ້, <ph name="CONNECTION_STATUS" />, ຄວາມແຮງສັນຍານ <ph name="SIGNAL_STRENGTH" />%, ລາຍລະອຽດ</translation>
 <translation id="3691184985318546178">ພາສາຊິນຮາລາ</translation>
+<translation id="3722341589402358578">ມີຄວາມຜິດພາດເກີດຂຶ້ນ. ບາງລາຍການອາດຈະບໍ່ໄດ້ຖືກສົ່ງໄປຖັງຂີ້ເຫຍື້ອ.</translation>
 <translation id="3726463242007121105">ບໍ່ສາມາດເປີດອຸປະກອນນີ້ໄດ້ ເພາະວ່າລະບົບໄຟລ໌ຂອງມັນບໍ່ຮອງຮັບ.</translation>
 <translation id="3727148787322499904">ການປ່ຽນການຕັ້ງຄ່ານີ້ຈະມີຜົນຕໍ່ກັບທຸກເຄືອຂ່າຍທີ່ໃຊ້ຮ່ວມກັນ</translation>
 <translation id="3737576078404241332">ລຶບອອກຈາກແຖບດ້ານຂ້າງ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_lt.xtb b/ui/chromeos/translations/ui_chromeos_strings_lt.xtb
index 99f7412..5b6602b 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_lt.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_lt.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Atšaukti <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_INDEX" /> tinklas iš <ph name="NETWORK_COUNT" />, „<ph name="NETWORK_NAME" />“, nesuaktyvintas, <ph name="CONNECTION_STATUS" />, signalo stiprumas <ph name="SIGNAL_STRENGTH" /> proc., išsami informacija</translation>
 <translation id="3691184985318546178">Sinhalų k.</translation>
+<translation id="3722341589402358578">Įvyko klaida. Gali būti, kad kai kurie elementai nebuvo perkelti į šiukšliadėžę.</translation>
 <translation id="3726463242007121105">Įrenginio negalima atidaryti, nes nepalaikoma jo failų išdėstymo sistema.</translation>
 <translation id="3727148787322499904">Šio nustatymo pakeitimas turės įtakos visiems bendrinamiems tinklams</translation>
 <translation id="3737576078404241332">Pašalinti iš šoninės juostos</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_mn.xtb b/ui/chromeos/translations/ui_chromeos_strings_mn.xtb
index 27f3999..a7d2933 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_mn.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_mn.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Пянзны бичлэг</translation>
 <translation id="3290356915286466215">Хамгаалалтгүй</translation>
 <translation id="3291218047831493686">SIM-н түгжээний тохиргоог өөрчлөхийн тулд энэ сүлжээнд холбогдоно уу</translation>
+<translation id="3293023191599135697">WEP сүлжээг дэмждэггүй</translation>
 <translation id="3295357220137379386">Төхөөрөмж завгүй байна</translation>
 <translation id="3296763833017966289">Гүрж хэл</translation>
 <translation id="3307875152560779385">Украин</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ms.xtb b/ui/chromeos/translations/ui_chromeos_strings_ms.xtb
index 96a15e02..3a4c147 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_ms.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_ms.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Rekod vinil</translation>
 <translation id="3290356915286466215">Tidak selamat</translation>
 <translation id="3291218047831493686">Sambung kepada rangkaian ini untuk menukar tetapan kunci SIM</translation>
+<translation id="3293023191599135697">Rangkaian WEP tidak disokong</translation>
 <translation id="3295357220137379386">Peranti sibuk</translation>
 <translation id="3296763833017966289">Bahasa Georgia</translation>
 <translation id="3307875152560779385">Ukraine</translation>
@@ -312,6 +313,7 @@
 <translation id="3689865792480713551">Batalkan <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Rangkaian <ph name="NETWORK_INDEX" /> daripada <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, Dinyahaktifkan, <ph name="CONNECTION_STATUS" />, Kekuatan Isyarat <ph name="SIGNAL_STRENGTH" />%, Butiran</translation>
 <translation id="3691184985318546178">Sinhala</translation>
+<translation id="3722341589402358578">Ralat telah berlaku. Sesetengah item mungkin belum dibuang.</translation>
 <translation id="3726463242007121105">Peranti ini tidak boleh dibuka kerana sistem failnya tidak disokong.</translation>
 <translation id="3727148787322499904">Tindakan menukar tetapan ini akan menjejaskan semua rangkaian yang dikongsi</translation>
 <translation id="3737576078404241332">Alih keluar daripada bar sisi</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_my.xtb b/ui/chromeos/translations/ui_chromeos_strings_my.xtb
index b9d6f42..8a9afc3 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_my.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_my.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551"><ph name="ACTIVITY_DESCRIPTION" /> ကို ပယ်ဖျက်မည်။</translation>
 <translation id="3690128548376345212">ကွန်ရက် <ph name="NETWORK_COUNT" /> ခုအနက် <ph name="NETWORK_INDEX" />၊<ph name="NETWORK_NAME" />၊ ဖွင့်မထားပါ၊ <ph name="CONNECTION_STATUS" />၊ လိုင်းဆွဲအား <ph name="SIGNAL_STRENGTH" />%၊ အသေးစိတ်</translation>
 <translation id="3691184985318546178">ဆင်ဟာလာ</translation>
+<translation id="3722341589402358578">အမှား ဖြစ်သွားသည်။ အချို့အရာများကို ပစ်လိုက်ခြင်းမရှိပါ။</translation>
 <translation id="3726463242007121105">ဤစက်ပစ္စည်း၏ ဖိုင်စနစ်ကို မထောက်ပံ့သောကြောင့် ဖွင့်၍မရပါ။</translation>
 <translation id="3727148787322499904">ဤဆက်တင်ကို ပြောင်းလဲခြင်းအားဖြင့် မျှဝေထားသည့် ကွန်ရက်အားလုံးကို အကျိုးသက်ရောက်စေပါလိမ့်မည်</translation>
 <translation id="3737576078404241332">ဆိုက်ဘားမှ ဖယ်ရှားရန်</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_nl.xtb b/ui/chromeos/translations/ui_chromeos_strings_nl.xtb
index 123a0c8..58be4f28 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_nl.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_nl.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551"><ph name="ACTIVITY_DESCRIPTION" /> annuleren.</translation>
 <translation id="3690128548376345212">Netwerk <ph name="NETWORK_INDEX" /> van <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, niet geactiveerd, <ph name="CONNECTION_STATUS" />, signaalsterkte <ph name="SIGNAL_STRENGTH" />%, details</translation>
 <translation id="3691184985318546178">Singalees</translation>
+<translation id="3722341589402358578">Er is een fout opgetreden. Sommige items zijn misschien niet verwijderd.</translation>
 <translation id="3726463242007121105">Dit apparaat kan niet worden geopend omdat het bijbehorende bestandssysteem niet wordt ondersteund.</translation>
 <translation id="3727148787322499904">Het wijzigen van deze instelling is van invloed op alle gedeelde netwerken</translation>
 <translation id="3737576078404241332">Verwijderen uit zijbalk</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_or.xtb b/ui/chromeos/translations/ui_chromeos_strings_or.xtb
index 67bd9a4..d1b7d8c 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_or.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_or.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551"><ph name="ACTIVITY_DESCRIPTION" /> ବାତିଲ୍ କରନ୍ତୁ।</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_NAME" />ର <ph name="NETWORK_COUNT" />ଟିରୁ <ph name="NETWORK_INDEX" /> ନମ୍ବର ନେଟୱାର୍କକୁ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି, <ph name="CONNECTION_STATUS" />, ସିଗନାଲର କ୍ଷମତା <ph name="SIGNAL_STRENGTH" />%, ବିବରଣୀ</translation>
 <translation id="3691184985318546178">ସିଂହଳ</translation>
+<translation id="3722341589402358578">ଏକ ତ୍ରୁଟି ହୋଇଛି। କିଛି ଆଇଟମକୁ ଟ୍ରାସ କରାଯାଇନପାରେ।</translation>
 <translation id="3726463242007121105">ଏହି ଡିଭାଇସ୍‌ ଖୋଲାଯାଇପାରିବ ନାହିଁ କାରଣ ଏହାର ଫାଇଲ୍‌ସିଷ୍ଟମ୍‌ ସମର୍ଥିତ ନୁହେଁ।</translation>
 <translation id="3727148787322499904">ଏହି ସେଟିଂସ୍‍‍ରେ ପରିବର୍ତ୍ତନ କରିବା ଦ୍ୱାରା ସମସ୍ତ ସେୟାର୍‍ କରାଯାଇଥିବା ନେଟ୍‍ୱର୍କ ପ୍ରଭାବିତ ହେବ</translation>
 <translation id="3737576078404241332">ସାଇଡବାରରୁ କାଢ଼ି ଦିଅନ୍ତୁ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_pl.xtb b/ui/chromeos/translations/ui_chromeos_strings_pl.xtb
index a383d2a..eceb9cc 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_pl.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_pl.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">Płyta winylowa</translation>
 <translation id="3290356915286466215">Niezabezpieczona</translation>
 <translation id="3291218047831493686">Połącz się z tą siecią, aby zmienić ustawienie blokady SIM</translation>
+<translation id="3293023191599135697">Sieci WEP nie są obsługiwane</translation>
 <translation id="3295357220137379386">Urządzenie jest zajęte</translation>
 <translation id="3296763833017966289">Gruziński</translation>
 <translation id="3307875152560779385">Ukraiński</translation>
@@ -312,6 +313,7 @@
 <translation id="3689865792480713551">Anuluj <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Sieć <ph name="NETWORK_INDEX" /> z <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, nieaktywowana, <ph name="CONNECTION_STATUS" />, siła sygnału <ph name="SIGNAL_STRENGTH" />%, szczegóły</translation>
 <translation id="3691184985318546178">Syngaleski</translation>
+<translation id="3722341589402358578">Wystąpił błąd. Niektóre elementy mogły nie zostać przeniesione do kosza.</translation>
 <translation id="3726463242007121105">Nie można otworzyć urządzenia, ponieważ jego system plików nie jest obsługiwany.</translation>
 <translation id="3727148787322499904">Zmiana tego ustawienia wpłynie na wszystkie sieci współdzielone</translation>
 <translation id="3737576078404241332">Usuń z paska bocznego</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ru.xtb b/ui/chromeos/translations/ui_chromeos_strings_ru.xtb
index 9f9964c..aaecc9e 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_ru.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_ru.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Отменить <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212">Сеть <ph name="NETWORK_INDEX" /> из <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, не активирована, <ph name="CONNECTION_STATUS" />, уровень сигнала – <ph name="SIGNAL_STRENGTH" /> %, подробная информация</translation>
 <translation id="3691184985318546178">Сингальский</translation>
+<translation id="3722341589402358578">Произошла ошибка. Возможно, не все объекты были удалены.</translation>
 <translation id="3726463242007121105">Невозможно получить доступ к устройству, так как его файловая система не поддерживается.</translation>
 <translation id="3727148787322499904">Изменение этого параметра повлияет на все общие сети</translation>
 <translation id="3737576078404241332">Удалить с боковой панели</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_si.xtb b/ui/chromeos/translations/ui_chromeos_strings_si.xtb
index 2941739..3e79e81 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_si.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_si.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551"><ph name="ACTIVITY_DESCRIPTION" /> අවලංගු කරන්න.</translation>
 <translation id="3690128548376345212">ජාල <ph name="NETWORK_COUNT" />කින් <ph name="NETWORK_INDEX" />, <ph name="NETWORK_NAME" />, සක්‍රිය නොකළ, <ph name="CONNECTION_STATUS" /> සංඥා ප්‍රබලතාව <ph name="SIGNAL_STRENGTH" />%, විස්තර</translation>
 <translation id="3691184985318546178">සිංහල</translation>
+<translation id="3722341589402358578">දෝෂයක් ඇති විය. සමහර අයිතම ප්‍රතිසාධනය කර නොතිබිය හැක.</translation>
 <translation id="3726463242007121105">ගොනුවේ ගොනුරටාව ආධාරක නොවන බැවින් උපාංගය විවෘත කළ නොහැක.</translation>
 <translation id="3727148787322499904">මෙම සැකසීම වෙනස් කිරීම සියලු බෙදා ගත් ජාලවලට බලපානු ඇත</translation>
 <translation id="3737576078404241332">පැති තීරුව වෙතින් ඉවත් කරන්න</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sk.xtb b/ui/chromeos/translations/ui_chromeos_strings_sk.xtb
index 891ca3d..5bb2d9e7 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_sk.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_sk.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">Zrušiť <ph name="ACTIVITY_DESCRIPTION" />.</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_INDEX" />. sieť z <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, neaktivovaná, <ph name="CONNECTION_STATUS" />, sila signálu: <ph name="SIGNAL_STRENGTH" /> %, podrobnosti</translation>
 <translation id="3691184985318546178">Sinhálska klávesnica</translation>
+<translation id="3722341589402358578">Vyskytla sa chyba. Niektoré položky sa zrejme nepodarilo presunúť do koša.</translation>
 <translation id="3726463242007121105">Toto zariadenie nie je možné otvoriť, pretože jeho systém súborov nie je podporovaný.</translation>
 <translation id="3727148787322499904">Zmena tohto nastavenia ovplyvní všetky zdieľané siete</translation>
 <translation id="3737576078404241332">Odstrániť z bočného panela</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb
index 4bb6ff3..cc6e7dd 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">取消<ph name="ACTIVITY_DESCRIPTION" />。</translation>
 <translation id="3690128548376345212">第 <ph name="NETWORK_INDEX" /> 个网络(共 <ph name="NETWORK_COUNT" /> 个),<ph name="NETWORK_NAME" />,未激活,<ph name="CONNECTION_STATUS" />,信号强度 <ph name="SIGNAL_STRENGTH" />%,详细信息</translation>
 <translation id="3691184985318546178">僧伽罗语</translation>
+<translation id="3722341589402358578">出错了。某些内容可能未成功移至回收站。</translation>
 <translation id="3726463242007121105">系统不支持此设备的文件系统,因此无法打开此设备。</translation>
 <translation id="3727148787322499904">更改此设置将会影响所有共享网络</translation>
 <translation id="3737576078404241332">从边栏中移除</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb
index 1357942..edeafab 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb
@@ -263,6 +263,7 @@
 <translation id="3280987981688031357">黑膠唱片</translation>
 <translation id="3290356915286466215">不安全</translation>
 <translation id="3291218047831493686">連接此網絡即可變更 SIM 卡鎖定設定</translation>
+<translation id="3293023191599135697">系統不支援 WEP 網絡</translation>
 <translation id="3295357220137379386">裝置忙碌中</translation>
 <translation id="3296763833017966289">喬治亞文</translation>
 <translation id="3307875152560779385">烏克蘭文</translation>
@@ -312,6 +313,7 @@
 <translation id="3689865792480713551">取消 <ph name="ACTIVITY_DESCRIPTION" />。</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_COUNT" /> 個網絡之中嘅第 <ph name="NETWORK_INDEX" /> 個網絡,<ph name="NETWORK_NAME" />,未啟用,<ph name="CONNECTION_STATUS" />,訊號強度係 <ph name="SIGNAL_STRENGTH" />%,詳細資料</translation>
 <translation id="3691184985318546178">錫蘭文</translation>
+<translation id="3722341589402358578">發生錯誤,某些項目可能尚未移至垃圾桶。</translation>
 <translation id="3726463242007121105">這部裝置所用的檔案系統不受支援,因此系統無法開啟這部裝置。</translation>
 <translation id="3727148787322499904">變更此設定將會影響所有共用網絡</translation>
 <translation id="3737576078404241332">從側欄中移除</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb
index dc89dfe..dbb9ceb5 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb
@@ -312,6 +312,7 @@
 <translation id="3689865792480713551">取消<ph name="ACTIVITY_DESCRIPTION" />。</translation>
 <translation id="3690128548376345212"><ph name="NETWORK_COUNT" /> 個網路中的第 <ph name="NETWORK_INDEX" /> 個,<ph name="NETWORK_NAME" />,未啟用,<ph name="CONNECTION_STATUS" />,訊號強度 <ph name="SIGNAL_STRENGTH" />%,詳細資料</translation>
 <translation id="3691184985318546178">錫蘭文</translation>
+<translation id="3722341589402358578">發生錯誤,某些項目可能尚未移至垃圾桶。</translation>
 <translation id="3726463242007121105">這個裝置所用的檔案系統不受支援,因此系統無法開啟這個裝置。</translation>
 <translation id="3727148787322499904">變更這項設定會影響所有共用網路</translation>
 <translation id="3737576078404241332">從側欄中移除</translation>
diff --git a/ui/events/platform/x11/x11_event_watcher_glib.cc b/ui/events/platform/x11/x11_event_watcher_glib.cc
index d690367c..d5fe253 100644
--- a/ui/events/platform/x11/x11_event_watcher_glib.cc
+++ b/ui/events/platform/x11/x11_event_watcher_glib.cc
@@ -112,7 +112,11 @@
     return;
 
   g_source_destroy(x_source_);
-  g_source_unref(x_source_);
+  // `g_source_unref` decreases the reference count on `x_source_`. The
+  // underlying memory is freed if the reference count goes to zero. We use
+  // ExtractAsDangling() here to avoid holding a briefly dangling ptr in case
+  // the memory is freed.
+  g_source_unref(x_source_.ExtractAsDangling());
   started_ = false;
 }
 
diff --git a/ui/events/platform/x11/x11_event_watcher_glib.h b/ui/events/platform/x11/x11_event_watcher_glib.h
index 9b9321f8..12a6858 100644
--- a/ui/events/platform/x11/x11_event_watcher_glib.h
+++ b/ui/events/platform/x11/x11_event_watcher_glib.h
@@ -35,7 +35,7 @@
   raw_ptr<X11EventSource> event_source_;
 
   // The GLib event source for X events.
-  raw_ptr<GSource, DanglingUntriaged> x_source_ = nullptr;
+  raw_ptr<GSource> x_source_ = nullptr;
 
   // The poll attached to |x_source_|.
   std::unique_ptr<GPollFD> x_poll_;
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index b06c0ef..4f8c605 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -196,6 +196,8 @@
   root_dir = "."
   out_dir = target_gen_dir
 
+  deps = [ "//ui/webui/resources:library" ]
+
   js_files = [
     "file_manager/common/js/volume_manager_types.js",
     "file_manager/externs/entry_location.js",
diff --git a/ui/file_manager/file_manager/background/js/file_operation_handler.js b/ui/file_manager/file_manager/background/js/file_operation_handler.js
index 3964dbd..1e641434 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_handler.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_handler.js
@@ -146,6 +146,10 @@
       default:
         console.error(`Invalid IOTaskState: ${event.state}`);
     }
+    if (!event.showNotification) {
+      // Set state to canceled so notification doesn't display.
+      item.state = ProgressItemState.CANCELED;
+    }
     this.progressCenter_.updateItem(item);
   }
 
diff --git a/ui/file_manager/file_manager/externs/ts/state.js b/ui/file_manager/file_manager/externs/ts/state.js
index 308d1b4..37ae86f8 100644
--- a/ui/file_manager/file_manager/externs/ts/state.js
+++ b/ui/file_manager/file_manager/externs/ts/state.js
@@ -9,6 +9,7 @@
  * The data for each individual file/entry.
  * @typedef {{
  *   entry: (Entry|FilesAppEntry),
+ *   label: string,
  *   volumeType: (VolumeManagerCommon.VolumeType|null),
  * }}
  */
diff --git a/ui/file_manager/file_manager/foreground/elements/BUILD.gn b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
index 596cf414..d62c53be 100644
--- a/ui/file_manager/file_manager/foreground/elements/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
@@ -83,12 +83,13 @@
     "//ui/file_manager/file_manager/common/js:volume_manager_types",
     "//ui/file_manager/file_manager/externs:volume_info",
     "//ui/file_manager/file_manager/foreground/js:file_rename",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("files_icon_button") {
@@ -119,17 +120,20 @@
     "//ui/file_manager/file_manager/common/js:test_error_reporting",
     "//ui/webui/resources/js:assert.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js" ]
 }
 
 js_library("files_password_dialog") {
   deps = [
     "//ui/file_manager/file_manager/common/js:async_util",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("files_quick_view") {
@@ -169,10 +173,11 @@
 js_library("files_toast") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_toast/cr_toast_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_toast/cr_toast_externs.js",
+  ]
 }
 
 # TODO(tapted): Move this to //ui/file_manager/base.
@@ -217,7 +222,8 @@
 }
 
 js_library("xf_button") {
-  deps = [ "//ui/webui/resources/cr_elements/cr_button:cr_button" ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("xf_circular_progress") {
diff --git a/ui/file_manager/file_manager/foreground/elements/files_password_dialog_unittest.js b/ui/file_manager/file_manager/foreground/elements/files_password_dialog_unittest.js
index 8925febe..684901e 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_password_dialog_unittest.js
+++ b/ui/file_manager/file_manager/foreground/elements/files_password_dialog_unittest.js
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
-import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {assertEquals, assertFalse, assertNotReached} from 'chrome://webui-test/chai_assert.js';
 
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 6c8384c..1d34933 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -1105,6 +1105,7 @@
     ":directory_model",
     ":folder_shortcuts_data_model",
     "//chrome/test/data/webui:chai_assert",
+    "//ui/file_manager/file_manager/common/js:dialog_type",
     "//ui/file_manager/file_manager/common/js:files_app_entry_types",
     "//ui/file_manager/file_manager/common/js:trash",
     "//ui/file_manager/file_manager/common/js:util",
@@ -1127,6 +1128,7 @@
     "//chrome/test/data/webui:chai_assert",
     "//ui/file_manager/file_manager/background/js:mock_volume_manager",
     "//ui/file_manager/file_manager/background/js:volume_info_impl",
+    "//ui/file_manager/file_manager/common/js:dialog_type",
     "//ui/file_manager/file_manager/common/js:files_app_entry_types",
     "//ui/file_manager/file_manager/common/js:mock_chrome",
     "//ui/file_manager/file_manager/common/js:mock_entry",
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 951458a00..141c1432 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -1328,7 +1328,8 @@
                 str('RECENT_ROOT_LABEL'), NavigationModelItemType.RECENT,
                 assert(this.recentEntry_)) :
             null,
-        assert(this.directoryModel_), assert(this.androidAppListModel_));
+        assert(this.directoryModel_), assert(this.androidAppListModel_),
+        this.dialogType);
 
     this.ui_.initDirectoryTree(directoryTree);
 
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
index ceb0ad4..1ac7fdcfe 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -5,6 +5,7 @@
 import {assertNotReached} from 'chrome://resources/js/assert.m.js';
 import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
 
+import {DialogType} from '../../common/js/dialog_type.js';
 import {EntryList, FakeEntryImpl, VolumeEntry} from '../../common/js/files_app_entry_types.js';
 import {TrashRootEntry} from '../../common/js/trash.js';
 import {str, util} from '../../common/js/util.js';
@@ -191,10 +192,11 @@
    * @param {NavigationModelFakeItem} recentModelItem Recent folder.
    * @param {!DirectoryModel} directoryModel
    * @param {!AndroidAppListModel} androidAppListModel
+   * @param {!DialogType} dialogType
    */
   constructor(
       volumeManager, shortcutListModel, recentModelItem, directoryModel,
-      androidAppListModel) {
+      androidAppListModel, dialogType) {
     super();
 
     /**
@@ -227,6 +229,11 @@
     this.androidAppListModel_ = androidAppListModel;
 
     /**
+     * @private {!DialogType}
+     */
+    this.dialogType_ = dialogType;
+
+    /**
      * Root folder for crostini Linux files.
      * This field will be modified when crostini is enabled/disabled.
      * @private {NavigationModelFakeItem}
@@ -745,8 +752,13 @@
     }
 
     // Add Trash.
-    // TODO(b/237351925): Trash should not show up when in File picker / saver.
-    if (util.isTrashEnabled()) {
+    // This should only show when Files app is open as a standalone app. The ARC
+    // file selector, however, opens Files app as a standalone app but passes a
+    // query parameter to indicate the mode. As Trash is a fake volume, it is
+    // not filtered out in the filtered volume manager so perform it here
+    // instead.
+    if (util.isTrashEnabled() && this.dialogType_ === DialogType.FULL_PAGE &&
+        !this.volumeManager_.getMediaStoreFilesOnlyFilterEnabled()) {
       if (!this.trashItem_) {
         this.trashItem_ = new NavigationModelFakeItem(
             str('TRASH_ROOT_LABEL'), NavigationModelItemType.TRASH,
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
index c965c40..b0028b7 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
@@ -6,6 +6,7 @@
 
 import {MockVolumeManager} from '../../background/js/mock_volume_manager.js';
 import {VolumeInfoImpl} from '../../background/js/volume_info_impl.js';
+import {DialogType} from '../../common/js/dialog_type.js';
 import {EntryList, FakeEntryImpl} from '../../common/js/files_app_entry_types.js';
 import {MockCommandLinePrivate} from '../../common/js/mock_chrome.js';
 import {MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js';
@@ -121,7 +122,7 @@
 
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModelWithApps);
+      directoryModel, androidAppListModelWithApps, DialogType.FULL_PAGE);
   model.linuxFilesItem = crostiniFakeItem;
 
   // Expect 9 items as 3 additional recent views (Audio, Images, Videos)
@@ -181,7 +182,7 @@
 
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
 
   assertEquals(3, model.length);
   assertEquals(
@@ -205,7 +206,7 @@
 
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
 
   assertEquals(3, model.length);
 
@@ -276,7 +277,7 @@
 
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
 
   assertEquals(3, model.length);
 
@@ -443,7 +444,7 @@
   // Constructor already calls orderAndNestItems_.
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModelWithApps);
+      directoryModel, androidAppListModelWithApps, DialogType.FULL_PAGE);
 
   // Check items order and that MTP/Archive/Removable respect the original
   // order.
@@ -566,7 +567,7 @@
   // Constructor already calls orderAndNestItems_.
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
   model.linuxFilesItem = crostiniFakeItem;
 
   assertEquals(2, model.length);
@@ -623,7 +624,7 @@
 
   const model = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
 
   // Check that the common root shows 3 partitions.
   let groupedUsbs = /** @type NavigationModelFakeItem */ (model.item(2));
diff --git a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
index 531edeb..3a1ac37 100644
--- a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/toolbar_controller.js
@@ -88,13 +88,6 @@
      * @private {!HTMLElement}
      * @const
      */
-    this.emptyTrashButton_ =
-        util.queryRequiredElement('#empty-trash-button', this.toolbar_);
-
-    /**
-     * @private {!HTMLElement}
-     * @const
-     */
     this.sharesheetButton_ =
         util.queryRequiredElement('#sharesheet-button', this.toolbar_);
 
@@ -259,9 +252,6 @@
     this.restoreFromTrashButton_.addEventListener(
         'click', this.onRestoreFromTrashButtonClicked_.bind(this));
 
-    this.emptyTrashButton_.addEventListener(
-        'click', this.onEmptyTrashButtonClicked_.bind(this));
-
     this.sharesheetButton_.addEventListener(
         'click', this.onSharesheetButtonClicked_.bind(this));
 
@@ -361,11 +351,6 @@
         this.directoryModel_.getCurrentRootType() !==
             VolumeManagerCommon.RootType.TRASH;
 
-    // Update visibility of the empty-trash button.
-    this.emptyTrashButton_.hidden =
-        this.directoryModel_.getCurrentRootType() !==
-        VolumeManagerCommon.RootType.TRASH;
-
     this.togglePinnedCommand_.canExecuteChange(this.listContainer_.currentList);
 
     // Set .selecting class to containing element to change the view
@@ -426,16 +411,6 @@
   }
 
   /**
-   * Handles click event for empty trash button to empty the trash.
-   * command.
-   * @private
-   */
-  onEmptyTrashButtonClicked_() {
-    this.emptyTrashCommand_.canExecuteChange(this.listContainer_.currentList);
-    this.emptyTrashCommand_.execute(this.listContainer_.currentList);
-  }
-
-  /**
    * Handles click event for sharesheet button to set button background color.
    * @private
    */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/banners/state_banner.html b/ui/file_manager/file_manager/foreground/js/ui/banners/state_banner.html
index 2a98a50..c93c93ed 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/banners/state_banner.html
+++ b/ui/file_manager/file_manager/foreground/js/ui/banners/state_banner.html
@@ -19,7 +19,8 @@
   }
 
   .state-icon {
-    background-image: url(/foreground/images/files/ui/state_banner_icon.svg);
+    background-image: var(--icon-src,
+        url(/foreground/images/files/ui/state_banner_icon.svg));
     background-size: 32px 32px;
     flex: none;
     height: 32px;
@@ -64,7 +65,9 @@
 </style>
 <div class="state-banner">
   <div id="state-text-group">
-    <div class="state-icon"></div>
+    <div class="state-icon">
+      <slot name="state-icon-holder"></slot>
+    </div>
     <div class="state-message body2-primary">
       <slot name="text"></slot>
     </div>
diff --git a/ui/file_manager/file_manager/foreground/js/ui/banners/trash_banner.html b/ui/file_manager/file_manager/foreground/js/ui/banners/trash_banner.html
index 7cd62fc..0e0e3ae 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/banners/trash_banner.html
+++ b/ui/file_manager/file_manager/foreground/js/ui/banners/trash_banner.html
@@ -1,3 +1,38 @@
+<style>
+  state-banner {
+    --icon-src: none;
+  }
+
+  #trash-icon {
+    -webkit-mask-image: url(/foreground/images/files/ui/delete_ng.svg);
+    -webkit-mask-position: center;
+    -webkit-mask-repeat: no-repeat;
+    background-color: var(--cros-color-prominent);
+    display: inline-block;
+    height: 20px;
+    width: 20px;
+  }
+
+  #trash-icon-background {
+    align-items: center;
+    background-color: var(--cros-highlight-color);
+    border-radius: 16px;
+    display: flex;
+    height: 32px;
+    justify-content: center;
+    margin-inline-end: 10px;
+    margin-inline-start: 10px;
+    width: 32px;
+  }
+</style>
 <state-banner>
+  <div slot="state-icon-holder">
+    <div id="trash-icon-background">
+      <span id="trash-icon"></span>
+    </div>
+  </div>
   <span slot="text">$i18n{TRASH_DELETED_FOREVER}</span>
+  <cr-button slot="extra-button" command="#empty-trash">
+    $i18n{EMPTY_TRASH_BUTTON_LABEL}
+  </cr-button>
 </state-banner>
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
index 65b7a3d..99386f1 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
@@ -6,6 +6,7 @@
 import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 import {MockVolumeManager} from '../../../background/js/mock_volume_manager.js';
+import {DialogType} from '../../../common/js/dialog_type.js';
 import {EntryList} from '../../../common/js/files_app_entry_types.js';
 import {metrics} from '../../../common/js/metrics.js';
 import {installMockChrome, MockCommandLinePrivate} from '../../../common/js/mock_chrome.js';
@@ -476,7 +477,7 @@
   const androidAppListModel = createFakeAndroidAppListModel(['android:app1']);
   const treeModel = new NavigationListModel(
       volumeManager, shortcutListModel.asFolderShortcutsDataModel(), recentItem,
-      directoryModel, androidAppListModel);
+      directoryModel, androidAppListModel, DialogType.FULL_PAGE);
   const myFilesItem = treeModel.item(0);
   const driveItem = treeModel.item(1);
   const androidAppItem = treeModel.item(2);
diff --git a/ui/file_manager/file_manager/lib/base_store.ts b/ui/file_manager/file_manager/lib/base_store.ts
index 6f2b7cc5..746441a8 100644
--- a/ui/file_manager/file_manager/lib/base_store.ts
+++ b/ui/file_manager/file_manager/lib/base_store.ts
@@ -131,16 +131,14 @@
   }
 
   /**
-   * TODO(lucmult): Update this doc.
+   * Dispatches an Action to the Store.
    *
-   * Handles a 'deferred' action, which can asynchronously dispatch actions
-   * to the Store in order to reach a new UI state. DeferredActions have the
-   * form `dispatchAsync(function(dispatch) { ... })`). Inside that function,
-   * the |dispatch| callback can be called asynchronously to dispatch Actions
-   * directly to the Store.
-   * param {DeferredAction} action
+   * For synchronous actions it sends the action to the reducers, which updates
+   * the Store state, then the Store notifies all subscribers.
+   * If the Store isn't initialized, the action is queued and dispatched to
+   * reducers during the initialization.
    */
-  dispatchAsync(action: ActionType) {
+  dispatch(action: ActionType) {
     if (!this.initialized_) {
       this.queuedActions_.push(action);
       return;
@@ -148,22 +146,8 @@
     this.dispatchInternal_(action);
   }
 
-  /**
-   * TODO(lucmult): Update this doc and review this implementation.
-   * Transition to a new UI state based on the supplied |action|, and notify
-   * observers of the change. If the Store has not yet been initialized, the
-   * action will be queued and performed upon initialization.
-   */
-  dispatch(action: ActionType) {
-    this.dispatchAsync(action);
-    // this.dispatchAsync(function(dispatch) {
-    //   dispatch(action);
-    // });
-  }
-
   /** Synchronously call apply the `action` by calling the reducer.  */
   private dispatchInternal_(action: ActionType) {
-    // action(this.reduce.bind(this));
     this.reduce(action);
   }
 
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 2674ce6..68f9911 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -402,13 +402,6 @@
               <files-ripple></files-ripple>
               <div class="icon"></div>
             </cr-button>
-            <cr-button id="empty-trash-button" class="icon-button menu-button" tabindex="0" hidden
-                    aria-label="$i18n{EMPTY_TRASH_BUTTON_LABEL}"
-                    visibleif="full-page"
-                    has-tooltip>
-              <files-ripple></files-ripple>
-              $i18n{EMPTY_TRASH_BUTTON_LABEL}
-            </cr-button>
             <div id="search-wrapper">
               <cr-button id="search-button" class="icon-button menu-button" tabindex="0"
                       aria-label="$i18n{SEARCH_TEXT_LABEL}"
diff --git a/ui/file_manager/file_manager/state/reducers/all_entries.ts b/ui/file_manager/file_manager/state/reducers/all_entries.ts
index 1a898bf..9a8b8619 100644
--- a/ui/file_manager/file_manager/state/reducers/all_entries.ts
+++ b/ui/file_manager/file_manager/state/reducers/all_entries.ts
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {util} from '../../common/js/util.js';
 import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
 import {State} from '../../externs/ts/state.js';
 import {Action, ActionType, ChangeDirectoryAction, ClearStaleCachedEntriesAction} from '../actions.js';
@@ -88,14 +89,17 @@
       return currentState;
     }
 
-    // TODO(lucmult): Find a correct way to grab the VolumeManager.
-    const volumeManager = window.fileManager?.volumeManager as any;
-    const volumeInfo = volumeManager?.getVolumeInfo(entry as Entry);
-    const volumeType = volumeInfo?.volumeType;
+    const volumeManager = window.fileManager?.volumeManager;
+    const volumeInfo = volumeManager?.getVolumeInfo(entry);
+    const locationInfo = volumeManager?.getLocationInfo(entry);
+    const label = locationInfo ? util.getEntryLabel(locationInfo, entry) : '';
+
+    const volumeType = volumeInfo?.volumeType || null;
 
     const entryData = allEntries[key] || {};
     allEntries[key] = Object.assign(entryData, {
       entry,
+      label,
       volumeType,
     });
 
diff --git a/ui/file_manager/file_manager/state/reducers/current_directory.ts b/ui/file_manager/file_manager/state/reducers/current_directory.ts
index 4952b033..7295138a 100644
--- a/ui/file_manager/file_manager/state/reducers/current_directory.ts
+++ b/ui/file_manager/file_manager/state/reducers/current_directory.ts
@@ -24,8 +24,7 @@
     return emptyDir;
   }
 
-  // TODO(lucmult): Find a correct way to grab the VolumeManager.
-  const volumeManager = window.fileManager.volumeManager;
+  const volumeManager = window.fileManager?.volumeManager;
   if (!volumeManager) {
     console.debug(`VolumeManager not available yet.`);
     return currentState.currentDirectory || emptyDir;
diff --git a/ui/file_manager/integration_tests/file_manager/BUILD.gn b/ui/file_manager/integration_tests/file_manager/BUILD.gn
index b3060fc..ad95a363 100644
--- a/ui/file_manager/integration_tests/file_manager/BUILD.gn
+++ b/ui/file_manager/integration_tests/file_manager/BUILD.gn
@@ -389,6 +389,7 @@
   deps = [
     ":tasks",
     ":test_data",
+    "//ui/file_manager/integration_tests:dialog_type",
     "//ui/file_manager/integration_tests:testcase",
   ]
 }
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js
index fe70a923..16e5a1c 100644
--- a/ui/file_manager/integration_tests/file_manager/background.js
+++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -102,10 +102,12 @@
   if (remoteCall.isSwaMode()) {
     const launchDir = appState ? appState.currentDirectoryURL : undefined;
     const type = appState ? appState.type : undefined;
+    const volumeFilter = appState ? appState.volumeFilter : undefined;
     appId = await sendTestMessage({
       name: 'launchFileManagerSwa',
       launchDir: launchDir,
       type: type,
+      volumeFilter,
     });
   } else {
     appId =
diff --git a/ui/file_manager/integration_tests/file_manager/trash.js b/ui/file_manager/integration_tests/file_manager/trash.js
index 2c882d23..15925d7 100644
--- a/ui/file_manager/integration_tests/file_manager/trash.js
+++ b/ui/file_manager/integration_tests/file_manager/trash.js
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {addEntries, ENTRIES, EntryType, getCaller, pending, repeatUntil, RootPath, sendTestMessage, TestEntryInfo} from '../test_util.js';
+import {DialogType} from '../dialog_type.js';
+import {addEntries, RootPath} from '../test_util.js';
 import {testcase} from '../testcase.js';
 
-import {expandTreeItem, IGNORE_APP_ERRORS, mountCrostini, navigateWithDirectoryTree, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
+import {navigateWithDirectoryTree, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
 import {DOWNLOADS_FAKE_TASKS} from './tasks.js';
 import {BASIC_ANDROID_ENTRY_SET, BASIC_LOCAL_ENTRY_SET} from './test_data.js';
 
@@ -253,7 +254,7 @@
 };
 
 /**
- * Delete files (move them into trash) then empty trash using toolbar.
+ * Delete files (move them into trash) then empty trash using the banner.
  */
 testcase.trashEmptyTrash = async () => {
   const appId = await setupAndWaitUntilReady(
@@ -274,7 +275,8 @@
       appId, '#file-list [file-name="hello.txt"]');
 
   // Empty trash and confirm delete (dialog shown).
-  await remoteCall.waitAndClickElement(appId, '#empty-trash-button');
+  await remoteCall.waitAndClickElement(
+      appId, ['trash-banner', 'cr-button[command="#empty-trash"]']);
   await remoteCall.waitAndClickElement(
       appId, '.files-confirm-dialog .cr-dialog-ok');
 
@@ -636,3 +638,43 @@
   await remoteCall.waitForElement(appId, `[scan-completed="Trash"]`);
   await remoteCall.waitForFiles(appId, []);
 };
+
+/**
+ * Tests the Trash root is not visible when opening Files app as a select file
+ * dialog.
+ */
+testcase.trashDontShowTrashRootOnSelectFileDialog = async () => {
+  // Open Files app on Downloads as a select file dialog.
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, [],
+      {type: DialogType.SELECT_OPEN_FILE});
+
+  // Navigate to the My files directory to ensure the directory tree has fully
+  // loaded and wait for My files to finish scanning.
+  await navigateWithDirectoryTree(appId, '/My files');
+  await remoteCall.waitForElement(appId, `[scan-completed="My files"]`);
+
+  // Ensure the Trash root entry is not visible on the page.
+  await remoteCall.waitForElementLost(
+      appId, '#directory-tree [entry-label="Trash"]');
+};
+
+/**
+ * Tests the Trash root is not visible when Files app is used as a select file
+ * dialog within Android applications.
+ */
+testcase.trashDontShowTrashRootWhenOpeningAsAndroidFilePicker = async () => {
+  // Open Files app on Downloads as an Android file picker.
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, [],
+      {volumeFilter: ['media-store-files-only']});
+
+  // Navigate to the My files directory to ensure the directory tree has fully
+  // loaded and wait for My files to finish scanning.
+  await navigateWithDirectoryTree(appId, '/My files');
+  await remoteCall.waitForElement(appId, `[scan-completed="My files"]`);
+
+  // Ensure the Trash root entry is not visible on the page.
+  await remoteCall.waitForElementLost(
+      appId, '#directory-tree [entry-label="Trash"]');
+};
diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc
index afb776ff..5e42e1b 100644
--- a/ui/gl/gl_image.cc
+++ b/ui/gl/gl_image.cc
@@ -126,10 +126,6 @@
 }
 #endif
 
-bool GLImage::HasMutableState() const {
-  return true;
-}
-
 scoped_refptr<gfx::NativePixmap> GLImage::GetNativePixmap() {
   return nullptr;
 }
diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h
index 18c6c12..bfa388f 100644
--- a/ui/gl/gl_image.h
+++ b/ui/gl/gl_image.h
@@ -152,10 +152,6 @@
   };
   virtual Type GetType() const;
 
-  // Workaround for StreamTexture which must be re-copied on each access.
-  // TODO(ericrk): Remove this once SharedImage transition is complete.
-  virtual bool HasMutableState() const;
-
   // Returns the NativePixmap backing the GLImage. If not backed by a
   // NativePixmap, returns null.
   virtual scoped_refptr<gfx::NativePixmap> GetNativePixmap();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index 30085664..18a19ac 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -534,9 +534,9 @@
 
 void WaylandDataDragController::DispatchPointerRelease() {
   DCHECK(pointer_grabber_for_window_drag_);
-  pointer_delegate_->OnPointerButtonEvent(ET_MOUSE_RELEASED,
-                                          EF_LEFT_MOUSE_BUTTON,
-                                          pointer_grabber_for_window_drag_);
+  pointer_delegate_->OnPointerButtonEvent(
+      ET_MOUSE_RELEASED, EF_LEFT_MOUSE_BUTTON, pointer_grabber_for_window_drag_,
+      wl::EventDispatchPolicy::kImmediate);
   pointer_grabber_for_window_drag_ = nullptr;
 }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc
index 39c5100..5a98674 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -283,9 +283,11 @@
     std::move(closure).Run();
 }
 
-void WaylandEventSource::OnPointerButtonEvent(EventType type,
-                                              int changed_button,
-                                              WaylandWindow* window) {
+void WaylandEventSource::OnPointerButtonEvent(
+    EventType type,
+    int changed_button,
+    WaylandWindow* window,
+    wl::EventDispatchPolicy dispatch_policy) {
   DCHECK(type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED);
   DCHECK(HasAnyPointerButtonFlag(changed_button));
 
@@ -294,26 +296,43 @@
   if (window)
     window_manager_->SetPointerFocusedWindow(window);
 
+  auto closure =
+      window ? base::BindOnce(
+                   [](WaylandWindowManager* wwm, WaylandWindow* window) {
+                     wwm->SetPointerFocusedWindow(window);
+                   },
+                   window_manager_, prev_focused_window)
+             : base::NullCallback();
+
   pointer_flags_ = type == ET_MOUSE_PRESSED
                        ? (pointer_flags_ | changed_button)
                        : (pointer_flags_ & ~changed_button);
   last_pointer_button_pressed_ = changed_button;
-  // MouseEvent's flags should contain the button that was released too.
-  int flags = pointer_flags_ | keyboard_modifiers_ | changed_button;
-  MouseEvent event(type, pointer_location_, pointer_location_,
-                   EventTimeForNow(), flags, changed_button,
-                   PointerDetailsForDispatching());
 
   auto* target = window_manager_->GetCurrentPointerFocusedWindow();
   // A window may be deleted when the event arrived from the server.
-  if (target)
-    SetTargetAndDispatchEvent(&event, target);
+  if (target) {
+    // MouseEvent's flags should contain the button that was released too.
+    int flags = pointer_flags_ | keyboard_modifiers_ | changed_button;
+    MouseEvent event(type, pointer_location_, pointer_location_,
+                     EventTimeForNow(), flags, changed_button,
+                     PointerDetailsForDispatching());
+    if (dispatch_policy == wl::EventDispatchPolicy::kImmediate) {
+      SetTargetAndDispatchEvent(&event, target);
+    } else {
+      pointer_frames_.push_back(
+          std::make_unique<FrameData>(event, std::move(closure)));
+      return;
+    }
+  }
 
-  if (window)
-    window_manager_->SetPointerFocusedWindow(prev_focused_window);
+  if (!closure.is_null())
+    std::move(closure).Run();
 }
 
-void WaylandEventSource::OnPointerMotionEvent(const gfx::PointF& location) {
+void WaylandEventSource::OnPointerMotionEvent(
+    const gfx::PointF& location,
+    wl::EventDispatchPolicy dispatch_policy) {
   pointer_location_ = location;
 
   int flags = pointer_flags_ | keyboard_modifiers_;
@@ -324,7 +343,13 @@
   // A window may be deleted when the event arrived from the server.
   if (!target)
     return;
-  SetTargetAndDispatchEvent(&event, target);
+
+  if (dispatch_policy == wl::EventDispatchPolicy::kImmediate) {
+    SetTargetAndDispatchEvent(&event, target);
+  } else {
+    pointer_frames_.push_back(
+        std::make_unique<FrameData>(event, base::NullCallback()));
+  }
 }
 
 void WaylandEventSource::OnPointerAxisEvent(const gfx::Vector2dF& offset) {
@@ -623,7 +648,8 @@
   // TODO(oshima): Investigate if we need to scale the delta
   // when surface_submission_in_pixel_coordinates is on.
   relative_pointer_location_ = *relative_pointer_location_ + delta;
-  OnPointerMotionEvent(*relative_pointer_location_);
+  OnPointerMotionEvent(*relative_pointer_location_,
+                       wl::EventDispatchPolicy::kImmediate);
 }
 
 bool WaylandEventSource::IsPointerButtonPressed(EventFlags button) const {
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h
index 756b705..26f9f88 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.h
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -117,8 +117,10 @@
                              wl::EventDispatchPolicy dispatch_policy) override;
   void OnPointerButtonEvent(EventType evtype,
                             int changed_button,
-                            WaylandWindow* window = nullptr) override;
-  void OnPointerMotionEvent(const gfx::PointF& location) override;
+                            WaylandWindow* window,
+                            wl::EventDispatchPolicy dispatch_policy) override;
+  void OnPointerMotionEvent(const gfx::PointF& location,
+                            wl::EventDispatchPolicy dispatch_policy) override;
   void OnPointerAxisEvent(const gfx::Vector2dF& offset) override;
   void OnPointerFrameEvent() override;
   void OnPointerAxisSourceEvent(uint32_t axis_source) override;
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc b/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
index eeb38c1..840d300 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source_unittest.cc
@@ -92,6 +92,7 @@
   wl_pointer_send_frame(pointer_res);
   wl_pointer_send_button(pointer_res, serial++, tstamp++, BTN_LEFT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_res);
   EXPECT_CALL(delegate, DispatchEvent(_)).Times(2);
   Sync();
 
@@ -99,6 +100,7 @@
 
   wl_pointer_send_button(pointer_res, serial++, tstamp++, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_res);
   EXPECT_CALL(delegate, DispatchEvent(_)).Times(1);
   Sync();
 
@@ -106,8 +108,10 @@
 
   wl_pointer_send_button(pointer_res, serial++, tstamp++, BTN_LEFT,
                          WL_POINTER_BUTTON_STATE_RELEASED);
+  wl_pointer_send_frame(pointer_res);
   wl_pointer_send_button(pointer_res, serial++, tstamp++, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_RELEASED);
+  wl_pointer_send_frame(pointer_res);
   EXPECT_CALL(delegate, DispatchEvent(_)).Times(2);
   Sync();
 
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer.cc b/ui/ozone/platform/wayland/host/wayland_pointer.cc
index f0fa9e7..1435713 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer.cc
+++ b/ui/ozone/platform/wayland/host/wayland_pointer.cc
@@ -19,6 +19,21 @@
 
 namespace ui {
 
+namespace {
+
+// Remove this method when Compositors other than Exo comply with
+// `wl_pointer.frame`.
+wl::EventDispatchPolicy EventDispatchPolicyForPlatform() {
+  return
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+      wl::EventDispatchPolicy::kOnFrame;
+#else
+      wl::EventDispatchPolicy::kImmediate;
+#endif
+}
+
+}  // namespace
+
 WaylandPointer::WaylandPointer(wl_pointer* pointer,
                                WaylandConnection* connection,
                                Delegate* delegate)
@@ -90,7 +105,8 @@
   const WaylandWindow* target = pointer->delegate_->GetPointerTarget();
 
   pointer->delegate_->OnPointerMotionEvent(
-      pointer->connection_->MaybeConvertLocation(location, target));
+      pointer->connection_->MaybeConvertLocation(location, target),
+      EventDispatchPolicyForPlatform());
 }
 
 // static
@@ -130,7 +146,9 @@
     pointer->connection_->serial_tracker().UpdateSerial(
         wl::SerialType::kMousePress, serial);
   }
-  pointer->delegate_->OnPointerButtonEvent(type, changed_button);
+  pointer->delegate_->OnPointerButtonEvent(type, changed_button,
+                                           /*window=*/nullptr,
+                                           EventDispatchPolicyForPlatform());
 }
 
 // static
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer.h b/ui/ozone/platform/wayland/host/wayland_pointer.h
index d1789a1..1197444f 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer.h
+++ b/ui/ozone/platform/wayland/host/wayland_pointer.h
@@ -117,10 +117,14 @@
       WaylandWindow* window,
       const gfx::PointF& location,
       wl::EventDispatchPolicy dispatch_policy) = 0;
-  virtual void OnPointerButtonEvent(EventType evtype,
-                                    int changed_button,
-                                    WaylandWindow* window = nullptr) = 0;
-  virtual void OnPointerMotionEvent(const gfx::PointF& location) = 0;
+  virtual void OnPointerButtonEvent(
+      EventType evtype,
+      int changed_button,
+      WaylandWindow* window,
+      wl::EventDispatchPolicy dispatch_policy) = 0;
+  virtual void OnPointerMotionEvent(
+      const gfx::PointF& location,
+      wl::EventDispatchPolicy dispatch_policy) = 0;
   virtual void OnPointerAxisEvent(const gfx::Vector2dF& offset) = 0;
   virtual void OnPointerFrameEvent() = 0;
   virtual void OnPointerAxisSourceEvent(uint32_t axis_source) = 0;
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
index 86742d5..92c1d11 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
@@ -146,6 +146,7 @@
 
   wl_pointer_send_button(pointer_->resource(), 4, 1004, BTN_LEFT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
   EXPECT_CALL(delegate_, DispatchEvent(_)).Times(2);
   EXPECT_CALL(other_delegate, DispatchEvent(_)).Times(2);
 
@@ -161,12 +162,14 @@
 
 TEST_P(WaylandPointerTest, Motion) {
   wl_pointer_send_enter(pointer_->resource(), 1, surface_->resource(), 0, 0);
+  wl_pointer_send_frame(pointer_->resource());
   Sync();  // We're interested in checking Motion event in this test case, so
            // skip Enter event here.
 
   wl_pointer_send_motion(pointer_->resource(), 1002,
                          wl_fixed_from_double(10.75),
                          wl_fixed_from_double(20.375));
+  wl_pointer_send_frame(pointer_->resource());
 
   std::unique_ptr<Event> event;
   EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce(CloneEvent(&event));
@@ -185,8 +188,11 @@
 
 TEST_P(WaylandPointerTest, MotionDragged) {
   wl_pointer_send_enter(pointer_->resource(), 1, surface_->resource(), 0, 0);
+  wl_pointer_send_frame(pointer_->resource());
+
   wl_pointer_send_button(pointer_->resource(), 2, 1002, BTN_MIDDLE,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
 
   Sync();
 
@@ -194,6 +200,7 @@
   EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce(CloneEvent(&event));
   wl_pointer_send_motion(pointer_->resource(), 1003, wl_fixed_from_int(400),
                          wl_fixed_from_int(500));
+  wl_pointer_send_frame(pointer_->resource());
 
   Sync();
 
@@ -392,6 +399,7 @@
 
   wl_pointer_send_button(pointer_->resource(), ++serial, ++time, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
   Sync();
 
   std::unique_ptr<Event> event1, event2, event3;
@@ -447,6 +455,7 @@
 
   wl_pointer_send_button(pointer_->resource(), ++serial, ++time, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
   Sync();
 
   std::unique_ptr<Event> event1, event2, event3;
@@ -502,6 +511,7 @@
 
   wl_pointer_send_button(pointer_->resource(), ++serial, ++time, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
   Sync();
 
   std::unique_ptr<Event> event1, event2, event3, event4;
@@ -569,6 +579,7 @@
 
   wl_pointer_send_button(pointer_->resource(), ++serial, ++time, BTN_RIGHT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_->resource());
   Sync();
 
   std::unique_ptr<Event> event1, event2, event3;
diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
index 8ab5b23..c44d421 100644
--- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
@@ -641,6 +641,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(10),
                          wl_fixed_from_int(20));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
@@ -658,6 +659,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(20),
                          wl_fixed_from_int(10));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
@@ -701,6 +703,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2),
                          wl_fixed_from_int(1));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
@@ -720,6 +723,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(1912),
                          wl_fixed_from_int(1071));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
@@ -752,6 +756,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2),
                          wl_fixed_from_int(3));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
@@ -767,6 +772,7 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2),
                          wl_fixed_from_int(1));
+  wl_pointer_send_frame(pointer->resource());
 
   Sync();
 
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
index c011b05..0817c44 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -268,7 +268,8 @@
   pointer_location_ = location;
 
   if (*drag_source_ == DragSource::kMouse) {
-    pointer_delegate_->OnPointerMotionEvent(location);
+    pointer_delegate_->OnPointerMotionEvent(
+        location, wl::EventDispatchPolicy::kImmediate);
   } else {
     base::TimeTicks timestamp = base::TimeTicks::Now();
     auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
@@ -319,7 +320,8 @@
     return;
 
   if (*drag_source_ == DragSource::kMouse) {
-    pointer_delegate_->OnPointerMotionEvent({pointer_location_.x(), -1});
+    pointer_delegate_->OnPointerMotionEvent(
+        {pointer_location_.x(), -1}, wl::EventDispatchPolicy::kImmediate);
   } else {
     base::TimeTicks timestamp = base::TimeTicks::Now();
     auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
@@ -493,7 +495,8 @@
   if (*drag_source_ == DragSource::kMouse) {
     if (pointer_grab_owner_) {
       pointer_delegate_->OnPointerButtonEvent(
-          ET_MOUSE_RELEASED, EF_LEFT_MOUSE_BUTTON, pointer_grab_owner_);
+          ET_MOUSE_RELEASED, EF_LEFT_MOUSE_BUTTON, pointer_grab_owner_,
+          wl::EventDispatchPolicy::kImmediate);
     }
   } else {
     auto touch_pointer_ids = touch_delegate_->GetActiveTouchPointIds();
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
index 9c5805b..8c2e687 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
@@ -106,6 +106,7 @@
     wl_fixed_t x = wl_fixed_from_int(location.x());
     wl_fixed_t y = wl_fixed_from_int(location.y());
     wl_pointer_send_motion(pointer_->resource(), NextTime(), x, y);
+    wl_pointer_send_frame(pointer_->resource());
 
     if (!sync_and_ensure_dispatched)
       return;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
index e53eff4..145dd50 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -1468,6 +1468,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(10.75),
                          wl_fixed_from_double(20.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   Sync();
 
@@ -1491,6 +1492,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(10.75),
                          wl_fixed_from_double(20.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   Sync();
 
@@ -1501,6 +1503,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(2.75),
                          wl_fixed_from_double(8.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   EXPECT_CALL(delegate_, DispatchEvent(_)).Times(0);
   std::unique_ptr<Event> event3;
@@ -1543,6 +1546,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(2.75),
                          wl_fixed_from_double(8.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   Sync();
 
@@ -1642,6 +1646,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(10.75),
                          wl_fixed_from_double(20.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   Sync();
 
@@ -1667,6 +1672,7 @@
   wl_pointer_send_motion(server_.seat()->pointer()->resource(), 1002,
                          wl_fixed_from_double(10.75),
                          wl_fixed_from_double(20.375));
+  wl_pointer_send_frame(server_.seat()->pointer()->resource());
 
   Sync();
 
@@ -3182,6 +3188,7 @@
   wl_pointer_send_frame(pointer_resource);
   wl_pointer_send_button(pointer_resource, 4u /*serial*/, 1, BTN_LEFT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer_resource);
   EXPECT_CALL(delegate, DispatchEvent(_)).Times(2);
   Sync();
   Mock::VerifyAndClearExpectations(&delegate);
@@ -3731,12 +3738,15 @@
   wl_pointer_send_frame(pointer->resource());
   wl_pointer_send_button(pointer->resource(), 2, 1004, BTN_LEFT,
                          WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_frame(pointer->resource());
 
   int count = 0;
   EXPECT_CALL(delegate_, DispatchEvent(_)).WillRepeatedly([&](Event* event) {
     count++;
     if (event->type() == ui::ET_MOUSE_PRESSED) {
       wl_pointer_send_leave(pointer->resource(), 3, surface_->resource());
+      wl_pointer_send_frame(pointer->resource());
+
       wl_pointer_send_enter(pointer->resource(), 4, other_surface->resource(),
                             0, 0);
       wl_pointer_send_frame(pointer->resource());
diff --git a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc
index e1c390ff..704b1b4 100644
--- a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc
+++ b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc
@@ -94,6 +94,7 @@
                            : WL_POINTER_BUTTON_STATE_RELEASED;
   wl_pointer_send_button(pointer_->resource(), serial, NextTime(), button,
                          state);
+  wl_pointer_send_frame(pointer_->resource());
 }
 
 void WaylandDragDropTest::SendTouchDown(WaylandWindow* window,
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc
index d83719a..7fe38484 100644
--- a/ui/views/bubble/bubble_dialog_model_host.cc
+++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -25,6 +25,7 @@
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/controls/label.h"
+#include "ui/views/controls/scroll_view.h"
 #include "ui/views/controls/separator.h"
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/controls/textfield/textfield.h"
@@ -38,6 +39,32 @@
 namespace views {
 namespace {
 
+BubbleDialogModelHost::ContentsView* SetAndGetContentsView(
+    BubbleDialogModelHost* parent,
+    ui::ModalType modal_type) {
+  auto contents_view_unique =
+      std::make_unique<BubbleDialogModelHost::ContentsView>(parent);
+  BubbleDialogModelHost::ContentsView* contents_view =
+      contents_view_unique.get();
+
+  // TODO(crbug.com/1348165): Non modal dialogs size is not dependent on its
+  // content. Thus, the content has to be manually set by the view inside a
+  // scroll view. Modal dialogs handle their own size via constrained windows,
+  // so we can add a scroll view to the DialogModel directly.
+  if (modal_type == ui::MODAL_TYPE_NONE) {
+    parent->SetContentsView(std::move(contents_view_unique));
+  } else {
+    constexpr int kMaxDialogHeight = 448;
+    auto scroll_view = std::make_unique<views::ScrollView>();
+    scroll_view->ClipHeightTo(0, kMaxDialogHeight);
+    scroll_view->SetHorizontalScrollBarMode(
+        views::ScrollView::ScrollBarMode::kDisabled);
+    scroll_view->SetContents(std::move(contents_view_unique));
+    parent->SetContentsView(std::move(scroll_view));
+  }
+  return contents_view;
+}
+
 BubbleDialogModelHost::FieldType GetFieldTypeForField(
     ui::DialogModelField* field,
     base::PassKey<ui::DialogModelHost> pass_key) {
@@ -185,8 +212,7 @@
 // into this class. This was done in steps to limit the size of the diff.
 class BubbleDialogModelHost::ContentsView : public View {
  public:
-  ContentsView(BubbleDialogModelHost* parent, ui::DialogModel* model)
-      : parent_(parent) {
+  explicit ContentsView(BubbleDialogModelHost* parent) : parent_(parent) {
     // Note that between-child spacing is manually handled using kMarginsKey.
     SetLayoutManager(
         std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical));
@@ -306,8 +332,7 @@
     ui::ModalType modal_type)
     : BubbleDialogDelegate(anchor_view, arrow),
       model_(std::move(model)),
-      contents_view_(
-          SetContentsView(std::make_unique<ContentsView>(this, model_.get()))) {
+      contents_view_(SetAndGetContentsView(this, modal_type)) {
   model_->set_host(GetPassKey(), this);
 
   // Note that this needs to be called before IsModalDialog() is called later in
@@ -488,6 +513,10 @@
   }
 }
 
+View* BubbleDialogModelHost::GetContentsViewForTesting() {
+  return contents_view_;
+}
+
 void BubbleDialogModelHost::Close() {
   DCHECK(model_);
   DCHECK(GetWidget());
diff --git a/ui/views/bubble/bubble_dialog_model_host.h b/ui/views/bubble/bubble_dialog_model_host.h
index ec01ade..627df7d 100644
--- a/ui/views/bubble/bubble_dialog_model_host.h
+++ b/ui/views/bubble/bubble_dialog_model_host.h
@@ -33,6 +33,8 @@
  public:
   enum class FieldType { kText, kControl, kMenuItem };
 
+  class ContentsView;
+
   class VIEWS_EXPORT CustomView : public ui::DialogModelCustomField::Field {
    public:
     CustomView(std::unique_ptr<View> view, FieldType field_type);
@@ -78,12 +80,13 @@
   View* GetInitiallyFocusedView() override;
   void OnWidgetInitialized() override;
 
+  View* GetContentsViewForTesting();
+
   // ui::DialogModelHost:
   void Close() override;
   void OnFieldAdded(ui::DialogModelField* field) override;
 
  private:
-  class ContentsView;
   // TODO(pbos): Consider externalizing this functionality into a different
   // format that could feasibly be adopted by LayoutManagers. This is used for
   // BoxLayouts (but could be others) to agree on columns' preferred width as a
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 38adf29..4c8420b 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -76,14 +76,6 @@
           [ "$target_gen_dir/cr_components/certificate_manager/resources.grdp" ]
     }
 
-    # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS.
-    if (is_chromeos_ash) {
-      public_deps += [ "//third_party/polymer/v1_0:build_grdp" ]
-      grdp_files += [
-        "$root_gen_dir/third_party/polymer/v1_0/polymer_1_0_resources.grdp",
-      ]
-    }
-
     if (!is_android) {
       public_deps += [ "cr_components/history_clusters:build_grdp" ]
       grdp_files += [ "$root_gen_dir/ui/webui/resources/cr_components/history_clusters/resources.grdp" ]
@@ -164,8 +156,6 @@
 preprocessed_folder = "$target_gen_dir/preprocessed"
 
 checked_in_dts_files = [
-  "cr_elements/cr_button/cr_button.d.ts",
-  "cr_elements/cr_dialog/cr_dialog.d.ts",
   "cr_elements/cr_lottie/cr_lottie.d.ts",
   "cr_elements/cr_scrollable_behavior.d.ts",
   "cr_elements/find_shortcut_behavior.d.ts",
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn
index 5f58506..de36f40 100644
--- a/ui/webui/resources/cr_components/BUILD.gn
+++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -15,7 +15,6 @@
     "$root_gen_dir/ui/webui/resources/preprocessed/cr_components"
 if (is_chromeos_ash) {
   preprocess_gen_manifest = "preprocessed_gen_manifest.json"
-  preprocess_polymer2_manifest = "preprocessed_polymer2_manifest.json"
 }
 preprocess_src_manifest = "preprocessed_src_manifest.json"
 
@@ -65,12 +64,8 @@
   }
   manifest_files = [ "$target_gen_dir/$preprocess_src_manifest" ]
 
-  # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS.
   if (is_chromeos_ash) {
-    manifest_files += [
-      "$target_gen_dir/$preprocess_gen_manifest",
-      "$target_gen_dir/$preprocess_polymer2_manifest",
-    ]
+    manifest_files += [ "$target_gen_dir/$preprocess_gen_manifest" ]
   }
 
   resource_path_prefix = "cr_components"
@@ -84,12 +79,7 @@
   ]
 
   if (is_chromeos_ash) {
-    public_deps += [
-      ":preprocess_generated",
-
-      # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS.
-      ":preprocess_polymer2",
-    ]
+    public_deps += [ ":preprocess_generated" ]
   }
 }
 
@@ -233,151 +223,6 @@
   ]
 }
 
-if (is_chromeos_ash) {
-  preprocess_if_expr("preprocess_polymer2") {
-    in_folder = "./"
-    out_folder = "$preprocess_folder"
-    out_manifest = "$target_gen_dir/$preprocess_polymer2_manifest"
-    in_files = []
-    if (!optimize_webui) {
-      in_files += [
-        "chromeos/network/network_apnlist.html",
-        "chromeos/network/network_apnlist.js",
-        "chromeos/network/network_choose_mobile.html",
-        "chromeos/network/network_choose_mobile.js",
-        "chromeos/network/network_config.html",
-        "chromeos/network/network_config.js",
-        "chromeos/network/network_config_element_behavior.html",
-        "chromeos/network/network_config_element_behavior.js",
-        "chromeos/network/network_config_input.html",
-        "chromeos/network/network_config_input.js",
-        "chromeos/network/network_config_select.html",
-        "chromeos/network/network_config_select.js",
-        "chromeos/network/network_config_toggle.html",
-        "chromeos/network/network_config_toggle.js",
-        "chromeos/network/network_ip_config.html",
-        "chromeos/network/network_ip_config.js",
-        "chromeos/network/network_nameservers.html",
-        "chromeos/network/network_nameservers.js",
-        "chromeos/network/network_password_input.html",
-        "chromeos/network/network_password_input.js",
-        "chromeos/network/network_property_list_mojo.html",
-        "chromeos/network/network_property_list_mojo.js",
-        "chromeos/network/network_proxy.html",
-        "chromeos/network/network_proxy.js",
-        "chromeos/network/network_proxy_exclusions.html",
-        "chromeos/network/network_proxy_exclusions.js",
-        "chromeos/network/network_proxy_input.html",
-        "chromeos/network/network_proxy_input.js",
-        "chromeos/network/network_siminfo.html",
-        "chromeos/network/network_siminfo.js",
-        "chromeos/network/network_shared_css.html",
-        "chromeos/network/sim_lock_dialogs.html",
-        "chromeos/network/sim_lock_dialogs.js",
-      ]
-    }
-    in_files += [
-      "chromeos/cellular_setup/activation_code_page.html",
-      "chromeos/cellular_setup/activation_code_page.js",
-      "chromeos/cellular_setup/activation_verification_page.html",
-      "chromeos/cellular_setup/activation_verification_page.js",
-      "chromeos/cellular_setup/base_page.html",
-      "chromeos/cellular_setup/base_page.js",
-      "chromeos/cellular_setup/button_bar.html",
-      "chromeos/cellular_setup/button_bar.js",
-      "chromeos/cellular_setup/cellular_setup_delegate.html",
-      "chromeos/cellular_setup/cellular_setup_delegate.js",
-      "chromeos/cellular_setup/cellular_setup_icons.html",
-      "chromeos/cellular_setup/cellular_setup.html",
-      "chromeos/cellular_setup/cellular_setup.js",
-      "chromeos/cellular_setup/cellular_types.html",
-      "chromeos/cellular_setup/cellular_types.js",
-      "chromeos/cellular_setup/confirmation_code_page.html",
-      "chromeos/cellular_setup/confirmation_code_page.js",
-      "chromeos/cellular_setup/esim_flow_ui.html",
-      "chromeos/cellular_setup/esim_flow_ui.js",
-      "chromeos/cellular_setup/final_page.html",
-      "chromeos/cellular_setup/final_page.js",
-      "chromeos/cellular_setup/mojo_interface_provider.html",
-      "chromeos/cellular_setup/mojo_interface_provider.js",
-      "chromeos/cellular_setup/esim_manager_listener_behavior.html",
-      "chromeos/cellular_setup/esim_manager_listener_behavior.js",
-      "chromeos/cellular_setup/esim_manager_utils.html",
-      "chromeos/cellular_setup/esim_manager_utils.js",
-      "chromeos/cellular_setup/profile_discovery_list_item.html",
-      "chromeos/cellular_setup/profile_discovery_list_item.js",
-      "chromeos/cellular_setup/profile_discovery_list_page.html",
-      "chromeos/cellular_setup/profile_discovery_list_page.js",
-      "chromeos/cellular_setup/provisioning_page.html",
-      "chromeos/cellular_setup/provisioning_page.js",
-      "chromeos/cellular_setup/psim_flow_ui.html",
-      "chromeos/cellular_setup/psim_flow_ui.js",
-      "chromeos/cellular_setup/cellular_eid_dialog.html",
-      "chromeos/cellular_setup/cellular_eid_dialog.js",
-      "chromeos/cellular_setup/setup_loading_page.html",
-      "chromeos/cellular_setup/setup_loading_page.js",
-      "chromeos/cellular_setup/subflow_behavior.html",
-      "chromeos/cellular_setup/subflow_behavior.js",
-      "chromeos/cellular_setup/webview_post_util.html",
-      "chromeos/cellular_setup/webview_post_util.js",
-      "chromeos/multidevice_setup/button_bar.html",
-      "chromeos/multidevice_setup/button_bar.js",
-      "chromeos/multidevice_setup/fake_mojo_service.html",
-      "chromeos/multidevice_setup/fake_mojo_service.js",
-      "chromeos/multidevice_setup/icons.html",
-      "chromeos/multidevice_setup/mojo_api.html",
-      "chromeos/multidevice_setup/mojo_api.js",
-      "chromeos/multidevice_setup/multidevice_setup_browser_proxy.html",
-      "chromeos/multidevice_setup/multidevice_setup_browser_proxy.js",
-      "chromeos/multidevice_setup/multidevice_setup_delegate.html",
-      "chromeos/multidevice_setup/multidevice_setup_delegate.js",
-      "chromeos/multidevice_setup/multidevice_setup.html",
-      "chromeos/multidevice_setup/multidevice_setup.js",
-      "chromeos/multidevice_setup/multidevice_setup_shared_css.html",
-      "chromeos/multidevice_setup/password_page.html",
-      "chromeos/multidevice_setup/password_page.js",
-      "chromeos/multidevice_setup/setup_succeeded_page.html",
-      "chromeos/multidevice_setup/setup_succeeded_page.js",
-      "chromeos/multidevice_setup/start_setup_page.html",
-      "chromeos/multidevice_setup/start_setup_page.js",
-      "chromeos/multidevice_setup/ui_page_container_behavior.html",
-      "chromeos/multidevice_setup/ui_page_container_behavior.js",
-      "chromeos/multidevice_setup/ui_page.html",
-      "chromeos/multidevice_setup/ui_page.js",
-      "chromeos/network/cr_policy_network_behavior_mojo.html",
-      "chromeos/network/cr_policy_network_behavior_mojo.js",
-      "chromeos/network/cr_policy_network_indicator_mojo.html",
-      "chromeos/network/cr_policy_network_indicator_mojo.js",
-      "chromeos/network/mojo_interface_provider.html",
-      "chromeos/network/mojo_interface_provider.js",
-      "chromeos/network/network_icon.html",
-      "chromeos/network/network_icon.js",
-      "chromeos/network/network_icons.html",
-      "chromeos/network/network_listener_behavior.html",
-      "chromeos/network/network_listener_behavior.js",
-      "chromeos/network/cellular_utils.html",
-      "chromeos/network/cellular_utils.js",
-      "chromeos/network/network_list.html",
-      "chromeos/network/network_list_item.html",
-      "chromeos/network/network_list_item.js",
-      "chromeos/network/network_list.js",
-      "chromeos/network/network_list_types.html",
-      "chromeos/network/network_list_types.js",
-      "chromeos/network/network_select.html",
-      "chromeos/network/network_select.js",
-      "chromeos/network/onc_mojo.html",
-      "chromeos/network/onc_mojo.js",
-      "chromeos/quick_unlock/lock_screen_constants.html",
-      "chromeos/quick_unlock/lock_screen_constants.js",
-      "chromeos/quick_unlock/pin_keyboard.html",
-      "chromeos/quick_unlock/pin_keyboard_icon.html",
-      "chromeos/quick_unlock/pin_keyboard.js",
-      "chromeos/quick_unlock/setup_pin_keyboard.html",
-      "chromeos/quick_unlock/setup_pin_keyboard.js",
-    ]
-  }
-}
-
 html_to_wrapper("html_wrapper_files") {
   in_files = [
     "localized_link/localized_link.html",
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn b/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
index 8bbd671..5cb2a844 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
@@ -73,7 +73,6 @@
 js_library("bluetooth_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
@@ -82,6 +81,7 @@
         "$externs_path/bluetooth.js",
         "$externs_path/bluetooth_private.js",
         "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+        "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
       ]
   extra_sources = [
     "$interfaces_path/bluetooth_interface.js",
@@ -145,9 +145,10 @@
   deps = [
     ":bluetooth_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
 }
 
 js_library("bluetooth_battery_icon_percentage") {
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js
index 16f5a6a8..d7aff52 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_base_page.js
@@ -10,10 +10,10 @@
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
 import {afterNextRender, html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
 
 import {assertNotReached} from '../../../js/assert.m.js';
 import {focusWithoutInk} from '../../../js/cr/ui/focus_without_ink.m.js';
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_dialog.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_dialog.js
index 3ecd1a8..9e6942d2 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_dialog.js
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_dialog.js
@@ -10,6 +10,7 @@
  */
 
 import '../../../cr_elements/cr_button/cr_button.js';
+import '../../../cr_elements/cr_dialog/cr_dialog.js';
 import '../../../cr_elements/cr_input/cr_input.js';
 import '../../../cr_elements/hidden_style_css.m.js';
 import '../../../js/cr.m.js';
@@ -18,7 +19,6 @@
 
 import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {CrDialogElement} from '../../../cr_elements/cr_dialog/cr_dialog.js';
 import {assert} from '../../../js/assert.m.js';
 import {I18nBehavior} from '../../../js/i18n_behavior.m.js';
 
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
index 03e1ce1..b4f66d66 100644
--- a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -84,14 +84,16 @@
     ":network_shared_css.m",
     ":onc_mojo.m",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/cr_elements/policy:cr_tooltip_icon",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
   extra_deps = [ ":network_apnlist_module" ]
-  externs_list = [ "$externs_path/metrics_private.js" ]
+  externs_list = [
+    "$externs_path/metrics_private.js",
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+  ]
 }
 
 js_library("network_choose_mobile.m") {
@@ -101,9 +103,10 @@
     "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile",
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
+  externs_list =
+      [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ]
   extra_deps = [ ":network_choose_mobile_module" ]
 }
 
@@ -122,13 +125,14 @@
     "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon",
     "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js",
+  ]
   extra_deps = [ ":network_config_module" ]
 }
 
@@ -306,11 +310,11 @@
     ":onc_mojo.m",
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
   externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
     "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
     "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js",
   ]
@@ -374,13 +378,14 @@
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior",
     "//ui/webui/resources/js/cr/ui:focus_without_ink.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js",
+  ]
   extra_deps = [ ":network_siminfo_module" ]
 }
 
@@ -413,12 +418,13 @@
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js",
+  ]
   extra_deps = [ ":sim_lock_dialogs_module" ]
 }
 
@@ -622,7 +628,7 @@
   js_file = "network_siminfo.js"
   html_file = "network_siminfo.html"
   html_type = "dom-module"
-  auto_imports = cr_components_chromeos_auto_imports + [ "ui/webui/resources/cr_elements/cr_button/cr_button.html|CrButtonElement" ]
+  auto_imports = cr_components_chromeos_auto_imports
   migrated_imports = cr_components_migrated_imports
   namespace_rewrites = cr_components_chromeos_namespace_rewrites
 }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
index dcb50bf..a9a9d9b 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
@@ -93,7 +93,7 @@
         </cr-radio-button>
         <template is="dom-if" if="[[showNameservers_(nameserversType_,
             nameserversTypeEnum_.GOOGLE, nameservers_)]]">
-          <div class="nameservers" changeable>
+          <div class="nameservers" changeable$="[[canChangeConfigType_]]">
             [[getNameserversString_(nameservers_)]]
           </div>
         </template>
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/OWNERS b/ui/webui/resources/cr_components/chromeos/quick_unlock/OWNERS
index b71a219..9f19c27 100644
--- a/ui/webui/resources/cr_components/chromeos/quick_unlock/OWNERS
+++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/OWNERS
@@ -2,4 +2,4 @@
 alemate@chromium.org
 
 # (in CET)
-rsorokin@chromium.org
+rsorokin@google.com
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.html b/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.html
index a72ca2c..84238eb 100644
--- a/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.html
+++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.html
@@ -1,7 +1,6 @@
 <link rel="import" href="../../../html/polymer.html">
 
 <link rel="import" href="lock_screen_constants.html">
-<link rel="import" href="../../../cr_elements/cr_dialog/cr_dialog.html">
 <link rel="import" href="../../../cr_elements/shared_vars_css.html">
 <link rel="import" href="../../../html/assert.html">
 <link rel="import" href="../../../html/i18n_behavior.html">
diff --git a/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn b/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn
index 6c8517cf..9bd61da 100644
--- a/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn
@@ -18,15 +18,17 @@
 js_library("add_smb_share_dialog") {
   deps = [
     ":smb_browser_proxy",
-    "//ui/webui/resources/cr_elements/cr_button:cr_button",
-    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  externs_list =
-      [ "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js" ]
+  externs_list = [
+    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
+    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
+  ]
 }
 
 js_library("smb_browser_proxy") {
diff --git a/ui/webui/resources/cr_components/managed_footnote/managed_footnote.html b/ui/webui/resources/cr_components/managed_footnote/managed_footnote.html
index 6b06173..d43dd0e 100644
--- a/ui/webui/resources/cr_components/managed_footnote/managed_footnote.html
+++ b/ui/webui/resources/cr_components/managed_footnote/managed_footnote.html
@@ -16,7 +16,6 @@
 
       a[href] {
         color: var(--cr-link-color);
-        text-decoration: none;
       }
 
       iron-icon {
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 4952e51..5eed86c 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -87,8 +87,6 @@
     out_folder = preprocess_folder
     out_manifest = "$target_gen_dir/$preprocess_gen_manifest"
     in_files = [
-      "cr_button/cr_button.js",
-      "cr_dialog/cr_dialog.js",
       "cr_icons_css.m.js",
       "cr_lottie/cr_lottie.js",
       "hidden_style_css.m.js",
@@ -111,8 +109,6 @@
     deps = [
       # Targets for auto-generated Polymer 3 JS Modules
       ":cr_elements_module_resources",
-      "cr_button:closure_compile_module",
-      "cr_dialog:closure_compile_module",
       "cr_lottie:closure_compile_module",
       "policy:closure_compile_module",
     ]
@@ -160,8 +156,6 @@
       ":icons_module",
       ":shared_style_css_module",
       ":shared_vars_css_module",
-      "cr_button:web_components",
-      "cr_dialog:web_components",
       "cr_lottie:web_components",
       "policy:web_components",
     ]
diff --git a/ui/webui/resources/cr_elements/action_link.css b/ui/webui/resources/cr_elements/action_link.css
index 73a52397..d8a23b4 100644
--- a/ui/webui/resources/cr_elements/action_link.css
+++ b/ui/webui/resources/cr_elements/action_link.css
@@ -11,7 +11,7 @@
 [is='action-link'] {
   cursor: pointer;
   display: inline-block;
-  text-decoration: none;
+  text-decoration: underline;
 }
 
 [is='action-link'],
diff --git a/ui/webui/resources/cr_elements/cr_button/BUILD.gn b/ui/webui/resources/cr_elements/cr_button/BUILD.gn
deleted file mode 100644
index c04be21a..0000000
--- a/ui/webui/resources/cr_elements/cr_button/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
-
-html_to_js("web_components") {
-  js_files = [ "cr_button.js" ]
-}
-
-js_type_check("closure_compile_module") {
-  is_polymer3 = true
-  deps = [ ":cr_button" ]
-}
-
-js_library("cr_button") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js/cr/ui:focus_outline_manager.m",
-  ]
-}
diff --git a/ui/webui/resources/cr_elements/cr_button/cr_button.d.ts b/ui/webui/resources/cr_elements/cr_button/cr_button.d.ts
deleted file mode 100644
index b2fd849..0000000
--- a/ui/webui/resources/cr_elements/cr_button/cr_button.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-interface CrButtonElement extends PolymerElement {
-  disabled: boolean;
-  customTabIndex: number|null|undefined;
-  hostAttributes: object|null;
-}
-
-export {CrButtonElement};
-
-declare global {
-  interface HTMLElementTagNameMap {
-    'cr-button': CrButtonElement;
-  }
-}
diff --git a/ui/webui/resources/cr_elements/cr_button/cr_button.js b/ui/webui/resources/cr_elements/cr_button/cr_button.ts
similarity index 67%
rename from ui/webui/resources/cr_elements/cr_button/cr_button.js
rename to ui/webui/resources/cr_elements/cr_button/cr_button.ts
index bebeafec..0d5f197 100644
--- a/ui/webui/resources/cr_elements/cr_button/cr_button.js
+++ b/ui/webui/resources/cr_elements/cr_button/cr_button.ts
@@ -12,34 +12,24 @@
 import '../shared_vars_css.m.js';
 
 import {PaperRippleBehavior} from '//resources/polymer/v3_0/paper-behaviors/paper-ripple-behavior.js';
-import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {FocusOutlineManager} from '../../js/cr/ui/focus_outline_manager.m.js';
 
-/** @interface */
-class PaperRippleBehaviorInterface {
-  /** @return {Element} */
-  getRipple() {}
+import {getTemplate} from './cr_button.html.js';
 
-  ensureRipple() {}
-}
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {PaperRippleBehaviorInterface}
- */
 const CrButtonElementBase =
-    mixinBehaviors([PaperRippleBehavior], PolymerElement);
+    mixinBehaviors([PaperRippleBehavior], PolymerElement) as {
+      new (): PolymerElement & PaperRippleBehavior,
+    };
 
-/** @polymer */
 export class CrButtonElement extends CrButtonElementBase {
   static get is() {
     return 'cr-button';
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
@@ -70,36 +60,34 @@
     };
   }
 
+  disabled: boolean;
+  customTabIndex: number;
+  circleRipple: boolean;
+
+  /**
+   * It is possible to activate a tab when the space key is pressed down. When
+   * this element has focus, the keyup event for the space key should not
+   * perform a 'click'. |spaceKeyDown_| tracks when a space pressed and
+   * handled by this element. Space keyup will only result in a 'click' when
+   * |spaceKeyDown_| is true. |spaceKeyDown_| is set to false when element
+   * loses focus.
+   */
+  private spaceKeyDown_: boolean = false;
+  private timeoutIds_: Set<number> = new Set();
+
   constructor() {
     super();
 
-    /**
-     * It is possible to activate a tab when the space key is pressed down. When
-     * this element has focus, the keyup event for the space key should not
-     * perform a 'click'. |spaceKeyDown_| tracks when a space pressed and
-     * handled by this element. Space keyup will only result in a 'click' when
-     * |spaceKeyDown_| is true. |spaceKeyDown_| is set to false when element
-     * loses focus.
-     * @private {boolean}
-     */
-    this.spaceKeyDown_ = false;
-
-    /** @private {Set<number>} */
-    this.timeoutIds_ = null;
-
     this.addEventListener('blur', this.onBlur_.bind(this));
     // Must be added in constructor so that stopImmediatePropagation() works as
     // expected.
     this.addEventListener('click', this.onClick_.bind(this));
-    this.addEventListener(
-        'keydown', e => this.onKeyDown_(/** @type {!KeyboardEvent} */ (e)));
-    this.addEventListener(
-        'keyup', e => this.onKeyUp_(/** @type {!KeyboardEvent} */ (e)));
+    this.addEventListener('keydown', this.onKeyDown_.bind(this));
+    this.addEventListener('keyup', this.onKeyUp_.bind(this));
     this.addEventListener('pointerdown', this.onPointerDown_.bind(this));
   }
 
-  /** @override */
-  ready() {
+  override ready() {
     super.ready();
     if (!this.hasAttribute('role')) {
       this.setAttribute('role', 'button');
@@ -108,26 +96,19 @@
       this.setAttribute('tabindex', '0');
     }
     if (!this.hasAttribute('aria-disabled')) {
-      this.setAttribute('aria-disabled', 'false');
+      this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
     }
 
     FocusOutlineManager.forDocument(document);
-    this.timeoutIds_ = new Set();
   }
 
-  /** @override */
-  disconnectedCallback() {
+  override disconnectedCallback() {
     super.disconnectedCallback();
     this.timeoutIds_.forEach(clearTimeout);
     this.timeoutIds_.clear();
   }
 
-  /**
-   * @param {!Function} fn
-   * @param {number=} delay
-   * @private
-   */
-  setTimeout_(fn, delay) {
+  private setTimeout_(fn: () => void, delay?: number) {
     if (!this.isConnected) {
       return;
     }
@@ -138,12 +119,7 @@
     this.timeoutIds_.add(id);
   }
 
-  /**
-   * @param {boolean} newValue
-   * @param {boolean|undefined} oldValue
-   * @private
-   */
-  disabledChanged_(newValue, oldValue) {
+  private disabledChanged_(newValue: boolean, oldValue: boolean|undefined) {
     if (!newValue && oldValue === undefined) {
       return;
     }
@@ -156,9 +132,8 @@
 
   /**
    * Updates the tabindex HTML attribute to the actual value.
-   * @private
    */
-  applyTabIndex_() {
+  private applyTabIndex_() {
     let value = this.customTabIndex;
     if (value === undefined) {
       value = this.disabled ? -1 : 0;
@@ -166,26 +141,17 @@
     this.setAttribute('tabindex', value.toString());
   }
 
-  /** @private */
-  onBlur_() {
+  private onBlur_() {
     this.spaceKeyDown_ = false;
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onClick_(e) {
+  private onClick_(e: Event) {
     if (this.disabled) {
       e.stopImmediatePropagation();
     }
   }
 
-  /**
-   * @param {!KeyboardEvent} e
-   * @private
-   */
-  onKeyDown_(e) {
+  private onKeyDown_(e: KeyboardEvent) {
     if (e.key !== ' ' && e.key !== 'Enter') {
       return;
     }
@@ -208,11 +174,7 @@
     }
   }
 
-  /**
-   * @param {!KeyboardEvent} e
-   * @private
-   */
-  onKeyUp_(e) {
+  private onKeyUp_(e: KeyboardEvent) {
     if (e.key !== ' ' && e.key !== 'Enter') {
       return;
     }
@@ -227,17 +189,16 @@
     }
   }
 
-  /** @private */
-  onPointerDown_() {
+  private onPointerDown_() {
     this.ensureRipple();
   }
 
   /**
    * Customize the element's ripple. Overriding the '_createRipple' function
    * from PaperRippleBehavior.
-   * @return {PaperRippleElement}
    */
-  _createRipple() {
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
+  override _createRipple() {
     const ripple = super._createRipple();
 
     if (this.circleRipple) {
@@ -249,4 +210,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'cr-button': CrButtonElement;
+  }
+}
+
 customElements.define(CrButtonElement.is, CrButtonElement);
diff --git a/ui/webui/resources/cr_elements/cr_button/cr_button_externs.js b/ui/webui/resources/cr_elements/cr_button/cr_button_externs.js
new file mode 100644
index 0000000..a6d64bd
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_button/cr_button_externs.js
@@ -0,0 +1,17 @@
+// 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.
+
+/* Minimal externs file provided for places in the code that
+ * still use JavaScript instead of TypeScript.
+ * @externs
+ */
+
+/**
+ * @constructor
+ * @extends {HTMLElement}
+ */
+function CrButtonElement() {}
+
+/** @type {boolean} */
+CrButtonElement.prototype.disabled;
diff --git a/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn b/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
deleted file mode 100644
index 5efc5d3..0000000
--- a/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
-
-html_to_js("web_components") {
-  js_files = [ "cr_dialog.js" ]
-}
-
-js_type_check("closure_compile_module") {
-  is_polymer3 = true
-  deps = [ ":cr_dialog" ]
-}
-
-js_library("cr_dialog") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js:assert.m",
-  ]
-}
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.d.ts b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.d.ts
deleted file mode 100644
index 6f4938c3..0000000
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.d.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-interface CrDialogElement extends HTMLElement {
-  open: boolean;
-  closeText: string|null|undefined;
-  ignorePopstate: boolean;
-  ignoreEnterKey: boolean;
-  consumeKeydownEvent: boolean;
-  noCancel: boolean;
-  showCloseButton: boolean;
-  showOnAttach: boolean;
-  showModal(): void;
-  cancel(): void;
-  close(): void;
-  setTitleAriaLabel(title: string): void;
-  getNative(): HTMLDialogElement;
-  focus(): void;
-
-  $: {
-    close: HTMLElement,
-  };
-}
-
-export {CrDialogElement};
-
-declare global {
-  interface HTMLElementTagNameMap {
-    'cr-dialog': CrDialogElement;
-  }
-}
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.ts
similarity index 78%
rename from ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
rename to ui/webui/resources/cr_elements/cr_dialog/cr_dialog.ts
index 19c9097..1f7c2aa 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.ts
@@ -24,33 +24,31 @@
 import '../hidden_style_css.m.js';
 import '../shared_vars_css.m.js';
 
-import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {assert} from '../../js/assert.m.js';
+import {assert} from '../../js/assert_ts.js';
 import {CrContainerShadowMixin} from '../cr_container_shadow_mixin.js';
+import {CrIconButtonElement} from '../cr_icon_button/cr_icon_button.js';
+import {CrInputElement} from '../cr_input/cr_input.js';
 
-class CrContainerShadowMixinInterface {
-  /** @param {boolean} enable */
-  enableShadowBehavior(enable) {}
+import {getTemplate} from './cr_dialog.html.js';
 
-  showDropShadows() {}
-}
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {CrContainerShadowMixinInterface}
- */
 const CrDialogElementBase = CrContainerShadowMixin(PolymerElement);
 
-/** @polymer */
+export interface CrDialogElement {
+  $: {
+    close: CrIconButtonElement,
+    dialog: HTMLDialogElement,
+  };
+}
+
 export class CrDialogElement extends CrDialogElementBase {
   static get is() {
     return 'cr-dialog';
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
@@ -115,43 +113,39 @@
     };
   }
 
-  constructor() {
-    super();
+  closeText: string;
+  consumeKeydownEvent: boolean;
+  ignoreEnterKey: boolean;
+  ignorePopstate: boolean;
+  noCancel: boolean;
+  open: boolean;
+  showCloseButton: boolean;
+  showOnAttach: boolean;
 
-    /** @private {?IntersectionObserver} */
-    this.intersectionObserver_ = null;
+  private intersectionObserver_: IntersectionObserver|null = null;
+  private mutationObserver_: MutationObserver|null = null;
+  private boundKeydown_: ((e: KeyboardEvent) => void)|null = null;
 
-    /** @private {?MutationObserver} */
-    this.mutationObserver_ = null;
-
-    /** @private {?Function} */
-    this.boundKeydown_ = null;
-  }
-
-  /** @override */
-  ready() {
+  override ready() {
     super.ready();
 
     // If the active history entry changes (i.e. user clicks back button),
     // all open dialogs should be cancelled.
-    window.addEventListener('popstate', function() {
+    window.addEventListener('popstate', () => {
       if (!this.ignorePopstate && this.$.dialog.open) {
         this.cancel();
       }
-    }.bind(this));
+    });
 
     if (!this.ignoreEnterKey) {
       this.addEventListener('keypress', this.onKeypress_.bind(this));
     }
-    this.addEventListener(
-        'pointerdown',
-        e => this.onPointerdown_(/** @type {!PointerEvent} */ (e)));
+    this.addEventListener('pointerdown', e => this.onPointerdown_(e));
   }
 
-  /** @override */
-  connectedCallback() {
+  override connectedCallback() {
     super.connectedCallback();
-    const mutationObserverCallback = function() {
+    const mutationObserverCallback = () => {
       if (this.$.dialog.open) {
         this.enableShadowBehavior(true);
         this.addKeydownListener_();
@@ -159,7 +153,7 @@
         this.enableShadowBehavior(false);
         this.removeKeydownListener_();
       }
-    }.bind(this);
+    };
 
     this.mutationObserver_ = new MutationObserver(mutationObserverCallback);
 
@@ -175,8 +169,7 @@
     }
   }
 
-  /** @override */
-  disconnectedCallback() {
+  override disconnectedCallback() {
     super.disconnectedCallback();
     this.removeKeydownListener_();
     if (this.mutationObserver_) {
@@ -185,8 +178,7 @@
     }
   }
 
-  /** @private */
-  addKeydownListener_() {
+  private addKeydownListener_() {
     if (!this.consumeKeydownEvent) {
       return;
     }
@@ -201,8 +193,7 @@
     document.body.addEventListener('keydown', this.boundKeydown_);
   }
 
-  /** @private */
-  removeKeydownListener_() {
+  private removeKeydownListener_() {
     if (!this.boundKeydown_) {
       return;
     }
@@ -236,28 +227,20 @@
 
   /**
    * Set the title of the dialog for a11y reader.
-   * @param {string} title Title of the dialog.
+   * @param title Title of the dialog.
    */
-  setTitleAriaLabel(title) {
+  setTitleAriaLabel(title: string) {
     this.$.dialog.removeAttribute('aria-labelledby');
     this.$.dialog.setAttribute('aria-label', title);
   }
 
-  /**
-   * @private
-   * @param {Event} e
-   */
-  onCloseKeypress_(e) {
+  private onCloseKeypress_(e: Event) {
     // Because the dialog may have a default Enter key handler, prevent
     // keypress events from bubbling up from this element.
     e.stopPropagation();
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onNativeDialogClose_(e) {
+  private onNativeDialogClose_(e: Event) {
     // Ignore any 'close' events not fired directly by the <dialog> element.
     if (e.target !== this.getNative()) {
       return;
@@ -269,11 +252,7 @@
         new CustomEvent('close', {bubbles: true, composed: true}));
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onNativeDialogCancel_(e) {
+  private onNativeDialogCancel_(e: Event) {
     // Ignore any 'cancel' events not fired directly by the <dialog> element.
     if (e.target !== this.getNative()) {
       return;
@@ -298,17 +277,12 @@
    * Expose the inner native <dialog> for some rare cases where it needs to be
    * directly accessed (for example to programmatically setheight/width, which
    * would not work on the wrapper).
-   * @return {!HTMLDialogElement}
    */
-  getNative() {
-    return /** @type {!HTMLDialogElement} */ (this.$.dialog);
+  getNative(): HTMLDialogElement {
+    return this.$.dialog;
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onKeypress_(e) {
+  private onKeypress_(e: KeyboardEvent) {
     if (e.key !== 'Enter') {
       return;
     }
@@ -320,23 +294,20 @@
     // trigger searching.
     const accept = e.target === this ||
         e.composedPath().some(
-            el => el.tagName === 'CR-INPUT' && el.type !== 'search');
+            el => (el as HTMLElement).tagName === 'CR-INPUT' &&
+                (el as CrInputElement).type !== 'search');
     if (!accept) {
       return;
     }
-    const actionButton =
-        this.querySelector('.action-button:not([disabled]):not([hidden])');
+    const actionButton = this.querySelector<HTMLElement>(
+        '.action-button:not([disabled]):not([hidden])');
     if (actionButton) {
       actionButton.click();
       e.preventDefault();
     }
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onKeydown_(e) {
+  private onKeydown_(e: KeyboardEvent) {
     assert(this.consumeKeydownEvent);
 
     if (!this.getNative().open) {
@@ -351,11 +322,11 @@
     e.stopPropagation();
   }
 
-  /** @param {!PointerEvent} e */
-  onPointerdown_(e) {
+  private onPointerdown_(e: PointerEvent) {
     // Only show pulse animation if user left-clicked outside of the dialog
     // contents.
-    if (e.button !== 0 || e.composedPath()[0].tagName !== 'DIALOG') {
+    if (e.button !== 0 ||
+        (e.composedPath()[0]! as HTMLElement).tagName !== 'DIALOG') {
       return;
     }
 
@@ -366,19 +337,28 @@
           {transform: 'scale(1.02)', offset: 0.6},
           {transform: 'scale(1)', offset: 1},
         ],
-        /** @type {!KeyframeAnimationOptions} */ ({
+        {
           duration: 180,
           easing: 'ease-in-out',
           iterations: 1,
-        }));
+        });
 
     // Prevent any text from being selected within the dialog when clicking in
     // the backdrop area.
     e.preventDefault();
   }
 
-  focus() {
-    this.shadowRoot.querySelector('.title-container').focus();
+  override focus() {
+    const titleContainer =
+        this.shadowRoot!.querySelector<HTMLElement>('.title-container');
+    assert(titleContainer);
+    titleContainer.focus();
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'cr-dialog': CrDialogElement;
   }
 }
 
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js
new file mode 100644
index 0000000..024ce1c6
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js
@@ -0,0 +1,26 @@
+// 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.
+
+/* Minimal externs file provided for places in the code that
+ * still use JavaScript instead of TypeScript.
+ * @externs
+ */
+
+/**
+ * @constructor
+ * @extends {HTMLElement}
+ */
+function CrDialogElement() {}
+
+/** @type {boolean} */
+CrDialogElement.prototype.open;
+
+CrDialogElement.prototype.showModal = function() {};
+
+CrDialogElement.prototype.cancel = function() {};
+
+CrDialogElement.prototype.close = function() {};
+
+/** @return {HTMLDialogElement} */
+CrDialogElement.prototype.getNative = function() {};
diff --git a/ui/webui/resources/cr_elements/cr_elements.gni b/ui/webui/resources/cr_elements/cr_elements.gni
index 0e30efc5..1526eab 100644
--- a/ui/webui/resources/cr_elements/cr_elements.gni
+++ b/ui/webui/resources/cr_elements/cr_elements.gni
@@ -30,7 +30,9 @@
   web_component_files_polymer_ts = [
     "cr_a11y_announcer/cr_a11y_announcer.ts",
     "cr_action_menu/cr_action_menu.ts",
+    "cr_button/cr_button.ts",
     "cr_checkbox/cr_checkbox.ts",
+    "cr_dialog/cr_dialog.ts",
     "cr_drawer/cr_drawer.ts",
     "cr_expand_button/cr_expand_button.ts",
     "cr_fingerprint/cr_fingerprint_progress_arc.ts",
diff --git a/ui/webui/resources/cr_elements/cr_nav_menu_item_style.css b/ui/webui/resources/cr_elements/cr_nav_menu_item_style.css
index 09be145e..af3b95d 100644
--- a/ui/webui/resources/cr_elements/cr_nav_menu_item_style.css
+++ b/ui/webui/resources/cr_elements/cr_nav_menu_item_style.css
@@ -25,6 +25,7 @@
   padding-block-start: 10px;
   padding-inline-start: 23px;
   position: relative;
+  text-decoration: none;
 }
 
 :host-context(cr-drawer) .cr-nav-menu-item {
diff --git a/weblayer/browser/proxying_url_loader_factory_impl.cc b/weblayer/browser/proxying_url_loader_factory_impl.cc
index 9cece1d..2fbf4e56 100644
--- a/weblayer/browser/proxying_url_loader_factory_impl.cc
+++ b/weblayer/browser/proxying_url_loader_factory_impl.cc
@@ -54,7 +54,8 @@
     return;
   }
 
-  client->OnReceiveResponse(std::move(response_head), std::move(consumer));
+  client->OnReceiveResponse(std::move(response_head), std::move(consumer),
+                            absl::nullopt);
 
   auto write_data = std::make_unique<WriteData>();
   write_data->client = std::move(client);