diff --git a/DEPS b/DEPS
index aedec9266..3b96694 100644
--- a/DEPS
+++ b/DEPS
@@ -271,15 +271,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': '791f4bcf3e388985d4bc90098a0df1242ba447ac',
+  'skia_revision': '8ad30fcbbe5ad4580ed8622ecc43cb89028dd46b',
   # 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': '17e7ead78176c125d210a0b63ab10dac0e0b41a3',
+  'v8_revision': '67a98573f48ed6402a58cea94687156fc0d62169',
   # 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': '9e0a7be6c9525b88587cd282920cfa2e00820807',
+  'angle_revision': 'cd48eedd9d9f689d6f78d59d7e9fee12f75deea7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -342,7 +342,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': '31caa70cfcb274182dc2e3c38086596655f9b08a',
+  'catapult_revision': '53943c0ef6f4328c70a83a0ec300e1fed77d2e7f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -350,7 +350,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': '8598178da6e22bf10f1b380ad6db5288914899a6',
+  'devtools_frontend_revision': '235544c629c5871cd4aaa37dff1bfa8058500519',
   # 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.
@@ -581,7 +581,7 @@
       'packages': [
           {
               'package': 'chromium/android_webview/tools/cts_archive',
-              'version': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'version': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
           },
       ],
       'condition': 'checkout_android',
@@ -916,7 +916,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '8nZar3DjrekVfqxGUS1BNrpYOi0G3KbQGMPKXZnsPfoC',
+          'version': 'BobEGaocUi64wlQHOALXRWncSh4kcaTyvSebOlg8yysC',
       },
     ],
     'condition': 'checkout_android',
@@ -1135,7 +1135,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '98ed2d205fbc588066199f319c68df2fdfaab3d1',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '26a1d24c04f7a911bebef82ba392a1fc8d6544f3',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1515,7 +1515,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + 'd3187ee254f2f7e7214074aefd9d2cc1b14f97e2',
+    Var('chromium_git') + '/openscreen' + '@' + '8803ea4ea78c8151948be1dcca4e51eb84ad5732',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1532,7 +1532,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '3aded8458ec316b21ef66cc9afd274ca2e4a604b',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b146e432cba8ac3c886a671169f1677519389ab2',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1707,7 +1707,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9618103c4aa25ea342ddad65848ff8bb0c1cee9a',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'f71315c480f9450ad2bb14a068b38fd47b23c8d8',
+    Var('webrtc_git') + '/src.git' + '@' + '794c54faf04fdc369329664f58460cbe9f1b3748',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1780,7 +1780,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0e156c81f10cb21f022b2efa5943bd4b748a5243',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@38f3838299391cccc87ce54c48b30245f694f0dd',
     'condition': 'checkout_src_internal',
   },
 
@@ -1832,7 +1832,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'LmSSJqjR5Vm1KHfkGZFFVnw5ntNeKIU5LcxHqcFlF_YC',
+        'version': 'LcIMSrJ-SNJDvxx6cpk60HCbRkAwTqVTYGJpoXw9k8kC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc
index 6e81df98..e02d026 100644
--- a/android_webview/common/aw_switches.cc
+++ b/android_webview/common/aw_switches.cc
@@ -82,4 +82,7 @@
 // PrivacySandboxAdsAPIsOverride and SharedStorageAPI.
 const char kWebViewShadowDOMFencedFrames[] = "webview-shadow-dom-fenced-frames";
 
+// Enables WebView to check for app recovery mitigations.
+const char kWebViewEnableAppRecovery[] = "webview-enable-app-recovery";
+
 }  // namespace switches
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h
index 25e3766e..a2ce64c 100644
--- a/android_webview/common/aw_switches.h
+++ b/android_webview/common/aw_switches.h
@@ -24,6 +24,7 @@
 extern const char kWebViewSelectiveImageInversionDarkening[];
 extern const char kWebViewMPArchFencedFrames[];
 extern const char kWebViewShadowDOMFencedFrames[];
+extern const char kWebViewEnableAppRecovery[];
 
 }  // namespace switches
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 4c5b393..a9a01e4 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -105,6 +105,8 @@
             Flag.commandLine(AwSwitches.WEBVIEW_SHADOW_DOM_FENCED_FRAMES,
                     "Enables ShadowDOM-based fenced frames. Also implies SharedStorageAPI, "
                             + "and PrivacySandboxAdsAPIsOverride"),
+            Flag.commandLine(AwSwitches.WEBVIEW_ENABLE_APP_RECOVERY,
+                    "Enables WebView to check for app recovery mitigations."),
             Flag.baseFeature(GpuFeatures.WEBVIEW_VULKAN,
                     "Use Vulkan for composite. Requires Android device and OS support. May crash "
                             + "if enabled on unsupported device."),
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/devui/FlagsFragmentTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/FlagsFragmentTest.java
index 49214dac..313a098 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/devui/FlagsFragmentTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/FlagsFragmentTest.java
@@ -224,6 +224,21 @@
     @Test
     @MediumTest
     @Feature({"AndroidWebView"})
+    public void testSearchMatchingNameAndDescriptionWithIndividualWordsInQuery() throws Throwable {
+        CallbackHelper helper = getFlagUiSearchBarListener();
+
+        int searchBarChangeCount = helper.getCallCount();
+        // The "verbose" part matches the name, and the "logcat" part matches the description.
+        onView(withId(R.id.flag_search_bar)).perform(replaceText("verbose logcat"));
+        helper.waitForCallback(searchBarChangeCount, 1);
+        onView(allOf(withId(R.id.flag_name), withText(AwSwitches.WEBVIEW_VERBOSE_LOGGING)))
+                .check(matches(isDisplayed()));
+        onView(withId(R.id.flags_list)).check(matches(withCount(1)));
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"AndroidWebView"})
     public void testCaseInsensitive() throws Throwable {
         CallbackHelper helper = getFlagUiSearchBarListener();
 
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
index 8b375cb..eeade00 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
@@ -324,15 +324,14 @@
             return false;
         }
 
-        // Match if the flag name contains the query as a substring (case-insensitive)
+        // Split the query into words, and look for each word in either the name or the description,
+        // matching case insensitively.
         String lowerCaseName = flag.getName().toLowerCase(Locale.getDefault());
-        if (lowerCaseName.contains(lowerCaseQuery)) return true;
-
-        // Or if the flag description contains the query as a substring (case-insensitive)
         String lowerCaseDescription = flag.getDescription().toLowerCase(Locale.getDefault());
-        if (lowerCaseDescription.contains(lowerCaseQuery)) return true;
-
-        return false;
+        for (String word : lowerCaseQuery.split("\\s+")) {
+            if (!lowerCaseName.contains(word) && !lowerCaseDescription.contains(word)) return false;
+        }
+        return true;
     }
 
     /**
diff --git a/android_webview/tools/cts_config/README.md b/android_webview/tools/cts_config/README.md
index 4d77993..c7130472 100644
--- a/android_webview/tools/cts_config/README.md
+++ b/android_webview/tools/cts_config/README.md
@@ -25,7 +25,18 @@
         {
           "apk": "location of the test apk in the cts zip file",
           "additional_apks": [
-            "<optional list of additional apks that need to be installed for the test to run>"
+            // optional list of additional apks that need to be installed
+            // for the test to run
+            {
+              "apk": "location of the additional apk in the cts zip file",
+            },
+            {
+              "apk": "location of the additional apk in the cts zip file",
+              // An optional boolean flag to indicate if the APK should
+              // be queryable by other APKs
+              // Only usable from Android 11+
+              "forced_queryable": true
+            }
           ]
         },
         {
diff --git a/android_webview/tools/cts_config/webview_cts_gcs_path.json b/android_webview/tools/cts_config/webview_cts_gcs_path.json
index d790da9..e0a6897 100644
--- a/android_webview/tools/cts_config/webview_cts_gcs_path.json
+++ b/android_webview/tools/cts_config/webview_cts_gcs_path.json
@@ -98,8 +98,12 @@
         "apk": "android-cts/repository/testcases/CtsAssistTestCases.apk",
         "voice_service": "android.assist.service/.MainInteractionService",
         "additional_apks": [
-          "android-cts/repository/testcases/CtsAssistApp.apk",
-          "android-cts/repository/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/repository/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/repository/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
@@ -148,8 +152,12 @@
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "voice_service": "android.assist.service/.MainInteractionService",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
@@ -183,8 +191,12 @@
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "voice_service": "android.assist.service/.MainInteractionService",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
@@ -229,8 +241,12 @@
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "voice_service": "android.assist.service/.MainInteractionService",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
@@ -298,8 +314,12 @@
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "voice_service": "android.assist.service/.MainInteractionService",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
@@ -366,14 +386,32 @@
       {
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
             "match": "android.assist.cts.WebViewTest#testWebView"
           }
         ]
+      },
+      {
+        "apk": "android-cts/testcases/CtsInputMethodTestCases.apk",
+        "additional_apks": [
+          {
+            "apk": "android-cts/testcases/CtsMockInputMethod.apk",
+            "forced_queryable": true
+          }
+        ],
+        "includes": [
+          {
+            "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView"
+          }
+        ]
       }
     ]
   },
@@ -434,14 +472,41 @@
       {
         "apk": "android-cts/testcases/CtsAssistTestCases.apk",
         "additional_apks": [
-          "android-cts/testcases/CtsAssistApp.apk",
-          "android-cts/testcases/CtsAssistService.apk"
+          {
+            "apk": "android-cts/testcases/CtsAssistApp.apk"
+          },
+          {
+            "apk": "android-cts/testcases/CtsAssistService.apk"
+          }
         ],
         "includes": [
           {
             "match": "android.assist.cts.WebViewTest#testWebView"
           }
         ]
+      },
+      {
+        "apk": "android-cts/testcases/CtsInputMethodTestCases.apk",
+        "additional_apks": [
+          {
+            "apk": "android-cts/testcases/CtsMockInputMethod.apk",
+            "forced_queryable": true
+          }
+        ],
+        "includes": [
+          {
+            "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView"
+          },
+          {
+            "match": "android.view.inputmethod.cts.InputMethodServiceTest#testBatchEdit_commitAndSetComposingRegion_webView"
+          },
+          {
+            "match": "android.view.inputmethod.cts.InputMethodServiceTest#testBatchEdit_commitSpaceThenSetComposingRegion_webView"
+          },
+          {
+            "match": "android.view.inputmethod.cts.InputMethodServiceTest#testBatchEdit_commitSpaceThenSetComposingRegion_webView"
+          }
+        ]
       }
     ]
   }
diff --git a/android_webview/tools/cts_utils.py b/android_webview/tools/cts_utils.py
index 1fab406..f4eb3d618 100644
--- a/android_webview/tools/cts_utils.py
+++ b/android_webview/tools/cts_utils.py
@@ -110,7 +110,7 @@
 
   def get_additional_apks(self, platform):
     return [
-        apk for r in self._config[platform]['test_runs']
+        apk['apk'] for r in self._config[platform]['test_runs']
         for apk in r.get('additional_apks', [])
     ]
 
diff --git a/android_webview/tools/cts_utils_test.py b/android_webview/tools/cts_utils_test.py
index 5bbf7bb..964d081 100755
--- a/android_webview/tools/cts_utils_test.py
+++ b/android_webview/tools/cts_utils_test.py
@@ -80,14 +80,21 @@
       {
         "apk": "p2/test1.apk",
         "additional_apks": [
-          "p2/additional_apk_a_1.apk"
+          {
+            "apk": "p2/additional_apk_a_1.apk"
+          }
         ]
       },
       {
         "apk": "p2/test2.apk",
         "additional_apks": [
-          "p2/additional_apk_b_1.apk",
-          "p2/additional_apk_b_2.apk"
+          {
+            "apk": "p2/additional_apk_b_1.apk",
+            "forced_queryable": true
+          },
+          {
+            "apk": "p2/additional_apk_b_2.apk"
+          }
         ]
       }
     ]
diff --git a/android_webview/tools/run_cts.py b/android_webview/tools/run_cts.py
index 286c654..ea6b15e 100755
--- a/android_webview/tools/run_cts.py
+++ b/android_webview/tools/run_cts.py
@@ -158,11 +158,14 @@
     local_test_runner_args += ['--use-voice-interaction-service', voice_service]
 
   if additional_apks:
-    for s in additional_apks:
-      local_test_runner_args += [
-          '--additional-apk',
-          os.path.join(local_cts_dir, s)
-      ]
+    for additional_apk in additional_apks:
+      additional_apk_tmp = os.path.join(local_cts_dir, additional_apk['apk'])
+      local_test_runner_args += ['--additional-apk', additional_apk_tmp]
+
+      if additional_apk.get('forced_queryable', False):
+        local_test_runner_args += [
+            '--forced-queryable-additional-apk', additional_apk_tmp
+        ]
 
   if json_results_file:
     local_test_runner_args += ['--json-results-file=%s' %
diff --git a/android_webview/tools/update_cts_test.py b/android_webview/tools/update_cts_test.py
index cf6207d..997a110c 100755
--- a/android_webview/tools/update_cts_test.py
+++ b/android_webview/tools/update_cts_test.py
@@ -90,7 +90,7 @@
         for test_run in config[p]['test_runs']:
           self.append_to_zip_file(o, test_run['apk'])
           for additional_apk in test_run.get('additional_apks', []):
-            self.append_to_zip_file(o, additional_apk)
+            self.append_to_zip_file(o, additional_apk['apk'])
 
   def append_to_zip_file(self, url, file_name):
     """Append files to any zip files associated with the url.
diff --git a/ash/assistant/ui/DEPS b/ash/assistant/ui/DEPS
index 0af496a..eb193752 100644
--- a/ash/assistant/ui/DEPS
+++ b/ash/assistant/ui/DEPS
@@ -20,7 +20,6 @@
   "+chromeos/services/libassistant/public/cpp",
   "+mojo/public/cpp",
   "+net/base",
-  "+third_party/abseil-cpp/absl",
   "+third_party/skia/include/core",
   "+ui",
 ]
diff --git a/ash/components/arc/session/arc_container_client_adapter.cc b/ash/components/arc/session/arc_container_client_adapter.cc
index bd5b0c1..1a038b74 100644
--- a/ash/components/arc/session/arc_container_client_adapter.cc
+++ b/ash/components/arc/session/arc_container_client_adapter.cc
@@ -127,6 +127,8 @@
     request.set_disable_download_provider(params.disable_download_provider);
     request.set_disable_ureadahead(params.disable_ureadahead);
     request.set_arc_generate_pai(params.arc_generate_play_auto_install);
+    request.set_enable_consumer_auto_update_toggle(
+        params.enable_consumer_auto_update_toggle);
     request.set_enable_notifications_refresh(
         params.enable_notifications_refresh);
     request.set_enable_tts_caching(params.enable_tts_caching);
diff --git a/ash/components/arc/session/arc_session_impl.cc b/ash/components/arc/session/arc_session_impl.cc
index 3756016..e487c244 100644
--- a/ash/components/arc/session/arc_session_impl.cc
+++ b/ash/components/arc/session/arc_session_impl.cc
@@ -464,6 +464,8 @@
   params.enable_notifications_refresh =
       ash::features::IsNotificationsRefreshEnabled();
   params.enable_tts_caching = base::FeatureList::IsEnabled(kEnableTTSCaching);
+  params.enable_consumer_auto_update_toggle = base::FeatureList::IsEnabled(
+      ash::features::kConsumerAutoUpdateToggleAllowed);
 
   // TODO (b/196460968): Remove after CTS run is complete.
   if (params.enable_notifications_refresh) {
diff --git a/ash/components/arc/session/arc_start_params.h b/ash/components/arc/session/arc_start_params.h
index e329370..d16376e 100644
--- a/ash/components/arc/session/arc_start_params.h
+++ b/ash/components/arc/session/arc_start_params.h
@@ -94,6 +94,9 @@
 
   // Flag to enable TTS caching.
   bool enable_tts_caching = false;
+
+  // Flag to enable disable consumer auto update toggle as part of EU new deal.
+  bool enable_consumer_auto_update_toggle = false;
 };
 
 }  // namespace arc
diff --git a/ash/components/arc/session/arc_vm_client_adapter.cc b/ash/components/arc/session/arc_vm_client_adapter.cc
index 8005d1f..0e20501 100644
--- a/ash/components/arc/session/arc_vm_client_adapter.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter.cc
@@ -26,6 +26,7 @@
 #include "ash/components/arc/session/connection_holder.h"
 #include "ash/components/arc/session/file_system_status.h"
 #include "ash/components/cryptohome/cryptohome_parameters.h"
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
 #include "base/callback.h"
@@ -500,6 +501,9 @@
     VLOG(1) << "Use BalanceAvailableBalloonPolicy";
   }
 
+  request.set_enable_consumer_auto_update_toggle(base::FeatureList::IsEnabled(
+      ash::features::kConsumerAutoUpdateToggleAllowed));
+
   return request;
 }
 
diff --git a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
index 51232448..f29efac2 100644
--- a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -27,6 +27,7 @@
 #include "ash/components/arc/test/fake_app_host.h"
 #include "ash/components/arc/test/fake_app_instance.h"
 #include "ash/components/cryptohome/cryptohome_parameters.h"
+#include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
@@ -2291,6 +2292,37 @@
                              "ro.boot.enable_arc_nearby_share=0"));
 }
 
+TEST_F(ArcVmClientAdapterTest,
+       StartArc_EnableConsumerAutoUpdateToggle_Default) {
+  StartMiniArc();
+  EXPECT_GE(GetTestConciergeClient()->start_arc_vm_call_count(), 1);
+  EXPECT_FALSE(is_system_shutdown().has_value());
+  const auto& request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_FALSE(request.enable_consumer_auto_update_toggle());
+}
+
+TEST_F(ArcVmClientAdapterTest,
+       StartArc_EnableConsumerAutoUpdateToggle_Enabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(ash::features::kConsumerAutoUpdateToggleAllowed);
+  StartMiniArc();
+  EXPECT_GE(GetTestConciergeClient()->start_arc_vm_call_count(), 1);
+  EXPECT_FALSE(is_system_shutdown().has_value());
+  const auto& request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_TRUE(request.enable_consumer_auto_update_toggle());
+}
+
+TEST_F(ArcVmClientAdapterTest,
+       StartArc_EnableConsumerAutoUpdateToggle_Disabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(ash::features::kConsumerAutoUpdateToggleAllowed);
+  StartMiniArc();
+  EXPECT_GE(GetTestConciergeClient()->start_arc_vm_call_count(), 1);
+  EXPECT_FALSE(is_system_shutdown().has_value());
+  const auto& request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_FALSE(request.enable_consumer_auto_update_toggle());
+}
+
 // Test that StartArcVmRequest has no androidboot.arcvm.logd.size field
 // when kLogdConfig is disabled.
 TEST_F(ArcVmClientAdapterTest, ArcVmLogdSizeDisabled) {
diff --git a/ash/components/arc/test/fake_file_system_instance.cc b/ash/components/arc/test/fake_file_system_instance.cc
index f7e7340..3fefc58 100644
--- a/ash/components/arc/test/fake_file_system_instance.cc
+++ b/ash/components/arc/test/fake_file_system_instance.cc
@@ -200,6 +200,24 @@
   recent_documents_[key].push_back(document);
 }
 
+void FakeFileSystemInstance::RemoveRecentDocument(const Document& document) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  // Unfortunately we don't know the root_id when deleting a document, so
+  // here we need to loop through all available roots to find the document.
+  for (auto const& doc : recent_documents_) {
+    const auto iter = std::find_if(
+        doc.second.begin(), doc.second.end(),
+        [&document](const Document& recent_document) {
+          return document.authority == recent_document.authority &&
+                 document.document_id == recent_document.document_id;
+        });
+    if (iter != doc.second.end()) {
+      recent_documents_[doc.first].erase(iter);
+      return;
+    }
+  }
+}
+
 void FakeFileSystemInstance::AddRoot(const Root& root) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   roots_list_.push_back(root);
@@ -575,6 +593,9 @@
         FROM_HERE, base::BindOnce(std::move(callback), false));
     return;
   }
+  // We also need to remove the document from the recent_documents_ if it was
+  // being added there.
+  RemoveRecentDocument(iter->second);
   documents_.erase(iter);
   size_t erased = child_documents_.erase(key);
   DCHECK_NE(0u, erased);
diff --git a/ash/components/arc/test/fake_file_system_instance.h b/ash/components/arc/test/fake_file_system_instance.h
index 4b34a60f..4fcb0a61 100644
--- a/ash/components/arc/test/fake_file_system_instance.h
+++ b/ash/components/arc/test/fake_file_system_instance.h
@@ -231,6 +231,9 @@
   // Adds a recent document accessible by document provider based methods.
   void AddRecentDocument(const std::string& root_id, const Document& document);
 
+  // Removes a recent document accessible by document provider based methods.
+  void RemoveRecentDocument(const Document& document);
+
   // Adds a root accessible by document provider based methods.
   void AddRoot(const Root& root);
 
diff --git a/ash/components/attestation/DEPS b/ash/components/attestation/DEPS
index cd9bcfe..516fd3af 100644
--- a/ash/components/attestation/DEPS
+++ b/ash/components/attestation/DEPS
@@ -7,7 +7,6 @@
   "+components/account_id",
   "+crypto",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
 ]
 
diff --git a/ash/components/audio/DEPS b/ash/components/audio/DEPS
index 8636921..bed6c70 100644
--- a/ash/components/audio/DEPS
+++ b/ash/components/audio/DEPS
@@ -11,6 +11,5 @@
   "+services/media_session/public",
   "+ui/events/devices",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api/dbus",
 ]
diff --git a/ash/components/audio/OWNERS b/ash/components/audio/OWNERS
index e71cb32..806624d 100644
--- a/ash/components/audio/OWNERS
+++ b/ash/components/audio/OWNERS
@@ -1,2 +1 @@
-jennyz@chromium.org
 hychao@chromium.org
diff --git a/ash/components/cryptohome/DEPS b/ash/components/cryptohome/DEPS
index 410db217..ab959df6 100644
--- a/ash/components/cryptohome/DEPS
+++ b/ash/components/cryptohome/DEPS
@@ -7,7 +7,6 @@
   "+components/account_id",
   "+components/device_event_log",
   "+components/user_manager",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
 ]
 
diff --git a/ash/components/login/auth/DEPS b/ash/components/login/auth/DEPS
index a14e5f7..b732d30 100644
--- a/ash/components/login/auth/DEPS
+++ b/ash/components/login/auth/DEPS
@@ -21,7 +21,6 @@
   "+google_apis",
   "+net",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/boringssl/src/include",
   "+third_party/cros_system_api",
   "+url",
diff --git a/ash/components/phonehub/BUILD.gn b/ash/components/phonehub/BUILD.gn
index 9826010..3a5dc50 100644
--- a/ash/components/phonehub/BUILD.gn
+++ b/ash/components/phonehub/BUILD.gn
@@ -47,6 +47,10 @@
     "find_my_device_controller.h",
     "find_my_device_controller_impl.cc",
     "find_my_device_controller_impl.h",
+    "icon_decoder.cc",
+    "icon_decoder.h",
+    "icon_decoder_impl.cc",
+    "icon_decoder_impl.h",
     "invalid_connection_disconnector.cc",
     "invalid_connection_disconnector.h",
     "message_receiver.cc",
@@ -121,6 +125,7 @@
     "//ash/components/multidevice/logging",
     "//ash/components/phonehub/proto",
     "//ash/constants",
+    "//ash/resources/vector_icons",
     "//ash/services/device_sync/public/cpp",
     "//ash/services/multidevice_setup/public/cpp",
     "//ash/services/multidevice_setup/public/cpp:prefs",
@@ -233,6 +238,7 @@
     "do_not_disturb_controller_impl_unittest.cc",
     "feature_status_provider_impl_unittest.cc",
     "find_my_device_controller_impl_unittest.cc",
+    "icon_decoder_impl_unittest.cc",
     "invalid_connection_disconnector_unittest.cc",
     "message_receiver_unittest.cc",
     "message_sender_unittest.cc",
diff --git a/ash/components/phonehub/fake_recent_apps_interaction_handler.cc b/ash/components/phonehub/fake_recent_apps_interaction_handler.cc
index 6c3aa60..60369a2 100644
--- a/ash/components/phonehub/fake_recent_apps_interaction_handler.cc
+++ b/ash/components/phonehub/fake_recent_apps_interaction_handler.cc
@@ -55,6 +55,11 @@
   return app_metadata_list;
 }
 
+void FakeRecentAppsInteractionHandler::SetStreamableApps(
+    const proto::StreamableApps& streamable_apps) {
+  // TODO(nayebi): Do we need to implement this?
+}
+
 void FakeRecentAppsInteractionHandler::ComputeAndUpdateUiState() {
   if (feature_state_ != FeatureState::kEnabledByUser) {
     ui_state_ = RecentAppsUiState::HIDDEN;
diff --git a/ash/components/phonehub/fake_recent_apps_interaction_handler.h b/ash/components/phonehub/fake_recent_apps_interaction_handler.h
index d920ae8e..812e31a 100644
--- a/ash/components/phonehub/fake_recent_apps_interaction_handler.h
+++ b/ash/components/phonehub/fake_recent_apps_interaction_handler.h
@@ -43,6 +43,7 @@
       const Notification::AppMetadata& app_metadata,
       base::Time last_accessed_timestamp) override;
   std::vector<Notification::AppMetadata> FetchRecentAppMetadataList() override;
+  void SetStreamableApps(const proto::StreamableApps& streamable_apps) override;
 
  private:
   void ComputeAndUpdateUiState();
diff --git a/ash/components/phonehub/icon_decoder.cc b/ash/components/phonehub/icon_decoder.cc
new file mode 100644
index 0000000..a0a1c7ce
--- /dev/null
+++ b/ash/components/phonehub/icon_decoder.cc
@@ -0,0 +1,15 @@
+// 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 "ash/components/phonehub/icon_decoder_impl.h"
+
+namespace ash {
+namespace phonehub {
+
+IconDecoder::DecodingData::DecodingData(unsigned long id,
+                                        const std::string& input_data)
+    : id(id), input_data(input_data) {}
+
+}  // namespace phonehub
+}  // namespace ash
diff --git a/ash/components/phonehub/icon_decoder.h b/ash/components/phonehub/icon_decoder.h
new file mode 100644
index 0000000..6c4ead7
--- /dev/null
+++ b/ash/components/phonehub/icon_decoder.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 ASH_COMPONENTS_PHONEHUB_ICON_DECODER_H_
+#define ASH_COMPONENTS_PHONEHUB_ICON_DECODER_H_
+
+#include "base/callback.h"
+#include "ui/gfx/image/image.h"
+
+namespace ash {
+namespace phonehub {
+
+// Decodes icons in batches.
+// TODO(b/233279034): s2e are three decoders now: `CameraRollThumbnailDecoder`
+// `IconDecoder`, and `NotificationProcessor`. It may makes sense
+// to abstract out the redundant logic in a single place.
+class IconDecoder {
+ public:
+  // Each decoding operation is associated with a unique id that later is used
+  // to identify the result in the batch output.
+  struct DecodingData {
+    DecodingData(unsigned long id, const std::string& input_data);
+
+    const unsigned long id;
+    const std::string& input_data;
+    gfx::Image result;
+  };
+
+  IconDecoder(const IconDecoder&) = delete;
+  IconDecoder& operator=(const IconDecoder&) = delete;
+  virtual ~IconDecoder() = default;
+
+  // Decodes the `input_data` in each item in `decide_items` and places the
+  // result inside the `result` field in the `decode_items`. At the end,
+  // `finished_callback` is called and the list of `DecodingData` items is
+  // returned back to the callee.
+  // Important note: If this method is called "BEFORE" the result of the
+  // previous call is ready, the previous call is cancelled without
+  // calling `finished_callback`.
+  virtual void BatchDecode(
+      std::unique_ptr<std::vector<DecodingData>> decode_items,
+      base::OnceCallback<void(std::unique_ptr<std::vector<DecodingData>>)>
+          finished_callback) = 0;
+
+ protected:
+  IconDecoder() = default;
+};
+
+}  // namespace phonehub
+}  // namespace ash
+
+#endif  // ASH_COMPONENTS_PHONEHUB_ICON_DECODER_H_
diff --git a/ash/components/phonehub/icon_decoder_impl.cc b/ash/components/phonehub/icon_decoder_impl.cc
new file mode 100644
index 0000000..5b9a0282
--- /dev/null
+++ b/ash/components/phonehub/icon_decoder_impl.cc
@@ -0,0 +1,96 @@
+// 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 "ash/components/phonehub/icon_decoder_impl.h"
+
+#include <functional>
+#include <utility>
+
+#include "ash/components/multidevice/logging/logging.h"
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
+#include "base/barrier_closure.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/callback_forward.h"
+#include "base/containers/flat_map.h"
+#include "base/memory/weak_ptr.h"
+#include "services/data_decoder/public/cpp/decode_image.h"
+#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
+#include "ubidiimp.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace ash {
+namespace phonehub {
+
+IconDecoderImpl::DecoderDelegate::DecoderDelegate() = default;
+
+IconDecoderImpl::DecoderDelegate::~DecoderDelegate() = default;
+
+void IconDecoderImpl::DecoderDelegate::Decode(
+    const DecodingData& request,
+    data_decoder::DecodeImageCallback callback) {
+  const std::string& encoded_icon = request.input_data;
+  data_decoder::DecodeImage(
+      &data_decoder_, base::as_bytes(base::make_span(encoded_icon)),
+      data_decoder::mojom::ImageCodec::kDefault,
+      /*shrink_to_fit=*/true, data_decoder::kDefaultMaxSizeInBytes,
+      /*desired_image_frame_size=*/gfx::Size(), std::move(callback));
+}
+
+IconDecoderImpl::IconDecoderImpl()
+    : decoder_delegate_(std::make_unique<DecoderDelegate>()) {}
+
+IconDecoderImpl::~IconDecoderImpl() = default;
+
+void IconDecoderImpl::BatchDecode(
+    std::unique_ptr<std::vector<DecodingData>> decode_items,
+    base::OnceCallback<void(std::unique_ptr<std::vector<DecodingData>>)>
+        finished_callback) {
+  CancelPendingRequests();
+  pending_items_ = std::move(decode_items);
+
+  barrier_closure_ =
+      base::BarrierClosure(pending_items_->size(),
+                           base::BindOnce(&IconDecoderImpl::OnAllIconsDecoded,
+                                          weak_ptr_factory_.GetWeakPtr(),
+                                          std::move(finished_callback)));
+
+  // If decode_items is empty, barrier closure must have been called by this
+  // point and the pending_items_ pointer must be already reset.
+  if (!pending_items_)
+    return;
+  for (DecodingData& request : *pending_items_) {
+    decoder_delegate_->Decode(
+        request,
+        base::BindOnce(&IconDecoderImpl::OnIconDecoded,
+                       weak_ptr_factory_.GetWeakPtr(), std::ref(request)));
+  }
+}
+
+void IconDecoderImpl::OnAllIconsDecoded(
+    base::OnceCallback<void(std::unique_ptr<std::vector<DecodingData>>)>
+        finished_callback) {
+  std::move(finished_callback).Run(std::move(pending_items_));
+}
+
+void IconDecoderImpl::OnIconDecoded(DecodingData& decoding_data,
+                                    const SkBitmap& result) {
+  gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(result);
+
+  // If |image_skia| is null, indicating that the data decoder failed to decode
+  // the image, the image will be empty, and cannot be made thread safe.
+  if (!image_skia.isNull())
+    image_skia.MakeThreadSafe();
+
+  decoding_data.result = gfx::Image(image_skia);
+  barrier_closure_.Run();
+}
+
+void IconDecoderImpl::CancelPendingRequests() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
+}  // namespace phonehub
+}  // namespace ash
diff --git a/ash/components/phonehub/icon_decoder_impl.h b/ash/components/phonehub/icon_decoder_impl.h
new file mode 100644
index 0000000..c09a76c
--- /dev/null
+++ b/ash/components/phonehub/icon_decoder_impl.h
@@ -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.
+
+#ifndef ASH_COMPONENTS_PHONEHUB_ICON_DECODER_IMPL_H_
+#define ASH_COMPONENTS_PHONEHUB_ICON_DECODER_IMPL_H_
+
+#include "ash/components/phonehub/icon_decoder.h"
+
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
+#include "ash/components/phonehub/recent_apps_interaction_handler.h"
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
+#include "services/data_decoder/public/cpp/decode_image.h"
+#include "ui/gfx/image/image.h"
+
+namespace ash {
+namespace phonehub {
+
+class IconDecoderImpl : public IconDecoder {
+ public:
+  IconDecoderImpl();
+  ~IconDecoderImpl() override;
+
+  void BatchDecode(
+      std::unique_ptr<std::vector<DecodingData>> decode_items,
+      base::OnceCallback<void(std::unique_ptr<std::vector<DecodingData>>)>
+          finished_callback) override;
+
+ private:
+  friend class IconDecoderImplTest;
+  friend class TestDecoderDelegate;
+  friend class RecentAppsInteractionHandlerTest;
+
+  // Delegate class that decodes icons. Can be overridden in tests.
+  class DecoderDelegate {
+   public:
+    DecoderDelegate();
+    virtual ~DecoderDelegate();
+
+    virtual void Decode(const DecodingData& data,
+                        data_decoder::DecodeImageCallback callback);
+
+   private:
+    // The instance of DataDecoder to decode thumbnail images. The underlying
+    // service instance is started lazily when needed and torn down when not in
+    // use.
+    data_decoder::DataDecoder data_decoder_;
+  };
+
+  void OnIconDecoded(DecodingData& decoding_data, const SkBitmap& result);
+  void OnAllIconsDecoded(
+      base::OnceCallback<void(std::unique_ptr<std::vector<DecodingData>>)>
+          finished_callback);
+  void CancelPendingRequests();
+
+  std::unique_ptr<DecoderDelegate> decoder_delegate_;
+  std::unique_ptr<std::vector<DecodingData>> pending_items_;
+  base::RepeatingClosure barrier_closure_;
+
+  // Contains weak pointers to callbacks passed to the |DecoderDelegate|.
+  base::WeakPtrFactory<IconDecoderImpl> weak_ptr_factory_{this};
+};
+
+}  // namespace phonehub
+}  // namespace ash
+
+#endif  // ASH_COMPONENTS_PHONEHUB_ICON_DECODER_IMPL_H_
diff --git a/ash/components/phonehub/icon_decoder_impl_unittest.cc b/ash/components/phonehub/icon_decoder_impl_unittest.cc
new file mode 100644
index 0000000..cbd7c5b
--- /dev/null
+++ b/ash/components/phonehub/icon_decoder_impl_unittest.cc
@@ -0,0 +1,207 @@
+// 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 "ash/components/phonehub/icon_decoder_impl.h"
+
+#include <memory>
+
+#include "ash/components/phonehub/icon_decoder.h"
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace ash {
+namespace phonehub {
+
+namespace {
+
+// Verifies the bitmaps in the decoded items match the id of the requests.
+// As the id % 10 is used as the width of the bitmaps, it checks to see if
+// the ids and bitmap sizes match ort not.
+void VerifyDecodedItem(IconDecoder::DecodingData& item) {
+  EXPECT_EQ((int)(item.id % 10), item.result.Width());
+}
+
+void VerifyDecodedItems(std::vector<IconDecoder::DecodingData>* items) {
+  for (IconDecoder::DecodingData& item : *items)
+    VerifyDecodedItem(item);
+}
+
+}  // namespace
+
+class TestDecoderDelegate : public IconDecoderImpl::DecoderDelegate {
+ public:
+  TestDecoderDelegate() = default;
+  ~TestDecoderDelegate() override = default;
+
+  void Decode(const IconDecoder::DecodingData& data,
+              data_decoder::DecodeImageCallback callback) override {
+    pending_callbacks_[data.id] = std::move(callback);
+  }
+
+  void CompleteRequest(const unsigned long id) {
+    SkBitmap test_bitmap;
+    test_bitmap.allocN32Pixels(id % 10, 1);
+    std::move(pending_callbacks_.at(id)).Run(test_bitmap);
+    pending_callbacks_.erase(id);
+  }
+
+  void FailRequest(const unsigned long id) {
+    SkBitmap test_bitmap;
+    std::move(pending_callbacks_.at(id)).Run(test_bitmap);
+    pending_callbacks_.erase(id);
+  }
+
+  void CompleteAllRequests() {
+    for (auto& it : pending_callbacks_)
+      CompleteRequest(it.first);
+    pending_callbacks_.clear();
+  }
+
+ private:
+  base::flat_map<unsigned long, data_decoder::DecodeImageCallback>
+      pending_callbacks_;
+};
+
+class IconDecoderImplTest : public testing::Test {
+ protected:
+  IconDecoderImplTest() = default;
+  IconDecoderImplTest(const IconDecoderImplTest&) = delete;
+  IconDecoderImplTest& operator=(const IconDecoderImplTest&) = delete;
+  ~IconDecoderImplTest() override = default;
+
+  void SetUp() override {
+    decoder_.decoder_delegate_ = std::make_unique<TestDecoderDelegate>();
+  }
+
+  void BatchDecode(
+      std::unique_ptr<std::vector<IconDecoder::DecodingData>> decode_items) {
+    decoder_.BatchDecode(std::move(decode_items),
+                         base::BindOnce(&IconDecoderImplTest::OnItemsDecoded,
+                                        weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  void CompleteDecodeRequest(const unsigned long id) {
+    static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
+        ->CompleteRequest(id);
+  }
+
+  void FailDecodeRequest(const unsigned long id) {
+    static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
+        ->FailRequest(id);
+  }
+
+  void CompleteAllDecodeRequests() {
+    static_cast<TestDecoderDelegate*>(decoder_.decoder_delegate_.get())
+        ->CompleteAllRequests();
+  }
+
+  int completed_batch_count() const { return completed_batch_count_; }
+  std::vector<IconDecoder::DecodingData>* last_decoded_batch() const {
+    return last_decoded_batch_.get();
+  }
+
+  void OnItemsDecoded(
+      std::unique_ptr<std::vector<IconDecoder::DecodingData>> decode_items) {
+    completed_batch_count_++;
+    last_decoded_batch_ = std::move(decode_items);
+  }
+
+ private:
+  IconDecoderImpl decoder_;
+  int completed_batch_count_ = 0;
+  std::unique_ptr<std::vector<IconDecoder::DecodingData>> last_decoded_batch_;
+
+  base::WeakPtrFactory<IconDecoderImplTest> weak_ptr_factory_{this};
+};
+
+TEST_F(IconDecoderImplTest, BatchDecodeWithNoExistingItems) {
+  auto decode_items =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
+  decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
+  decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
+
+  BatchDecode(std::move(decode_items));
+
+  CompleteDecodeRequest(3);
+  CompleteDecodeRequest(2);
+  EXPECT_EQ(0, completed_batch_count());
+
+  // The batch of items won't be added until decode request are completed for
+  // all items.
+  CompleteDecodeRequest(1);
+  EXPECT_EQ(1, completed_batch_count());
+  auto* result = last_decoded_batch();
+  EXPECT_EQ(3UL, result->size());
+}
+
+TEST_F(IconDecoderImplTest, BatchDecodeWithOutOfOrderCompletions) {
+  auto decode_items =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
+  decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
+  decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
+
+  BatchDecode(std::move(decode_items));
+
+  CompleteDecodeRequest(2);
+  CompleteDecodeRequest(1);
+  CompleteDecodeRequest(3);
+
+  EXPECT_EQ(1, completed_batch_count());
+  auto* result = last_decoded_batch();
+  EXPECT_EQ(3UL, result->size());
+  VerifyDecodedItems(result);
+}
+
+TEST_F(IconDecoderImplTest, BatchDecodeWithErrors) {
+  auto decode_items =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  decode_items->push_back(IconDecoder::DecodingData(1, "input1"));
+  decode_items->push_back(IconDecoder::DecodingData(2, "input2"));
+  decode_items->push_back(IconDecoder::DecodingData(3, "input3"));
+
+  BatchDecode(std::move(decode_items));
+
+  FailDecodeRequest(2);
+  CompleteDecodeRequest(1);
+  CompleteDecodeRequest(3);
+
+  EXPECT_EQ(1, completed_batch_count());
+  auto* result = last_decoded_batch();
+  EXPECT_EQ(3UL, result->size());
+  VerifyDecodedItem((*result)[0]);
+  VerifyDecodedItem((*result)[2]);
+  EXPECT_EQ(0, (*result)[1].result.Width());
+}
+
+TEST_F(IconDecoderImplTest, BatchDecodeWithInProgresRequests) {
+  auto decode_items1 =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  decode_items1->push_back(IconDecoder::DecodingData(2, "input2"));
+  decode_items1->push_back(IconDecoder::DecodingData(1, "input1"));
+
+  BatchDecode(std::move(decode_items1));
+  CompleteDecodeRequest(1);
+
+  auto decode_items2 =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  decode_items2->push_back(IconDecoder::DecodingData(3, "input3"));
+  decode_items2->push_back(IconDecoder::DecodingData(2, "input2"));
+
+  BatchDecode(std::move(decode_items2));  // This will cancel the previous call.
+  CompleteDecodeRequest(2);
+  CompleteDecodeRequest(3);
+
+  EXPECT_EQ(1, completed_batch_count());
+  auto* result = last_decoded_batch();
+  EXPECT_EQ(2UL, result->size());
+  VerifyDecodedItems(result);
+}
+
+}  // namespace phonehub
+}  // namespace ash
diff --git a/ash/components/phonehub/phone_hub_manager_impl.cc b/ash/components/phonehub/phone_hub_manager_impl.cc
index e8dfeb5..87e92363 100644
--- a/ash/components/phonehub/phone_hub_manager_impl.cc
+++ b/ash/components/phonehub/phone_hub_manager_impl.cc
@@ -14,6 +14,8 @@
 #include "ash/components/phonehub/do_not_disturb_controller_impl.h"
 #include "ash/components/phonehub/feature_status_provider_impl.h"
 #include "ash/components/phonehub/find_my_device_controller_impl.h"
+#include "ash/components/phonehub/icon_decoder.h"
+#include "ash/components/phonehub/icon_decoder_impl.h"
 #include "ash/components/phonehub/invalid_connection_disconnector.h"
 #include "ash/components/phonehub/message_receiver_impl.h"
 #include "ash/components/phonehub/message_sender_impl.h"
@@ -119,7 +121,8 @@
               ? std::make_unique<RecentAppsInteractionHandlerImpl>(
                     pref_service,
                     multidevice_setup_client,
-                    multidevice_feature_access_manager_.get())
+                    multidevice_feature_access_manager_.get(),
+                    std::make_unique<IconDecoderImpl>())
               : nullptr),
       phone_status_processor_(std::make_unique<PhoneStatusProcessor>(
           do_not_disturb_controller_.get(),
diff --git a/ash/components/phonehub/phone_status_processor.cc b/ash/components/phonehub/phone_status_processor.cc
index 7a7a649..78f63d459 100644
--- a/ash/components/phonehub/phone_status_processor.cc
+++ b/ash/components/phonehub/phone_status_processor.cc
@@ -317,6 +317,7 @@
                << phone_status_snapshot.properties().gmscore_version();
   ProcessReceivedNotifications(phone_status_snapshot.notifications());
   SetReceivedPhoneStatusModelStates(phone_status_snapshot.properties());
+  SetStreamableApps(phone_status_snapshot.streamable_apps());
 }
 
 void PhoneStatusProcessor::OnPhoneStatusUpdateReceived(
@@ -340,5 +341,11 @@
   MaybeSetPhoneModelName(host_device_with_status.second);
 }
 
+void PhoneStatusProcessor::SetStreamableApps(
+    const proto::StreamableApps& streamable_apps) {
+  if (streamable_apps.apps_size() > 0)
+    recent_apps_interaction_handler_->SetStreamableApps(streamable_apps);
+}
+
 }  // namespace phonehub
 }  // namespace ash
diff --git a/ash/components/phonehub/phone_status_processor.h b/ash/components/phonehub/phone_status_processor.h
index cd23f02..4cb9a126 100644
--- a/ash/components/phonehub/phone_status_processor.h
+++ b/ash/components/phonehub/phone_status_processor.h
@@ -65,6 +65,8 @@
       const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
           host_device_with_status) override;
 
+  void SetStreamableApps(const proto::StreamableApps& streamable_apps);
+
   void ProcessReceivedNotifications(
       const RepeatedPtrField<proto::Notification>& notification_protos);
 
diff --git a/ash/components/phonehub/proto/phonehub_api.proto b/ash/components/phonehub/proto/phonehub_api.proto
index 6589f18..1ad50eb 100644
--- a/ash/components/phonehub/proto/phonehub_api.proto
+++ b/ash/components/phonehub/proto/phonehub_api.proto
@@ -275,9 +275,20 @@
   Category category = 11;
 }
 
+// Stores the information about the apps that are ready to be streamed.
+// We used a dedicated proto for this instead of inlining this to make it
+// future proof.
+message StreamableApps {
+  // List of apps that are ready to be streamed.
+  // The order of the apps in the list is important and is set by the source.
+  // The client should show the apps in the same order.
+  repeated App apps = 1;
+}
+
 message PhoneStatusSnapshot {
   PhoneProperties properties = 1;
   repeated Notification notifications = 2;
+  StreamableApps streamable_apps = 3;
 }
 
 message PhoneStatusUpdate {
diff --git a/ash/components/phonehub/recent_apps_interaction_handler.h b/ash/components/phonehub/recent_apps_interaction_handler.h
index 1293a1f6..967f852 100644
--- a/ash/components/phonehub/recent_apps_interaction_handler.h
+++ b/ash/components/phonehub/recent_apps_interaction_handler.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include "ash/components/phonehub/notification.h"
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
 #include "ash/components/phonehub/recent_app_click_observer.h"
 #include "base/gtest_prod_util.h"
 #include "base/observer_list.h"
@@ -69,6 +70,8 @@
       base::Time last_accessed_timestamp) = 0;
   virtual std::vector<Notification::AppMetadata>
   FetchRecentAppMetadataList() = 0;
+  virtual void SetStreamableApps(
+      const proto::StreamableApps& streamable_apps) = 0;
 
  protected:
   RecentAppsInteractionHandler();
diff --git a/ash/components/phonehub/recent_apps_interaction_handler_impl.cc b/ash/components/phonehub/recent_apps_interaction_handler_impl.cc
index f2bb94f..86e3d683 100644
--- a/ash/components/phonehub/recent_apps_interaction_handler_impl.cc
+++ b/ash/components/phonehub/recent_apps_interaction_handler_impl.cc
@@ -4,12 +4,22 @@
 
 #include "ash/components/phonehub/recent_apps_interaction_handler_impl.h"
 
+#include <memory>
+
 #include "ash/components/multidevice/logging/logging.h"
+#include "ash/components/phonehub/icon_decoder.h"
 #include "ash/components/phonehub/notification.h"
 #include "ash/components/phonehub/pref_names.h"
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
 #include "ash/constants/ash_features.h"
+#include "ash/resources/vector_icons/vector_icons.h"
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/paint_vector_icon.h"
 
 namespace ash {
 namespace phonehub {
@@ -34,10 +44,12 @@
 RecentAppsInteractionHandlerImpl::RecentAppsInteractionHandlerImpl(
     PrefService* pref_service,
     multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
-    MultideviceFeatureAccessManager* multidevice_feature_access_manager)
+    MultideviceFeatureAccessManager* multidevice_feature_access_manager,
+    std::unique_ptr<IconDecoder> icon_decoder)
     : pref_service_(pref_service),
       multidevice_setup_client_(multidevice_setup_client),
-      multidevice_feature_access_manager_(multidevice_feature_access_manager) {
+      multidevice_feature_access_manager_(multidevice_feature_access_manager),
+      icon_decoder_(std::move(icon_decoder)) {
   multidevice_setup_client_->AddObserver(this);
   multidevice_feature_access_manager_->AddObserver(this);
 }
@@ -187,6 +199,56 @@
   ComputeAndUpdateUiState();
 }
 
+void RecentAppsInteractionHandlerImpl::SetStreamableApps(
+    const proto::StreamableApps& streamable_apps) {
+  PA_LOG(INFO) << "ClearRecentAppMetadataListAndPref to update the list of "
+               << streamable_apps.apps_size() << " items.";
+  ClearRecentAppMetadataListAndPref();
+  std::unique_ptr<std::vector<IconDecoder::DecodingData>> decoding_data_list =
+      std::make_unique<std::vector<IconDecoder::DecodingData>>();
+  std::hash<std::string> str_hash;
+  gfx::Image image =
+      gfx::Image(CreateVectorIcon(kPhoneHubPhoneIcon, gfx::kGoogleGrey700));
+  for (const auto& app : streamable_apps.apps()) {
+    // TODO(nayebi): AppMetadata is no longer limited to Notification class,
+    // let's move it outside of the Notification class.s2
+    recent_app_metadata_list_.emplace_back(
+        Notification::AppMetadata(base::UTF8ToUTF16(app.visible_name()),
+                                  app.package_name(), image, absl::nullopt,
+                                  app.icon_styling() ==
+                                      proto::NotificationIconStyling::
+                                          ICON_STYLE_MONOCHROME_SMALL_ICON,
+                                  app.user_id()),
+        base::Time::FromDoubleT(0));
+    decoding_data_list->emplace_back(
+        IconDecoder::DecodingData(str_hash(app.package_name()), app.icon()));
+  }
+
+  icon_decoder_->BatchDecode(
+      std::move(decoding_data_list),
+      base::BindOnce(&RecentAppsInteractionHandlerImpl::IconsDecoded,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void RecentAppsInteractionHandlerImpl::IconsDecoded(
+    std::unique_ptr<std::vector<IconDecoder::DecodingData>>
+        decoding_data_list) {
+  std::hash<std::string> str_hash;
+  for (const IconDecoder::DecodingData& decoding_data : *decoding_data_list) {
+    if (decoding_data.result.IsEmpty())
+      continue;
+    // find the associated app metadata
+    for (auto& app_metadata : recent_app_metadata_list_) {
+      if (decoding_data.id == str_hash(app_metadata.first.package_name)) {
+        app_metadata.first.icon = decoding_data.result;
+        continue;
+      }
+    }
+  }
+  SaveRecentAppMetadataListToPref();
+  ComputeAndUpdateUiState();
+}
+
 void RecentAppsInteractionHandlerImpl::ComputeAndUpdateUiState() {
   ui_state_ = RecentAppsUiState::HIDDEN;
 
diff --git a/ash/components/phonehub/recent_apps_interaction_handler_impl.h b/ash/components/phonehub/recent_apps_interaction_handler_impl.h
index 8b0160d..55ac49d3 100644
--- a/ash/components/phonehub/recent_apps_interaction_handler_impl.h
+++ b/ash/components/phonehub/recent_apps_interaction_handler_impl.h
@@ -6,9 +6,13 @@
 #define ASH_COMPONENTS_PHONEHUB_RECENT_APPS_INTERACTION_HANDLER_IMPL_H_
 
 #include <stdint.h>
+#include <memory>
 
+#include "ash/components/phonehub/icon_decoder.h"
+#include "ash/components/phonehub/icon_decoder_impl.h"
 #include "ash/components/phonehub/multidevice_feature_access_manager.h"
 #include "ash/components/phonehub/notification.h"
+#include "ash/components/phonehub/proto/phonehub_api.pb.h"
 #include "ash/components/phonehub/recent_app_click_observer.h"
 #include "ash/components/phonehub/recent_apps_interaction_handler.h"
 #include "ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
@@ -34,7 +38,8 @@
   explicit RecentAppsInteractionHandlerImpl(
       PrefService* pref_service,
       multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
-      MultideviceFeatureAccessManager* multidevice_feature_access_manager);
+      MultideviceFeatureAccessManager* multidevice_feature_access_manager,
+      std::unique_ptr<IconDecoder> icon_decoder);
   ~RecentAppsInteractionHandlerImpl() override;
 
   // RecentAppsInteractionHandler:
@@ -59,8 +64,17 @@
   void OnNotificationAccessChanged() override;
   void OnAppsAccessChanged() override;
 
+  void SetStreamableApps(const proto::StreamableApps& streamable_apps) override;
+  void IconsDecoded(std::unique_ptr<std::vector<IconDecoder::DecodingData>>
+                        decoding_data_list);
+
+  std::vector<std::pair<Notification::AppMetadata, base::Time>>*
+  recent_app_metadata_list_for_testing() {
+    return &recent_app_metadata_list_;
+  }
+
  private:
-  FRIEND_TEST_ALL_PREFIXES(RecentAppsInteractionHandlerTest, RecentAppsUpdated);
+  friend class RecentAppsInteractionHandlerTest;
 
   void LoadRecentAppMetadataListFromPrefIfNeed();
   void SaveRecentAppMetadataListToPref();
@@ -78,6 +92,10 @@
   PrefService* pref_service_;
   multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
   MultideviceFeatureAccessManager* multidevice_feature_access_manager_;
+  std::unique_ptr<IconDecoder> icon_decoder_;
+
+  base::WeakPtrFactory<RecentAppsInteractionHandlerImpl> weak_ptr_factory_{
+      this};
 };
 
 }  // namespace phonehub
diff --git a/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc b/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
index a5e38a6..2ac8daf 100644
--- a/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
+++ b/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
@@ -7,6 +7,8 @@
 #include <memory>
 
 #include "ash/components/phonehub/fake_multidevice_feature_access_manager.h"
+#include "ash/components/phonehub/icon_decoder.h"
+#include "ash/components/phonehub/icon_decoder_impl.h"
 #include "ash/components/phonehub/notification.h"
 #include "ash/components/phonehub/pref_names.h"
 #include "ash/constants/ash_features.h"
@@ -50,6 +52,40 @@
 }  // namespace
 
 class RecentAppsInteractionHandlerTest : public testing::Test {
+  class TestDecoderDelegate : public IconDecoderImpl::DecoderDelegate {
+   public:
+    TestDecoderDelegate() = default;
+    ~TestDecoderDelegate() override = default;
+
+    void Decode(const IconDecoder::DecodingData& data,
+                data_decoder::DecodeImageCallback callback) override {
+      pending_callbacks_[data.id] = std::move(callback);
+    }
+
+    void CompleteRequest(const unsigned long id) {
+      SkBitmap test_bitmap;
+      test_bitmap.allocN32Pixels(id % 10, 1);
+      std::move(pending_callbacks_.at(id)).Run(test_bitmap);
+      pending_callbacks_.erase(id);
+    }
+
+    void FailRequest(const unsigned long id) {
+      SkBitmap test_bitmap;
+      std::move(pending_callbacks_.at(id)).Run(test_bitmap);
+      pending_callbacks_.erase(id);
+    }
+
+    void CompleteAllRequests() {
+      for (auto& it : pending_callbacks_)
+        CompleteRequest(it.first);
+      pending_callbacks_.clear();
+    }
+
+   private:
+    base::flat_map<unsigned long, data_decoder::DecodeImageCallback>
+        pending_callbacks_;
+  };
+
  protected:
   RecentAppsInteractionHandlerTest() = default;
   RecentAppsInteractionHandlerTest(const RecentAppsInteractionHandlerTest&) =
@@ -66,9 +102,14 @@
     RecentAppsInteractionHandlerImpl::RegisterPrefs(pref_service_.registry());
     fake_multidevice_setup_client_ =
         std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
+    auto icon_decoder = std::make_unique<IconDecoderImpl>();
+    icon_decoder.get()->decoder_delegate_ =
+        std::make_unique<TestDecoderDelegate>();
+    decoder_delegate_ = static_cast<TestDecoderDelegate*>(
+        icon_decoder.get()->decoder_delegate_.get());
     interaction_handler_ = std::make_unique<RecentAppsInteractionHandlerImpl>(
         &pref_service_, fake_multidevice_setup_client_.get(),
-        &fake_multidevice_feature_access_manager_);
+        &fake_multidevice_feature_access_manager_, std::move(icon_decoder));
     interaction_handler_->AddRecentAppClickObserver(&fake_click_handler_);
   }
 
@@ -239,6 +280,7 @@
   TestingPrefServiceSimple pref_service_;
   FakeMultideviceFeatureAccessManager fake_multidevice_feature_access_manager_;
   base::test::ScopedFeatureList feature_list_;
+  TestDecoderDelegate* decoder_delegate_;
 };
 
 TEST_F(RecentAppsInteractionHandlerTest, RecentAppsClicked) {
@@ -274,18 +316,93 @@
   const base::Time now = base::Time::Now();
 
   handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now);
-  EXPECT_EQ(1U, handler().recent_app_metadata_list_.size());
-  EXPECT_EQ(now, handler().recent_app_metadata_list_[0].second);
+  EXPECT_EQ(1U, handler().recent_app_metadata_list_for_testing()->size());
+  EXPECT_EQ(now,
+            handler().recent_app_metadata_list_for_testing()->at(0).second);
 
   // The same package name only update last accessed timestamp.
   const base::Time next_minute = base::Time::Now() + base::Minutes(1);
   handler().NotifyRecentAppAddedOrUpdated(app_metadata1, next_minute);
-  EXPECT_EQ(1U, handler().recent_app_metadata_list_.size());
-  EXPECT_EQ(next_minute, handler().recent_app_metadata_list_[0].second);
+  EXPECT_EQ(1U, handler().recent_app_metadata_list_for_testing()->size());
+  EXPECT_EQ(next_minute,
+            handler().recent_app_metadata_list_for_testing()->at(0).second);
 
   const base::Time next_hour = base::Time::Now() + base::Hours(1);
   handler().NotifyRecentAppAddedOrUpdated(app_metadata2, next_hour);
-  EXPECT_EQ(2U, handler().recent_app_metadata_list_.size());
+  EXPECT_EQ(2U, handler().recent_app_metadata_list_for_testing()->size());
+}
+
+TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps) {
+  proto::StreamableApps streamable_apps;
+  auto* app1 = streamable_apps.add_apps();
+  app1->set_visible_name("VisName1");
+  app1->set_package_name("App1");
+  app1->set_icon("icon1");
+
+  auto* app2 = streamable_apps.add_apps();
+  app2->set_visible_name("VisName2");
+  app2->set_package_name("App2");
+  app2->set_icon("icon2");
+
+  handler().SetStreamableApps(streamable_apps);
+
+  EXPECT_EQ(2U, handler().recent_app_metadata_list_for_testing()->size());
+  EXPECT_EQ("App1", handler()
+                        .recent_app_metadata_list_for_testing()
+                        ->at(0)
+                        .first.package_name);
+  EXPECT_EQ("App2", handler()
+                        .recent_app_metadata_list_for_testing()
+                        ->at(1)
+                        .first.package_name);
+}
+
+TEST_F(RecentAppsInteractionHandlerTest,
+       SetStreamableApps_ClearsPreviousState) {
+  proto::StreamableApps streamable_apps;
+  auto* app1 = streamable_apps.add_apps();
+  app1->set_visible_name("VisName1");
+  app1->set_package_name("App1");
+  app1->set_icon("icon1");
+
+  auto* app2 = streamable_apps.add_apps();
+  app2->set_visible_name("VisName2");
+  app2->set_package_name("App2");
+  app2->set_icon("icon2");
+
+  handler().SetStreamableApps(streamable_apps);
+
+  EXPECT_EQ(2U, handler().recent_app_metadata_list_for_testing()->size());
+  EXPECT_EQ("App1", handler()
+                        .recent_app_metadata_list_for_testing()
+                        ->at(0)
+                        .first.package_name);
+  EXPECT_EQ("App2", handler()
+                        .recent_app_metadata_list_for_testing()
+                        ->at(1)
+                        .first.package_name);
+
+  proto::StreamableApps streamable_apps2;
+  auto* app3 = streamable_apps2.add_apps();
+  app3->set_visible_name("VisName3");
+  app3->set_package_name("App3");
+  app3->set_icon("icon3");
+
+  handler().SetStreamableApps(streamable_apps2);
+
+  EXPECT_EQ(1U, handler().recent_app_metadata_list_for_testing()->size());
+  EXPECT_EQ("App3", handler()
+                        .recent_app_metadata_list_for_testing()
+                        ->at(0)
+                        .first.package_name);
+}
+
+TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps_EmptyList) {
+  proto::StreamableApps streamable_apps;
+
+  handler().SetStreamableApps(streamable_apps);
+
+  EXPECT_TRUE(handler().recent_app_metadata_list_for_testing()->empty());
 }
 
 TEST_F(RecentAppsInteractionHandlerTest, FetchRecentAppMetadataList) {
diff --git a/ash/components/tpm/DEPS b/ash/components/tpm/DEPS
index ee09834..73676ef 100644
--- a/ash/components/tpm/DEPS
+++ b/ash/components/tpm/DEPS
@@ -11,6 +11,5 @@
   "+components/policy/proto",
   "+google_apis/gaia",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
 ]
diff --git a/ash/services/recording/DEPS b/ash/services/recording/DEPS
index 426d679c..b60a9c8 100644
--- a/ash/services/recording/DEPS
+++ b/ash/services/recording/DEPS
@@ -10,7 +10,6 @@
   "+mojo/public",
   "+services/audio/public",
   "+services/viz/privileged/mojom/compositing",
-  "+third_party/abseil-cpp/absl",
   "+ui/gfx",
 ]
 
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index 41d1929..5e44a23 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -718,12 +718,42 @@
   if (!to_be_deleted)
     return;
 
-  grouped_notifications_container_->RemoveChildViewT(to_be_deleted);
-  total_grouped_notifications_--;
-  left_content_->SetVisible(total_grouped_notifications_ == 0);
-  UpdateGroupedNotificationsVisibility();
-  expand_button_->UpdateGroupedNotificationsCount(total_grouped_notifications_);
-  PreferredSizeChanged();
+  auto on_notification_slid_out = base::BindRepeating(
+      [](base::WeakPtr<AshNotificationView> self,
+         const std::string& notification_id) {
+        if (!self || !self->grouped_notifications_container_)
+          return;
+
+        views::View* to_be_deleted =
+            self->FindGroupNotificationView(notification_id);
+        if (!to_be_deleted)
+          return;
+
+        self->grouped_notifications_container_->RemoveChildViewT(to_be_deleted);
+
+        self->total_grouped_notifications_--;
+        self->left_content_->SetVisible(self->total_grouped_notifications_ ==
+                                        0);
+        self->expand_button_->UpdateGroupedNotificationsCount(
+            self->total_grouped_notifications_);
+
+        self->PreferredSizeChanged();
+      },
+      weak_factory_.GetWeakPtr(), notification_id);
+
+  // If the removed notification has a layer transform it has already been slid
+  // out (For example user swiped it by dragging). We only need to animate a
+  // slide out if there is no transform.
+  if (to_be_deleted->layer()->transform().IsIdentity()) {
+    message_center_utils::SlideOutView(
+        to_be_deleted, on_notification_slid_out,
+        /*delay_in_ms=*/0,
+        /*duration_in_ms=*/kSlideOutGroupedNotificationAnimationDurationMs,
+        gfx::Tween::LINEAR,
+        "Ash.Notification.GroupNotification.SlideOut.AnimationSmoothness");
+  } else {
+    on_notification_slid_out.Run();
+  }
 }
 
 const char* AshNotificationView::GetClassName() const {
diff --git a/ash/system/message_center/ash_notification_view.h b/ash/system/message_center/ash_notification_view.h
index 3e06d679..ffe03d0 100644
--- a/ash/system/message_center/ash_notification_view.h
+++ b/ash/system/message_center/ash_notification_view.h
@@ -270,11 +270,13 @@
 
   // Cached background color to avoid unnecessary update.
   SkColor background_color_ = SK_ColorTRANSPARENT;
+
   // Whether the notification associated with this view is a parent or child
   // in a grouped notification. Used to update visibility of UI elements
   // specific to each type of notification.
   bool is_grouped_parent_view_ = false;
   bool is_grouped_child_view_ = false;
+
   // Whether this view is shown in a notification popup.
   bool shown_in_popup_ = false;
 
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc
index f5f3acb..a35cad1 100644
--- a/ash/system/message_center/ash_notification_view_unittest.cc
+++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -18,6 +18,7 @@
 #include "ash/system/message_center/unified_message_list_view.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
+#include "ash/test/layer_animation_stopped_waiter.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
@@ -192,10 +193,8 @@
                                int data_point_count = 1) {
     ui::Compositor* compositor = view->layer()->GetCompositor();
 
-    // Wait for the animation to finish.
-    while (view->layer()->GetAnimator()->is_animating()) {
-      EXPECT_TRUE(ui::WaitForNextFrameToBePresented(compositor));
-    }
+    LayerAnimationStoppedWaiter animation_waiter;
+    animation_waiter.Wait(view->layer());
 
     // Force a frame then wait, ensuring there is one more frame presented after
     // animation finishes to allow animation throughput data to be passed from
@@ -945,6 +944,41 @@
       /*data_point_count=*/2);
 }
 
+TEST_F(AshNotificationViewTest,
+       GroupNotificationSlideOutAnimationRecordSmoothness) {
+  base::HistogramTester histograms;
+
+  message_center::MessageCenter::Get()->RemoveAllNotifications(
+      /*by_user=*/true, message_center::MessageCenter::RemoveType::ALL);
+
+  auto notification = CreateTestNotification();
+
+  GetPrimaryUnifiedSystemTray()->ShowBubble();
+  auto* notification_view =
+      GetNotificationViewFromMessageCenter(notification->id());
+  MakeNotificationGroupParent(
+      notification_view,
+      2 * message_center_style::kMaxGroupedNotificationsInCollapsedState);
+
+  notification_view->ToggleExpand();
+  EXPECT_TRUE(notification_view->IsExpanded());
+
+  // Enable animations.
+  ui::ScopedAnimationDurationScaleMode duration(
+      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
+
+  auto* child_view = GetFirstGroupedChildNotificationView(notification_view);
+  notification_view->RemoveGroupNotification(child_view->notification_id());
+
+  base::HistogramTester histogram;
+
+  // The child view should slide out before being deleted and the smoothness
+  // should be recorded.
+  CheckSmoothnessRecorded(
+      histograms, child_view,
+      "Ash.Notification.GroupNotification.SlideOut.AnimationSmoothness");
+}
+
 TEST_F(AshNotificationViewTest, RecordExpandButtonClickAction) {
   base::HistogramTester histograms;
   auto notification = CreateTestNotification();
diff --git a/ash/system/message_center/message_center_constants.h b/ash/system/message_center/message_center_constants.h
index 4e3cb85..11c117c4 100644
--- a/ash/system/message_center/message_center_constants.h
+++ b/ash/system/message_center/message_center_constants.h
@@ -117,6 +117,9 @@
 constexpr int kGeneralExpandAnimationDuration = 300;
 constexpr int kGeneralCollapseAnimationDuration = 200;
 
+// Animation durations for adding / removing grouped child views
+constexpr int kSlideOutGroupedNotificationAnimationDurationMs = 200;
+
 }  // namespace ash
 
 #endif  // ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_CONSTANTS_H_
diff --git a/ash/system/message_center/message_center_utils.cc b/ash/system/message_center/message_center_utils.cc
index 300c08b..6ba8259 100644
--- a/ash/system/message_center/message_center_utils.cc
+++ b/ash/system/message_center/message_center_utils.cc
@@ -10,6 +10,7 @@
 #include "ui/compositor/animation_throughput_reporter.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/message_center/message_center.h"
 #include "ui/views/animation/animation_builder.h"
 #include "ui/views/view.h"
@@ -145,6 +146,44 @@
       .SetOpacity(view, 0.0f, tween_type);
 }
 
+void SlideOutView(views::View* view,
+                  base::OnceClosure on_animation_ended,
+                  int delay_in_ms,
+                  int duration_in_ms,
+                  gfx::Tween::Type tween_type,
+                  const std::string& animation_histogram_name) {
+  // If we are in testing with animation (non zero duration), we shouldn't have
+  // delays so that we can properly track when animation is completed in test.
+  if (ui::ScopedAnimationDurationScaleMode::duration_multiplier() ==
+      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION) {
+    delay_in_ms = 0;
+  }
+
+  std::pair<base::OnceClosure, base::OnceClosure> split =
+      base::SplitOnceCallback(std::move(on_animation_ended));
+
+  // The view must have a layer to perform animation.
+  DCHECK(view->layer());
+
+  ui::AnimationThroughputReporter reporter(
+      view->layer()->GetAnimator(),
+      metrics_util::ForSmoothness(base::BindRepeating(
+          &ReportAnimationSmoothness, animation_histogram_name)));
+
+  gfx::Transform transform;
+  transform.Translate(gfx::Vector2dF(view->bounds().width(), 0));
+
+  views::AnimationBuilder()
+      .SetPreemptionStrategy(
+          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
+      .OnEnded(std::move(split.first))
+      .OnAborted(std::move(split.second))
+      .Once()
+      .At(base::Milliseconds(delay_in_ms))
+      .SetDuration(base::Milliseconds(duration_in_ms))
+      .SetTransform(view->layer(), transform);
+}
+
 }  // namespace message_center_utils
 
 }  // namespace ash
diff --git a/ash/system/message_center/message_center_utils.h b/ash/system/message_center/message_center_utils.h
index dfb109a12..fc491038 100644
--- a/ash/system/message_center/message_center_utils.h
+++ b/ash/system/message_center/message_center_utils.h
@@ -57,6 +57,14 @@
                  gfx::Tween::Type tween_type = gfx::Tween::LINEAR,
                  const std::string& animation_histogram_name = std::string());
 
+// Slide out animation using AnimationBuilder.
+void SlideOutView(views::View* view,
+                  base::OnceClosure on_animation_ended,
+                  int delay_in_ms,
+                  int duration_in_ms,
+                  gfx::Tween::Type tween_type = gfx::Tween::LINEAR,
+                  const std::string& animation_histogram_name = std::string());
+
 }  // namespace message_center_utils
 
 }  // namespace ash
diff --git a/ash/system/message_center/notification_grouping_controller.cc b/ash/system/message_center/notification_grouping_controller.cc
index e1a64c3..02e4c7a 100644
--- a/ash/system/message_center/notification_grouping_controller.cc
+++ b/ash/system/message_center/notification_grouping_controller.cc
@@ -266,12 +266,6 @@
   const std::string parent_id =
       grouped_notification_list_->GetParentForChild(notification_id);
 
-  MessageView* parent_view =
-      GetActiveNotificationViewController()->GetMessageViewForNotificationId(
-          parent_id);
-  if (parent_view)
-    parent_view->RemoveGroupNotification(notification_id);
-
   // Remove parent notification if we are removing the last child notification
   // in a grouped notification.
   auto grouped_notifications =
diff --git a/ash/system/tray/tray_event_filter.cc b/ash/system/tray/tray_event_filter.cc
index 0b35ca2..81426eb 100644
--- a/ash/system/tray/tray_event_filter.cc
+++ b/ash/system/tray/tray_event_filter.cc
@@ -126,10 +126,13 @@
               ->GetStatusAreaWidget();
       UnifiedSystemTray* tray = status_area->unified_system_tray();
 
-      // See the `DateTray` and the `UnifiedSystemTray` together as one button
-      // when clicking outside of the tray.
-      if (features::IsCalendarViewEnabled())
-        bounds.Union(status_area->date_tray()->GetBoundsInScreen());
+      // When Quick Settings bubble is opened and the date tray is clicked, the
+      // bubble should not be closed since it will transition to show calendar.
+      if (features::IsCalendarViewEnabled() &&
+          status_area->date_tray()->GetBoundsInScreen().Contains(
+              screen_location)) {
+        continue;
+      }
 
       TrayBubbleBase* system_tray_bubble = tray->bubble();
       if (tray->IsBubbleShown() && system_tray_bubble != bubble) {
diff --git a/ash/webui/media_app_ui/resources/index_dark_light.html b/ash/webui/media_app_ui/resources/index_dark_light.html
index 8c2beeb4..877e8f4 100644
--- a/ash/webui/media_app_ui/resources/index_dark_light.html
+++ b/ash/webui/media_app_ui/resources/index_dark_light.html
@@ -39,6 +39,7 @@
   }
 </style>
 <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
+<script src="/first_message_received.js"></script>
 <iframe src="chrome-untrusted://media-app/app.html" allow="fullscreen; cross-origin-isolated;"></iframe>
 <script src="/launch.js" type="module"></script>
 </html>
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn
index 3566c332..4c2ef63 100644
--- a/ash/webui/personalization_app/resources/BUILD.gn
+++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -139,7 +139,10 @@
 ]
 
 static_resource_files = [
+  "hub_icon_64.png",
+  "hub_icon_128.png",
   "hub_icon_192.png",
+  "hub_icon_256.png",
   "icon_192.png",
 
   "common/ambient_mode_disabled.svg",
diff --git a/ash/webui/personalization_app/resources/hub_icon_128.png b/ash/webui/personalization_app/resources/hub_icon_128.png
new file mode 100644
index 0000000..0272072
--- /dev/null
+++ b/ash/webui/personalization_app/resources/hub_icon_128.png
Binary files differ
diff --git a/ash/webui/personalization_app/resources/hub_icon_256.png b/ash/webui/personalization_app/resources/hub_icon_256.png
new file mode 100644
index 0000000..f1f3495
--- /dev/null
+++ b/ash/webui/personalization_app/resources/hub_icon_256.png
Binary files differ
diff --git a/ash/webui/personalization_app/resources/hub_icon_64.png b/ash/webui/personalization_app/resources/hub_icon_64.png
new file mode 100644
index 0000000..512f5fc2
--- /dev/null
+++ b/ash/webui/personalization_app/resources/hub_icon_64.png
Binary files differ
diff --git a/ash/webui/shimless_rma/resources/onboarding_landing_page.html b/ash/webui/shimless_rma/resources/onboarding_landing_page.html
index 3713921..67609d6 100644
--- a/ash/webui/shimless_rma/resources/onboarding_landing_page.html
+++ b/ash/webui/shimless_rma/resources/onboarding_landing_page.html
@@ -62,14 +62,14 @@
             hidden$="[[!getStartedButtonClicked]]" active>
         </paper-spinner-lite>
       </cr-button>
-      <cr-button id="landingCancel" class="pill"
-          on-click="onLandingCancelButtonClicked_"
+      <cr-button id="landingExit" class="pill"
+          on-click="onLandingExitButtonClicked_"
           disabled="[[allButtonsDisabled]]">
-        <span id="cancelButtonLabel">
+        <span id="exitButtonLabel">
           [[i18n('exitButtonLabel')]]
         </span>
         <paper-spinner-lite class="button-spinner"
-            hidden$="[[!landingCancelButtonClicked]]" active>
+            hidden$="[[!landingExitButtonClicked]]" active>
         </paper-spinner-lite>
       </cr-button>
     </div>
diff --git a/ash/webui/shimless_rma/resources/onboarding_landing_page.js b/ash/webui/shimless_rma/resources/onboarding_landing_page.js
index 92d148c..cd9d448 100644
--- a/ash/webui/shimless_rma/resources/onboarding_landing_page.js
+++ b/ash/webui/shimless_rma/resources/onboarding_landing_page.js
@@ -81,10 +81,10 @@
       },
 
       /**
-       * After the cancel button is clicked, true until the next state is
+       * After the exit button is clicked, true until the next state is
        * processed. It is set back to false by shimless_rma.js.
        */
-      landingCancelButtonClicked: {
+      landingExitButtonClicked: {
         type: Boolean,
         value: false,
       },
@@ -146,13 +146,13 @@
   /**
    * @protected
    */
-  onLandingCancelButtonClicked_(e) {
+  onLandingExitButtonClicked_(e) {
     e.preventDefault();
 
-    this.landingCancelButtonClicked = true;
+    this.landingExitButtonClicked = true;
 
     this.dispatchEvent(new CustomEvent(
-        'click-cancel-button',
+        'click-exit-button',
         {
           bubbles: true,
           composed: true,
diff --git a/ash/webui/shimless_rma/resources/reimaging_calibration_failed_page.js b/ash/webui/shimless_rma/resources/reimaging_calibration_failed_page.js
index 2ada8f34..492d0e1 100644
--- a/ash/webui/shimless_rma/resources/reimaging_calibration_failed_page.js
+++ b/ash/webui/shimless_rma/resources/reimaging_calibration_failed_page.js
@@ -80,12 +80,12 @@
 
     /**
      * The "Skip calibration" button on this page is styled and positioned like
-     * a cancel button. So we use the common cancel button from shimless_rma.js
+     * a exit button. So we use the common exit button from shimless_rma.js
      * This function needs to be public, because it's invoked by
-     * shimless_rma.js as part of the response to the cancel button click.
+     * shimless_rma.js as part of the response to the exit button click.
      * @return {!Promise<!StateResult>}
      */
-    this.onCancelButtonClick = () => {
+    this.onExitButtonClick = () => {
       if (this.tryingToSkipWithFailedComponents_()) {
         this.shadowRoot.querySelector('#failedComponentsDialog').showModal();
         return Promise.reject(
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.html b/ash/webui/shimless_rma/resources/shimless_rma.html
index 0dbaea27..9d8a6d5 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma.html
+++ b/ash/webui/shimless_rma/resources/shimless_rma.html
@@ -46,7 +46,7 @@
     top: 24px;
   }
 
-  #cancel {
+  #exit {
     margin-inline-end: 8px;
     top: 24px;
   }
@@ -61,7 +61,7 @@
     width: var(--cr-icon-size);
   }
 
-  #cancelButtonSpinner,
+  #exitButtonSpinner,
   #nextButtonCaret,
   #nextButtonSpinner {
     margin-inline-start: 8px;
@@ -108,14 +108,14 @@
   <div id="contentContainer"></div>
   <div id="footer">
     <cr-button
-      id="cancel" class="pill" on-click="onCancelButtonClicked_"
-      disabled="[[isButtonDisabled_(currentPage_.buttonCancel, allButtonsDisabled_)]]"
-      hidden$="[[isButtonHidden_(currentPage_.buttonCancel)]]">
-      <span id="cancelButtonLabel">
-        [[getCancelButtonLabel_(currentPage_.buttonCancelLabelKey)]]
+      id="exit" class="pill" on-click="onExitButtonClicked_"
+      disabled="[[isButtonDisabled_(currentPage_.buttonExit, allButtonsDisabled_)]]"
+      hidden$="[[isButtonHidden_(currentPage_.buttonExit)]]">
+      <span id="exitButtonLabel">
+        [[getExitButtonLabel_(currentPage_.buttonExitLabelKey)]]
       </span>
-      <paper-spinner-lite id="cancelButtonSpinner" class="busy-icon"
-          hidden$="[[!cancelButtonClicked_]]" active>
+      <paper-spinner-lite id="exitButtonSpinner" class="busy-icon"
+          hidden$="[[!exitButtonClicked_]]" active>
       </paper-spinner-lite>
     </cr-button>
     <cr-button
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js
index b34c704..2ca89ed2 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma.js
+++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -56,8 +56,8 @@
  *  requiresReloadWhenShown: boolean,
  *  buttonNext: !ButtonState,
  *  buttonNextLabelKey: ?string,
- *  buttonCancelLabelKey: ?string,
- *  buttonCancel: !ButtonState,
+ *  buttonExitLabelKey: ?string,
+ *  buttonExit: !ButtonState,
  *  buttonBack: !ButtonState,
  * }}
  */
@@ -72,7 +72,7 @@
     componentIs: 'critical-error-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.HIDDEN,
   },
   [State.kWelcomeScreen]: {
@@ -80,7 +80,7 @@
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
     buttonNextLabelKey: 'getStartedButtonLabel',
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kConfigureNetwork]: {
@@ -88,7 +88,7 @@
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
     buttonNextLabelKey: 'skipButtonLabel',
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kUpdateOs]: {
@@ -96,126 +96,126 @@
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
     buttonNextLabelKey: 'skipButtonLabel',
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kSelectComponents]: {
     componentIs: 'onboarding-select-components-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kChooseDestination]: {
     componentIs: 'onboarding-choose-destination-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kChooseWipeDevice]: {
     componentIs: 'onboarding-choose-wipe-device-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kChooseWriteProtectDisableMethod]: {
     componentIs: 'onboarding-choose-wp-disable-method-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kEnterRSUWPDisableCode]: {
     componentIs: 'onboarding-enter-rsu-wp-disable-code-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kWaitForManualWPDisable]: {
     componentIs: 'onboarding-wait-for-manual-wp-disable-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kWPDisableComplete]: {
     componentIs: 'onboarding-wp-disable-complete-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kUpdateRoFirmware]: {
     componentIs: 'reimaging-firmware-update-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kUpdateDeviceInformation]: {
     componentIs: 'reimaging-device-information-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kCheckCalibration]: {
     componentIs: 'reimaging-calibration-failed-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.DISABLED,
-    buttonCancelLabelKey: 'calibrationFailedSkipCalibrationButtonLabel',
-    buttonCancel: ButtonState.VISIBLE,
+    buttonExitLabelKey: 'calibrationFailedSkipCalibrationButtonLabel',
+    buttonExit: ButtonState.VISIBLE,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kRunCalibration]: {
     componentIs: 'reimaging-calibration-run-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kSetupCalibration]: {
     componentIs: 'reimaging-calibration-setup-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kProvisionDevice]: {
     componentIs: 'reimaging-provisioning-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kWaitForManualWPEnable]: {
     componentIs: 'wrapup-wait-for-manual-wp-enable-page',
     requiresReloadWhenShown: true,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kRestock]: {
     componentIs: 'wrapup-restock-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kFinalize]: {
     componentIs: 'wrapup-finalize-page',
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kRepairComplete]: {
     componentIs: 'wrapup-repair-complete-page',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
-    buttonCancel: ButtonState.HIDDEN,
+    buttonExit: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
 };
@@ -256,7 +256,7 @@
           componentIs: 'splash-screen',
           requiresReloadWhenShown: false,
           buttonNext: ButtonState.HIDDEN,
-          buttonCancel: ButtonState.HIDDEN,
+          buttonExit: ButtonState.HIDDEN,
           buttonBack: ButtonState.HIDDEN,
         },
       },
@@ -310,11 +310,11 @@
       },
 
       /**
-       * After the cancel button is clicked, true until the next state is
+       * After the exit button is clicked, true until the next state is
        * processed.
        * @protected
        */
-      cancelButtonClicked_: {
+      exitButtonClicked_: {
         type: Boolean,
         value: false,
       },
@@ -386,12 +386,12 @@
     };
 
     /**
-     * The cancelButtonCallback_ callback is used by the landing page to create
-     * its own Cancel button in the left pane.
+     * The exitButtonCallback_ callback is used by the landing page to create
+     * its own Exit button in the left pane.
      * @private {?Function}
      */
-    this.cancelButtonCallback_ = (e) => {
-      this.onCancelButtonClicked_();
+    this.exitButtonCallback_ = (e) => {
+      this.onExitButtonClicked_();
     };
 
     /**
@@ -426,7 +426,7 @@
         'disable-all-buttons', this.disableAllButtonsCallback_);
     window.addEventListener(
         'enable-all-buttons', this.enableAllButtonsCallback_);
-    window.addEventListener('click-cancel-button', this.cancelButtonCallback_);
+    window.addEventListener('click-exit-button', this.exitButtonCallback_);
     window.addEventListener('click-next-button', this.nextButtonCallback_);
   }
 
@@ -442,8 +442,7 @@
         'disable-all-buttons', this.disableAllButtonsCallback_);
     window.removeEventListener(
         'enable-all-buttons', this.enableAllButtonsCallback_);
-    window.removeEventListener(
-        'click-cancel-button', this.cancelButtonCallback_);
+    window.removeEventListener('click-exit-button', this.exitButtonCallback_);
     window.removeEventListener('click-next-button', this.nextButtonCallback_);
   }
 
@@ -532,7 +531,7 @@
     // Reset clicked variables to hide the spinners.
     this.nextButtonClicked_ = false;
     this.backButtonClicked_ = false;
-    this.cancelButtonClicked_ = false;
+    this.exitButtonClicked_ = false;
 
     const nextStatePageInfo = StateComponentMapping[stateResult.state];
     assert(nextStatePageInfo);
@@ -550,7 +549,7 @@
       // Set the next page as the current page.
       this.currentPage_ = nextStatePageInfo;
       if (!stateResult.canCancel) {
-        this.currentPage_.buttonCancel = ButtonState.HIDDEN;
+        this.currentPage_.buttonExit = ButtonState.HIDDEN;
       }
       if (!stateResult.canGoBack) {
         this.currentPage_.buttonBack = ButtonState.HIDDEN;
@@ -565,7 +564,7 @@
       // A special case for the landing page, which has its own navigation
       // buttons.
       currentPageComponent.getStartedButtonClicked = false;
-      currentPageComponent.landingCancelButtonClicked = false;
+      currentPageComponent.landingExitButtonClicked = false;
     }
 
     this.setAllButtonsState_(
@@ -694,28 +693,28 @@
   }
 
   /** @protected */
-  onCancelButtonClicked_() {
-    this.cancelButtonClicked_ = true;
+  onExitButtonClicked_() {
+    this.exitButtonClicked_ = true;
     this.setAllButtonsState_(
         /* shouldDisableButtons= */ true, /* showBusyStateOverlay= */ true);
     const page = this.shadowRoot.querySelector(this.currentPage_.componentIs);
-    if (page.onCancelButtonClick) {
+    if (page.onExitButtonClick) {
       // A special case for the calibration failed page, where the skip button
-      // replaces the cancel button.
+      // replaces the exit button.
       // TODO(swifton): find a more straightforward solution for this case.
-      page.onCancelButtonClick()
+      page.onExitButtonClick()
           .then((stateResult) => {
             this.processStateResult_(stateResult);
           })
           .catch((err) => {
-            this.cancelButtonClicked_ = false;
+            this.exitButtonClicked_ = false;
             this.setAllButtonsState_(
                 /* shouldDisableButtons= */ false,
                 /* showBusyStateOverlay= */ false);
           });
     } else {
       this.shimlessRmaService_.abortRma().then((result) => {
-        this.cancelButtonClicked_ = false;
+        this.exitButtonClicked_ = false;
         this.handleStandardAndCriticalError_(result.error);
       });
     }
@@ -736,10 +735,10 @@
    * @return {string}
    * @protected
    */
-  getCancelButtonLabel_() {
+  getExitButtonLabel_() {
     return this.i18n(
-        this.currentPage_.buttonCancelLabelKey ?
-            this.currentPage_.buttonCancelLabelKey :
+        this.currentPage_.buttonExitLabelKey ?
+            this.currentPage_.buttonExitLabelKey :
             'exitButtonLabel');
   }
 }
diff --git a/base/PRESUBMIT.py b/base/PRESUBMIT.py
index d0410f6..f23fb21 100644
--- a/base/PRESUBMIT.py
+++ b/base/PRESUBMIT.py
@@ -12,6 +12,24 @@
 USE_PYTHON3 = True
 
 
+def CheckChangeLintsClean(input_api, output_api):
+  """Makes sure that the code is cpplint clean."""
+  # lint_filters=[] stops the OFF_BY_DEFAULT_LINT_FILTERS from being disabled,
+  # finding many more issues. verbose_level=1 finds a small number of additional
+  # issues.
+  # The only valid extensions for cpplint are .cc, .h, .cpp, .cu, and .ch.
+  # Only process those extensions which are used in Chromium, in directories
+  # that currently lint clean.
+  CLEAN_CPP_FILES_ONLY = (r'base[\\/]win[\\/].*\.(cc|h)$', )
+  source_file_filter = lambda x: input_api.FilterSourceFile(
+      x,
+      files_to_check=CLEAN_CPP_FILES_ONLY,
+      files_to_skip=input_api.DEFAULT_FILES_TO_SKIP)
+  return input_api.canned_checks.CheckChangeLintsClean(
+      input_api, output_api, source_file_filter=source_file_filter,
+      lint_filters=[], verbose_level=1)
+
+
 def _CheckNoInterfacesInBase(input_api, output_api):
   """Checks to make sure no files in libbase.a have |@interface|."""
   pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE)
@@ -129,6 +147,7 @@
   results.extend(_CheckNoInterfacesInBase(input_api, output_api))
   results.extend(_CheckNoTraceEventInclude(input_api, output_api))
   results.extend(_WarnPbzeroIncludes(input_api, output_api))
+  results.extend(CheckChangeLintsClean(input_api, output_api))
   return results
 
 
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc
index 37c6429..5875ec1f 100644
--- a/base/allocator/partition_allocator/partition_root.cc
+++ b/base/allocator/partition_allocator/partition_root.cc
@@ -12,6 +12,7 @@
 #include "base/allocator/partition_allocator/page_allocator.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"
 #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
@@ -563,7 +564,7 @@
 }  // namespace internal
 
 template <bool thread_safe>
-[[noreturn]] NOINLINE void PartitionRoot<thread_safe>::OutOfMemory(
+[[noreturn]] PA_NOINLINE void PartitionRoot<thread_safe>::OutOfMemory(
     size_t size) {
   const size_t virtual_address_space_size =
       total_size_of_super_pages.load(std::memory_order_relaxed) +
@@ -988,7 +989,7 @@
   return result;
 #else
   bool no_hooks = flags & AllocFlags::kNoHooks;
-  if (UNLIKELY(!ptr)) {
+  if (PA_UNLIKELY(!ptr)) {
     return no_hooks
                ? AllocWithFlagsNoHooks(flags, new_size,
                                        internal::PartitionPageSize())
@@ -996,7 +997,7 @@
                      flags, new_size, internal::PartitionPageSize(), type_name);
   }
 
-  if (UNLIKELY(!new_size)) {
+  if (PA_UNLIKELY(!new_size)) {
     Free(ptr);
     return nullptr;
   }
@@ -1010,11 +1011,11 @@
   const bool hooks_enabled = PartitionAllocHooks::AreHooksEnabled();
   bool overridden = false;
   size_t old_usable_size;
-  if (UNLIKELY(!no_hooks && hooks_enabled)) {
+  if (PA_UNLIKELY(!no_hooks && hooks_enabled)) {
     overridden = PartitionAllocHooks::ReallocOverrideHookIfEnabled(
         &old_usable_size, ptr);
   }
-  if (LIKELY(!overridden)) {
+  if (PA_LIKELY(!overridden)) {
     // |ptr| may have been allocated in another root.
     SlotSpan* slot_span = SlotSpan::FromObject(ptr);
     auto* old_root = PartitionRoot::FromSlotSpan(slot_span);
@@ -1026,7 +1027,7 @@
       PA_DCHECK(IsValidSlotSpan(slot_span));
       old_usable_size = slot_span->GetUsableSize(old_root);
 
-      if (UNLIKELY(slot_span->bucket->is_direct_mapped())) {
+      if (PA_UNLIKELY(slot_span->bucket->is_direct_mapped())) {
         tried_in_place_for_direct_map = true;
         // We may be able to perform the realloc in place by changing the
         // accessibility of memory pages and, if reducing the size, decommitting
@@ -1035,14 +1036,14 @@
       }
     }
     if (success) {
-      if (UNLIKELY(!no_hooks && hooks_enabled)) {
+      if (PA_UNLIKELY(!no_hooks && hooks_enabled)) {
         PartitionAllocHooks::ReallocObserverHookIfEnabled(ptr, ptr, new_size,
                                                           type_name);
       }
       return ptr;
     }
 
-    if (LIKELY(!tried_in_place_for_direct_map)) {
+    if (PA_LIKELY(!tried_in_place_for_direct_map)) {
       if (old_root->TryReallocInPlaceForNormalBuckets(ptr, slot_span, new_size))
         return ptr;
     }
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index 051b81d..98b4d5b 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -43,6 +43,7 @@
 #include "base/allocator/partition_allocator/partition_address_space.h"
 #include "base/allocator/partition_allocator/partition_alloc-inl.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_base/thread_annotations.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/time/time.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
@@ -66,7 +67,6 @@
 #include "base/allocator/partition_allocator/tagging.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
 #include "base/base_export.h"
-#include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 #include "build/chromecast_buildflags.h"
@@ -108,7 +108,8 @@
 #if DCHECK_IS_ON()
 BASE_EXPORT void DCheckIfManagedByPartitionAllocBRPPool(uintptr_t address);
 #else
-ALWAYS_INLINE void DCheckIfManagedByPartitionAllocBRPPool(uintptr_t address) {}
+PA_ALWAYS_INLINE void DCheckIfManagedByPartitionAllocBRPPool(
+    uintptr_t address) {}
 #endif
 
 #if defined(PA_USE_PARTITION_ROOT_ENUMERATOR)
@@ -199,7 +200,7 @@
 // Never instantiate a PartitionRoot directly, instead use
 // PartitionAllocator.
 template <bool thread_safe>
-struct ALIGNAS(64) BASE_EXPORT PartitionRoot {
+struct PA_ALIGNAS(64) BASE_EXPORT PartitionRoot {
   using SlotSpan = internal::SlotSpanMetadata<thread_safe>;
   using Page = internal::PartitionPage<thread_safe>;
   using Bucket = internal::PartitionBucket<thread_safe>;
@@ -370,48 +371,49 @@
 
   void EnableThreadCacheIfSupported();
 
-  ALWAYS_INLINE static bool IsValidSlotSpan(SlotSpan* slot_span);
-  ALWAYS_INLINE static PartitionRoot* FromSlotSpan(SlotSpan* slot_span);
+  PA_ALWAYS_INLINE static bool IsValidSlotSpan(SlotSpan* slot_span);
+  PA_ALWAYS_INLINE static PartitionRoot* FromSlotSpan(SlotSpan* slot_span);
   // These two functions work unconditionally for normal buckets.
   // For direct map, they only work for the first super page of a reservation,
   // (see partition_alloc_constants.h for the direct map allocation layout).
   // In particular, the functions always work for a pointer to the start of a
   // reservation.
-  ALWAYS_INLINE static PartitionRoot* FromFirstSuperPage(uintptr_t super_page);
-  ALWAYS_INLINE static PartitionRoot* FromAddrInFirstSuperpage(
+  PA_ALWAYS_INLINE static PartitionRoot* FromFirstSuperPage(
+      uintptr_t super_page);
+  PA_ALWAYS_INLINE static PartitionRoot* FromAddrInFirstSuperpage(
       uintptr_t address);
 
-  ALWAYS_INLINE void DecreaseTotalSizeOfAllocatedBytes(SlotSpan* slot_span)
+  PA_ALWAYS_INLINE void DecreaseTotalSizeOfAllocatedBytes(SlotSpan* slot_span)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void IncreaseTotalSizeOfAllocatedBytes(SlotSpan* slot_span,
-                                                       size_t raw_size)
+  PA_ALWAYS_INLINE void IncreaseTotalSizeOfAllocatedBytes(SlotSpan* slot_span,
+                                                          size_t raw_size)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void DecreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
-                                                       size_t len)
+  PA_ALWAYS_INLINE void DecreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
+                                                          size_t len)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void IncreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
-                                                       size_t len,
-                                                       size_t raw_size)
+  PA_ALWAYS_INLINE void IncreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
+                                                          size_t len,
+                                                          size_t raw_size)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void IncreaseCommittedPages(size_t len);
-  ALWAYS_INLINE void DecreaseCommittedPages(size_t len);
-  ALWAYS_INLINE void DecommitSystemPagesForData(
+  PA_ALWAYS_INLINE void IncreaseCommittedPages(size_t len);
+  PA_ALWAYS_INLINE void DecreaseCommittedPages(size_t len);
+  PA_ALWAYS_INLINE void DecommitSystemPagesForData(
       uintptr_t address,
       size_t length,
       PageAccessibilityDisposition accessibility_disposition)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void RecommitSystemPagesForData(
+  PA_ALWAYS_INLINE void RecommitSystemPagesForData(
       uintptr_t address,
       size_t length,
       PageAccessibilityDisposition accessibility_disposition)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE bool TryRecommitSystemPagesForData(
+  PA_ALWAYS_INLINE bool TryRecommitSystemPagesForData(
       uintptr_t address,
       size_t length,
       PageAccessibilityDisposition accessibility_disposition)
       PA_LOCKS_EXCLUDED(lock_);
 
-  [[noreturn]] NOINLINE void OutOfMemory(size_t size);
+  [[noreturn]] PA_NOINLINE void OutOfMemory(size_t size);
 
   // Returns a pointer aligned on |alignment|, or nullptr.
   //
@@ -421,21 +423,20 @@
   //
   // NOTE: This is incompatible with anything that adds extras before the
   // returned pointer, such as ref-count.
-  ALWAYS_INLINE void* AlignedAllocWithFlags(unsigned int flags,
-                                            size_t alignment,
-                                            size_t requested_size);
+  PA_ALWAYS_INLINE void* AlignedAllocWithFlags(unsigned int flags,
+                                               size_t alignment,
+                                               size_t requested_size);
 
   // PartitionAlloc supports multiple partitions, and hence multiple callers to
-  // these functions. Setting ALWAYS_INLINE bloats code, and can be detrimental
-  // to performance, for instance if multiple callers are hot (by increasing
-  // cache footprint).
-  // Set NOINLINE on the "basic" top-level functions to mitigate that for
-  // "vanilla" callers.
-  NOINLINE PA_MALLOC_FN void* Alloc(size_t requested_size,
-                                    const char* type_name) PA_MALLOC_ALIGNED;
-  ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlags(unsigned int flags,
-                                                  size_t requested_size,
-                                                  const char* type_name)
+  // these functions. Setting PA_ALWAYS_INLINE bloats code, and can be
+  // detrimental to performance, for instance if multiple callers are hot (by
+  // increasing cache footprint). Set PA_NOINLINE on the "basic" top-level
+  // functions to mitigate that for "vanilla" callers.
+  PA_NOINLINE PA_MALLOC_FN void* Alloc(size_t requested_size,
+                                       const char* type_name) PA_MALLOC_ALIGNED;
+  PA_ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlags(unsigned int flags,
+                                                     size_t requested_size,
+                                                     const char* type_name)
       PA_MALLOC_ALIGNED;
   // Same as |AllocWithFlags()|, but allows specifying |slot_span_alignment|. It
   // has to be a multiple of partition page size, greater than 0 and no greater
@@ -443,7 +444,7 @@
   // special action is taken as PartitoinAlloc naturally guarantees this
   // alignment, otherwise a sub-optimial allocation strategy is used to
   // guarantee the higher-order alignment.
-  ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlagsInternal(
+  PA_ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlagsInternal(
       unsigned int flags,
       size_t requested_size,
       size_t slot_span_alignment,
@@ -456,38 +457,39 @@
   // exists. However, |AlignedAlloc()| and |Realloc()| have few callers, so
   // taking the extra branch in the non-malloc() case doesn't hurt. In addition,
   // for the malloc() case, the compiler correctly removes the branch, since
-  // this is marked |ALWAYS_INLINE|.
-  ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlagsNoHooks(
+  // this is marked |PA_ALWAYS_INLINE|.
+  PA_ALWAYS_INLINE PA_MALLOC_FN void* AllocWithFlagsNoHooks(
       unsigned int flags,
       size_t requested_size,
       size_t slot_span_alignment) PA_MALLOC_ALIGNED;
 
-  NOINLINE void* Realloc(void* ptr,
-                         size_t newize,
-                         const char* type_name) PA_MALLOC_ALIGNED;
+  PA_NOINLINE void* Realloc(void* ptr,
+                            size_t newize,
+                            const char* type_name) PA_MALLOC_ALIGNED;
   // Overload that may return nullptr if reallocation isn't possible. In this
   // case, |ptr| remains valid.
-  NOINLINE void* TryRealloc(void* ptr,
-                            size_t new_size,
-                            const char* type_name) PA_MALLOC_ALIGNED;
-  NOINLINE void* ReallocWithFlags(unsigned int flags,
-                                  void* ptr,
-                                  size_t new_size,
-                                  const char* type_name) PA_MALLOC_ALIGNED;
-  NOINLINE static void Free(void* object);
-  ALWAYS_INLINE static void FreeWithFlags(unsigned int flags, void* object);
+  PA_NOINLINE void* TryRealloc(void* ptr,
+                               size_t new_size,
+                               const char* type_name) PA_MALLOC_ALIGNED;
+  PA_NOINLINE void* ReallocWithFlags(unsigned int flags,
+                                     void* ptr,
+                                     size_t new_size,
+                                     const char* type_name) PA_MALLOC_ALIGNED;
+  PA_NOINLINE static void Free(void* object);
+  PA_ALWAYS_INLINE static void FreeWithFlags(unsigned int flags, void* object);
   // Same as |Free()|, bypasses the allocator hooks.
-  ALWAYS_INLINE static void FreeNoHooks(void* object);
+  PA_ALWAYS_INLINE static void FreeNoHooks(void* object);
   // Immediately frees the pointer bypassing the quarantine. |slot_start| is the
   // beginning of the slot that contains |object|.
-  ALWAYS_INLINE void FreeNoHooksImmediate(void* object,
-                                          SlotSpan* slot_span,
-                                          uintptr_t slot_start);
+  PA_ALWAYS_INLINE void FreeNoHooksImmediate(void* object,
+                                             SlotSpan* slot_span,
+                                             uintptr_t slot_start);
 
-  ALWAYS_INLINE static size_t GetUsableSize(void* ptr);
+  PA_ALWAYS_INLINE static size_t GetUsableSize(void* ptr);
 
-  ALWAYS_INLINE size_t AllocationCapacityFromPtr(void* ptr) const;
-  ALWAYS_INLINE size_t AllocationCapacityFromRequestedSize(size_t size) const;
+  PA_ALWAYS_INLINE size_t AllocationCapacityFromPtr(void* ptr) const;
+  PA_ALWAYS_INLINE size_t
+  AllocationCapacityFromRequestedSize(size_t size) const;
 
   // Frees memory from this partition, if possible, by decommitting pages or
   // even entire slot spans. |flags| is an OR of base::PartitionPurgeFlags.
@@ -515,21 +517,23 @@
   static uint16_t SizeToBucketIndex(size_t size,
                                     bool with_denser_bucket_distribution);
 
-  ALWAYS_INLINE void FreeInSlotSpan(uintptr_t slot_start, SlotSpan* slot_span)
+  PA_ALWAYS_INLINE void FreeInSlotSpan(uintptr_t slot_start,
+                                       SlotSpan* slot_span)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Frees memory, with |slot_start| as returned by |RawAlloc()|.
-  ALWAYS_INLINE void RawFree(uintptr_t slot_start);
-  ALWAYS_INLINE void RawFree(uintptr_t slot_start, SlotSpan* slot_span)
+  PA_ALWAYS_INLINE void RawFree(uintptr_t slot_start);
+  PA_ALWAYS_INLINE void RawFree(uintptr_t slot_start, SlotSpan* slot_span)
       PA_LOCKS_EXCLUDED(lock_);
 
-  ALWAYS_INLINE void RawFreeBatch(FreeListEntry* head,
-                                  FreeListEntry* tail,
-                                  size_t size,
-                                  SlotSpan* slot_span) PA_LOCKS_EXCLUDED(lock_);
+  PA_ALWAYS_INLINE void RawFreeBatch(FreeListEntry* head,
+                                     FreeListEntry* tail,
+                                     size_t size,
+                                     SlotSpan* slot_span)
+      PA_LOCKS_EXCLUDED(lock_);
 
-  ALWAYS_INLINE void RawFreeWithThreadCache(uintptr_t slot_start,
-                                            SlotSpan* slot_span);
+  PA_ALWAYS_INLINE void RawFreeWithThreadCache(uintptr_t slot_start,
+                                               SlotSpan* slot_span);
 
   // This is safe to do because we are switching to a bucket distribution with
   // more buckets, meaning any allocations we have done before the switch are
@@ -579,19 +583,19 @@
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
   }
 
-  ALWAYS_INLINE bool IsQuarantineAllowed() const {
+  PA_ALWAYS_INLINE bool IsQuarantineAllowed() const {
     return flags.quarantine_mode != QuarantineMode::kAlwaysDisabled;
   }
 
-  ALWAYS_INLINE bool IsQuarantineEnabled() const {
+  PA_ALWAYS_INLINE bool IsQuarantineEnabled() const {
     return flags.quarantine_mode == QuarantineMode::kEnabled;
   }
 
-  ALWAYS_INLINE bool ShouldQuarantine(void* object) const {
-    if (UNLIKELY(flags.quarantine_mode != QuarantineMode::kEnabled))
+  PA_ALWAYS_INLINE bool ShouldQuarantine(void* object) const {
+    if (PA_UNLIKELY(flags.quarantine_mode != QuarantineMode::kEnabled))
       return false;
 #if defined(PA_HAS_MEMORY_TAGGING)
-    if (UNLIKELY(quarantine_always_for_testing))
+    if (PA_UNLIKELY(quarantine_always_for_testing))
       return true;
     // If quarantine is enabled and the tag overflows, move the containing slot
     // to quarantine, to prevent the attacker from exploiting a pointer that has
@@ -602,17 +606,17 @@
 #endif
   }
 
-  ALWAYS_INLINE void SetQuarantineAlwaysForTesting(bool value) {
+  PA_ALWAYS_INLINE void SetQuarantineAlwaysForTesting(bool value) {
     quarantine_always_for_testing = value;
   }
 
-  ALWAYS_INLINE bool IsScanEnabled() const {
+  PA_ALWAYS_INLINE bool IsScanEnabled() const {
     // Enabled scan implies enabled quarantine.
     PA_DCHECK(flags.scan_mode != ScanMode::kEnabled || IsQuarantineEnabled());
     return flags.scan_mode == ScanMode::kEnabled;
   }
 
-  static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+  static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
   GetDirectMapMetadataAndGuardPagesSize() {
     // Because we need to fake a direct-map region to look like a super page, we
     // need to allocate more pages around the payload:
@@ -625,7 +629,7 @@
     return 2 * internal::PartitionPageSize();
   }
 
-  static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+  static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
   GetDirectMapSlotSize(size_t raw_size) {
     // Caller must check that the size is not above the MaxDirectMapped()
     // limit before calling. This also guards against integer overflow in the
@@ -635,7 +639,7 @@
         raw_size, internal::SystemPageSize());
   }
 
-  static ALWAYS_INLINE size_t
+  static PA_ALWAYS_INLINE size_t
   GetDirectMapReservationSize(size_t padded_raw_size) {
     // Caller must check that the size is not above the MaxDirectMapped()
     // limit before calling. This also guards against integer overflow in the
@@ -646,7 +650,7 @@
         internal::DirectMapAllocationGranularity());
   }
 
-  ALWAYS_INLINE size_t AdjustSize0IfNeeded(size_t size) const {
+  PA_ALWAYS_INLINE size_t AdjustSize0IfNeeded(size_t size) const {
     // There are known cases where allowing size 0 would lead to problems:
     // 1. If extras are present only before allocation (e.g. BRP ref-count), the
     //    extras will fill the entire kAlignment-sized slot, leading to
@@ -669,14 +673,14 @@
     // be rather complex. Then there is also the fear of the unknown. The
     // existing cases were discovered through obscure, painful-to-debug crashes.
     // Better save ourselves trouble with not-yet-discovered cases.
-    if (UNLIKELY(size == 0))
+    if (PA_UNLIKELY(size == 0))
       return 1;
     return size;
   }
 
   // Adjusts the size by adding extras. Also include the 0->1 adjustment if
   // needed.
-  ALWAYS_INLINE size_t AdjustSizeForExtrasAdd(size_t size) const {
+  PA_ALWAYS_INLINE size_t AdjustSizeForExtrasAdd(size_t size) const {
     size = AdjustSize0IfNeeded(size);
     PA_DCHECK(size + flags.extras_size >= size);
     return size + flags.extras_size;
@@ -686,31 +690,31 @@
   // which leads to an asymmetry with AdjustSizeForExtrasAdd, but callers of
   // AdjustSizeForExtrasSubtract either expect the adjustment to be included, or
   // are indifferent.
-  ALWAYS_INLINE size_t AdjustSizeForExtrasSubtract(size_t size) const {
+  PA_ALWAYS_INLINE size_t AdjustSizeForExtrasSubtract(size_t size) const {
     return size - flags.extras_size;
   }
 
-  ALWAYS_INLINE void* SlotStartToObject(uintptr_t slot_start) const {
+  PA_ALWAYS_INLINE void* SlotStartToObject(uintptr_t slot_start) const {
     // TODO(bartekn): Move MTE tagging here.
     // TODO(bartekn): Check that |slot_start| is indeed a slot start.
     return reinterpret_cast<void*>(slot_start + flags.extras_offset);
   }
 
-  ALWAYS_INLINE uintptr_t ObjectToSlotStart(void* object) const {
+  PA_ALWAYS_INLINE uintptr_t ObjectToSlotStart(void* object) const {
     // TODO(bartekn): Move MTE untagging here.
     return reinterpret_cast<uintptr_t>(object) - flags.extras_offset;
     // TODO(bartekn): Check that the result is indeed a slot start.
   }
 
-  static ALWAYS_INLINE uintptr_t ObjectInnerPtr2Addr(void* object) {
+  static PA_ALWAYS_INLINE uintptr_t ObjectInnerPtr2Addr(void* object) {
     // TODO(bartekn): Add MTE untagging here.
     return reinterpret_cast<uintptr_t>(object);
   }
-  static ALWAYS_INLINE uintptr_t ObjectPtr2Addr(void* object) {
+  static PA_ALWAYS_INLINE uintptr_t ObjectPtr2Addr(void* object) {
     // TODO(bartekn): Check that |object| is indeed an object start.
     return ObjectInnerPtr2Addr(object);
   }
-  static ALWAYS_INLINE void* SlotStartAddr2Ptr(uintptr_t slot_start) {
+  static PA_ALWAYS_INLINE void* SlotStartAddr2Ptr(uintptr_t slot_start) {
     // TODO(bartekn): Move MTE tagging here.
     // TODO(bartekn): Check that |slot_start| is indeed a slot start.
     return reinterpret_cast<void*>(slot_start);
@@ -724,7 +728,7 @@
 #endif
   }
 
-  ALWAYS_INLINE bool uses_configurable_pool() const {
+  PA_ALWAYS_INLINE bool uses_configurable_pool() const {
     return flags.use_configurable_pool;
   }
 
@@ -737,7 +741,7 @@
   }
 
 #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
-  ALWAYS_INLINE partition_alloc::PartitionTag GetNewPartitionTag() {
+  PA_ALWAYS_INLINE partition_alloc::PartitionTag GetNewPartitionTag() {
     // TODO(crbug.com/1298696): performance is not an issue. We can use
     // random tags in lieu of sequential ones.
     auto tag = ++current_partition_tag;
@@ -761,7 +765,7 @@
   //
   // See crbug.com/1150772 for an instance of Clusterfuzz / UBSAN detecting
   // this.
-  ALWAYS_INLINE const Bucket& NO_SANITIZE("undefined")
+  PA_ALWAYS_INLINE const Bucket& PA_NO_SANITIZE("undefined")
       bucket_at(size_t i) const {
     PA_DCHECK(i <= internal::kNumBuckets);
     return buckets[i];
@@ -780,7 +784,7 @@
   // - The bucket is relatively frequently written to, by *all* threads
   //   (e.g. every time a slot span becomes full or empty), so accessing it will
   //   result in some amount of cacheline ping-pong.
-  ALWAYS_INLINE bool IsDirectMappedBucket(Bucket* bucket) const {
+  PA_ALWAYS_INLINE bool IsDirectMappedBucket(Bucket* bucket) const {
     // All regular allocations are associated with a bucket in the |buckets_|
     // array. A range check is then sufficient to identify direct-mapped
     // allocations.
@@ -796,18 +800,18 @@
   //   |requested_size|.
   // - |usable_size| and |is_already_zeroed| are output only. |usable_size| is
   //   guaranteed to be larger or equal to AllocWithFlags()'s |requested_size|.
-  ALWAYS_INLINE uintptr_t RawAlloc(Bucket* bucket,
-                                   unsigned int flags,
-                                   size_t raw_size,
-                                   size_t slot_span_alignment,
-                                   size_t* usable_size,
-                                   bool* is_already_zeroed);
-  ALWAYS_INLINE uintptr_t AllocFromBucket(Bucket* bucket,
-                                          unsigned int flags,
-                                          size_t raw_size,
-                                          size_t slot_span_alignment,
-                                          size_t* usable_size,
-                                          bool* is_already_zeroed)
+  PA_ALWAYS_INLINE uintptr_t RawAlloc(Bucket* bucket,
+                                      unsigned int flags,
+                                      size_t raw_size,
+                                      size_t slot_span_alignment,
+                                      size_t* usable_size,
+                                      bool* is_already_zeroed);
+  PA_ALWAYS_INLINE uintptr_t AllocFromBucket(Bucket* bucket,
+                                             unsigned int flags,
+                                             size_t raw_size,
+                                             size_t slot_span_alignment,
+                                             size_t* usable_size,
+                                             bool* is_already_zeroed)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   bool TryReallocInPlaceForNormalBuckets(void* ptr,
@@ -817,7 +821,7 @@
       internal::SlotSpanMetadata<thread_safe>* slot_span,
       size_t requested_size) PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
   void DecommitEmptySlotSpans() PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
-  ALWAYS_INLINE void RawFreeLocked(uintptr_t slot_start)
+  PA_ALWAYS_INLINE void RawFreeLocked(uintptr_t slot_start)
       PA_EXCLUSIVE_LOCKS_REQUIRED(lock_);
   uintptr_t MaybeInitThreadCacheAndAlloc(uint16_t bucket_index,
                                          size_t* slot_size);
@@ -862,7 +866,7 @@
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
 
-ALWAYS_INLINE uintptr_t
+PA_ALWAYS_INLINE uintptr_t
 PartitionAllocGetDirectMapSlotStartInBRPPool(uintptr_t address) {
   PA_DCHECK(IsManagedByPartitionAllocBRPPool(address));
 #if defined(PA_HAS_64_BITS_POINTERS)
@@ -907,7 +911,8 @@
 // This isn't a general purpose function, it is used specifically for obtaining
 // BackupRefPtr's ref-count. The caller is responsible for ensuring that the
 // ref-count is in place for this allocation.
-ALWAYS_INLINE uintptr_t PartitionAllocGetSlotStartInBRPPool(uintptr_t address) {
+PA_ALWAYS_INLINE uintptr_t
+PartitionAllocGetSlotStartInBRPPool(uintptr_t address) {
   address = ::partition_alloc::internal::UnmaskPtr(address);
 
   // Adjust to support pointers right past the end of an allocation, which in
@@ -924,7 +929,7 @@
 
   uintptr_t directmap_slot_start =
       PartitionAllocGetDirectMapSlotStartInBRPPool(address);
-  if (UNLIKELY(directmap_slot_start))
+  if (PA_UNLIKELY(directmap_slot_start))
     return directmap_slot_start;
   auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromAddr(address);
   auto* root = PartitionRoot<ThreadSafe>::FromSlotSpan(slot_span);
@@ -949,8 +954,8 @@
 //
 // This isn't a general purpose function. The caller is responsible for ensuring
 // that the ref-count is in place for this allocation.
-ALWAYS_INLINE bool PartitionAllocIsValidPtrDelta(uintptr_t address,
-                                                 ptrdiff_t delta_in_bytes) {
+PA_ALWAYS_INLINE bool PartitionAllocIsValidPtrDelta(uintptr_t address,
+                                                    ptrdiff_t delta_in_bytes) {
   // Required for pointers right past an allocation. See
   // |PartitionAllocGetSlotStartInBRPPool()|.
   uintptr_t adjusted_address = address - kPartitionPastAllocationAdjustment;
@@ -977,7 +982,7 @@
          new_address <= object_addr + slot_span->GetUsableSize(root);
 }
 
-ALWAYS_INLINE void PartitionAllocFreeForRefCounting(uintptr_t slot_start) {
+PA_ALWAYS_INLINE void PartitionAllocFreeForRefCounting(uintptr_t slot_start) {
   PA_DCHECK(!PartitionRefCountPointer(slot_start)->IsAlive());
 
   auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotStart(slot_start);
@@ -1008,7 +1013,7 @@
 }  // namespace internal
 
 template <bool thread_safe>
-ALWAYS_INLINE uintptr_t
+PA_ALWAYS_INLINE uintptr_t
 PartitionRoot<thread_safe>::AllocFromBucket(Bucket* bucket,
                                             unsigned int flags,
                                             size_t raw_size,
@@ -1031,8 +1036,8 @@
   // first active slot span. However, fall back to the slow path if a
   // higher-order alignment is requested, because an inner slot of an existing
   // slot span is unlikely to satisfy it.
-  if (LIKELY(slot_span_alignment <= internal::PartitionPageSize() &&
-             slot_start)) {
+  if (PA_LIKELY(slot_span_alignment <= internal::PartitionPageSize() &&
+                slot_start)) {
     *is_already_zeroed = false;
     // This is a fast path, so avoid calling GetUsableSize() on Release builds
     // as it is more costly. Copy its small bucket path instead.
@@ -1054,7 +1059,7 @@
   } else {
     slot_start = bucket->SlowPathAlloc(this, flags, raw_size,
                                        slot_span_alignment, is_already_zeroed);
-    if (UNLIKELY(!slot_start))
+    if (PA_UNLIKELY(!slot_start))
       return 0;
 
     slot_span = SlotSpan::FromSlotStart(slot_start);
@@ -1074,14 +1079,15 @@
 
 // static
 template <bool thread_safe>
-NOINLINE void PartitionRoot<thread_safe>::Free(void* object) {
+PA_NOINLINE void PartitionRoot<thread_safe>::Free(void* object) {
   return FreeWithFlags(0, object);
 }
 
 // static
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeWithFlags(unsigned int flags,
-                                                             void* object) {
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeWithFlags(
+    unsigned int flags,
+    void* object) {
   PA_DCHECK(flags < FreeFlags::kLastFlag << 1);
 
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
@@ -1090,7 +1096,7 @@
     return;
   }
 #endif  // defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
-  if (UNLIKELY(!object))
+  if (PA_UNLIKELY(!object))
     return;
 
   if (PartitionAllocHooks::AreHooksEnabled()) {
@@ -1104,8 +1110,8 @@
 
 // static
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooks(void* object) {
-  if (UNLIKELY(!object))
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooks(void* object) {
+  if (PA_UNLIKELY(!object))
     return;
   // Almost all calls to FreeNoNooks() will end up writing to |*object|, the
   // only cases where we don't would be delayed free() in PCScan, but |*object|
@@ -1146,7 +1152,7 @@
 
 #if defined(PA_HAS_MEMORY_TAGGING)
   const size_t slot_size = slot_span->bucket->slot_size;
-  if (LIKELY(slot_size <= internal::kMaxMemoryTaggingSize)) {
+  if (PA_LIKELY(slot_size <= internal::kMaxMemoryTaggingSize)) {
     // TODO(bartekn): |slot_start| shouldn't have MTE tag.
     slot_start = ::partition_alloc::internal::TagMemoryRangeIncrement(
         slot_start, slot_size);
@@ -1178,12 +1184,12 @@
   }
 #endif  // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
 
-  // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by
+  // TODO(bikineev): Change the condition to PA_LIKELY once PCScan is enabled by
   // default.
-  if (UNLIKELY(root->ShouldQuarantine(object))) {
+  if (PA_UNLIKELY(root->ShouldQuarantine(object))) {
     // PCScan safepoint. Call before potentially scheduling scanning task.
     PCScan::JoinScanIfNeeded();
-    if (LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
+    if (PA_LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
       PCScan::MoveToQuarantine(object, slot_span->GetUsableSize(root),
                                slot_start, slot_span->bucket->slot_size);
       return;
@@ -1194,7 +1200,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooksImmediate(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooksImmediate(
     void* object,
     SlotSpan* slot_span,
     uintptr_t slot_start) {
@@ -1242,10 +1248,10 @@
   }
 #endif
 
-  // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by
+  // TODO(bikineev): Change the condition to PA_LIKELY once PCScan is enabled by
   // default.
-  if (UNLIKELY(IsQuarantineEnabled())) {
-    if (LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
+  if (PA_UNLIKELY(IsQuarantineEnabled())) {
+    if (PA_LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
       uintptr_t unmasked_slot_start =
           ::partition_alloc::internal::UnmaskPtr(slot_start);
       // Mark the state in the state bitmap as freed.
@@ -1255,18 +1261,18 @@
   }
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  // TODO(keishi): Add LIKELY when brp is fully enabled as |brp_enabled| will be
-  // false only for the aligned partition.
+  // TODO(keishi): Add PA_LIKELY when brp is fully enabled as |brp_enabled| will
+  // be false only for the aligned partition.
   if (brp_enabled()) {
     auto* ref_count = internal::PartitionRefCountPointer(slot_start);
     // If there are no more references to the allocation, it can be freed
     // immediately. Otherwise, defer the operation and zap the memory to turn
     // potential use-after-free issues into unexploitable crashes.
-    if (UNLIKELY(!ref_count->IsAliveWithNoKnownRefs()))
+    if (PA_UNLIKELY(!ref_count->IsAliveWithNoKnownRefs()))
       internal::SecureMemset(object, internal::kQuarantinedByte,
                              slot_span->GetUsableSize(this));
 
-    if (UNLIKELY(!(ref_count->ReleaseFromAllocator()))) {
+    if (PA_UNLIKELY(!(ref_count->ReleaseFromAllocator()))) {
       total_size_of_brp_quarantined_bytes.fetch_add(
           slot_span->GetSlotSizeForBookkeeping(), std::memory_order_relaxed);
       total_count_of_brp_quarantined_slots.fetch_add(1,
@@ -1287,7 +1293,7 @@
 #elif defined(PA_ZERO_RANDOMLY_ON_FREE)
   // `memset` only once in a while: we're trading off safety for time
   // efficiency.
-  if (UNLIKELY(internal::RandomPeriod()) &&
+  if (PA_UNLIKELY(internal::RandomPeriod()) &&
       !IsDirectMappedBucket(slot_span->bucket)) {
     internal::SecureMemset(SlotStartAddr2Ptr(slot_start), 0,
                            slot_span->GetUtilizedSlotSize()
@@ -1302,7 +1308,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeInSlotSpan(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeInSlotSpan(
     uintptr_t slot_start,
     SlotSpan* slot_span) {
   DecreaseTotalSizeOfAllocatedBytes(slot_span);
@@ -1310,14 +1316,15 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFree(uintptr_t slot_start) {
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFree(
+    uintptr_t slot_start) {
   SlotSpan* slot_span = SlotSpan::FromSlotStart(slot_start);
   RawFree(slot_start, slot_span);
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFree(uintptr_t slot_start,
-                                                       SlotSpan* slot_span) {
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFree(uintptr_t slot_start,
+                                                          SlotSpan* slot_span) {
   // At this point we are about to acquire the lock, so we try to minimize the
   // risk of blocking inside the locked section.
   //
@@ -1355,7 +1362,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeBatch(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeBatch(
     FreeListEntry* head,
     FreeListEntry* tail,
     size_t size,
@@ -1374,19 +1381,19 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeWithThreadCache(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeWithThreadCache(
     uintptr_t slot_start,
     SlotSpan* slot_span) {
   // TLS access can be expensive, do a cheap local check first.
   //
-  // LIKELY: performance-sensitive partitions have a thread cache, direct-mapped
-  // allocations are uncommon.
-  if (LIKELY(flags.with_thread_cache &&
-             !IsDirectMappedBucket(slot_span->bucket))) {
+  // PA_LIKELY: performance-sensitive partitions have a thread cache,
+  // direct-mapped allocations are uncommon.
+  if (PA_LIKELY(flags.with_thread_cache &&
+                !IsDirectMappedBucket(slot_span->bucket))) {
     size_t bucket_index = slot_span->bucket - this->buckets;
     auto* thread_cache = ThreadCache::Get();
-    if (LIKELY(ThreadCache::IsValid(thread_cache) &&
-               thread_cache->MaybePutInCache(slot_start, bucket_index))) {
+    if (PA_LIKELY(ThreadCache::IsValid(thread_cache) &&
+                  thread_cache->MaybePutInCache(slot_start, bucket_index))) {
       return;
     }
   }
@@ -1395,7 +1402,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeLocked(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RawFreeLocked(
     uintptr_t slot_start) {
   SlotSpan* slot_span = SlotSpan::FromSlotStart(slot_start);
   // Direct-mapped deallocation releases then re-acquires the lock. The caller
@@ -1407,7 +1414,7 @@
 
 // static
 template <bool thread_safe>
-ALWAYS_INLINE bool PartitionRoot<thread_safe>::IsValidSlotSpan(
+PA_ALWAYS_INLINE bool PartitionRoot<thread_safe>::IsValidSlotSpan(
     SlotSpan* slot_span) {
   slot_span = ::partition_alloc::internal::UnmaskPtr(slot_span);
   PartitionRoot* root = FromSlotSpan(slot_span);
@@ -1415,7 +1422,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE PartitionRoot<thread_safe>*
+PA_ALWAYS_INLINE PartitionRoot<thread_safe>*
 PartitionRoot<thread_safe>::FromSlotSpan(SlotSpan* slot_span) {
   auto* extent_entry = reinterpret_cast<SuperPageExtentEntry*>(
       reinterpret_cast<uintptr_t>(slot_span) & internal::SystemPageBaseMask());
@@ -1423,7 +1430,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE PartitionRoot<thread_safe>*
+PA_ALWAYS_INLINE PartitionRoot<thread_safe>*
 PartitionRoot<thread_safe>::FromFirstSuperPage(uintptr_t super_page) {
   PA_DCHECK(internal::IsReservationStart(super_page));
   auto* extent_entry =
@@ -1434,7 +1441,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE PartitionRoot<thread_safe>*
+PA_ALWAYS_INLINE PartitionRoot<thread_safe>*
 PartitionRoot<thread_safe>::FromAddrInFirstSuperpage(uintptr_t address) {
   uintptr_t super_page = address & internal::kSuperPageBaseMask;
   PA_DCHECK(internal::IsReservationStart(super_page));
@@ -1442,7 +1449,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void
+PA_ALWAYS_INLINE void
 PartitionRoot<thread_safe>::IncreaseTotalSizeOfAllocatedBytes(
     SlotSpan* slot_span,
     size_t raw_size) {
@@ -1452,7 +1459,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void
+PA_ALWAYS_INLINE void
 PartitionRoot<thread_safe>::DecreaseTotalSizeOfAllocatedBytes(
     SlotSpan* slot_span) {
   DecreaseTotalSizeOfAllocatedBytes(reinterpret_cast<uintptr_t>(slot_span),
@@ -1460,7 +1467,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void
+PA_ALWAYS_INLINE void
 PartitionRoot<thread_safe>::IncreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
                                                               size_t len,
                                                               size_t raw_size) {
@@ -1473,7 +1480,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void
+PA_ALWAYS_INLINE void
 PartitionRoot<thread_safe>::DecreaseTotalSizeOfAllocatedBytes(uintptr_t addr,
                                                               size_t len) {
   // An underflow here means we've miscounted |total_size_of_allocated_bytes|
@@ -1486,7 +1493,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::IncreaseCommittedPages(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::IncreaseCommittedPages(
     size_t len) {
   const auto old_total =
       total_size_of_committed_pages.fetch_add(len, std::memory_order_relaxed);
@@ -1504,13 +1511,13 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::DecreaseCommittedPages(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::DecreaseCommittedPages(
     size_t len) {
   total_size_of_committed_pages.fetch_sub(len, std::memory_order_relaxed);
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::DecommitSystemPagesForData(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::DecommitSystemPagesForData(
     uintptr_t address,
     size_t length,
     PageAccessibilityDisposition accessibility_disposition) {
@@ -1521,7 +1528,7 @@
 
 // Not unified with TryRecommitSystemPagesForData() to preserve error codes.
 template <bool thread_safe>
-ALWAYS_INLINE void PartitionRoot<thread_safe>::RecommitSystemPagesForData(
+PA_ALWAYS_INLINE void PartitionRoot<thread_safe>::RecommitSystemPagesForData(
     uintptr_t address,
     size_t length,
     PageAccessibilityDisposition accessibility_disposition) {
@@ -1530,7 +1537,7 @@
   bool ok = TryRecommitSystemPages(
       address, length, PageAccessibilityConfiguration::kReadWriteTagged,
       accessibility_disposition);
-  if (UNLIKELY(!ok)) {
+  if (PA_UNLIKELY(!ok)) {
     // Decommit some memory and retry. The alternative is crashing.
     DecommitEmptySlotSpans();
     RecommitSystemPages(address, length,
@@ -1542,7 +1549,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE bool PartitionRoot<thread_safe>::TryRecommitSystemPagesForData(
+PA_ALWAYS_INLINE bool PartitionRoot<thread_safe>::TryRecommitSystemPagesForData(
     uintptr_t address,
     size_t length,
     PageAccessibilityDisposition accessibility_disposition) {
@@ -1551,7 +1558,7 @@
       address, length, PageAccessibilityConfiguration::kReadWriteTagged,
       accessibility_disposition);
 #if defined(PA_COMMIT_CHARGE_IS_LIMITED)
-  if (UNLIKELY(!ok)) {
+  if (PA_UNLIKELY(!ok)) {
     {
       ::partition_alloc::internal::ScopedGuard guard(lock_);
       DecommitEmptySlotSpans();
@@ -1579,7 +1586,7 @@
 // where this isn't the case. Note, an inner object pointer won't work for
 // direct map, unless it is within the first partition page.
 template <bool thread_safe>
-ALWAYS_INLINE size_t PartitionRoot<thread_safe>::GetUsableSize(void* ptr) {
+PA_ALWAYS_INLINE size_t PartitionRoot<thread_safe>::GetUsableSize(void* ptr) {
   // malloc_usable_size() is expected to handle NULL gracefully and return 0.
   if (!ptr)
     return 0;
@@ -1593,7 +1600,7 @@
 // a new allocation (or realloc) happened with that returned value, it'd use
 // the same amount of underlying memory.
 template <bool thread_safe>
-ALWAYS_INLINE size_t
+PA_ALWAYS_INLINE size_t
 PartitionRoot<thread_safe>::AllocationCapacityFromPtr(void* object) const {
   uintptr_t slot_start = ObjectToSlotStart(object);
   auto* slot_span = SlotSpan::FromSlotStart(slot_start);
@@ -1602,7 +1609,7 @@
 
 // static
 template <bool thread_safe>
-ALWAYS_INLINE uint16_t PartitionRoot<thread_safe>::SizeToBucketIndex(
+PA_ALWAYS_INLINE uint16_t PartitionRoot<thread_safe>::SizeToBucketIndex(
     size_t size,
     bool with_denser_bucket_distribution) {
   if (with_denser_bucket_distribution)
@@ -1612,7 +1619,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlags(
+PA_ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlags(
     unsigned int flags,
     size_t requested_size,
     const char* type_name) {
@@ -1621,7 +1628,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlagsInternal(
+PA_ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlagsInternal(
     unsigned int flags,
     size_t requested_size,
     size_t slot_span_alignment,
@@ -1646,7 +1653,7 @@
 #endif  // defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
   void* object = nullptr;
   const bool hooks_enabled = PartitionAllocHooks::AreHooksEnabled();
-  if (UNLIKELY(hooks_enabled)) {
+  if (PA_UNLIKELY(hooks_enabled)) {
     if (PartitionAllocHooks::AllocationOverrideHookIfEnabled(
             &object, flags, requested_size, type_name)) {
       PartitionAllocHooks::AllocationObserverHookIfEnabled(
@@ -1657,7 +1664,7 @@
 
   object = AllocWithFlagsNoHooks(flags, requested_size, slot_span_alignment);
 
-  if (UNLIKELY(hooks_enabled)) {
+  if (PA_UNLIKELY(hooks_enabled)) {
     PartitionAllocHooks::AllocationObserverHookIfEnabled(object, requested_size,
                                                          type_name);
   }
@@ -1666,7 +1673,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlagsNoHooks(
+PA_ALWAYS_INLINE void* PartitionRoot<thread_safe>::AllocWithFlagsNoHooks(
     unsigned int flags,
     size_t requested_size,
     size_t slot_span_alignment) {
@@ -1701,29 +1708,29 @@
 
   const bool is_quarantine_enabled = IsQuarantineEnabled();
   // PCScan safepoint. Call before trying to allocate from cache.
-  // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by
+  // TODO(bikineev): Change the condition to PA_LIKELY once PCScan is enabled by
   // default.
-  if (UNLIKELY(is_quarantine_enabled)) {
+  if (PA_UNLIKELY(is_quarantine_enabled)) {
     PCScan::JoinScanIfNeeded();
   }
 
   // Don't use thread cache if higher order alignment is requested, because the
   // thread cache will not be able to satisfy it.
   //
-  // LIKELY: performance-sensitive partitions use the thread cache.
-  if (LIKELY(this->flags.with_thread_cache &&
-             slot_span_alignment <= internal::PartitionPageSize())) {
+  // PA_LIKELY: performance-sensitive partitions use the thread cache.
+  if (PA_LIKELY(this->flags.with_thread_cache &&
+                slot_span_alignment <= internal::PartitionPageSize())) {
     auto* tcache = ThreadCache::Get();
-    // LIKELY: Typically always true, except for the very first allocation of
+    // PA_LIKELY: Typically always true, except for the very first allocation of
     // this thread.
-    if (LIKELY(ThreadCache::IsValid(tcache))) {
+    if (PA_LIKELY(ThreadCache::IsValid(tcache))) {
       slot_start = tcache->GetFromCache(bucket_index, &slot_size);
     } else {
       slot_start = MaybeInitThreadCacheAndAlloc(bucket_index, &slot_size);
     }
 
-    // LIKELY: median hit rate in the thread cache is 95%, from metrics.
-    if (LIKELY(slot_start)) {
+    // PA_LIKELY: median hit rate in the thread cache is 95%, from metrics.
+    if (PA_LIKELY(slot_start)) {
       // This follows the logic of SlotSpanMetadata::GetUsableSize for small
       // buckets, which is too expensive to call here.
       // Keep it in sync!
@@ -1753,7 +1760,7 @@
                  &usable_size, &is_already_zeroed);
   }
 
-  if (UNLIKELY(!slot_start))
+  if (PA_UNLIKELY(!slot_start))
     return nullptr;
 
   // Layout inside the slot:
@@ -1814,8 +1821,8 @@
   // Fill the region kUninitializedByte (on debug builds, if not requested to 0)
   // or 0 (if requested and not 0 already).
   bool zero_fill = flags & AllocFlags::kZeroFill;
-  // LIKELY: operator new() calls malloc(), not calloc().
-  if (LIKELY(!zero_fill)) {
+  // PA_LIKELY: operator new() calls malloc(), not calloc().
+  if (PA_LIKELY(!zero_fill)) {
     // memset() can be really expensive.
 #if EXPENSIVE_DCHECKS_ARE_ON()
     internal::DebugMemset(object, internal::kUninitializedByte, usable_size);
@@ -1825,8 +1832,8 @@
   }
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  // TODO(keishi): Add LIKELY when brp is fully enabled as |brp_enabled| will be
-  // false only for the aligned partition.
+  // TODO(keishi): Add PA_LIKELY when brp is fully enabled as |brp_enabled| will
+  // be false only for the aligned partition.
   if (brp_enabled()) {
     auto* ref_count = new (internal::PartitionRefCountPointer(slot_start))
         internal::PartitionRefCount();
@@ -1838,10 +1845,10 @@
   }
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
 
-  // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by
+  // TODO(bikineev): Change the condition to PA_LIKELY once PCScan is enabled by
   // default.
-  if (UNLIKELY(is_quarantine_enabled)) {
-    if (LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
+  if (PA_UNLIKELY(is_quarantine_enabled)) {
+    if (PA_LIKELY(internal::IsManagedByNormalBuckets(slot_start))) {
       uintptr_t unmasked_slot_start =
           ::partition_alloc::internal::UnmaskPtr(slot_start);
       // Mark the corresponding bits in the state bitmap as allocated.
@@ -1854,7 +1861,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE uintptr_t
+PA_ALWAYS_INLINE uintptr_t
 PartitionRoot<thread_safe>::RawAlloc(Bucket* bucket,
                                      unsigned int flags,
                                      size_t raw_size,
@@ -1867,7 +1874,7 @@
 }
 
 template <bool thread_safe>
-ALWAYS_INLINE void* PartitionRoot<thread_safe>::AlignedAllocWithFlags(
+PA_ALWAYS_INLINE void* PartitionRoot<thread_safe>::AlignedAllocWithFlags(
     unsigned int flags,
     size_t alignment,
     size_t requested_size) {
@@ -1907,7 +1914,7 @@
     // Handle cases such as size = 16, alignment = 64.
     // Wastes memory when a large alignment is requested with a small size, but
     // this is hard to avoid, and should not be too common.
-    if (UNLIKELY(raw_size < alignment)) {
+    if (PA_UNLIKELY(raw_size < alignment)) {
       raw_size = alignment;
     } else {
       // PartitionAlloc only guarantees alignment for power-of-two sized
@@ -1924,7 +1931,7 @@
     adjusted_size = AdjustSizeForExtrasSubtract(raw_size);
 
     // Overflow check. adjusted_size must be larger or equal to requested_size.
-    if (UNLIKELY(adjusted_size < requested_size)) {
+    if (PA_UNLIKELY(adjusted_size < requested_size)) {
       if (flags & AllocFlags::kReturnNull)
         return nullptr;
       // OutOfMemoryDeathTest.AlignedAlloc requires
@@ -1957,22 +1964,23 @@
 }
 
 template <bool thread_safe>
-NOINLINE void* PartitionRoot<thread_safe>::Alloc(size_t requested_size,
-                                                 const char* type_name) {
+PA_NOINLINE void* PartitionRoot<thread_safe>::Alloc(size_t requested_size,
+                                                    const char* type_name) {
   return AllocWithFlags(0, requested_size, type_name);
 }
 
 template <bool thread_safe>
-NOINLINE void* PartitionRoot<thread_safe>::Realloc(void* ptr,
-                                                   size_t new_size,
-                                                   const char* type_name) {
+PA_NOINLINE void* PartitionRoot<thread_safe>::Realloc(void* ptr,
+                                                      size_t new_size,
+                                                      const char* type_name) {
   return ReallocWithFlags(0, ptr, new_size, type_name);
 }
 
 template <bool thread_safe>
-NOINLINE void* PartitionRoot<thread_safe>::TryRealloc(void* ptr,
-                                                      size_t new_size,
-                                                      const char* type_name) {
+PA_NOINLINE void* PartitionRoot<thread_safe>::TryRealloc(
+    void* ptr,
+    size_t new_size,
+    const char* type_name) {
   return ReallocWithFlags(AllocFlags::kReturnNull, ptr, new_size, type_name);
 }
 
@@ -1982,7 +1990,7 @@
 // returned value, it'd use the same amount of underlying memory as the
 // allocation with |size|.
 template <bool thread_safe>
-ALWAYS_INLINE size_t
+PA_ALWAYS_INLINE size_t
 PartitionRoot<thread_safe>::AllocationCapacityFromRequestedSize(
     size_t size) const {
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
@@ -1995,7 +2003,7 @@
   PA_DCHECK(!bucket.slot_size || bucket.slot_size >= size);
   PA_DCHECK(!(bucket.slot_size % internal::kSmallestBucket));
 
-  if (LIKELY(!bucket.is_direct_mapped())) {
+  if (PA_LIKELY(!bucket.is_direct_mapped())) {
     size = bucket.slot_size;
   } else if (size > internal::MaxDirectMapped()) {
     // Too large to allocate => return the size unchanged.
diff --git a/base/allocator/partition_allocator/partition_tag.h b/base/allocator/partition_allocator/partition_tag.h
index 3e24a2f..d8e3a5a 100644
--- a/base/allocator/partition_allocator/partition_tag.h
+++ b/base/allocator/partition_allocator/partition_tag.h
@@ -11,6 +11,7 @@
 #include <string.h>
 
 #include "base/allocator/buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
 #include "base/allocator/partition_allocator/partition_alloc_notreached.h"
 #include "base/allocator/partition_allocator/partition_cookie.h"
@@ -33,7 +34,7 @@
     sizeof(PartitionTag) == internal::tag_bitmap::kPartitionTagSize,
     "sizeof(PartitionTag) must be equal to bitmap::kPartitionTagSize.");
 
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(uintptr_t addr) {
+PA_ALWAYS_INLINE PartitionTag* PartitionTagPointer(uintptr_t addr) {
   // TODO(crbug.com/1307514): Add direct map support. For now, just assume
   // that direct maps don't have tags.
   PA_DCHECK(internal::IsManagedByNormalBuckets(addr));
@@ -51,16 +52,16 @@
   return reinterpret_cast<PartitionTag*>(bitmap_base + offset_in_bitmap);
 }
 
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(const void* ptr) {
+PA_ALWAYS_INLINE PartitionTag* PartitionTagPointer(const void* ptr) {
   return PartitionTagPointer(
       internal::UnmaskPtr(reinterpret_cast<uintptr_t>(ptr)));
 }
 
 namespace internal {
 
-ALWAYS_INLINE void PartitionTagSetValue(uintptr_t addr,
-                                        size_t size,
-                                        PartitionTag value) {
+PA_ALWAYS_INLINE void PartitionTagSetValue(uintptr_t addr,
+                                           size_t size,
+                                           PartitionTag value) {
   PA_DCHECK((size % tag_bitmap::kBytesPerPartitionTag) == 0);
   size_t tag_count = size >> tag_bitmap::kBytesPerPartitionTagShift;
   PartitionTag* tag_ptr = PartitionTagPointer(addr);
@@ -72,24 +73,24 @@
   }
 }
 
-ALWAYS_INLINE void PartitionTagSetValue(void* ptr,
-                                        size_t size,
-                                        PartitionTag value) {
+PA_ALWAYS_INLINE void PartitionTagSetValue(void* ptr,
+                                           size_t size,
+                                           PartitionTag value) {
   PartitionTagSetValue(reinterpret_cast<uintptr_t>(ptr), size, value);
 }
 
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) {
+PA_ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) {
   return *PartitionTagPointer(ptr);
 }
 
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t size) {
+PA_ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t size) {
   size_t tag_region_size = size >> tag_bitmap::kBytesPerPartitionTagShift
                                        << tag_bitmap::kPartitionTagSizeShift;
   PA_DCHECK(!memchr(PartitionTagPointer(ptr), 0, tag_region_size));
   memset(PartitionTagPointer(ptr), 0, tag_region_size);
 }
 
-ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {
+PA_ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {
   PartitionTag tag = PartitionTagGetValue(ptr);
   PartitionTag new_tag = tag;
   ++new_tag;
@@ -113,22 +114,22 @@
 
 using PartitionTag = uint8_t;
 
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) {
+PA_ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) {
   PA_NOTREACHED();
   return nullptr;
 }
 
 namespace internal {
 
-ALWAYS_INLINE void PartitionTagSetValue(void*, size_t, PartitionTag) {}
+PA_ALWAYS_INLINE void PartitionTagSetValue(void*, size_t, PartitionTag) {}
 
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void*) {
+PA_ALWAYS_INLINE PartitionTag PartitionTagGetValue(void*) {
   return 0;
 }
 
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t) {}
+PA_ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t) {}
 
-ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {}
+PA_ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {}
 
 }  // namespace internal
 
diff --git a/base/allocator/partition_allocator/partition_tag_bitmap.h b/base/allocator/partition_allocator/partition_tag_bitmap.h
index 9d149aa..d494fa4 100644
--- a/base/allocator/partition_allocator/partition_tag_bitmap.h
+++ b/base/allocator/partition_allocator/partition_tag_bitmap.h
@@ -7,6 +7,7 @@
 
 #include "base/allocator/buildflags.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_constants.h"
 
 namespace partition_alloc::internal {
@@ -68,7 +69,7 @@
 //   PartitionPageSize()
 // Finally,
 //   kTagBitmapSize >= (kSuperPageSize - 2 * PartitionPageSize()) / (1 + Y)
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
 NumPartitionPagesPerTagBitmap() {
   return tag_bitmap::CeilCountOfUnits(
       kSuperPageSize / PartitionPageSize() - 2,
@@ -79,7 +80,7 @@
 // number of SystemPages of TagBitmap. If kNumSystemPagesPerTagBitmap *
 // SystemPageSize() < kTagBitmapSize, guard pages will be created. (c.f. no
 // guard pages if sizeof(PartitionTag) == 2.)
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
 NumSystemPagesPerTagBitmap() {
   return tag_bitmap::CeilCountOfUnits(
       kSuperPageSize / SystemPageSize() -
@@ -87,13 +88,13 @@
       tag_bitmap::kBytesPerPartitionTagRatio + 1);
 }
 
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
 ActualTagBitmapSize() {
   return NumSystemPagesPerTagBitmap() * SystemPageSize();
 }
 
 // PartitionPageSize-aligned tag bitmap size.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
 ReservedTagBitmapSize() {
   return PartitionPageSize() * NumPartitionPagesPerTagBitmap();
 }
@@ -110,7 +111,7 @@
 // The region available for slot spans is the reminder of the super page, after
 // taking away the first and last partition page (for metadata and guard pages)
 // and partition pages reserved for the tag bitmap.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
+PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR PA_ALWAYS_INLINE size_t
 SlotSpansSize() {
   return kSuperPageSize - 2 * PartitionPageSize() - ReservedTagBitmapSize();
 }
@@ -126,15 +127,15 @@
 
 #else
 
-constexpr ALWAYS_INLINE size_t NumPartitionPagesPerTagBitmap() {
+constexpr PA_ALWAYS_INLINE size_t NumPartitionPagesPerTagBitmap() {
   return 0;
 }
 
-constexpr ALWAYS_INLINE size_t ActualTagBitmapSize() {
+constexpr PA_ALWAYS_INLINE size_t ActualTagBitmapSize() {
   return 0;
 }
 
-constexpr ALWAYS_INLINE size_t ReservedTagBitmapSize() {
+constexpr PA_ALWAYS_INLINE size_t ReservedTagBitmapSize() {
   return 0;
 }
 
diff --git a/base/allocator/partition_allocator/partition_tls.h b/base/allocator/partition_allocator/partition_tls.h
index 8bc72cf9..ec90b7b7 100644
--- a/base/allocator/partition_allocator/partition_tls.h
+++ b/base/allocator/partition_allocator/partition_tls.h
@@ -5,10 +5,10 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TLS_H_
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TLS_H_
 
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/immediate_crash.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/base_export.h"
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_POSIX)
@@ -34,7 +34,7 @@
 #if BUILDFLAG(IS_MAC) && defined(ARCH_CPU_X86_64)
 namespace {
 
-ALWAYS_INLINE void* FastTlsGet(intptr_t index) {
+PA_ALWAYS_INLINE void* FastTlsGet(intptr_t index) {
   // On macOS, pthread_getspecific() is in libSystem, so a call to it has to go
   // through PLT. However, and contrary to some other platforms, *all* TLS keys
   // are in a static array in the thread structure. So they are *always* at a
@@ -61,12 +61,12 @@
 }  // namespace
 #endif  // BUILDFLAG(IS_MAC) && defined(ARCH_CPU_X86_64)
 
-ALWAYS_INLINE bool PartitionTlsCreate(PartitionTlsKey* key,
-                                      void (*destructor)(void*)) {
+PA_ALWAYS_INLINE bool PartitionTlsCreate(PartitionTlsKey* key,
+                                         void (*destructor)(void*)) {
   return !pthread_key_create(key, destructor);
 }
 
-ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
+PA_ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
 #if BUILDFLAG(IS_MAC) && defined(ARCH_CPU_X86_64)
   PA_DCHECK(pthread_getspecific(key) == FastTlsGet(key));
   return FastTlsGet(key);
@@ -75,7 +75,7 @@
 #endif
 }
 
-ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
+PA_ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
   int ret = pthread_setspecific(key, value);
   PA_DCHECK(!ret);
 }
@@ -88,7 +88,7 @@
 BASE_EXPORT bool PartitionTlsCreate(PartitionTlsKey* key,
                                     void (*destructor)(void*));
 
-ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
+PA_ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
   // Accessing TLS resets the last error, which then makes |GetLastError()|
   // return something misleading. While this means that properly using
   // |GetLastError()| is difficult, there is currently code in Chromium which
@@ -105,12 +105,12 @@
   DWORD saved_error = GetLastError();
   void* ret = TlsGetValue(key);
   // Only non-zero errors need to be restored.
-  if (UNLIKELY(saved_error))
+  if (PA_UNLIKELY(saved_error))
     SetLastError(saved_error);
   return ret;
 }
 
-ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
+PA_ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
   BOOL ret = TlsSetValue(key, value);
   PA_DCHECK(ret);
 }
@@ -122,17 +122,17 @@
 // Not supported.
 using PartitionTlsKey = int;
 
-ALWAYS_INLINE bool PartitionTlsCreate(PartitionTlsKey* key,
-                                      void (*destructor)(void*)) {
+PA_ALWAYS_INLINE bool PartitionTlsCreate(PartitionTlsKey* key,
+                                         void (*destructor)(void*)) {
   // NOTIMPLEMENTED() may allocate, crash instead.
   PA_IMMEDIATE_CRASH();
 }
 
-ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
+PA_ALWAYS_INLINE void* PartitionTlsGet(PartitionTlsKey key) {
   PA_IMMEDIATE_CRASH();
 }
 
-ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
+PA_ALWAYS_INLINE void PartitionTlsSet(PartitionTlsKey key, void* value) {
   PA_IMMEDIATE_CRASH();
 }
 
diff --git a/base/allocator/partition_allocator/reservation_offset_table.h b/base/allocator/partition_allocator/reservation_offset_table.h
index a26bd830..2c614d4 100644
--- a/base/allocator/partition_allocator/reservation_offset_table.h
+++ b/base/allocator/partition_allocator/reservation_offset_table.h
@@ -13,11 +13,11 @@
 #include "base/allocator/buildflags.h"
 #include "base/allocator/partition_allocator/address_pool_manager.h"
 #include "base/allocator/partition_allocator/partition_address_space.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
 #include "base/allocator/partition_allocator/tagging.h"
 #include "base/base_export.h"
-#include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 
@@ -102,45 +102,48 @@
 };
 
 #if defined(PA_HAS_64_BITS_POINTERS)
-ALWAYS_INLINE uint16_t* GetReservationOffsetTable(pool_handle handle) {
+PA_ALWAYS_INLINE uint16_t* GetReservationOffsetTable(pool_handle handle) {
   PA_DCHECK(0 < handle && handle <= kNumPools);
   return ReservationOffsetTable::reservation_offset_tables_[handle - 1].offsets;
 }
 
-ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(pool_handle handle) {
+PA_ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(
+    pool_handle handle) {
   return GetReservationOffsetTable(handle) +
          ReservationOffsetTable::kReservationOffsetTableLength;
 }
 
-ALWAYS_INLINE uint16_t* GetReservationOffsetTable(uintptr_t address) {
+PA_ALWAYS_INLINE uint16_t* GetReservationOffsetTable(uintptr_t address) {
   pool_handle handle = GetPool(address);
   return GetReservationOffsetTable(handle);
 }
 
-ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(uintptr_t address) {
+PA_ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(
+    uintptr_t address) {
   pool_handle handle = GetPool(address);
   return GetReservationOffsetTableEnd(handle);
 }
 
-ALWAYS_INLINE uint16_t* ReservationOffsetPointer(pool_handle pool,
-                                                 uintptr_t offset_in_pool) {
+PA_ALWAYS_INLINE uint16_t* ReservationOffsetPointer(pool_handle pool,
+                                                    uintptr_t offset_in_pool) {
   size_t table_index = offset_in_pool >> kSuperPageShift;
   PA_DCHECK(table_index <
             ReservationOffsetTable::kReservationOffsetTableLength);
   return GetReservationOffsetTable(pool) + table_index;
 }
 #else
-ALWAYS_INLINE uint16_t* GetReservationOffsetTable(uintptr_t address) {
+PA_ALWAYS_INLINE uint16_t* GetReservationOffsetTable(uintptr_t address) {
   return ReservationOffsetTable::reservation_offset_table_.offsets;
 }
 
-ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(uintptr_t address) {
+PA_ALWAYS_INLINE const uint16_t* GetReservationOffsetTableEnd(
+    uintptr_t address) {
   return ReservationOffsetTable::reservation_offset_table_.offsets +
          ReservationOffsetTable::kReservationOffsetTableLength;
 }
 #endif
 
-ALWAYS_INLINE uint16_t* ReservationOffsetPointer(uintptr_t address) {
+PA_ALWAYS_INLINE uint16_t* ReservationOffsetPointer(uintptr_t address) {
 #if defined(PA_HAS_64_BITS_POINTERS)
   // In 64-bit mode, find the owning Pool and compute the offset from its base.
   address = ::partition_alloc::internal::UnmaskPtr(address);
@@ -154,15 +157,15 @@
 #endif
 }
 
-ALWAYS_INLINE uintptr_t ComputeReservationStart(uintptr_t address,
-                                                uint16_t* offset_ptr) {
+PA_ALWAYS_INLINE uintptr_t ComputeReservationStart(uintptr_t address,
+                                                   uint16_t* offset_ptr) {
   return (address & kSuperPageBaseMask) -
          (static_cast<size_t>(*offset_ptr) << kSuperPageShift);
 }
 
 // If the given address doesn't point to direct-map allocated memory,
 // returns 0.
-ALWAYS_INLINE uintptr_t GetDirectMapReservationStart(uintptr_t address) {
+PA_ALWAYS_INLINE uintptr_t GetDirectMapReservationStart(uintptr_t address) {
 #if DCHECK_IS_ON()
   bool is_in_brp_pool = IsManagedByPartitionAllocBRPPool(address);
   bool is_in_regular_pool = IsManagedByPartitionAllocRegularPool(address);
@@ -201,9 +204,10 @@
 // returns 0.
 // This variant has better performance than the regular one on 64-bit builds if
 // the Pool that an allocation belongs to is known.
-ALWAYS_INLINE uintptr_t GetDirectMapReservationStart(uintptr_t address,
-                                                     pool_handle pool,
-                                                     uintptr_t offset_in_pool) {
+PA_ALWAYS_INLINE uintptr_t
+GetDirectMapReservationStart(uintptr_t address,
+                             pool_handle pool,
+                             uintptr_t offset_in_pool) {
   PA_DCHECK(AddressPoolManager::GetInstance().GetPoolBaseAddress(pool) +
                 offset_in_pool ==
             address);
@@ -221,7 +225,7 @@
 // reservation, i.e. either a normal bucket super page, or the first super page
 // of direct map.
 // |address| must belong to an allocated super page.
-ALWAYS_INLINE bool IsReservationStart(uintptr_t address) {
+PA_ALWAYS_INLINE bool IsReservationStart(uintptr_t address) {
   uint16_t* offset_ptr = ReservationOffsetPointer(address);
   PA_DCHECK(*offset_ptr != kOffsetTagNotAllocated);
   return ((*offset_ptr == kOffsetTagNormalBuckets) || (*offset_ptr == 0)) &&
@@ -229,13 +233,13 @@
 }
 
 // Returns true if |address| belongs to a normal bucket super page.
-ALWAYS_INLINE bool IsManagedByNormalBuckets(uintptr_t address) {
+PA_ALWAYS_INLINE bool IsManagedByNormalBuckets(uintptr_t address) {
   uint16_t* offset_ptr = ReservationOffsetPointer(address);
   return *offset_ptr == kOffsetTagNormalBuckets;
 }
 
 // Returns true if |address| belongs to a direct map region.
-ALWAYS_INLINE bool IsManagedByDirectMap(uintptr_t address) {
+PA_ALWAYS_INLINE bool IsManagedByDirectMap(uintptr_t address) {
   uint16_t* offset_ptr = ReservationOffsetPointer(address);
   return *offset_ptr != kOffsetTagNormalBuckets &&
          *offset_ptr != kOffsetTagNotAllocated;
@@ -243,7 +247,7 @@
 
 // Returns true if |address| belongs to a normal bucket super page or a direct
 // map region, i.e. belongs to an allocated super page.
-ALWAYS_INLINE bool IsManagedByNormalBucketsOrDirectMap(uintptr_t address) {
+PA_ALWAYS_INLINE bool IsManagedByNormalBucketsOrDirectMap(uintptr_t address) {
   uint16_t* offset_ptr = ReservationOffsetPointer(address);
   return *offset_ptr != kOffsetTagNotAllocated;
 }
diff --git a/base/allocator/partition_allocator/spinning_mutex.cc b/base/allocator/partition_allocator/spinning_mutex.cc
index 875c596..9b06852 100644
--- a/base/allocator/partition_allocator/spinning_mutex.cc
+++ b/base/allocator/partition_allocator/spinning_mutex.cc
@@ -4,6 +4,7 @@
 
 #include "base/allocator/partition_allocator/spinning_mutex.h"
 
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "build/build_config.h"
 
@@ -53,7 +54,7 @@
   int tries = 0;
   int backoff = 1;
   do {
-    if (LIKELY(Try()))
+    if (PA_LIKELY(Try()))
       return;
     // Note: Per the intel optimization manual
     // (https://software.intel.com/content/dam/develop/public/us/en/documents/64-ia-32-architectures-optimization-manual.pdf),
diff --git a/base/allocator/partition_allocator/spinning_mutex.h b/base/allocator/partition_allocator/spinning_mutex.h
index 3bf1e1e..a6f92c9 100644
--- a/base/allocator/partition_allocator/spinning_mutex.h
+++ b/base/allocator/partition_allocator/spinning_mutex.h
@@ -9,12 +9,12 @@
 #include <atomic>
 
 #include "base/allocator/buildflags.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/yield_processor.h"
 #include "base/base_export.h"
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_WIN)
@@ -68,14 +68,14 @@
 class PA_LOCKABLE BASE_EXPORT SpinningMutex {
  public:
   inline constexpr SpinningMutex();
-  ALWAYS_INLINE void Acquire() PA_EXCLUSIVE_LOCK_FUNCTION();
-  ALWAYS_INLINE void Release() PA_UNLOCK_FUNCTION();
-  ALWAYS_INLINE bool Try() PA_EXCLUSIVE_TRYLOCK_FUNCTION(true);
+  PA_ALWAYS_INLINE void Acquire() PA_EXCLUSIVE_LOCK_FUNCTION();
+  PA_ALWAYS_INLINE void Release() PA_UNLOCK_FUNCTION();
+  PA_ALWAYS_INLINE bool Try() PA_EXCLUSIVE_TRYLOCK_FUNCTION(true);
   void AssertAcquired() const {}  // Not supported.
   void Reinit() PA_UNLOCK_FUNCTION();
 
  private:
-  NOINLINE void AcquireSpinThenBlock() PA_EXCLUSIVE_LOCK_FUNCTION();
+  PA_NOINLINE void AcquireSpinThenBlock() PA_EXCLUSIVE_LOCK_FUNCTION();
   void LockSlow() PA_EXCLUSIVE_LOCK_FUNCTION();
 
   // See below, the latency of PA_YIELD_PROCESSOR can be as high as ~150
@@ -115,18 +115,18 @@
 #endif  // BUILDFLAG(IS_APPLE)
 
   // Spinlock-like, fallback.
-  ALWAYS_INLINE bool TrySpinLock();
-  ALWAYS_INLINE void ReleaseSpinLock();
+  PA_ALWAYS_INLINE bool TrySpinLock();
+  PA_ALWAYS_INLINE void ReleaseSpinLock();
   void LockSlowSpinLock();
 
 #endif  // defined(PA_HAS_FAST_MUTEX)
 };
 
-ALWAYS_INLINE void SpinningMutex::Acquire() {
-  // Not marked LIKELY(), as:
+PA_ALWAYS_INLINE void SpinningMutex::Acquire() {
+  // Not marked PA_LIKELY(), as:
   // 1. We don't know how much contention the lock would experience
   // 2. This may lead to weird-looking code layout when inlined into a caller
-  // with (UN)LIKELY() annotations.
+  // with (UN)PA_LIKELY() annotations.
   if (Try())
     return;
 
@@ -139,7 +139,7 @@
 
 #if defined(PA_HAS_LINUX_KERNEL)
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   // Using the weak variant of compare_exchange(), which may fail spuriously. On
   // some architectures such as ARM, CAS is typically performed as a LDREX/STREX
   // pair, where the store may fail. In the strong version, there is a loop
@@ -154,9 +154,9 @@
                                       std::memory_order_relaxed);
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
-  if (UNLIKELY(state_.exchange(kUnlocked, std::memory_order_release) ==
-               kLockedContended)) {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
+  if (PA_UNLIKELY(state_.exchange(kUnlocked, std::memory_order_release) ==
+                  kLockedContended)) {
     // |kLockedContended|: there is a waiter to wake up.
     //
     // Here there is a window where the lock is unlocked, since we just set it
@@ -176,34 +176,34 @@
 
 #elif BUILDFLAG(IS_WIN)
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   return !!::TryAcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&lock_));
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
   ::ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&lock_));
 }
 
 #elif BUILDFLAG(IS_POSIX)
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   int retval = pthread_mutex_trylock(&lock_);
   PA_DCHECK(retval == 0 || retval == EBUSY);
   return retval == 0;
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
   int retval = pthread_mutex_unlock(&lock_);
   PA_DCHECK(retval == 0);
 }
 
 #elif BUILDFLAG(IS_FUCHSIA)
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   return sync_mutex_trylock(&lock_) == ZX_OK;
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
   sync_mutex_unlock(&lock_);
 }
 
@@ -211,42 +211,42 @@
 
 #else  // defined(PA_HAS_FAST_MUTEX)
 
-ALWAYS_INLINE bool SpinningMutex::TrySpinLock() {
+PA_ALWAYS_INLINE bool SpinningMutex::TrySpinLock() {
   // Possibly faster than CAS. The theory is that if the cacheline is shared,
   // then it can stay shared, for the contended case.
   return !lock_.load(std::memory_order_relaxed) &&
          !lock_.exchange(true, std::memory_order_acquire);
 }
 
-ALWAYS_INLINE void SpinningMutex::ReleaseSpinLock() {
+PA_ALWAYS_INLINE void SpinningMutex::ReleaseSpinLock() {
   lock_.store(false, std::memory_order_release);
 }
 
 #if BUILDFLAG(IS_APPLE)
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   return os_unfair_lock_trylock(&unfair_lock_);
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
   return os_unfair_lock_unlock(&unfair_lock_);
 }
 
-ALWAYS_INLINE void SpinningMutex::LockSlow() {
+PA_ALWAYS_INLINE void SpinningMutex::LockSlow() {
   return os_unfair_lock_lock(&unfair_lock_);
 }
 
 #else
 
-ALWAYS_INLINE bool SpinningMutex::Try() {
+PA_ALWAYS_INLINE bool SpinningMutex::Try() {
   return TrySpinLock();
 }
 
-ALWAYS_INLINE void SpinningMutex::Release() {
+PA_ALWAYS_INLINE void SpinningMutex::Release() {
   return ReleaseSpinLock();
 }
 
-ALWAYS_INLINE void SpinningMutex::LockSlow() {
+PA_ALWAYS_INLINE void SpinningMutex::LockSlow() {
   return LockSlowSpinLock();
 }
 
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h
index aeb4dfa..3ae585a 100644
--- a/base/allocator/partition_allocator/thread_cache.h
+++ b/base/allocator/partition_allocator/thread_cache.h
@@ -10,6 +10,7 @@
 #include <limits>
 #include <memory>
 
+#include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/gtest_prod_util.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/time/time.h"
@@ -21,7 +22,6 @@
 #include "base/allocator/partition_allocator/partition_stats.h"
 #include "base/allocator/partition_allocator/partition_tls.h"
 #include "base/base_export.h"
-#include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 
@@ -279,14 +279,16 @@
   // Returns true if the slot was put in the cache, and false otherwise. This
   // can happen either because the cache is full or the allocation was too
   // large.
-  ALWAYS_INLINE bool MaybePutInCache(uintptr_t slot_start, size_t bucket_index);
+  PA_ALWAYS_INLINE bool MaybePutInCache(uintptr_t slot_start,
+                                        size_t bucket_index);
 
   // Tries to allocate a memory slot from the cache.
   // Returns 0 on failure.
   //
   // Has the same behavior as RawAlloc(), that is: no cookie nor ref-count
   // handling. Sets |slot_size| to the allocated size upon success.
-  ALWAYS_INLINE uintptr_t GetFromCache(size_t bucket_index, size_t* slot_size);
+  PA_ALWAYS_INLINE uintptr_t GetFromCache(size_t bucket_index,
+                                          size_t* slot_size);
 
   // Asks this cache to trigger |Purge()| at a later point. Can be called from
   // any thread.
@@ -367,7 +369,7 @@
   template <bool crash_on_corruption>
   void ClearBucketHelper(Bucket& bucket, size_t limit);
   void ClearBucket(Bucket& bucket, size_t limit);
-  ALWAYS_INLINE void PutInBucket(Bucket& bucket, uintptr_t slot_start);
+  PA_ALWAYS_INLINE void PutInBucket(Bucket& bucket, uintptr_t slot_start);
   void ResetForTesting();
   // Releases the entire freelist starting at |head| to the root.
   template <bool crash_on_corruption>
@@ -457,12 +459,12 @@
   PA_FRIEND_TEST_ALL_PREFIXES(PartitionAllocThreadCacheTest, ClearFromTail);
 };
 
-ALWAYS_INLINE bool ThreadCache::MaybePutInCache(uintptr_t slot_start,
-                                                size_t bucket_index) {
+PA_ALWAYS_INLINE bool ThreadCache::MaybePutInCache(uintptr_t slot_start,
+                                                   size_t bucket_index) {
   PA_REENTRANCY_GUARD(is_in_thread_cache_);
   PA_INCREMENT_COUNTER(stats_.cache_fill_count);
 
-  if (UNLIKELY(bucket_index > largest_active_bucket_index_)) {
+  if (PA_UNLIKELY(bucket_index > largest_active_bucket_index_)) {
     PA_INCREMENT_COUNTER(stats_.cache_fill_misses);
     return false;
   }
@@ -481,18 +483,18 @@
   // gambling that the compiler would not issue multiple loads.
   uint8_t limit = bucket.limit.load(std::memory_order_relaxed);
   // Batched deallocation, amortizing lock acquisitions.
-  if (UNLIKELY(bucket.count > limit)) {
+  if (PA_UNLIKELY(bucket.count > limit)) {
     ClearBucket(bucket, limit / 2);
   }
 
-  if (UNLIKELY(should_purge_.load(std::memory_order_relaxed)))
+  if (PA_UNLIKELY(should_purge_.load(std::memory_order_relaxed)))
     PurgeInternal();
 
   return true;
 }
 
-ALWAYS_INLINE uintptr_t ThreadCache::GetFromCache(size_t bucket_index,
-                                                  size_t* slot_size) {
+PA_ALWAYS_INLINE uintptr_t ThreadCache::GetFromCache(size_t bucket_index,
+                                                     size_t* slot_size) {
 #if defined(PA_THREAD_CACHE_ALLOC_STATS)
   stats_.allocs_per_bucket_[bucket_index]++;
 #endif
@@ -500,14 +502,14 @@
   PA_REENTRANCY_GUARD(is_in_thread_cache_);
   PA_INCREMENT_COUNTER(stats_.alloc_count);
   // Only handle "small" allocations.
-  if (UNLIKELY(bucket_index > largest_active_bucket_index_)) {
+  if (PA_UNLIKELY(bucket_index > largest_active_bucket_index_)) {
     PA_INCREMENT_COUNTER(stats_.alloc_miss_too_large);
     PA_INCREMENT_COUNTER(stats_.alloc_misses);
     return 0;
   }
 
   auto& bucket = buckets_[bucket_index];
-  if (LIKELY(bucket.freelist_head)) {
+  if (PA_LIKELY(bucket.freelist_head)) {
     PA_INCREMENT_COUNTER(stats_.alloc_hits);
   } else {
     PA_DCHECK(bucket.count == 0);
@@ -518,7 +520,7 @@
 
     // Very unlikely, means that the central allocator is out of memory. Let it
     // deal with it (may return 0, may crash).
-    if (UNLIKELY(!bucket.freelist_head))
+    if (PA_UNLIKELY(!bucket.freelist_head))
       return 0;
   }
 
@@ -541,8 +543,8 @@
   return reinterpret_cast<uintptr_t>(result);
 }
 
-ALWAYS_INLINE void ThreadCache::PutInBucket(Bucket& bucket,
-                                            uintptr_t slot_start) {
+PA_ALWAYS_INLINE void ThreadCache::PutInBucket(Bucket& bucket,
+                                               uintptr_t slot_start) {
 #if defined(PA_HAS_FREELIST_SHADOW_ENTRY) && defined(ARCH_CPU_X86_64) && \
     defined(PA_HAS_64_BITS_POINTERS)
   // We see freelist corruption crashes happening in the wild.  These are likely
@@ -560,7 +562,7 @@
   // Everything below requires this alignment.
   static_assert(internal::kAlignment == 16, "");
 
-#if HAS_BUILTIN(__builtin_assume_aligned)
+#if PA_HAS_BUILTIN(__builtin_assume_aligned)
   uintptr_t address = reinterpret_cast<uintptr_t>(__builtin_assume_aligned(
       reinterpret_cast<void*>(slot_start), internal::kAlignment));
 #else
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h
index 2941f80..01594755 100644
--- a/base/containers/flat_tree.h
+++ b/base/containers/flat_tree.h
@@ -137,7 +137,7 @@
 // sorted vector as the backing store. Do not use directly.
 //
 // The use of "value" in this is like std::map uses, meaning it's the thing
-// contained (in the case of map it's a <Kay, Mapped> pair). The Key is how
+// contained (in the case of map it's a <Key, Mapped> pair). The Key is how
 // things are looked up. In the case of a set, Key == Value. In the case of
 // a map, the Key is a component of a Value.
 //
diff --git a/base/feature_list.h b/base/feature_list.h
index b7c62c6..1aecbd8 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -401,7 +401,7 @@
 
   // Returns the override state of a given |feature|. If the feature was not
   // overridden, returns OVERRIDE_USE_DEFAULT. Performs any necessary callbacks
-  // for when the feature state has been observed, e.g. actvating field trials.
+  // for when the feature state has been observed, e.g. activating field trials.
   OverrideState GetOverrideState(const Feature& feature) const;
 
   // Same as GetOverrideState(), but without a default value.
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index b92bc85..76054e3 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -36,6 +36,7 @@
 #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
 #include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/allocator/partition_allocator/tagging.h"
+#include "base/check_op.h"
 #endif  // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
 
 #if BUILDFLAG(IS_WIN)
@@ -151,7 +152,7 @@
     //
     // TODO(crbug.com/1307514): Allow direct-map buckets.
     return partition_alloc::IsManagedByPartitionAlloc(as_uintptr) &&
-           partition_alloc::IsManagedByNormalBuckets(as_uintptr);
+           partition_alloc::internal::IsManagedByNormalBuckets(as_uintptr);
   }
 
   // Returns pointer to the tag that protects are pointed by |ptr|.
diff --git a/base/metrics/dummy_histogram.cc b/base/metrics/dummy_histogram.cc
index fb0da279..bb73787 100644
--- a/base/metrics/dummy_histogram.cc
+++ b/base/metrics/dummy_histogram.cc
@@ -36,12 +36,10 @@
 
 class DummyHistogramSamples : public HistogramSamples {
  public:
-  DummyHistogramSamples() : HistogramSamples(0, new LocalMetadata()) {}
+  DummyHistogramSamples()
+      : HistogramSamples(0, std::make_unique<LocalMetadata>()) {}
   DummyHistogramSamples(const DummyHistogramSamples&) = delete;
   DummyHistogramSamples& operator=(const DummyHistogramSamples&) = delete;
-  ~DummyHistogramSamples() override {
-    delete static_cast<LocalMetadata*>(meta());
-  }
 
   // HistogramSamples:
   void Accumulate(HistogramBase::Sample value,
diff --git a/base/metrics/histogram_samples.cc b/base/metrics/histogram_samples.cc
index eaccb37..edfcaea 100644
--- a/base/metrics/histogram_samples.cc
+++ b/base/metrics/histogram_samples.cc
@@ -187,6 +187,11 @@
     meta_->id = id;
 }
 
+HistogramSamples::HistogramSamples(uint64_t id, std::unique_ptr<Metadata> meta)
+    : HistogramSamples(id, meta.get()) {
+  meta_owned_ = std::move(meta);
+}
+
 // This mustn't do anything with |meta_|. It was passed to the ctor and may
 // be invalid by the time this dtor gets called.
 HistogramSamples::~HistogramSamples() = default;
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h
index feb74690..d54ac4e 100644
--- a/base/metrics/histogram_samples.h
+++ b/base/metrics/histogram_samples.h
@@ -130,7 +130,6 @@
     LocalMetadata();
   };
 
-  HistogramSamples(uint64_t id, Metadata* meta);
   HistogramSamples(const HistogramSamples&) = delete;
   HistogramSamples& operator=(const HistogramSamples&) = delete;
   virtual ~HistogramSamples();
@@ -182,6 +181,9 @@
     MAX_NEGATIVE_SAMPLE_REASONS
   };
 
+  HistogramSamples(uint64_t id, Metadata* meta);
+  HistogramSamples(uint64_t id, std::unique_ptr<Metadata> meta);
+
   // Based on |op| type, add or subtract sample counts data from the iterator.
   enum Operator { ADD, SUBTRACT };
   virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0;
@@ -230,9 +232,12 @@
   Metadata* meta() { return meta_; }
 
  private:
-  // Depending on derived class meta values can come from local stoarge or
-  // external storage in which case HistogramSamples class cannot take ownership
-  // of Metadata*.
+  // Depending on derived class `meta_` can come from:
+  // - Local storage: Then `meta_owned_` is set and meta_ points to it.
+  // - External storage: Then `meta_owned_` is null, and `meta_` point toward an
+  //   external object. The callers guarantees the value will outlive this
+  //   instance.
+  std::unique_ptr<Metadata> meta_owned_;
   raw_ptr<Metadata> meta_;
 };
 
diff --git a/base/metrics/sample_map.cc b/base/metrics/sample_map.cc
index 4be0d74..1e6675e 100644
--- a/base/metrics/sample_map.cc
+++ b/base/metrics/sample_map.cc
@@ -77,11 +77,10 @@
 
 SampleMap::SampleMap() : SampleMap(0) {}
 
-SampleMap::SampleMap(uint64_t id) : HistogramSamples(id, new LocalMetadata()) {}
+SampleMap::SampleMap(uint64_t id)
+    : HistogramSamples(id, std::make_unique<LocalMetadata>()) {}
 
-SampleMap::~SampleMap() {
-  delete static_cast<LocalMetadata*>(meta());
-}
+SampleMap::~SampleMap() = default;
 
 void SampleMap::Accumulate(Sample value, Count count) {
   sample_counts_[value] += count;
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
index 5a7769d9..e89144d 100644
--- a/base/metrics/sample_vector.cc
+++ b/base/metrics/sample_vector.cc
@@ -32,6 +32,13 @@
   CHECK_GE(bucket_ranges_->bucket_count(), 1u);
 }
 
+SampleVectorBase::SampleVectorBase(uint64_t id,
+                                   std::unique_ptr<Metadata> meta,
+                                   const BucketRanges* bucket_ranges)
+    : HistogramSamples(id, std::move(meta)), bucket_ranges_(bucket_ranges) {
+  CHECK_GE(bucket_ranges_->bucket_count(), 1u);
+}
+
 SampleVectorBase::~SampleVectorBase() = default;
 
 void SampleVectorBase::Accumulate(Sample value, Count count) {
@@ -303,11 +310,9 @@
     : SampleVector(0, bucket_ranges) {}
 
 SampleVector::SampleVector(uint64_t id, const BucketRanges* bucket_ranges)
-    : SampleVectorBase(id, new LocalMetadata(), bucket_ranges) {}
+    : SampleVectorBase(id, std::make_unique<LocalMetadata>(), bucket_ranges) {}
 
-SampleVector::~SampleVector() {
-  delete static_cast<LocalMetadata*>(meta());
-}
+SampleVector::~SampleVector() = default;
 
 bool SampleVector::MountExistingCountsStorage() const {
   // There is never any existing storage other than what is already in use.
diff --git a/base/metrics/sample_vector.h b/base/metrics/sample_vector.h
index 72de213..a7a2037 100644
--- a/base/metrics/sample_vector.h
+++ b/base/metrics/sample_vector.h
@@ -31,9 +31,6 @@
 
 class BASE_EXPORT SampleVectorBase : public HistogramSamples {
  public:
-  SampleVectorBase(uint64_t id,
-                   Metadata* meta,
-                   const BucketRanges* bucket_ranges);
   SampleVectorBase(const SampleVectorBase&) = delete;
   SampleVectorBase& operator=(const SampleVectorBase&) = delete;
   ~SampleVectorBase() override;
@@ -52,6 +49,13 @@
   const BucketRanges* bucket_ranges() const { return bucket_ranges_; }
 
  protected:
+  SampleVectorBase(uint64_t id,
+                   Metadata* meta,
+                   const BucketRanges* bucket_ranges);
+  SampleVectorBase(uint64_t id,
+                   std::unique_ptr<Metadata> meta,
+                   const BucketRanges* bucket_ranges);
+
   bool AddSubtractImpl(
       SampleCountIterator* iter,
       HistogramSamples::Operator op) override;  // |op| is ADD or SUBTRACT.
diff --git a/base/system/sys_info_chromeos.cc b/base/system/sys_info_chromeos.cc
index fba0a0d6..95bd78b 100644
--- a/base/system/sys_info_chromeos.cc
+++ b/base/system/sys_info_chromeos.cc
@@ -264,4 +264,25 @@
   CHECK_NE(track.find(kTestImageRelease), std::string::npos);
 }
 
+SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
+  HardwareInfo info;
+  // Manufacturer of ChromeOS device is always Google so hardcode it.
+  info.manufacturer = "Google";
+  if (IsRunningOnChromeOS()) {
+    // Read the model name from cros-configfs.
+    constexpr char kModelNamePath[] = "/run/chromeos-config/v1/name";
+    constexpr size_t kMaxStringSize = 100u;
+    std::string data;
+    if (ReadFileToStringWithMaxSize(FilePath(kModelNamePath), &data,
+                                    kMaxStringSize)) {
+      TrimWhitespaceASCII(data, TrimPositions::TRIM_ALL, &info.model);
+    }
+    DCHECK(IsStringUTF8(info.model));
+  } else {
+    // Fake model name on chromeos linux-emulator (for both linux/ash).
+    info.model = "linux-emulator";
+  }
+  return info;
+}
+
 }  // namespace base
diff --git a/base/system/sys_info_linux.cc b/base/system/sys_info_linux.cc
index 53c910c..881db6f5 100644
--- a/base/system/sys_info_linux.cc
+++ b/base/system/sys_info_linux.cc
@@ -127,7 +127,7 @@
   return std::string();
 }
 
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
 // static
 SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
   static const size_t kMaxStringSize = 100u;
diff --git a/base/win/access_token.cc b/base/win/access_token.cc
index 0e34b82c..ad8694c 100644
--- a/base/win/access_token.cc
+++ b/base/win/access_token.cc
@@ -6,6 +6,8 @@
 
 #include <windows.h>
 
+#include <utility>
+
 #include "base/strings/stringprintf.h"
 
 namespace base {
diff --git a/base/win/access_token.h b/base/win/access_token.h
index f1529df7..17c4205 100644
--- a/base/win/access_token.h
+++ b/base/win/access_token.h
@@ -229,7 +229,7 @@
   bool IsIdentification() const;
 
  private:
-  AccessToken(HANDLE token);
+  explicit AccessToken(HANDLE token);
   ScopedHandle token_;
 };
 
diff --git a/base/win/access_token_unittest.cc b/base/win/access_token_unittest.cc
index 584ea573..2785711 100644
--- a/base/win/access_token_unittest.cc
+++ b/base/win/access_token_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "base/win/access_token.h"
 
+#include <windows.h>
+
 #include <algorithm>
 #include <cstdint>
 #include <map>
 
-#include <windows.h>
-
 #include "base/win/atl.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/windows_version.h"
diff --git a/base/win/atl.h b/base/win/atl.h
index 8397afb..fdb9cfd0 100644
--- a/base/win/atl.h
+++ b/base/win/atl.h
@@ -13,16 +13,16 @@
 // Declare our own exception thrower (atl_throw.h includes atldef.h).
 #include "base/win/atl_throw.h"
 
-#include <atlbase.h>
-#include <atlcom.h>
-#include <atlctl.h>
-#include <atlhost.h>
-#include <atlsecurity.h>
-#include <atlwin.h>
+#include <atlbase.h>      // NOLINT(build/include_order)
+#include <atlcom.h>       // NOLINT(build/include_order)
+#include <atlctl.h>       // NOLINT(build/include_order)
+#include <atlhost.h>      // NOLINT(build/include_order)
+#include <atlsecurity.h>  // NOLINT(build/include_order)
+#include <atlwin.h>       // NOLINT(build/include_order)
 
 // Undefine the poisonous defines
-#include "base/win/windows_undefines.inc"
+#include "base/win/windows_undefines.inc"  // NOLINT(build/include)
 // Check no poisonous defines follow this include
-#include "base/win/windows_defines.inc"
+#include "base/win/windows_defines.inc"  // NOLINT(build/include)
 
 #endif  // BASE_WIN_ATL_H_
diff --git a/base/win/cet_shadow_stack_unittest.cc b/base/win/cet_shadow_stack_unittest.cc
index d80187db..62112a5b 100644
--- a/base/win/cet_shadow_stack_unittest.cc
+++ b/base/win/cet_shadow_stack_unittest.cc
@@ -47,9 +47,9 @@
 NOINLINE void Bug() {
   void* pvAddressOfReturnAddress = _AddressOfReturnAddress();
   if (!return_address)
-    return_address = *(void**)pvAddressOfReturnAddress;
+    return_address = *reinterpret_cast<void**>(pvAddressOfReturnAddress);
   else
-    *(void**)pvAddressOfReturnAddress = return_address;
+    *reinterpret_cast<void**>(pvAddressOfReturnAddress) = return_address;
 }
 
 NOINLINE void A() {
diff --git a/base/win/com_init_check_hook.cc b/base/win/com_init_check_hook.cc
index 9892f3133..88af932a 100644
--- a/base/win/com_init_check_hook.cc
+++ b/base/win/com_init_check_hook.cc
@@ -11,6 +11,7 @@
 #include <string.h>
 
 #include <ostream>
+#include <string>
 
 #include "base/notreached.h"
 #include "base/strings/stringprintf.h"
diff --git a/base/win/event_trace_controller.h b/base/win/event_trace_controller.h
index e3a52fc0..f5dda6ae 100644
--- a/base/win/event_trace_controller.h
+++ b/base/win/event_trace_controller.h
@@ -74,7 +74,6 @@
   // larger buffer to allow storing the logger name and logger file
   // name contiguously with the structure.
   union {
-   public:
     // Our properties header.
     EVENT_TRACE_PROPERTIES properties_;
     // The actual size of the buffer is forced by this member.
diff --git a/base/win/hstring_reference_unittest.cc b/base/win/hstring_reference_unittest.cc
index ef9a96f..52759997 100644
--- a/base/win/hstring_reference_unittest.cc
+++ b/base/win/hstring_reference_unittest.cc
@@ -3,9 +3,11 @@
 // found in the LICENSE file.
 
 #include "base/win/hstring_reference.h"
+
+#include <string>
+
 #include "base/strings/string_piece.h"
 #include "base/win/scoped_hstring.h"
-
 #include "base/win/windows_version.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/win/map.h b/base/win/map.h
index 7705a17f..162b207 100644
--- a/base/win/map.h
+++ b/base/win/map.h
@@ -9,6 +9,7 @@
 #include <wrl/implements.h>
 
 #include <map>
+#include <utility>
 
 #include "base/check_op.h"
 #include "base/containers/contains.h"
@@ -366,8 +367,7 @@
   IFACEMETHODIMP Clear() override {
     map_.clear();
     NotifyMapChanged(
-        ABI::Windows::Foundation::Collections::CollectionChange_Reset,
-        0);  // NOLINT(modernize-use-nullptr): AbiK may not be a pointer.
+        ABI::Windows::Foundation::Collections::CollectionChange_Reset, 0);
     return S_OK;
   }
 
diff --git a/base/win/map_unittest.cc b/base/win/map_unittest.cc
index 1517188..be076e8 100644
--- a/base/win/map_unittest.cc
+++ b/base/win/map_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <windows.foundation.h>
 
+#include <utility>
+
 #include "base/memory/raw_ptr.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/core_winrt_util.h"
diff --git a/base/win/message_window.cc b/base/win/message_window.cc
index 596f939..2ab5812 100644
--- a/base/win/message_window.cc
+++ b/base/win/message_window.cc
@@ -4,14 +4,16 @@
 
 #include "base/win/message_window.h"
 
+#include <windows.h>
+
+#include <utility>
+
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/win/current_module.h"
 #include "base/win/wrapped_window_proc.h"
 
-#include <windows.h>
-
 // To avoid conflicts with the macro from the Windows SDK...
 #undef FindWindow
 
diff --git a/base/win/message_window.h b/base/win/message_window.h
index c1a63d2a..e93de2d 100644
--- a/base/win/message_window.h
+++ b/base/win/message_window.h
@@ -28,8 +28,11 @@
   // Implement this callback to handle messages received by the message window.
   // If the callback returns |false|, the first four parameters are passed to
   // DefWindowProc(). Otherwise, |*result| is returned by the window procedure.
-  using MessageCallback = base::RepeatingCallback<
-      bool(UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result)>;
+  using MessageCallback =
+      base::RepeatingCallback<bool(UINT message,
+                                   WPARAM wparam,
+                                   LPARAM lparam,
+                                   LRESULT* result)>;  // NOLINT
 
   MessageWindow();
 
diff --git a/base/win/message_window_unittest.cc b/base/win/message_window_unittest.cc
index 4217707..ecf3fe0 100644
--- a/base/win/message_window_unittest.cc
+++ b/base/win/message_window_unittest.cc
@@ -3,14 +3,15 @@
 // found in the LICENSE file.
 
 #include "base/win/message_window.h"
+
+#include <windows.h>
+
 #include "base/bind.h"
 #include "base/guid.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#include <windows.h>
-
 // To avoid conflicts with the macro from the Windows SDK...
 #undef FindWindow
 
diff --git a/base/win/nt_status.cc b/base/win/nt_status.cc
index 690a9566..1cfb385 100644
--- a/base/win/nt_status.cc
+++ b/base/win/nt_status.cc
@@ -4,11 +4,11 @@
 
 #include "base/win/nt_status.h"
 
-#include "base/check.h"
-
 #include <windows.h>
 #include <winternl.h>
 
+#include "base/check.h"
+
 using GetLastNtStatusFn = NTSTATUS NTAPI (*)();
 
 constexpr const wchar_t kNtDllName[] = L"ntdll.dll";
diff --git a/base/win/propvarutil.h b/base/win/propvarutil.h
index d95c5ad1..92850113 100644
--- a/base/win/propvarutil.h
+++ b/base/win/propvarutil.h
@@ -9,11 +9,11 @@
 // Undefine before windows header will make the poisonous defines
 #include "base/win/windows_undefines.inc"
 
-#include <propvarutil.h>
+#include <propvarutil.h>  // NOLINT(build/include_order)
 
 // Undefine the poisonous defines
-#include "base/win/windows_undefines.inc"
+#include "base/win/windows_undefines.inc"  // NOLINT(build/include)
 // Check no poisonous defines follow this include
-#include "base/win/windows_defines.inc"
+#include "base/win/windows_defines.inc"  // NOLINT(build/include)
 
 #endif  // BASE_WIN_PROPVARUTIL_H_
diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h
index 3a7d47e..ed893c4 100644
--- a/base/win/scoped_handle.h
+++ b/base/win/scoped_handle.h
@@ -5,8 +5,6 @@
 #ifndef BASE_WIN_SCOPED_HANDLE_H_
 #define BASE_WIN_SCOPED_HANDLE_H_
 
-#include "base/win/windows_types.h"
-
 #include <ostream>
 
 #include "base/base_export.h"
@@ -14,6 +12,7 @@
 #include "base/dcheck_is_on.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
+#include "base/win/windows_types.h"
 #include "build/build_config.h"
 
 // TODO(rvargas): remove this with the rest of the verifier.
diff --git a/base/win/scoped_handle_unittest.cc b/base/win/scoped_handle_unittest.cc
index 459e288..fa1a073 100644
--- a/base/win/scoped_handle_unittest.cc
+++ b/base/win/scoped_handle_unittest.cc
@@ -6,6 +6,9 @@
 
 #include <winternl.h>
 
+#include <string>
+#include <utility>
+
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/debug/handle_hooks_win.h"
diff --git a/base/win/scoped_hstring.cc b/base/win/scoped_hstring.cc
index 5cea8b0..8ea5ef4a 100644
--- a/base/win/scoped_hstring.cc
+++ b/base/win/scoped_hstring.cc
@@ -6,6 +6,8 @@
 
 #include <winstring.h>
 
+#include <string>
+
 #include "base/check.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
diff --git a/base/win/scoped_hstring.h b/base/win/scoped_hstring.h
index 048a52e..cd5ee7a 100644
--- a/base/win/scoped_hstring.h
+++ b/base/win/scoped_hstring.h
@@ -7,6 +7,8 @@
 
 #include <hstring.h>
 
+#include <string>
+
 #include "base/scoped_generic.h"
 #include "base/strings/string_piece_forward.h"
 
diff --git a/base/win/scoped_hstring_unittest.cc b/base/win/scoped_hstring_unittest.cc
index e6334122..9acdd9bb 100644
--- a/base/win/scoped_hstring_unittest.cc
+++ b/base/win/scoped_hstring_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <winstring.h>
 
+#include <string>
+
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/core_winrt_util.h"
 #include "base/win/windows_version.h"
diff --git a/base/win/scoped_safearray_unittest.cc b/base/win/scoped_safearray_unittest.cc
index 48d181a..d1e7d90 100644
--- a/base/win/scoped_safearray_unittest.cc
+++ b/base/win/scoped_safearray_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <array>
+#include <utility>
 #include <vector>
 
 #include "base/test/gtest_util.h"
diff --git a/base/win/scoped_variant.cc b/base/win/scoped_variant.cc
index e2d1487..b612a986 100644
--- a/base/win/scoped_variant.cc
+++ b/base/win/scoped_variant.cc
@@ -40,7 +40,7 @@
   var_.bstrVal = ::SysAllocStringLen(str, length);
 }
 
-ScopedVariant::ScopedVariant(long value, VARTYPE vt) {
+ScopedVariant::ScopedVariant(long value, VARTYPE vt) {  // NOLINT(runtime/int)
   var_.vt = vt;
   var_.lVal = value;
 }
diff --git a/base/win/scoped_variant.h b/base/win/scoped_variant.h
index dfe13bd..00fdc369 100644
--- a/base/win/scoped_variant.h
+++ b/base/win/scoped_variant.h
@@ -42,7 +42,8 @@
 
   // Creates a new integral type variant and assigns the value to
   // VARIANT.lVal (32 bit sized field).
-  explicit ScopedVariant(long value, VARTYPE vt = VT_I4);
+  explicit ScopedVariant(long value,  // NOLINT(runtime/int)
+                         VARTYPE vt = VT_I4);
 
   // Creates a new integral type variant for the int type and assigns the value
   // to VARIANT.lVal (32 bit sized field).
diff --git a/base/win/scoped_variant_unittest.cc b/base/win/scoped_variant_unittest.cc
index 437efc2..25833bd 100644
--- a/base/win/scoped_variant_unittest.cc
+++ b/base/win/scoped_variant_unittest.cc
@@ -147,7 +147,7 @@
 
 TEST(ScopedVariantTest, SetSigned2Byte) {
   ScopedVariant var;
-  var.Set(static_cast<short>(123));
+  var.Set(static_cast<int16_t>(123));
   ExpectVariantType(VT_I2, var);
   EXPECT_EQ(123, V_I2(var.ptr()));
 }
@@ -175,7 +175,7 @@
 
 TEST(ScopedVariantTest, SetUnsigned2Byte) {
   ScopedVariant var;
-  var.Set(static_cast<unsigned short>(123));
+  var.Set(static_cast<uint16_t>(123));
   ExpectVariantType(VT_UI2, var);
   EXPECT_EQ(123u, V_UI2(var.ptr()));
 }
diff --git a/base/win/shlwapi.h b/base/win/shlwapi.h
index b60353c..88ae9aa 100644
--- a/base/win/shlwapi.h
+++ b/base/win/shlwapi.h
@@ -9,11 +9,11 @@
 // Undefine before windows header will make the poisonous defines
 #include "base/win/windows_undefines.inc"
 
-#include <shlwapi.h>
+#include <shlwapi.h>  // NOLINT(build/include_order)
 
 // Undefine the poisonous defines
-#include "base/win/windows_undefines.inc"
+#include "base/win/windows_undefines.inc"  // NOLINT(build/include)
 // Check no poisonous defines follow this include
-#include "base/win/windows_defines.inc"
+#include "base/win/windows_defines.inc"  // NOLINT(build/include)
 
 #endif  // BASE_WIN_SHLWAPI_H_
diff --git a/base/win/shortcut.h b/base/win/shortcut.h
index d889821..db0ecf9 100644
--- a/base/win/shortcut.h
+++ b/base/win/shortcut.h
@@ -5,8 +5,7 @@
 #ifndef BASE_WIN_SHORTCUT_H_
 #define BASE_WIN_SHORTCUT_H_
 
-#include "guiddef.h"
-
+#include <guiddef.h>
 #include <stdint.h>
 
 #include "base/base_export.h"
diff --git a/base/win/sid.cc b/base/win/sid.cc
index 943645d..74b3ef4 100644
--- a/base/win/sid.cc
+++ b/base/win/sid.cc
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 
 #include <iterator>
+#include <utility>
 
 #include "base/check.h"
 #include "base/notreached.h"
diff --git a/base/win/sid_unittest.cc b/base/win/sid_unittest.cc
index 58fc1d8..d7fe84c 100644
--- a/base/win/sid_unittest.cc
+++ b/base/win/sid_unittest.cc
@@ -6,12 +6,12 @@
 
 #include "base/win/sid.h"
 
-#include <algorithm>
-
 #include <windows.h>
 
 #include <sddl.h>
 
+#include <algorithm>
+
 #include "base/win/atl.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_localalloc.h"
diff --git a/base/win/sphelper.h b/base/win/sphelper.h
index 38a547f..1ec9e4c8 100644
--- a/base/win/sphelper.h
+++ b/base/win/sphelper.h
@@ -9,11 +9,11 @@
 // Undefine before windows header will make the poisonous defines
 #include "base/win/windows_undefines.inc"
 
-#include <sphelper.h>
+#include <sphelper.h>  // NOLINT(build/include_order)
 
 // Undefine the poisonous defines
-#include "base/win/windows_undefines.inc"
+#include "base/win/windows_undefines.inc"  // NOLINT(build/include)
 // Check no poisonous defines follow this include
-#include "base/win/windows_defines.inc"
+#include "base/win/windows_defines.inc"  // NOLINT(build/include)
 
 #endif  // BASE_WIN_SPHELPER_H_
diff --git a/base/win/startup_information.cc b/base/win/startup_information.cc
index c7be1ca..b63f56a5 100644
--- a/base/win/startup_information.cc
+++ b/base/win/startup_information.cc
@@ -4,6 +4,7 @@
 
 #include "base/win/startup_information.h"
 
+#include <utility>
 
 namespace base {
 namespace win {
diff --git a/base/win/startup_information_unittest.cc b/base/win/startup_information_unittest.cc
index aa09a33..f88db2f 100644
--- a/base/win/startup_information_unittest.cc
+++ b/base/win/startup_information_unittest.cc
@@ -18,7 +18,7 @@
 namespace {
 class ScopedProcessTerminator {
  public:
-  ScopedProcessTerminator(const PROCESS_INFORMATION& process_info)
+  explicit ScopedProcessTerminator(const PROCESS_INFORMATION& process_info)
       : process_info_(process_info) {}
 
   ScopedProcessTerminator(const ScopedProcessTerminator&) = delete;
diff --git a/base/win/win_includes_unittest.cc b/base/win/win_includes_unittest.cc
index b9ea2dd..95ed58eb 100644
--- a/base/win/win_includes_unittest.cc
+++ b/base/win/win_includes_unittest.cc
@@ -28,9 +28,9 @@
 #include "base/win/windows_types.h"
 
 // windows.h must be included before objidl.h
-#include <windows.h>
+#include <windows.h>  // NOLINT(build/include_order)
 
-#include <objidl.h>
+#include <objidl.h>  // NOLINT(build/include_order)
 
 // Check that type sizes match.
 static_assert(sizeof(CHROME_CONDITION_VARIABLE) == sizeof(CONDITION_VARIABLE),
diff --git a/base/win/windows_types.h b/base/win/windows_types.h
index 117c359c..62af913d 100644
--- a/base/win/windows_types.h
+++ b/base/win/windows_types.h
@@ -19,15 +19,15 @@
 
 // typedef and define the most commonly used Windows integer types.
 
-typedef unsigned long DWORD;
-typedef long LONG;
+typedef unsigned long DWORD;  // NOLINT(runtime/int)
+typedef long LONG;            // NOLINT(runtime/int)
 typedef __int64 LONGLONG;
 typedef unsigned __int64 ULONGLONG;
 
 #define VOID void
 typedef char CHAR;
-typedef short SHORT;
-typedef long LONG;
+typedef short SHORT;  // NOLINT(runtime/int)
+typedef long LONG;    // NOLINT(runtime/int)
 typedef int INT;
 typedef unsigned int UINT;
 typedef unsigned int* PUINT;
@@ -39,7 +39,7 @@
 typedef unsigned char BYTE;
 typedef BYTE BOOLEAN;
 typedef DWORD ULONG;
-typedef unsigned short WORD;
+typedef unsigned short WORD;  // NOLINT(runtime/int)
 typedef WORD UWORD;
 typedef WORD ATOM;
 
@@ -53,15 +53,15 @@
 typedef __w64 int INT_PTR, *PINT_PTR;
 typedef __w64 unsigned int UINT_PTR, *PUINT_PTR;
 
-typedef __w64 long LONG_PTR, *PLONG_PTR;
-typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
+typedef __w64 long LONG_PTR, *PLONG_PTR;             // NOLINT(runtime/int)
+typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;  // NOLINT(runtime/int)
 #endif
 
 typedef UINT_PTR WPARAM;
 typedef LONG_PTR LPARAM;
 typedef LONG_PTR LRESULT;
 #define LRESULT LONG_PTR
-typedef _Return_type_success_(return >= 0) long HRESULT;
+typedef _Return_type_success_(return >= 0) long HRESULT;  // NOLINT(runtime/int)
 
 typedef ULONG_PTR SIZE_T, *PSIZE_T;
 typedef LONG_PTR SSIZE_T, *PSSIZE_T;
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index dafeb24..7896143 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -224,7 +224,7 @@
 }
 
 OSInfo::VersionNumber OSInfo::Kernel32VersionNumber() const {
-  DCHECK(Kernel32BaseVersion().components().size() == 4);
+  DCHECK_EQ(Kernel32BaseVersion().components().size(), 4u);
   static const VersionNumber version = {
       .major = Kernel32BaseVersion().components()[0],
       .minor = Kernel32BaseVersion().components()[1],
diff --git a/base/win/windows_version.h b/base/win/windows_version.h
index 6357255..01fe778 100644
--- a/base/win/windows_version.h
+++ b/base/win/windows_version.h
@@ -33,29 +33,29 @@
 enum class Version {
   PRE_XP = 0,  // Not supported.
   XP = 1,
-  SERVER_2003 = 2,  // Also includes XP Pro x64 and Server 2003 R2.
-  VISTA = 3,        // Also includes Windows Server 2008.
-  WIN7 = 4,         // Also includes Windows Server 2008 R2.
-  WIN8 = 5,         // Also includes Windows Server 2012.
-  WIN8_1 = 6,       // Also includes Windows Server 2012 R2.
-  WIN10 = 7,        // Threshold 1: Version 1507, Build 10240.
-  WIN10_TH2 = 8,    // Threshold 2: Version 1511, Build 10586.
-  WIN10_RS1 = 9,    // Redstone 1: Version 1607, Build 14393.
-                    // Also includes Windows Server 2016
-  WIN10_RS2 = 10,   // Redstone 2: Version 1703, Build 15063.
-  WIN10_RS3 = 11,   // Redstone 3: Version 1709, Build 16299.
-  WIN10_RS4 = 12,   // Redstone 4: Version 1803, Build 17134.
-  WIN10_RS5 = 13,   // Redstone 5: Version 1809, Build 17763.
-                    // Also includes Windows Server 2019
-  WIN10_19H1 = 14,  // 19H1: Version 1903, Build 18362.
-  WIN10_19H2 = 15,  // 19H2: Version 1909, Build 18363.
-  WIN10_20H1 = 16,  // 20H1: Build 19041.
-  WIN10_20H2 = 17,  // 20H2: Build 19042.
-  WIN10_21H1 = 18,  // 21H1: Build 19043.
-  WIN10_21H2 = 19,  // Win10 21H2: Build 19044.
-  SERVER_2022 = 20, // Server 2022: Build 20348.
-  WIN11 = 21,       // Win11 21H2: Build 22000.
-  WIN_LAST,         // Indicates error condition.
+  SERVER_2003 = 2,   // Also includes XP Pro x64 and Server 2003 R2.
+  VISTA = 3,         // Also includes Windows Server 2008.
+  WIN7 = 4,          // Also includes Windows Server 2008 R2.
+  WIN8 = 5,          // Also includes Windows Server 2012.
+  WIN8_1 = 6,        // Also includes Windows Server 2012 R2.
+  WIN10 = 7,         // Threshold 1: Version 1507, Build 10240.
+  WIN10_TH2 = 8,     // Threshold 2: Version 1511, Build 10586.
+  WIN10_RS1 = 9,     // Redstone 1: Version 1607, Build 14393.
+                     // Also includes Windows Server 2016
+  WIN10_RS2 = 10,    // Redstone 2: Version 1703, Build 15063.
+  WIN10_RS3 = 11,    // Redstone 3: Version 1709, Build 16299.
+  WIN10_RS4 = 12,    // Redstone 4: Version 1803, Build 17134.
+  WIN10_RS5 = 13,    // Redstone 5: Version 1809, Build 17763.
+                     // Also includes Windows Server 2019
+  WIN10_19H1 = 14,   // 19H1: Version 1903, Build 18362.
+  WIN10_19H2 = 15,   // 19H2: Version 1909, Build 18363.
+  WIN10_20H1 = 16,   // 20H1: Build 19041.
+  WIN10_20H2 = 17,   // 20H2: Build 19042.
+  WIN10_21H1 = 18,   // 21H1: Build 19043.
+  WIN10_21H2 = 19,   // Win10 21H2: Build 19044.
+  SERVER_2022 = 20,  // Server 2022: Build 20348.
+  WIN11 = 21,        // Win11 21H2: Build 22000.
+  WIN_LAST,          // Indicates error condition.
 };
 
 // A rough bucketing of the available types of versions of Windows. This is used
diff --git a/base/win/winrt_storage_util.cc b/base/win/winrt_storage_util.cc
index f2f4fa33..7d1efac6 100644
--- a/base/win/winrt_storage_util.cc
+++ b/base/win/winrt_storage_util.cc
@@ -8,6 +8,8 @@
 #include <string.h>
 #include <wrl/client.h>
 
+#include <utility>
+
 #include "base/strings/string_util.h"
 #include "base/win/core_winrt_util.h"
 #include "base/win/scoped_hstring.h"
diff --git a/base/win/winrt_storage_util_unittest.cc b/base/win/winrt_storage_util_unittest.cc
index 530ab23..14adf88 100644
--- a/base/win/winrt_storage_util_unittest.cc
+++ b/base/win/winrt_storage_util_unittest.cc
@@ -7,6 +7,8 @@
 #include <string.h>
 #include <wrl/client.h>
 
+#include <vector>
+
 #include "base/strings/string_util.h"
 #include "base/win/core_winrt_util.h"
 #include "base/win/scoped_com_initializer.h"
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py
index c39af6e..b98c9310 100644
--- a/build/android/pylib/instrumentation/instrumentation_test_instance.py
+++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -629,6 +629,7 @@
     super().__init__()
 
     self._additional_apks = []
+    self._forced_queryable_additional_apks = []
     self._apk_under_test = None
     self._apk_under_test_incremental_install_json = None
     self._modules = None
@@ -807,11 +808,15 @@
           '(This may just mean that the test package is '
           'currently being installed.)', self._test_package)
 
-    for apk in args.additional_apks:
-      if not os.path.exists(apk):
-        error_func('Unable to find additional APK: %s' % apk)
-    self._additional_apks = (
-        [apk_helper.ToHelper(x) for x in args.additional_apks])
+    for x in set(args.additional_apks + args.forced_queryable_additional_apks):
+      if not os.path.exists(x):
+        error_func('Unable to find additional APK: %s' % x)
+
+      apk = apk_helper.ToHelper(x)
+      self._additional_apks.append(apk)
+
+      if x in args.forced_queryable_additional_apks:
+        self._forced_queryable_additional_apks.append(apk)
 
   def _initializeDataDependencyAttributes(self, args, data_deps_delegate):
     self._data_deps = []
@@ -1129,6 +1134,9 @@
       logging.warning('Unmatched Filter: %s', self._test_filter)
     return filtered_tests
 
+  def IsApkForceQueryable(self, apk):
+    return apk in self._forced_queryable_additional_apks
+
   # pylint: disable=no-self-use
   def _InflateTests(self, tests):
     inflated_tests = []
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index 7cbf5523..46efec2 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -250,12 +250,14 @@
         @trace_event.traced
         def install_helper_internal(d, apk_path=None):
           # pylint: disable=unused-argument
-          d.Install(apk,
-                    modules=modules,
-                    fake_modules=fake_modules,
-                    permissions=permissions,
-                    additional_locales=additional_locales,
-                    instant_app=instant_app)
+          d.Install(
+              apk,
+              modules=modules,
+              fake_modules=fake_modules,
+              permissions=permissions,
+              additional_locales=additional_locales,
+              instant_app=instant_app,
+              force_queryable=self._test_instance.IsApkForceQueryable(apk))
 
         return install_helper_internal
 
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 70387d1..1136c91 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -426,6 +426,13 @@
       type=_RealPath,
       help='Additional apk that must be installed on '
            'the device when the tests are run')
+  parser.add_argument('--forced-queryable-additional-apk',
+                      action='append',
+                      dest='forced_queryable_additional_apks',
+                      default=[],
+                      type=_RealPath,
+                      help='Configures an additional-apk to be forced '
+                      'to be queryable by other APKs.')
   parser.add_argument(
       '-A', '--annotation',
       dest='annotation_str',
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index ca5acf5..9e4e0f3 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220523.3.1
+8.20220524.0.1
diff --git a/cc/layers/video_frame_provider.h b/cc/layers/video_frame_provider.h
index 7ae0890..7dff50c3 100644
--- a/cc/layers/video_frame_provider.h
+++ b/cc/layers/video_frame_provider.h
@@ -97,6 +97,10 @@
   // the client.
   virtual base::TimeDelta GetPreferredRenderInterval() = 0;
 
+  // Inform the provider that the context is lost. The provider need to reset
+  // the current frame if it's invald.
+  virtual void OnContextLost() = 0;
+
  protected:
   virtual ~VideoFrameProvider() {}
 };
diff --git a/cc/test/fake_video_frame_provider.h b/cc/test/fake_video_frame_provider.h
index 5fe8354d..58ed7cf 100644
--- a/cc/test/fake_video_frame_provider.h
+++ b/cc/test/fake_video_frame_provider.h
@@ -24,6 +24,7 @@
   scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
   void PutCurrentFrame() override;
   base::TimeDelta GetPreferredRenderInterval() override;
+  void OnContextLost() override {}
 
   Client* client() { return client_; }
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 22bb9cb..0e77f6e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=104
 MINOR=0
-BUILD=5081
+BUILD=5082
 PATCH=0
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index e377d73c..4119762 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -1386,6 +1386,22 @@
           A Chromium profile with this account already exists on this device
         </message>
 
+        <!-- First Run Experience -->
+        <if expr="chromeos_lacros">
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE" desc="Title of the landing screen in first run experience for the primary profile. The screen promotes Chromium sync.">
+            Welcome to Chromium, <ph name="ACCOUNT_FIRST_NAME">$1<ex>Jane</ex></ph>
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE" desc="Title of the screen shown when the user runs Chromium for the first time. A simple, generic welcome message.">
+            Welcome to Chromium
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE" desc="Subtitle of the landing screen in first run experience for the primary profile. The screen promotes Chromium sync.">
+            Get your Chromium browser stuff from <ph name="ACCOUNT_EMAIL">$1<ex>Jane.Doe@gmail.com</ex></ph>
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION" desc="Disclaimer on the landing screen in first run experience for the primary profile, informing that the session is managed by an administrator.">
+            Your account is managed by <ph name="MANAGER_NAME">$1<ex>example.com</ex></ph>. Your administrator can see and edit this Chromium browser profile and its data like bookmarks, history, and passwords.
+          </message>
+        </if>
+
         <!-- Profile switch IPH -->
         <message name="IDS_PROFILE_SWITCH_PROMO" desc="Text of the In-Product-Help bubble for profile switching.">
           You can switch between Chromium profiles here
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
similarity index 100%
rename from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
rename to chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
similarity index 100%
rename from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
rename to chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
similarity index 100%
rename from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
rename to chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
similarity index 100%
rename from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
rename to chrome/app/chromium_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index c33b66a6..62ff616a 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -1481,6 +1481,22 @@
           A Chrome profile with this account already exists on this device
         </message>
 
+        <!-- First Run Experience -->
+        <if expr="chromeos_lacros">
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE" desc="Title of the landing screen in first run experience for the primary profile. The screen promotes Chrome sync.">
+            Welcome to Chrome, <ph name="ACCOUNT_FIRST_NAME">$1<ex>Jane</ex></ph>
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE" desc="Title of the screen shown when the user runs Chrome for the first time. A simple, generic welcome message.">
+            Welcome to Chrome
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE" desc="Subtitle of the landing screen in first run experience for the primary profile. The screen promotes Chrome sync.">
+            Get your Chrome browser stuff from <ph name="ACCOUNT_EMAIL">$1<ex>Jane.Doe@gmail.com</ex></ph>
+          </message>
+          <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION" desc="Disclaimer on the landing screen in first run experience for the primary profile, informing that the session is managed by an administrator.">
+            Your account is managed by <ph name="MANAGER_NAME">$1<ex>example.com</ex></ph>. Your administrator can see and edit this Chrome browser profile and its data like bookmarks, history, and passwords.
+          </message>
+        </if>
+
         <!-- Profile switch IPH -->
         <message name="IDS_PROFILE_SWITCH_PROMO" desc="Text of the In-Product-Help bubble for profile switching.">
           You can switch between Chrome profiles here
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
similarity index 100%
copy from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
copy to chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
similarity index 100%
copy from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
copy to chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
similarity index 100%
copy from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
copy to chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE.png.sha1
diff --git a/chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
similarity index 100%
copy from chrome/app/profiles_strings_grdp/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
copy to chrome/app/google_chrome_strings_grd/IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE.png.sha1
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp
index 619c648..20ca3a2 100644
--- a/chrome/app/profiles_strings.grdp
+++ b/chrome/app/profiles_strings.grdp
@@ -689,23 +689,11 @@
         Delete this profile and browsing data?
       </message>
       <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu">
-          This will permanently delete browsing data from this device. The Google Accounts in this profile may be used by other apps on your Chromebook. You can remove these accounts in <ph name="BEGIN_LINK">&lt;a is="action-link" target="_blank"&gt;</ph><ph name="SETTING_SECTION">$1<ex>Settings</ex></ph> > <ph name="ACCOUNTS_SECTION">$2<ex>Accounts</ex></ph><ph name="END_LINK">&lt;/a&gt;</ph>.
-      </message>
-      <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_TITLE" desc="Title of the landing screen in first run experience for the primary profile. The screen promotes Chrome sync.">
-        Welcome to Chrome, <ph name="ACCOUNT_FIRST_NAME">$1<ex>Jane</ex></ph>
-      </message>
-      <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_NO_NAME_TITLE" desc="Title of the screen shown when the user runs Chrome for the first time. A simple, generic welcome message.">
-        Welcome to Chrome
-      </message>
-      <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SUBTITLE" desc="Subtitle of the landing screen in first run experience for the primary profile. The screen promotes Chrome sync.">
-        Get your Chrome browser stuff from <ph name="ACCOUNT_EMAIL">$1<ex>Jane.Doe@gmail.com</ex></ph>
+        This will permanently delete browsing data from this device. The Google Accounts in this profile may be used by other apps on your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. You can remove these accounts in <ph name="BEGIN_LINK">&lt;a is="action-link" target="_blank"&gt;</ph><ph name="SETTING_SECTION">$2<ex>Settings</ex></ph> > <ph name="ACCOUNTS_SECTION">$3<ex>Accounts</ex></ph><ph name="END_LINK">&lt;/a&gt;</ph>.
       </message>
       <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_NEXT_BUTTON_LABEL" desc="Label of the 'next' button of the landing screen in first run experience for the primary profile. The screen promotes Chrome sync.">
         Let's go
       </message>
-      <message name="IDS_PRIMARY_PROFILE_FIRST_RUN_SESSION_MANAGED_BY_DESCRIPTION" desc="Disclaimer on the landing screen in first run experience for the primary profile, informing that the session is managed by an administrator.">
-        Your account is managed by <ph name="MANAGER_NAME">$1<ex>example.com</ex></ph>. Your administrator can see and edit this Chrome browser profile and its data like bookmarks, history, and passwords.
-      </message>
     </if>
 
   </if>
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS.png.sha1
index 1fde74d..1e0a4f57 100644
--- a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS.png.sha1
+++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS.png.sha1
@@ -1 +1 @@
-94f45972c7c9ad785bdaa96a38b531940fa1aa01
\ No newline at end of file
+8292b6d2785d07f1c2c292bb80dd89f729153b39
\ No newline at end of file
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.cc b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
index 9d0d762..460488e 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
@@ -70,6 +70,19 @@
   AppRegistryCacheWrapper::Get().RemoveAppRegistryCache(&app_registry_cache_);
 }
 
+bool AppServiceProxyAsh::IsValidProfile() {
+  if (!profile_) {
+    return false;
+  }
+
+  // Use OTR profile for Guest Session.
+  if (profile_->IsGuestSession()) {
+    return profile_->IsOffTheRecord();
+  }
+
+  return AppServiceProxyBase::IsValidProfile();
+}
+
 void AppServiceProxyAsh::Initialize() {
   if (!IsValidProfile()) {
     return;
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.h b/chrome/browser/apps/app_service/app_service_proxy_ash.h
index 6e68c14b..89948b22 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.h
@@ -129,6 +129,7 @@
   using UninstallDialogs =
       base::flat_map<std::string, std::unique_ptr<apps::UninstallDialog>>;
 
+  bool IsValidProfile() override;
   void Initialize() override;
 
   // KeyedService overrides.
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h
index 8550f5c..2b76662 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_base.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -352,7 +352,7 @@
     raw_ptr<apps::IconLoader> overriding_icon_loader_for_testing_;
   };
 
-  bool IsValidProfile();
+  virtual bool IsValidProfile();
 
   // Called in AppServiceProxyFactory::BuildServiceInstanceFor immediately
   // following the creation of AppServiceProxy. Use this method to perform any
diff --git a/chrome/browser/apps/app_service/app_service_proxy_factory.cc b/chrome/browser/apps/app_service/app_service_proxy_factory.cc
index e3b20a8..31adec0 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_factory.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_factory.cc
@@ -43,8 +43,14 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // An exception on Chrome OS is the guest profile, which is incognito, but
   // can have apps within it.
+
+  // Use OTR profile for Guest Session.
+  if (profile->IsGuestSession()) {
+    return profile->IsOffTheRecord();
+  }
+
   return (!ash::ProfileHelper::IsSigninProfile(profile) &&
-          (!profile->IsOffTheRecord() || profile->IsGuestSession()));
+          !profile->IsOffTheRecord());
 #else
   return !profile->IsOffTheRecord();
 #endif
@@ -118,7 +124,9 @@
   // We must have a proxy in guest mode to ensure default extension-based apps
   // are served.
   if (profile->IsGuestSession()) {
-    return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+    return profile->IsOffTheRecord()
+               ? chrome::GetBrowserContextOwnInstanceInIncognito(context)
+               : nullptr;
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
diff --git a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
index b1a564c..97dfaac 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
@@ -267,12 +267,28 @@
   TestingProfile::Builder guest_builder;
   guest_builder.SetGuestSession();
   auto guest_profile = guest_builder.Build();
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // App service is not available for original profile.
+  EXPECT_FALSE(apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(
+      guest_profile.get()));
+
+  // App service is available for OTR profile in Guest mode.
+  auto* guest_otr_profile =
+      guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+  EXPECT_TRUE(apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(
+      guest_otr_profile));
+  auto* guest_otr_proxy =
+      apps::AppServiceProxyFactory::GetForProfile(guest_otr_profile);
+  EXPECT_TRUE(guest_otr_proxy);
+  EXPECT_NE(guest_otr_proxy, proxy);
+#else
   EXPECT_TRUE(apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(
       guest_profile.get()));
   auto* guest_proxy =
       apps::AppServiceProxyFactory::GetForProfile(guest_profile.get());
   EXPECT_TRUE(guest_proxy);
   EXPECT_NE(guest_proxy, proxy);
+#endif
 }
 
 // The parameter indicates whether the kAppServiceLoadIconWithoutMojom feature
diff --git a/chrome/browser/apps/user_type_filter.cc b/chrome/browser/apps/user_type_filter.cc
index 48ba8d4e..05249258 100644
--- a/chrome/browser/apps/user_type_filter.cc
+++ b/chrome/browser/apps/user_type_filter.cc
@@ -23,9 +23,9 @@
 
 std::string DetermineUserType(Profile* profile) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(!profile->IsOffTheRecord());
   if (profile->IsGuestSession())
     return kUserTypeGuest;
+  DCHECK(!profile->IsOffTheRecord());
   if (profile->IsChild())
     return kUserTypeChild;
   if (profile->GetProfilePolicyConnector()->IsManaged()) {
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 3d740ba..2f0f7d1 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -648,6 +648,212 @@
     "bruschetta/bruschetta_service.h",
     "bruschetta/bruschetta_service_factory.cc",
     "bruschetta/bruschetta_service_factory.h",
+    "camera_detector.cc",
+    "camera_detector.h",
+    "camera_mic/vm_camera_mic_manager.cc",
+    "camera_mic/vm_camera_mic_manager.h",
+    "camera_presence_notifier.cc",
+    "camera_presence_notifier.h",
+    "cert_provisioning/cert_provisioning_common.cc",
+    "cert_provisioning/cert_provisioning_common.h",
+    "cert_provisioning/cert_provisioning_invalidator.cc",
+    "cert_provisioning/cert_provisioning_invalidator.h",
+    "cert_provisioning/cert_provisioning_metrics.cc",
+    "cert_provisioning/cert_provisioning_metrics.h",
+    "cert_provisioning/cert_provisioning_platform_keys_helpers.cc",
+    "cert_provisioning/cert_provisioning_platform_keys_helpers.h",
+    "cert_provisioning/cert_provisioning_scheduler.cc",
+    "cert_provisioning/cert_provisioning_scheduler.h",
+    "cert_provisioning/cert_provisioning_scheduler_user_service.cc",
+    "cert_provisioning/cert_provisioning_scheduler_user_service.h",
+    "cert_provisioning/cert_provisioning_serializer.cc",
+    "cert_provisioning/cert_provisioning_serializer.h",
+    "cert_provisioning/cert_provisioning_worker.cc",
+    "cert_provisioning/cert_provisioning_worker.h",
+    "certificate_provider/certificate_info.cc",
+    "certificate_provider/certificate_info.h",
+    "certificate_provider/certificate_provider.h",
+    "certificate_provider/certificate_provider_service.cc",
+    "certificate_provider/certificate_provider_service.h",
+    "certificate_provider/certificate_provider_service_factory.cc",
+    "certificate_provider/certificate_provider_service_factory.h",
+    "certificate_provider/certificate_requests.cc",
+    "certificate_provider/certificate_requests.h",
+    "certificate_provider/pin_dialog_manager.cc",
+    "certificate_provider/pin_dialog_manager.h",
+    "certificate_provider/security_token_pin_dialog_host.h",
+    "certificate_provider/security_token_pin_dialog_host_popup_impl.cc",
+    "certificate_provider/security_token_pin_dialog_host_popup_impl.h",
+    "certificate_provider/sign_requests.cc",
+    "certificate_provider/sign_requests.h",
+    "certificate_provider/thread_safe_certificate_map.cc",
+    "certificate_provider/thread_safe_certificate_map.h",
+    "child_accounts/child_policy_observer.cc",
+    "child_accounts/child_policy_observer.h",
+    "child_accounts/child_status_reporting_service.cc",
+    "child_accounts/child_status_reporting_service.h",
+    "child_accounts/child_status_reporting_service_factory.cc",
+    "child_accounts/child_status_reporting_service_factory.h",
+    "child_accounts/child_user_service.cc",
+    "child_accounts/child_user_service.h",
+    "child_accounts/child_user_service_factory.cc",
+    "child_accounts/child_user_service_factory.h",
+    "child_accounts/edu_coexistence_tos_store_utils.cc",
+    "child_accounts/edu_coexistence_tos_store_utils.h",
+    "child_accounts/event_based_status_reporting_service.cc",
+    "child_accounts/event_based_status_reporting_service.h",
+    "child_accounts/event_based_status_reporting_service_factory.cc",
+    "child_accounts/event_based_status_reporting_service_factory.h",
+    "child_accounts/family_features.cc",
+    "child_accounts/family_features.h",
+    "child_accounts/family_user_app_metrics.cc",
+    "child_accounts/family_user_app_metrics.h",
+    "child_accounts/family_user_chrome_activity_metrics.cc",
+    "child_accounts/family_user_chrome_activity_metrics.h",
+    "child_accounts/family_user_device_metrics.cc",
+    "child_accounts/family_user_device_metrics.h",
+    "child_accounts/family_user_metrics_service.cc",
+    "child_accounts/family_user_metrics_service.h",
+    "child_accounts/family_user_metrics_service_factory.cc",
+    "child_accounts/family_user_metrics_service_factory.h",
+    "child_accounts/family_user_parental_control_metrics.cc",
+    "child_accounts/family_user_parental_control_metrics.h",
+    "child_accounts/family_user_session_metrics.cc",
+    "child_accounts/family_user_session_metrics.h",
+    "child_accounts/parent_access_code/authenticator.cc",
+    "child_accounts/parent_access_code/authenticator.h",
+    "child_accounts/parent_access_code/config_source.cc",
+    "child_accounts/parent_access_code/config_source.h",
+    "child_accounts/parent_access_code/parent_access_service.cc",
+    "child_accounts/parent_access_code/parent_access_service.h",
+    "child_accounts/screen_time_controller.cc",
+    "child_accounts/screen_time_controller.h",
+    "child_accounts/screen_time_controller_factory.cc",
+    "child_accounts/screen_time_controller_factory.h",
+    "child_accounts/time_limit_notifier.cc",
+    "child_accounts/time_limit_notifier.h",
+    "child_accounts/time_limit_override.cc",
+    "child_accounts/time_limit_override.h",
+    "child_accounts/time_limits/app_activity_registry.cc",
+    "child_accounts/time_limits/app_activity_registry.h",
+    "child_accounts/time_limits/app_activity_report_interface.cc",
+    "child_accounts/time_limits/app_activity_report_interface.h",
+    "child_accounts/time_limits/app_service_wrapper.cc",
+    "child_accounts/time_limits/app_service_wrapper.h",
+    "child_accounts/time_limits/app_time_controller.cc",
+    "child_accounts/time_limits/app_time_controller.h",
+    "child_accounts/time_limits/app_time_limit_interface.cc",
+    "child_accounts/time_limits/app_time_limit_interface.h",
+    "child_accounts/time_limits/app_time_limit_utils.cc",
+    "child_accounts/time_limits/app_time_limit_utils.h",
+    "child_accounts/time_limits/app_time_limits_allowlist_policy_wrapper.cc",
+    "child_accounts/time_limits/app_time_limits_allowlist_policy_wrapper.h",
+    "child_accounts/time_limits/app_time_notification_delegate.h",
+    "child_accounts/time_limits/app_time_policy_helpers.cc",
+    "child_accounts/time_limits/app_time_policy_helpers.h",
+    "child_accounts/time_limits/app_types.cc",
+    "child_accounts/time_limits/app_types.h",
+    "child_accounts/time_limits/persisted_app_info.cc",
+    "child_accounts/time_limits/persisted_app_info.h",
+    "child_accounts/time_limits/web_time_activity_provider.cc",
+    "child_accounts/time_limits/web_time_activity_provider.h",
+    "child_accounts/time_limits/web_time_limit_enforcer.cc",
+    "child_accounts/time_limits/web_time_limit_enforcer.h",
+    "child_accounts/time_limits/web_time_limit_navigation_throttle.cc",
+    "child_accounts/time_limits/web_time_limit_navigation_throttle.h",
+    "child_accounts/time_limits/web_time_navigation_observer.cc",
+    "child_accounts/time_limits/web_time_navigation_observer.h",
+    "child_accounts/usage_time_limit_processor.cc",
+    "child_accounts/usage_time_limit_processor.h",
+    "child_accounts/usage_time_state_notifier.cc",
+    "child_accounts/usage_time_state_notifier.h",
+    "child_accounts/website_approval_notifier.cc",
+    "child_accounts/website_approval_notifier.h",
+    "chrome_browser_main_parts_ash.cc",
+    "chrome_browser_main_parts_ash.h",
+    "concierge_helper_service.cc",
+    "concierge_helper_service.h",
+    "crostini/ansible/ansible_management_service.cc",
+    "crostini/ansible/ansible_management_service.h",
+    "crostini/ansible/ansible_management_service_factory.cc",
+    "crostini/ansible/ansible_management_service_factory.h",
+    "crostini/crostini_capabilities.cc",
+    "crostini/crostini_capabilities.h",
+    "crostini/crostini_disk.cc",
+    "crostini/crostini_disk.h",
+    "crostini/crostini_engagement_metrics_service.cc",
+    "crostini/crostini_engagement_metrics_service.h",
+    "crostini/crostini_export_import.cc",
+    "crostini/crostini_export_import.h",
+    "crostini/crostini_export_import_notification_controller.cc",
+    "crostini/crostini_export_import_notification_controller.h",
+    "crostini/crostini_export_import_status_tracker.cc",
+    "crostini/crostini_export_import_status_tracker.h",
+    "crostini/crostini_features.cc",
+    "crostini/crostini_features.h",
+    "crostini/crostini_force_close_watcher.cc",
+    "crostini/crostini_force_close_watcher.h",
+    "crostini/crostini_installer.cc",
+    "crostini/crostini_installer.h",
+    "crostini/crostini_installer_ui_delegate.h",
+    "crostini/crostini_low_disk_notification.cc",
+    "crostini/crostini_low_disk_notification.h",
+    "crostini/crostini_manager.cc",
+    "crostini/crostini_manager.h",
+    "crostini/crostini_manager_factory.cc",
+    "crostini/crostini_manager_factory.h",
+    "crostini/crostini_package_notification.cc",
+    "crostini/crostini_package_notification.h",
+    "crostini/crostini_package_operation_status.h",
+    "crostini/crostini_package_service.cc",
+    "crostini/crostini_package_service.h",
+    "crostini/crostini_port_forwarder.cc",
+    "crostini/crostini_port_forwarder.h",
+    "crostini/crostini_pref_names.cc",
+    "crostini/crostini_pref_names.h",
+    "crostini/crostini_remover.cc",
+    "crostini/crostini_remover.h",
+    "crostini/crostini_reporting_util.cc",
+    "crostini/crostini_reporting_util.h",
+    "crostini/crostini_shelf_utils.cc",
+    "crostini/crostini_shelf_utils.h",
+    "crostini/crostini_simple_types.cc",
+    "crostini/crostini_simple_types.h",
+    "crostini/crostini_sshfs.cc",
+    "crostini/crostini_sshfs.h",
+    "crostini/crostini_terminal.cc",
+    "crostini/crostini_terminal.h",
+    "crostini/crostini_unsupported_action_notifier.cc",
+    "crostini/crostini_unsupported_action_notifier.h",
+    "crostini/crostini_upgrade_available_notification.cc",
+    "crostini/crostini_upgrade_available_notification.h",
+    "crostini/crostini_upgrader.cc",
+    "crostini/crostini_upgrader.h",
+    "crostini/crostini_upgrader_ui_delegate.h",
+    "crostini/crostini_util.cc",
+    "crostini/crostini_util.h",
+    "crostini/fake_crostini_installer_ui_delegate.cc",
+    "crostini/fake_crostini_installer_ui_delegate.h",
+    "crostini/termina_installer.cc",
+    "crostini/termina_installer.h",
+    "crostini/throttle/crostini_active_window_throttle_observer.cc",
+    "crostini/throttle/crostini_active_window_throttle_observer.h",
+    "crostini/throttle/crostini_throttle.cc",
+    "crostini/throttle/crostini_throttle.h",
+    "cryptauth/client_app_metadata_provider_service.cc",
+    "cryptauth/client_app_metadata_provider_service.h",
+    "cryptauth/client_app_metadata_provider_service_factory.cc",
+    "cryptauth/client_app_metadata_provider_service_factory.h",
+    "cryptauth/cryptauth_device_id_provider_impl.cc",
+    "cryptauth/cryptauth_device_id_provider_impl.h",
+    "cryptauth/gcm_device_info_provider_impl.cc",
+    "cryptauth/gcm_device_info_provider_impl.h",
+    "customization/customization_document.cc",
+    "customization/customization_document.h",
+    "customization/customization_wallpaper_downloader.cc",
+    "customization/customization_wallpaper_downloader.h",
+    "customization/customization_wallpaper_util.cc",
+    "customization/customization_wallpaper_util.h",
   ]
 
   allow_circular_includes_from = [
@@ -673,20 +879,26 @@
     "//ash/components/audio",
     "//ash/components/disks",
     "//ash/components/login/auth",
+    "//ash/components/security_token_pin",
+    "//ash/components/settings",
     "//ash/components/tpm",
     "//ash/public/cpp",
     "//ash/public/cpp/external_arc",
+    "//ash/services/device_sync/proto",
+    "//ash/services/device_sync/public/cpp",
     "//ash/services/multidevice_setup/public/cpp",
     "//ash/services/multidevice_setup/public/cpp:android_sms_app_helper_delegate",
     "//ash/services/multidevice_setup/public/cpp:android_sms_pairing_state_tracker",
     "//base",
     "//chrome/browser/ash/arc/input_overlay/db/proto",
     "//chrome/browser/ash/crosapi",
+    "//chrome/browser/ash/crostini:crostini_installer_types_mojom",
     "//chrome/browser/chromeos",
     "//chrome/browser/extensions",
     "//chrome/browser/image_decoder",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings",
+    "//chrome/browser/ui/webui/chromeos/crostini_upgrader:mojo_bindings_headers",
     "//chrome/browser/web_applications",
     "//chrome/common:buildflags",
     "//chrome/common:constants",
@@ -696,15 +908,22 @@
     "//chromeos/ash/components/dbus/authpolicy",
     "//chromeos/ash/components/dbus/authpolicy:authpolicy_proto",
     "//chromeos/ash/components/dbus/cicerone",
+    "//chromeos/ash/components/dbus/cicerone:cicerone_proto",
     "//chromeos/ash/components/dbus/concierge",
+    "//chromeos/ash/components/dbus/concierge:concierge_proto",
+    "//chromeos/ash/components/dbus/system_clock",
+    "//chromeos/ash/components/memory",
     "//chromeos/components/sharesheet:constants",
     "//chromeos/crosapi/mojom",
+    "//chromeos/dbus/anomaly_detector",
+    "//chromeos/dbus/anomaly_detector:proto",
     "//chromeos/dbus/attestation",
     "//chromeos/dbus/attestation:attestation_proto",
     "//chromeos/dbus/common",
     "//chromeos/dbus/constants",
     "//chromeos/dbus/dlcservice",
     "//chromeos/dbus/power",
+    "//chromeos/dbus/power:power_manager_proto",
     "//chromeos/dbus/resourced",
     "//chromeos/dbus/session_manager",
     "//chromeos/dbus/tpm_manager:tpm_manager_proto",
@@ -719,6 +938,9 @@
     "//components/arc/common",
     "//components/content_settings/core/browser",
     "//components/exo",
+    "//components/gcm_driver/instance_id",
+    "//components/guest_os",
+    "//components/invalidation/public",
     "//components/keyed_service/content",
     "//components/keyed_service/core",
     "//components/policy:cloud_policy_proto_generated_compile",
@@ -727,12 +949,14 @@
     "//components/policy/core/common",
     "//components/policy/core/common:common_constants",
     "//components/policy/core/common:policy_namespace",
+    "//components/policy/proto",
     "//components/prefs",
     "//components/printing/common:mojo_interfaces",
     "//components/services/app_service/public/cpp:app_types",
     "//components/services/app_service/public/cpp:app_update",
     "//components/services/app_service/public/cpp:icon_types",
     "//components/services/app_service/public/cpp:instance_update",
+    "//components/services/app_service/public/mojom",
     "//components/services/app_service/public/mojom:types_headers",
     "//components/session_manager/core",
     "//components/signin/public/identity_manager",
@@ -749,6 +973,7 @@
     "//extensions/common",
     "//gpu/command_buffer/client",
     "//media:media_buildflags",
+    "//media/capture:capture_lib",
     "//mojo/public/c/system:headers",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/system",
@@ -759,6 +984,7 @@
     "//services/network/public/cpp",
     "//services/network/public/mojom:cookies_mojom",
     "//services/tracing/public/cpp",
+    "//skia",
     "//storage/browser",
     "//third_party/abseil-cpp:absl",
     "//third_party/boringssl",
@@ -773,6 +999,7 @@
     "//ui/base/metadata",
     "//ui/compositor",
     "//ui/display",
+    "//ui/display/types",
     "//ui/events",
     "//ui/events:dom_keycode_converter",
     "//ui/events/types:headers",
@@ -795,24 +1022,36 @@
     "//ash/components/arc/media_session",
     "//ash/components/arc/mojom:protected_buffer_manager",
     "//ash/components/cryptohome",
+    "//ash/components/device_activity",
+    "//ash/components/drivefs",
+    "//ash/components/fwupd",
+    "//ash/components/login/session",
     "//ash/components/multidevice/logging",
-    "//ash/components/settings",
+    "//ash/components/peripheral_notification",
+    "//ash/components/power",
     "//ash/constants",
+    "//ash/keyboard/ui",
     "//ash/public/mojom",
     "//ash/resources/vector_icons",
     "//ash/services/multidevice_setup/public/cpp:prefs",
     "//ash/services/multidevice_setup/public/mojom",
+    "//ash/webui/camera_app_ui:document_scanning",
     "//base:i18n",
+    "//build:branding_buildflags",
     "//chrome/app:chromium_strings",
     "//chrome/app:generated_resources",
+    "//chrome/app/theme:chrome_unscaled_resources",
     "//chrome/app/theme:theme_resources",
     "//chrome/app/vector_icons",
     "//chrome/browser:browser_process",
     "//chrome/browser:resources",
+    "//chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page",
     "//chrome/browser/ash/crosapi:browser_util",
     "//chrome/browser/chromeos:attestation_proto",
+    "//chrome/browser/metrics/structured",
     "//chrome/browser/profiles",
     "//chrome/browser/resources:component_extension_resources",
+    "//chrome/browser/ui/webui/chromeos/crostini_upgrader:mojo_bindings",
     "//chrome/browser/ui/webui/settings/chromeos/constants:mojom",
     "//chrome/browser/webshare:storage",
     "//chrome/common",
@@ -820,38 +1059,47 @@
     "//chrome/common:chrome_features",
     "//chrome/common:non_code_constants",
     "//chrome/common/net",
-    "//chromeos/ash/components/dbus/cicerone:cicerone_proto",
-    "//chromeos/ash/components/dbus/concierge:concierge_proto",
+    "//chromeos/ash/components/dbus/services",
     "//chromeos/ash/components/dbus/upstart",
     "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_browser",
+    "//chromeos/components/local_search_service/public/cpp",
     "//chromeos/components/onc",
+    "//chromeos/components/sensors",
     "//chromeos/constants",
     "//chromeos/dbus",
     "//chromeos/dbus:vm_applications_apps_proto",
     "//chromeos/dbus:vm_launch_proto",
     "//chromeos/dbus/arc",
     "//chromeos/dbus/cdm_factory_daemon",
+    "//chromeos/dbus/cros_disks",
     "//chromeos/dbus/cryptohome:attestation_proto",
+    "//chromeos/dbus/debug_daemon",
     "//chromeos/dbus/dlcservice:dlcservice_proto",
-    "//chromeos/dbus/power:power_manager_proto",
+    "//chromeos/dbus/image_loader",
+    "//chromeos/dbus/permission_broker",
     "//chromeos/dbus/session_manager",
     "//chromeos/dbus/tpm_manager",
     "//chromeos/dbus/userdataauth",
+    "//chromeos/dbus/util",
     "//chromeos/dbus/virtual_file_provider",
+    "//chromeos/login/login_state",
     "//chromeos/network",
     "//chromeos/services/assistant/public/cpp",
+    "//chromeos/services/cros_healthd/private/cpp",
     "//chromeos/services/cros_healthd/public/cpp",
+    "//chromeos/services/machine_learning/public/cpp",
     "//chromeos/system",
     "//chromeos/ui/vector_icons",
     "//components/app_constants",
     "//components/arc/common:arc_intent_helper_constants",
+    "//components/component_updater",
     "//components/consent_auditor",
     "//components/content_settings/core/common",
     "//components/crx_file",
     "//components/device_event_log",
     "//components/embedder_support:browser_util",
-    "//components/guest_os",
     "//components/guest_os:prefs",
+    "//components/invalidation/impl",
     "//components/language/core/browser",
     "//components/language/core/common",
     "//components/live_caption:constants",
@@ -860,15 +1108,20 @@
     "//components/ownership",
     "//components/permissions",
     "//components/pref_registry",
+    "//components/quirks",
+    "//components/rlz",
+    "//components/safe_browsing/core/common:safe_browsing_prefs",
     "//components/services/app_service/public/cpp:intents",
     "//components/services/app_service/public/cpp:types",
     "//components/services/app_service/public/mojom:types",
     "//components/services/filesystem/public/mojom",
     "//components/signin/public/base",
+    "//components/storage_monitor",
     "//components/strings:components_strings",
     "//components/sync/base",
     "//components/sync/driver",
     "//components/translate/core/browser",
+    "//components/url_matcher",
     "//components/version_info",
     "//components/version_info:channel",
     "//components/webapps/browser",
@@ -885,17 +1138,21 @@
     "//gpu/command_buffer/client:gles2_interface",
     "//gpu/command_buffer/common",
     "//gpu/ipc/common",
+    "//media/capture/video/chromeos/mojom:cros_camera_shared",
+    "//media/capture/video/chromeos/public",
     "//mojo/public/cpp/bindings:bindings_base",
     "//mojo/public/cpp/platform",
+    "//net/traffic_annotation",
     "//printing",
     "//printing:printing_base",
+    "//printing/backend",
     "//printing/mojom",
+    "//rlz/buildflags",
     "//services/audio/public/cpp",
     "//services/network/public/cpp:cpp_base",
     "//services/network/public/mojom",
     "//services/network/public/mojom:url_loader_base",
     "//services/tracing/public/mojom",
-    "//skia",
     "//third_party/blink/public/common:headers",
     "//third_party/blink/public/mojom:mojom_platform",
     "//third_party/icu",
@@ -905,17 +1162,20 @@
     "//ui/accessibility:ax_enums_mojo",
     "//ui/base:features",
     "//ui/chromeos",
+    "//ui/chromeos/events",
     "//ui/chromeos/resources",
     "//ui/chromeos/styles:cros_styles_views",
+    "//ui/color:color_headers",
+    "//ui/color:mixers",
     "//ui/content_accelerators",
     "//ui/display/manager",
-    "//ui/display/types",
     "//ui/events:event_constants",
     "//ui/events:events_base",
     "//ui/events/blink",
     "//ui/gfx:color_utils",
     "//ui/gfx:memory_buffer",
     "//ui/gfx/codec",
+    "//ui/native_theme",
     "//ui/strings",
     "//ui/views/controls/webview",
     "//ui/wm",
diff --git a/chrome/browser/ash/arc/intent_helper/custom_tab_session_impl.cc b/chrome/browser/ash/arc/intent_helper/custom_tab_session_impl.cc
index b8de8ec..bc0b8c82 100644
--- a/chrome/browser/ash/arc/intent_helper/custom_tab_session_impl.cc
+++ b/chrome/browser/ash/arc/intent_helper/custom_tab_session_impl.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/metrics/histogram_macros.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "components/arc/intent_helper/custom_tab.h"
@@ -40,38 +39,15 @@
 }
 
 CustomTabSessionImpl::~CustomTabSessionImpl() {
-  // Keep in sync with ArcCustomTabsSessionEndReason in
-  // tools/metrics/histograms/enums.xml.
-  enum class SessionEndReason {
-    CLOSED = 0,
-    FORWARDED_TO_NORMAL_TAB = 1,
-    kMaxValue = FORWARDED_TO_NORMAL_TAB,
-  } session_end_reason = forwarded_to_normal_tab_
-                             ? SessionEndReason::FORWARDED_TO_NORMAL_TAB
-                             : SessionEndReason::CLOSED;
-  UMA_HISTOGRAM_ENUMERATION("Arc.CustomTabs.SessionEndReason",
-                            session_end_reason);
-  auto elapsed = lifetime_timer_.Elapsed();
-  UMA_HISTOGRAM_LONG_TIMES("Arc.CustomTabs.SessionLifetime2.All", elapsed);
-  switch (session_end_reason) {
-    case SessionEndReason::CLOSED:
-      UMA_HISTOGRAM_LONG_TIMES("Arc.CustomTabs.SessionLifetime2.Closed",
-                               elapsed);
-      break;
-    case SessionEndReason::FORWARDED_TO_NORMAL_TAB:
-      UMA_HISTOGRAM_LONG_TIMES(
-          "Arc.CustomTabs.SessionLifetime2.ForwardedToNormalTab", elapsed);
-      break;
-  }
+  if (!browser_)
+    return;
 
-  if (browser_) {
-    auto* tab_strip_model = browser_->tab_strip_model();
-    DCHECK(tab_strip_model);
-    tab_strip_model->RemoveObserver(this);
-    int index = tab_strip_model->GetIndexOfWebContents(
-        tab_strip_model->GetActiveWebContents());
-    tab_strip_model->DetachAndDeleteWebContentsAt(index);
-  }
+  auto* tab_strip_model = browser_->tab_strip_model();
+  DCHECK(tab_strip_model);
+  tab_strip_model->RemoveObserver(this);
+  int index = tab_strip_model->GetIndexOfWebContents(
+      tab_strip_model->GetActiveWebContents());
+  tab_strip_model->DetachAndDeleteWebContentsAt(index);
 }
 
 void CustomTabSessionImpl::OnOpenInChromeClicked() {
diff --git a/chrome/browser/ash/borealis/borealis_app_launcher_unittest.cc b/chrome/browser/ash/borealis/borealis_app_launcher_unittest.cc
index ce571594..1d9fa97 100644
--- a/chrome/browser/ash/borealis/borealis_app_launcher_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_app_launcher_unittest.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/ash/borealis/borealis_context.h"
 #include "chrome/browser/ash/borealis/borealis_util.h"
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.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/test/base/testing_profile.h"
@@ -33,7 +33,7 @@
     StrictCallbackFactory<void(BorealisAppLauncher::LaunchResult)>;
 
 class BorealisAppLauncherTest : public testing::Test,
-                                protected FakeVmServicesHelper {
+                                protected guest_os::FakeVmServicesHelper {
  public:
   BorealisAppLauncherTest()
       : ctx_(BorealisContext::CreateBorealisContextForTesting(&profile_)) {
diff --git a/chrome/browser/ash/borealis/borealis_context_manager_unittest.cc b/chrome/browser/ash/borealis/borealis_context_manager_unittest.cc
index 066a780..4acd125 100644
--- a/chrome/browser/ash/borealis/borealis_context_manager_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_context_manager_unittest.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/ash/borealis/borealis_metrics.h"
 #include "chrome/browser/ash/borealis/borealis_task.h"
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/guest_os/guest_os_stability_monitor.h"
 #include "chrome/browser/ash/login/users/mock_user_manager.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
@@ -89,7 +89,7 @@
     StrictCallbackFactory<void(BorealisContextManager::ContextOrFailure)>;
 
 class BorealisContextManagerTest : public testing::Test,
-                                   protected FakeVmServicesHelper {
+                                   protected guest_os::FakeVmServicesHelper {
  public:
   BorealisContextManagerTest() = default;
   BorealisContextManagerTest(const BorealisContextManagerTest&) = delete;
diff --git a/chrome/browser/ash/borealis/borealis_context_unittest.cc b/chrome/browser/ash/borealis/borealis_context_unittest.cc
index 416885e6..c77da45 100644
--- a/chrome/browser/ash/borealis/borealis_context_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_context_unittest.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/ash/borealis/borealis_window_manager.h"
 #include "chrome/browser/ash/borealis/borealis_window_manager_test_helper.h"
 #include "chrome/browser/ash/borealis/testing/apps.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/guest_os/guest_os_stability_monitor.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h"
@@ -35,7 +35,7 @@
 namespace borealis {
 
 class BorealisContextTest : public testing::Test,
-                            protected FakeVmServicesHelper {
+                            protected guest_os::FakeVmServicesHelper {
  public:
   BorealisContextTest()
       : new_window_provider_(std::make_unique<ash::TestNewWindowDelegate>()) {
diff --git a/chrome/browser/ash/borealis/borealis_disk_manager_unittest.cc b/chrome/browser/ash/borealis/borealis_disk_manager_unittest.cc
index 8fa779d..a98e3d2 100644
--- a/chrome/browser/ash/borealis/borealis_disk_manager_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_disk_manager_unittest.cc
@@ -18,7 +18,7 @@
 #include "chrome/browser/ash/borealis/borealis_service_fake.h"
 #include "chrome/browser/ash/borealis/borealis_window_manager.h"
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h"
@@ -91,7 +91,7 @@
 };
 
 class BorealisDiskManagerTest : public testing::Test,
-                                protected FakeVmServicesHelper {
+                                protected guest_os::FakeVmServicesHelper {
  public:
   BorealisDiskManagerTest() = default;
   ~BorealisDiskManagerTest() override = default;
diff --git a/chrome/browser/ash/borealis/borealis_installer_unittest.cc b/chrome/browser/ash/borealis/borealis_installer_unittest.cc
index 9a697a0..c5b2f688 100644
--- a/chrome/browser/ash/borealis/borealis_installer_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_installer_unittest.cc
@@ -23,8 +23,8 @@
 #include "chrome/browser/ash/borealis/infra/described.h"
 #include "chrome/browser/ash/borealis/testing/apps.h"
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
 #include "chrome/browser/ash/borealis/testing/features.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.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/common/chrome_features.h"
@@ -57,7 +57,7 @@
 };
 
 class BorealisInstallerTest : public testing::Test,
-                              protected FakeVmServicesHelper {
+                              protected guest_os::FakeVmServicesHelper {
  public:
   BorealisInstallerTest() = default;
   ~BorealisInstallerTest() override = default;
diff --git a/chrome/browser/ash/borealis/borealis_launch_watcher_unittest.cc b/chrome/browser/ash/borealis/borealis_launch_watcher_unittest.cc
index 777664b0..a1263a5 100644
--- a/chrome/browser/ash/borealis/borealis_launch_watcher_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_launch_watcher_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h"
@@ -22,7 +22,7 @@
     StrictCallbackFactory<void(absl::optional<std::string>)>;
 
 class BorealisLaunchWatcherTest : public testing::Test,
-                                  protected FakeVmServicesHelper {
+                                  protected guest_os::FakeVmServicesHelper {
  protected:
   content::BrowserTaskEnvironment task_environment_;
   // This test doesn't actually need the profile for anything meaningful,
diff --git a/chrome/browser/ash/borealis/borealis_task_unittest.cc b/chrome/browser/ash/borealis/borealis_task_unittest.cc
index 18ec382..0a9b8bc 100644
--- a/chrome/browser/ash/borealis/borealis_task_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_task_unittest.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ash/borealis/borealis_disk_manager.h"
 #include "chrome/browser/ash/borealis/borealis_metrics.h"
 #include "chrome/browser/ash/borealis/testing/callback_factory.h"
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h"
@@ -62,7 +62,8 @@
 using CallbackFactory =
     NiceCallbackFactory<void(BorealisStartupResult, std::string)>;
 
-class BorealisTasksTest : public testing::Test, protected FakeVmServicesHelper {
+class BorealisTasksTest : public testing::Test,
+                          protected guest_os::FakeVmServicesHelper {
  public:
   BorealisTasksTest() = default;
   ~BorealisTasksTest() override = default;
diff --git a/chrome/browser/ash/crostini/crostini_disk.h b/chrome/browser/ash/crostini/crostini_disk.h
index 77c7064..eb2eaa0 100644
--- a/chrome/browser/ash/crostini/crostini_disk.h
+++ b/chrome/browser/ash/crostini/crostini_disk.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "chrome/browser/ash/crostini/crostini_simple_types.h"
-#include "chrome/browser/ash/crostini/crostini_types.mojom-forward.h"
+#include "chrome/browser/ash/crostini/crostini_types.mojom.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_service.pb.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ash/crostini/crostini_manager.h b/chrome/browser/ash/crostini/crostini_manager.h
index 36abc10..8071855 100644
--- a/chrome/browser/ash/crostini/crostini_manager.h
+++ b/chrome/browser/ash/crostini/crostini_manager.h
@@ -36,7 +36,6 @@
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/network_state_handler_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "services/device/public/mojom/usb_manager.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
diff --git a/chrome/browser/ash/crostini/crostini_upgrader.cc b/chrome/browser/ash/crostini/crostini_upgrader.cc
index fb3425fd7..89bd1303 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader.cc
+++ b/chrome/browser/ash/crostini/crostini_upgrader.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ash/crostini/crostini_manager_factory.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader.mojom.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h b/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
index 7aba48f..f73b02d 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
+++ b/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader.mojom.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader.mojom-forward.h"
 
 namespace base {
 class FilePath;
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 61d6a67..c127f66 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -1706,6 +1706,42 @@
     ::testing::Values(
         TestCase("recentsA11yMessages").EnableFiltersInRecents(),
         TestCase("recentsA11yMessages").EnableFiltersInRecents().FilesSwa(),
+        TestCase("recentsAllowCut")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsAllowCut")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
+        TestCase("recentsAllowDeletion")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsAllowDeletion")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
+        TestCase("recentsAllowMultipleFilesDeletion")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsAllowMultipleFilesDeletion")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
+        TestCase("recentsAllowRename")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsAllowRename")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
         TestCase("recentsDownloads"),
         TestCase("recentsDownloads").FilesSwa(),
         TestCase("recentsDownloads").EnableFiltersInRecents(),
@@ -1752,6 +1788,15 @@
         TestCase("recentsNested").FilesSwa(),
         TestCase("recentsNested").EnableFiltersInRecents(),
         TestCase("recentsNested").EnableFiltersInRecents().FilesSwa(),
+        TestCase("recentsNoRenameForPlayFiles")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsNoRenameForPlayFiles")
+            .EnableArc()
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
         TestCase("recentsPlayFiles").EnableArc(),
         TestCase("recentsPlayFiles").EnableArc().FilesSwa(),
         TestCase("recentsPlayFiles").EnableArc().EnableFiltersInRecents(),
@@ -1759,6 +1804,13 @@
             .EnableArc()
             .EnableFiltersInRecents()
             .FilesSwa(),
+        TestCase("recentsReadOnlyHidden")
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2(),
+        TestCase("recentsReadOnlyHidden")
+            .EnableFiltersInRecents()
+            .EnableFiltersInRecentsV2()
+            .FilesSwa(),
         TestCase("recentAudioDownloads"),
         TestCase("recentAudioDownloads").FilesSwa(),
         TestCase("recentAudioDownloads").EnableFiltersInRecents(),
diff --git a/chrome/browser/ash/file_manager/trash_io_task.cc b/chrome/browser/ash/file_manager/trash_io_task.cc
index 4bec5fa..124e3d8 100644
--- a/chrome/browser/ash/file_manager/trash_io_task.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task.cc
@@ -34,9 +34,8 @@
                              const base::FilePath& trash_parent_path,
                              TrashEntry& entry) {
   std::string relative_restore_path = original_path.value();
-  if (!file_manager::util::ReplacePrefix(
-          &relative_restore_path,
-          trash_parent_path.AsEndingWithSeparator().value(), "")) {
+  if (!file_manager::util::ReplacePrefix(&relative_restore_path,
+                                         trash_parent_path.value(), "")) {
     return false;
   }
 
diff --git a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
index 2f91102..7b7febb 100644
--- a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
@@ -116,9 +116,8 @@
   const std::string CreateTrashInfoContentsFromPath(
       const base::FilePath& file_path) {
     std::string relative_restore_path = file_path.value();
-    EXPECT_TRUE(file_manager::util::ReplacePrefix(
-        &relative_restore_path, downloads_dir_.AsEndingWithSeparator().value(),
-        ""));
+    EXPECT_TRUE(file_manager::util::ReplacePrefix(&relative_restore_path,
+                                                  downloads_dir_.value(), ""));
     return base::StrCat({"[Trash Info]\nPath=", relative_restore_path,
                          "\nDeletionDate=", base::TimeToISO8601(base::Time())});
   }
diff --git a/chrome/browser/ash/borealis/testing/dbus.cc b/chrome/browser/ash/guest_os/dbus_test_helper.cc
similarity index 94%
rename from chrome/browser/ash/borealis/testing/dbus.cc
rename to chrome/browser/ash/guest_os/dbus_test_helper.cc
index 06a2e7d5..71a6a3f 100644
--- a/chrome/browser/ash/borealis/testing/dbus.cc
+++ b/chrome/browser/ash/guest_os/dbus_test_helper.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/borealis/testing/dbus.h"
+#include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 
 #include "chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h"
 #include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h"
@@ -10,7 +10,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/dlcservice/fake_dlcservice_client.h"
 
-namespace borealis {
+namespace guest_os {
 
 BasicDBusHelper::BasicDBusHelper() {
   chromeos::DBusThreadManager::Initialize();
@@ -79,4 +79,4 @@
       FakeDlcserviceHelper(this),
       FakeConciergeHelper(this) {}
 
-}  // namespace borealis
+}  // namespace guest_os
diff --git a/chrome/browser/ash/borealis/testing/dbus.h b/chrome/browser/ash/guest_os/dbus_test_helper.h
similarity index 76%
rename from chrome/browser/ash/borealis/testing/dbus.h
rename to chrome/browser/ash/guest_os/dbus_test_helper.h
index 9dd0aff..693676c8 100644
--- a/chrome/browser/ash/borealis/testing/dbus.h
+++ b/chrome/browser/ash/guest_os/dbus_test_helper.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_BOREALIS_TESTING_DBUS_H_
-#define CHROME_BROWSER_ASH_BOREALIS_TESTING_DBUS_H_
+#ifndef CHROME_BROWSER_ASH_GUEST_OS_DBUS_TEST_HELPER_H_
+#define CHROME_BROWSER_ASH_GUEST_OS_DBUS_TEST_HELPER_H_
 
 namespace ash {
 class FakeCiceroneClient;
@@ -15,7 +15,7 @@
 class FakeDlcserviceClient;
 }  // namespace chromeos
 
-namespace borealis {
+namespace guest_os {
 
 class BasicDBusHelper {
  public:
@@ -58,6 +58,10 @@
   ash::FakeConciergeClient* FakeConciergeClient();
 };
 
+// A class for less boilerplate in VM tests. Have your fixture inherit from this
+// class, and the dbus services common to most VMs get initialised with fakes
+// during before your test and torn down correctly after.
+// You can access the fakes with e.g. this->FakeConciergeClient.
 class FakeVmServicesHelper : public BasicDBusHelper,
                              public FakeCiceroneHelper,
                              public FakeSeneschalHelper,
@@ -67,6 +71,6 @@
   FakeVmServicesHelper();
 };
 
-}  // namespace borealis
+}  // namespace guest_os
 
-#endif  // CHROME_BROWSER_ASH_BOREALIS_TESTING_DBUS_H_
+#endif  // CHROME_BROWSER_ASH_GUEST_OS_DBUS_TEST_HELPER_H_
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
index 41f9d1f..9dd38f4 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
@@ -32,7 +32,6 @@
 #include "crypto/sha2.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/private_membership/src/membership_response_map.h"
 #include "url/gurl.h"
 
 namespace policy {
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
index 638d24c8..e9014ab 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <memory>
 #include <string>
-#include <tuple>
 #include <utility>
 #include <vector>
 
@@ -17,8 +16,7 @@
 #include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
+#include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
@@ -27,10 +25,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/enrollment/auto_enrollment_controller.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/testing_psm_rlwe_id_provider.h"
+#include "chrome/browser/ash/policy/enrollment/private_membership/fake_psm_rlwe_dmserver_client.h"
 #include "chrome/browser/ash/policy/server_backed_state/server_backed_device_state.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
@@ -48,15 +43,15 @@
 #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/private_membership/src/internal/testing/regression_test_data/regression_test_data.pb.h"
-#include "third_party/shell-encryption/src/testing/status_testing.h"
 
 namespace em = enterprise_management;
-namespace psm_rlwe = private_membership::rlwe;
 
 // An enum for PSM execution result values.
 using PsmExecutionResult = em::DeviceRegisterRequest::PsmExecutionResult;
 
+// A struct reporesents the PSM execution result params.
+using PsmResultHolder = policy::PsmRlweDmserverClient::ResultHolder;
+
 namespace policy {
 
 namespace {
@@ -85,32 +80,6 @@
 using ::testing::Mock;
 using ::testing::SaveArg;
 
-// Number of test cases exist in cros_test_data.binarypb file, which is part of
-// private_membership third_party library.
-const int kNumberOfPsmTestCases = 10;
-
-// Invalid test case index which acts as a dummy value when the PSM (private set
-// membership) is disabled.
-const int kInvalidPsmTestCaseIndex = -1;
-
-// PrivateSetMembership regression tests maximum file size which is 4MB.
-const size_t kMaxFileSizeInBytes = 4 * 1024 * 1024;
-
-bool ParseProtoFromFile(const base::FilePath& file_path,
-                        google::protobuf::MessageLite* out_proto) {
-  if (!out_proto) {
-    return false;
-  }
-
-  std::string file_content;
-  if (!base::ReadFileToStringWithMaxSize(file_path, &file_content,
-                                         kMaxFileSizeInBytes)) {
-    return false;
-  }
-
-  return out_proto->ParseFromString(file_content);
-}
-
 enum class AutoEnrollmentProtocol { kFRE = 0, kInitialEnrollment = 1 };
 
 enum class PsmState { kEnabled = 0, kDisabled = 1 };
@@ -128,11 +97,8 @@
   PsmState psm_state;
 };
 
-// The integer parameter represents the index of PSM test case.
 class AutoEnrollmentClientImplTest
-    : public testing::Test,
-      public ::testing::WithParamInterface<
-          std::tuple<AutoEnrollmentClientImplTestState, int>> {
+    : public testing::TestWithParam<AutoEnrollmentClientImplTestState> {
  public:
   AutoEnrollmentClientImplTest(const AutoEnrollmentClientImplTest&) = delete;
   AutoEnrollmentClientImplTest& operator=(const AutoEnrollmentClientImplTest&) =
@@ -156,12 +122,10 @@
   }
 
   AutoEnrollmentProtocol GetAutoEnrollmentProtocol() const {
-    return std::get<0>(GetParam()).auto_enrollment_protocol;
+    return GetParam().auto_enrollment_protocol;
   }
 
-  PsmState GetPsmState() const { return std::get<0>(GetParam()).psm_state; }
-
-  int GetPsmTestCaseIndex() const { return std::get<1>(GetParam()); }
+  PsmState GetPsmState() const { return GetParam().psm_state; }
 
   std::string GetAutoEnrollmentProtocolUmaSuffix() const {
     return GetAutoEnrollmentProtocol() ==
@@ -192,17 +156,19 @@
       // PSM has to be enabled whenever creating a client for initial
       // enrollment.
       DCHECK_EQ(GetPsmState(), PsmState::kEnabled);
-      DCHECK(psm_rlwe_test_client_factory_);
+
+      // Store a non-owned smart pointer of FakePsmRlweDmserverClient in
+      // `fake_psm_rlwe_dmserver_client_ptr_`.
+      auto fake_psm_rlwe_dmserver_client =
+          std::make_unique<FakePsmRlweDmserverClient>();
+      fake_psm_rlwe_dmserver_client_ptr_ = fake_psm_rlwe_dmserver_client.get();
 
       client_ =
           AutoEnrollmentClientImpl::FactoryImpl().CreateForInitialEnrollment(
               progress_callback, service_.get(), local_state_,
               shared_url_loader_factory_, kSerialNumber, kBrandCode,
               power_initial, power_limit,
-              std::make_unique<PsmRlweDmserverClientImpl>(
-                  service_.get(), shared_url_loader_factory_,
-                  psm_rlwe_test_client_factory_.get(),
-                  testing_psm_rlwe_id_provider_.get()));
+              std::move(fake_psm_rlwe_dmserver_client));
     }
   }
 
@@ -557,17 +523,9 @@
     return static_cast<AutoEnrollmentClientImpl*>(client_.release());
   }
 
-  // Sets which PSM RLWE client will be created, depending on the factory. It is
-  // only used for PSM during creating the client for initial enrollment.
-  std::unique_ptr<TestingPrivateMembershipRlweClient::FactoryImpl>
-      psm_rlwe_test_client_factory_;
-
-  // Sets the PSM RLWE ID directly for testing.
-  std::unique_ptr<TestingPsmRlweIdProvider> testing_psm_rlwe_id_provider_;
-
-  base::HistogramTester histogram_tester_;
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  base::HistogramTester histogram_tester_;
   ScopedTestingLocalState scoped_testing_local_state_;
   TestingPrefServiceSimple* local_state_;
   testing::StrictMock<MockJobCreationHandler> job_creation_handler_;
@@ -583,6 +541,10 @@
   DeviceManagementService::JobConfiguration::JobType state_retrieval_job_type_ =
       DeviceManagementService::JobConfiguration::TYPE_INVALID;
 
+  // Sets the final result of PSM protocol for testing.
+  base::raw_ptr<FakePsmRlweDmserverClient> fake_psm_rlwe_dmserver_client_ptr_ =
+      nullptr;
+
  private:
   em::DeviceManagementResponse GetAutoEnrollmentResponse(
       int64_t modulus,
@@ -1522,13 +1484,11 @@
 // PSM is disabed to test only Hash dance for FRE case extensively instead. That
 // is because PSM is running only for initial enrollment, and Hash dance for FRE
 // use case.
-INSTANTIATE_TEST_SUITE_P(
-    FRE,
-    AutoEnrollmentClientImplTest,
-    testing::Combine(testing::Values(AutoEnrollmentClientImplTestState(
-                         AutoEnrollmentProtocol::kFRE,
-                         PsmState::kDisabled)),
-                     testing::Values(kInvalidPsmTestCaseIndex)));
+INSTANTIATE_TEST_SUITE_P(FRE,
+                         AutoEnrollmentClientImplTest,
+                         testing::Values(AutoEnrollmentClientImplTestState(
+                             AutoEnrollmentProtocol::kFRE,
+                             PsmState::kDisabled)));
 
 using AutoEnrollmentClientImplFREToInitialEnrollmentTest =
     AutoEnrollmentClientImplTest;
@@ -1640,17 +1600,15 @@
 // PSM is disabed to test only Hash dance for FRE case extensively instead. That
 // is because PSM is running only for initial enrollment, and Hash dance for FRE
 // use case.
-INSTANTIATE_TEST_SUITE_P(
-    FREToInitialEnrollment,
-    AutoEnrollmentClientImplFREToInitialEnrollmentTest,
-    testing::Combine(testing::Values(AutoEnrollmentClientImplTestState(
-                         AutoEnrollmentProtocol::kFRE,
-                         PsmState::kDisabled)),
-                     testing::Values(kInvalidPsmTestCaseIndex)));
+INSTANTIATE_TEST_SUITE_P(FREToInitialEnrollment,
+                         AutoEnrollmentClientImplFREToInitialEnrollmentTest,
+                         testing::Values(AutoEnrollmentClientImplTestState(
+                             AutoEnrollmentProtocol::kFRE,
+                             PsmState::kDisabled)));
 
-// This class is used to test any PSM related test cases only. Therefore, the
-// PsmState param has to be kEnabled.
-class PsmHelperTest : public AutoEnrollmentClientImplTest {
+// This class is used to test PSM for initial enrollment test cases only.
+// Therefore, the PsmState param has to be kEnabled.
+class PsmHelperInitialEnrollmentTest : public AutoEnrollmentClientImplTest {
  protected:
   // Indicates the state of the PSM protocol.
   enum class StateDiscoveryResult {
@@ -1664,8 +1622,8 @@
     kSuccessHasServerSideState = 2,
   };
 
-  PsmHelperTest() {}
-  ~PsmHelperTest() {
+  PsmHelperInitialEnrollmentTest() {}
+  ~PsmHelperInitialEnrollmentTest() {
     // Flush any deletion tasks.
     base::RunLoop().RunUntilIdle();
   }
@@ -1681,115 +1639,15 @@
               nullptr);
     ASSERT_EQ(local_state_->GetUserPref(prefs::kEnrollmentPsmResult), nullptr);
 
-    // Create PSM test case, before setting up the base class, to construct the
-    // PSM RLWE testing client factory and its RLWE ID.
-    CreatePsmTestCase();
-
-    // Set up the base class AutoEnrollmentClientImplTest after creating the PSM
-    // RLWE client factory for testing in |psm_rlwe_test_client_factory_|, and
-    // PSM RLWE ID provider in |testing_psm_rlwe_id_provider_|.
     AutoEnrollmentClientImplTest::SetUp();
   }
 
-  void CreatePsmTestCase() {
-    // Verify PSM test case index is valid.
-    ASSERT_GE(GetPsmTestCaseIndex(), 0);
-
-    // Retrieve the PSM test case.
-    base::FilePath src_root_dir;
-    EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root_dir));
-    const base::FilePath kPsmTestDataPath =
-        src_root_dir.AppendASCII("third_party")
-            .AppendASCII("private_membership")
-            .AppendASCII("src")
-            .AppendASCII("internal")
-            .AppendASCII("testing")
-            .AppendASCII("regression_test_data")
-            .AppendASCII("test_data.binarypb");
-    EXPECT_TRUE(base::PathExists(kPsmTestDataPath));
-    psm_rlwe::PrivateMembershipRlweClientRegressionTestData test_data;
-    EXPECT_TRUE(ParseProtoFromFile(kPsmTestDataPath, &test_data));
-    EXPECT_EQ(test_data.test_cases_size(), kNumberOfPsmTestCases);
-    psm_test_case_ = test_data.test_cases(GetPsmTestCaseIndex());
-
-    std::vector<private_membership::rlwe::RlwePlaintextId> plaintext_ids{
-        psm_test_case_.plaintext_id()};
-
-    // Sets the PSM RLWE client factory to testing client.
-    psm_rlwe_test_client_factory_ =
-        std::make_unique<TestingPrivateMembershipRlweClient::FactoryImpl>(
-            psm_test_case_.ec_cipher_key(), psm_test_case_.seed(),
-            plaintext_ids);
-
-    // Sets the PSM RLWE ID.
-    testing_psm_rlwe_id_provider_ = std::make_unique<TestingPsmRlweIdProvider>(
-        psm_test_case_.plaintext_id());
-  }
-
-  void ServerWillReplyWithPsmOprfResponse() {
-    em::DeviceManagementResponse response = GetPsmOprfResponse();
-
-    ServerWillReplyForPsm(net::OK, DeviceManagementService::kSuccess, response);
-  }
-
-  void ServerWillReplyWithPsmQueryResponse() {
-    em::DeviceManagementResponse response = GetPsmQueryResponse();
-
-    ServerWillReplyForPsm(net::OK, DeviceManagementService::kSuccess, response);
-  }
-
-  void ServerWillReplyWithEmptyPsmResponse() {
-    em::DeviceManagementResponse dummy_response;
-    ServerWillReplyForPsm(net::OK, DeviceManagementService::kSuccess,
-                          dummy_response);
-  }
-
-  void ServerWillFailForPsm(int net_error, int response_code) {
-    em::DeviceManagementResponse dummy_response;
-    ServerWillReplyForPsm(net_error, response_code, dummy_response);
-  }
-
-  // Mocks the server reply and captures the job type in |psm_last_job_type_|,
-  // and the request in |psm_last_request_|.
-  void ServerWillReplyForPsm(int net_error,
-                             int response_code,
-                             const em::DeviceManagementResponse& response) {
-    EXPECT_CALL(job_creation_handler_, OnJobCreation)
-        .WillOnce(DoAll(
-            service_->CaptureJobType(&psm_last_job_type_),
-            service_->CaptureRequest(&psm_last_request_),
-            service_->SendJobResponseAsync(net_error, response_code, response)))
-        .RetiresOnSaturation();
-  }
-
-  // Holds the full control of the given job in |job| and captures the job type
-  // in |psm_last_job_type_|, and its request in |psm_last_request_|.
-  void ServerWillReplyAsyncForPsm(DeviceManagementService::JobForTesting* job) {
-    EXPECT_CALL(job_creation_handler_, OnJobCreation)
-        .WillOnce(DoAll(service_->CaptureJobType(&psm_last_job_type_),
-                        service_->CaptureRequest(&psm_last_request_),
-                        SaveArg<0>(job)));
-  }
-
-  void ServerReplyForPsmAsyncJobWithOprfResponse(
-      DeviceManagementService::JobForTesting* job) {
-    em::DeviceManagementResponse response = GetPsmOprfResponse();
-    service_->SendJobOKNow(job, response);
-  }
-
-  void ServerReplyForPsmAsyncJobWithQueryResponse(
-      DeviceManagementService::JobForTesting* job) {
-    em::DeviceManagementResponse response = GetPsmQueryResponse();
-    service_->SendJobOKNow(job, response);
-  }
-
-  void ServerFailsForAsyncJob(DeviceManagementService::JobForTesting* job) {
-    service_->SendJobResponseNow(job, net::OK,
-                                 DeviceManagementService::kServiceUnavailable);
-  }
-
-  const em::PrivateSetMembershipRequest& psm_request() const {
-    return psm_last_request_.private_set_membership_request();
+  void PsmWillReplyWith(PsmResult psm_result,
+                        absl::optional<bool> membership_result = absl::nullopt,
+                        absl::optional<base::Time>
+                            membership_determination_time = absl::nullopt) {
+    fake_psm_rlwe_dmserver_client_ptr_->WillReplyWith(PsmResultHolder(
+        psm_result, membership_result, membership_determination_time));
   }
 
   // Returns the PSM execution result that has been stored in
@@ -1825,95 +1683,44 @@
                : StateDiscoveryResult::kSuccessNoServerSideState;
   }
 
-  // Returns the expected membership result for the current private set
-  // membership test case.
-  bool GetExpectedMembershipResult() const {
-    return psm_test_case_.is_positive_membership_expected();
-  }
-
-  // Expects a sample for kUMAPsmResult to be recorded once with value
-  // |protocol_result|.
-  // If |success_time_recorded| is true it expects one sample
-  // for kUMAPsmSuccessTime. Otherwise, expects no sample to be recorded for
-  // kUMAPsmSuccessTime.
-  void ExpectPsmHistograms(PsmResult protocol_result,
-                           bool success_time_recorded) const {
-    histogram_tester_.ExpectBucketCount(
-        kUMAPsmResult + GetAutoEnrollmentProtocolUmaSuffix(), protocol_result,
-        /*expected_count=*/1);
-    histogram_tester_.ExpectTotalCount(kUMAPsmSuccessTime,
-                                       success_time_recorded ? 1 : 0);
-  }
-
-  // Expects a sample |dm_status| for kUMAPsmDmServerRequestStatus with count
-  // |dm_status_count|.
-  void ExpectPsmRequestStatusHistogram(DeviceManagementStatus dm_status,
-                                       int dm_status_count) const {
-    histogram_tester_.ExpectBucketCount(
-        kUMAPsmDmServerRequestStatus + GetAutoEnrollmentProtocolUmaSuffix(),
-        dm_status, dm_status_count);
-  }
-
-  // Expects one sample for |kUMAPsmNetworkErrorCode| which has value of
-  // |network_error|.
-  void ExpectPsmNetworkErrorHistogram(int network_error) const {
-    histogram_tester_.ExpectBucketCount(
-        kUMAPsmNetworkErrorCode + GetAutoEnrollmentProtocolUmaSuffix(),
-        network_error, /*expected_count=*/1);
-  }
-
-  void VerifyPsmLastRequestJobType() const {
-    EXPECT_EQ(DeviceManagementService::JobConfiguration::
-                  TYPE_PSM_HAS_DEVICE_STATE_REQUEST,
-              psm_last_job_type_);
-  }
-
-  void VerifyPsmRlweOprfRequest() const {
-    EXPECT_EQ(psm_test_case_.expected_oprf_request().SerializeAsString(),
-              psm_request().rlwe_request().oprf_request().SerializeAsString());
-  }
-
-  void VerifyPsmRlweQueryRequest() const {
-    EXPECT_EQ(psm_test_case_.expected_query_request().SerializeAsString(),
-              psm_request().rlwe_request().query_request().SerializeAsString());
-  }
-
-  // Disallow copy constructor and assignment operator.
-  PsmHelperTest(const PsmHelperTest&) = delete;
-  PsmHelperTest& operator=(const PsmHelperTest&) = delete;
-
- private:
-  em::DeviceManagementResponse GetPsmOprfResponse() const {
-    em::DeviceManagementResponse response;
-    em::PrivateSetMembershipResponse* psm_response =
-        response.mutable_private_set_membership_response();
-
-    *psm_response->mutable_rlwe_response()->mutable_oprf_response() =
-        psm_test_case_.oprf_response();
-    return response;
-  }
-
-  em::DeviceManagementResponse GetPsmQueryResponse() const {
-    em::DeviceManagementResponse response;
-    em::PrivateSetMembershipResponse* psm_response =
-        response.mutable_private_set_membership_response();
-
-    *psm_response->mutable_rlwe_response()->mutable_query_response() =
-        psm_test_case_.query_response();
-    return response;
-  }
-
-  psm_rlwe::PrivateMembershipRlweClientRegressionTestData::TestCase
-      psm_test_case_;
-  DeviceManagementService::JobConfiguration::JobType psm_last_job_type_ =
-      DeviceManagementService::JobConfiguration::TYPE_INVALID;
-  em::DeviceManagementRequest psm_last_request_;
+  // Style guide requires the class to be non-copyable/non-movable by default.
+  PsmHelperInitialEnrollmentTest(const PsmHelperInitialEnrollmentTest&) =
+      delete;
+  PsmHelperInitialEnrollmentTest& operator=(
+      const PsmHelperInitialEnrollmentTest&) = delete;
 };
 
-TEST_P(PsmHelperTest, MembershipRetrievedSuccessfully) {
-  InSequence sequence;
+TEST_P(PsmHelperInitialEnrollmentTest,
+       RetryLogicAfterNetworkFailureForRlweQueryResponse) {
+  PsmWillReplyWith(PsmResult::kServerError);
 
-  const bool kExpectedMembershipResult = GetExpectedMembershipResult();
+  client()->Start();
+  base::RunLoop().RunUntilIdle();
+
+  const StateDiscoveryResult kExpectedStateResult =
+      StateDiscoveryResult::kFailure;
+  const PsmExecutionResult kExpectedPsmExecutionResult =
+      em::DeviceRegisterRequest::PSM_RESULT_ERROR;
+  EXPECT_EQ(GetStateDiscoveryResult(), kExpectedStateResult);
+  EXPECT_EQ(GetPsmExecutionResult(), kExpectedPsmExecutionResult);
+  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
+
+  // Verify that PSM cached membership result hasn't changed.
+
+  client()->Retry();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(GetStateDiscoveryResult(), kExpectedStateResult);
+  EXPECT_EQ(GetPsmExecutionResult(), kExpectedPsmExecutionResult);
+  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
+
+  // Verify initial enrollment state retrieval.
+  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_SERVER_ERROR);
+}
+
+TEST_P(PsmHelperInitialEnrollmentTest,
+       RetryLogicAfterMembershipSuccessfullyRetrieved) {
+  const bool kExpectedMembershipResult = false;
   const base::TimeDelta kOneSecondTimeDelta = base::Seconds(1);
   const base::Time kExpectedPsmDeterminationTimestamp =
       base::Time::NowFromSystemTime() + kOneSecondTimeDelta;
@@ -1921,193 +1728,9 @@
   // Advance the time forward one second.
   task_environment_.FastForwardBy(kOneSecondTimeDelta);
 
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillReplyWithPsmQueryResponse();
-
-  // Fail for DeviceInitialEnrollmentStateRequest if the device has a
-  // server-backed state.
-  if (kExpectedMembershipResult)
-    ServerWillFail(net::OK, DeviceManagementService::kServiceUnavailable);
-
-  client()->Start();
-
-  // TODO(crbug.com/1143634) Remove all usages of RunUntilIdle for all PSM
-  // tests, after removing support of Hash dance from client side.
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(GetStateDiscoveryResult(),
-            kExpectedMembershipResult
-                ? StateDiscoveryResult::kSuccessHasServerSideState
-                : StateDiscoveryResult::kSuccessNoServerSideState);
-  EXPECT_EQ(
-      GetPsmExecutionResult(),
-      kExpectedMembershipResult
-          ? em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITH_STATE
-          : em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
-  EXPECT_EQ(kExpectedPsmDeterminationTimestamp, GetPsmDeterminationTimestamp());
-  ExpectPsmHistograms(PsmResult::kSuccessfulDetermination,
-                      /*success_time_recorded=*/true);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/2);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  if (kExpectedMembershipResult) {
-    EXPECT_EQ(failed_job_type_, GetExpectedStateRetrievalJobType());
-    EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_SERVER_ERROR);
-  } else {
-    EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_NO_ENROLLMENT);
-  }
-}
-
-TEST_P(PsmHelperTest, EmptyRlweQueryResponse) {
-  InSequence sequence;
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillReplyWithEmptyPsmResponse();
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kEmptyQueryResponseError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/2);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_NO_ENROLLMENT);
-}
-
-TEST_P(PsmHelperTest, EmptyRlweOprfResponse) {
-  InSequence sequence;
-  ServerWillReplyWithEmptyPsmResponse();
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kEmptyOprfResponseError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/1);
-  VerifyPsmRlweOprfRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_NO_ENROLLMENT);
-}
-
-TEST_P(PsmHelperTest, ConnectionErrorForRlweQueryResponse) {
-  InSequence sequence;
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillFailForPsm(net::ERR_FAILED, DeviceManagementService::kSuccess);
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kConnectionError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/1);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_REQUEST_FAILED,
-                                  /*dm_status_count=*/1);
-  ExpectPsmNetworkErrorHistogram(-net::ERR_FAILED);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
-}
-
-TEST_P(PsmHelperTest, ConnectionErrorForRlweOprfResponse) {
-  InSequence sequence;
-  ServerWillFailForPsm(net::ERR_FAILED, DeviceManagementService::kSuccess);
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kConnectionError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_REQUEST_FAILED,
-                                  /*dm_status_count=*/1);
-  ExpectPsmNetworkErrorHistogram(-net::ERR_FAILED);
-  VerifyPsmRlweOprfRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
-}
-
-TEST_P(PsmHelperTest, NetworkFailureForRlweOprfResponse) {
-  InSequence sequence;
-  ServerWillFailForPsm(net::OK, net::ERR_CONNECTION_CLOSED);
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kServerError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_HTTP_STATUS_ERROR,
-                                  /*dm_status_count=*/1);
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_SERVER_ERROR);
-}
-
-TEST_P(PsmHelperTest, NetworkFailureForRlweQueryResponse) {
-  InSequence sequence;
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillFailForPsm(net::OK, net::ERR_CONNECTION_CLOSED);
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(GetStateDiscoveryResult(), StateDiscoveryResult::kFailure);
-  EXPECT_EQ(GetPsmExecutionResult(),
-            em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kServerError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/1);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_HTTP_STATUS_ERROR,
-                                  /*dm_status_count=*/1);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_SERVER_ERROR);
-}
-
-TEST_P(PsmHelperTest, RetryLogicAfterMembershipSuccessfullyRetrieved) {
-  InSequence sequence;
-
-  const bool kExpectedMembershipResult = GetExpectedMembershipResult();
-  const base::TimeDelta kOneSecondTimeDelta = base::Seconds(1);
-  const base::Time kExpectedPsmDeterminationTimestamp =
-      base::Time::NowFromSystemTime() + kOneSecondTimeDelta;
-
-  // Advance the time forward one second.
-  task_environment_.FastForwardBy(kOneSecondTimeDelta);
-
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillReplyWithPsmQueryResponse();
+  PsmWillReplyWith(PsmResult::kSuccessfulDetermination,
+                   kExpectedMembershipResult,
+                   kExpectedPsmDeterminationTimestamp);
 
   // Fail for DeviceInitialEnrollmentStateRequest if the device has a
   // server-backed state.
@@ -2130,8 +1753,7 @@
           : em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
   EXPECT_EQ(kExpectedPsmDeterminationTimestamp, GetPsmDeterminationTimestamp());
 
-  // Verify that none of the PSM requests have been sent again. And its cached
-  // membership result hasn't changed.
+  // Verify that PSM cached membership result hasn't changed.
 
   // Fail for DeviceInitialEnrollmentStateRequest with connection error, if the
   // device has a server-backed state.
@@ -2142,12 +1764,6 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(GetStateDiscoveryResult(), expected_state_result);
-  ExpectPsmHistograms(PsmResult::kSuccessfulDetermination,
-                      /*success_time_recorded=*/true);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/2);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
 
   // Verify initial enrollment state retrieval.
   if (kExpectedMembershipResult) {
@@ -2158,91 +1774,8 @@
   }
 }
 
-TEST_P(PsmHelperTest, RetryLogicAfterNetworkFailureForRlweQueryResponse) {
-  InSequence sequence;
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillFailForPsm(net::OK, net::ERR_CONNECTION_CLOSED);
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-
-  const StateDiscoveryResult kExpectedStateResult =
-      StateDiscoveryResult::kFailure;
-  const PsmExecutionResult kExpectedPsmExecutionResult =
-      em::DeviceRegisterRequest::PSM_RESULT_ERROR;
-  EXPECT_EQ(GetStateDiscoveryResult(), kExpectedStateResult);
-  EXPECT_EQ(GetPsmExecutionResult(), kExpectedPsmExecutionResult);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-
-  // Verify that none of the PSM requests have been sent again. And its cached
-  // membership result hasn't changed.
-
-  client()->Retry();
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(GetStateDiscoveryResult(), kExpectedStateResult);
-  EXPECT_EQ(GetPsmExecutionResult(), kExpectedPsmExecutionResult);
-  EXPECT_TRUE(GetPsmDeterminationTimestamp().is_null());
-  ExpectPsmHistograms(PsmResult::kServerError,
-                      /*success_time_recorded=*/false);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/1);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_HTTP_STATUS_ERROR,
-                                  /*dm_status_count=*/1);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
-
-  // Verify initial enrollment state retrieval.
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_SERVER_ERROR);
-}
-
-TEST_P(PsmHelperTest, CancelAndDeleteSoonWithPendingRequest) {
-  DeviceManagementService::JobForTesting psm_rlwe_oprf_job;
-
-  // Expect one request to be captured when available in |psm_rlwe_oprf_job|.
-  ServerWillReplyAsyncForPsm(&psm_rlwe_oprf_job);
-
-  // Verify that the PSM RLWE OPRF request has not been captured yet.
-  EXPECT_FALSE(psm_rlwe_oprf_job.IsActive());
-
-  client()->Start();
-  base::RunLoop().RunUntilIdle();
-
-  // Verify the PSM RLWE OPRF request has been captured.
-  ASSERT_TRUE(psm_rlwe_oprf_job.IsActive());
-  VerifyPsmRlweOprfRequest();
-  VerifyPsmLastRequestJobType();
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_PENDING);
-
-  // Cancel any running jobs and delete the client by `CancelAndDeleteSoon()`
-  // while PSM RLWE OPRF request is in flight.
-  EXPECT_TRUE(base::CurrentThread::Get()->IsIdleForTesting());
-  release_client()->CancelAndDeleteSoon();
-
-  // Verify the client has been deleted immediately and inexistence of any
-  // pending jobs.
-  EXPECT_TRUE(base::CurrentThread::Get()->IsIdleForTesting());
-  EXPECT_FALSE(psm_rlwe_oprf_job.IsActive());
-  EXPECT_EQ(state_, AUTO_ENROLLMENT_STATE_PENDING);
-}
-
-// PSM is enabled to test initial enrollment case extensively only.
-// Note that: PSM is running only for initial enrollment, and Hash dance for FRE
-// use case.
-INSTANTIATE_TEST_SUITE_P(
-    Psm,
-    PsmHelperTest,
-    testing::Combine(testing::Values(AutoEnrollmentClientImplTestState(
-                         AutoEnrollmentProtocol::kInitialEnrollment,
-                         PsmState::kEnabled)),
-                     ::testing::Range(0, kNumberOfPsmTestCases)));
-
-using PsmHelperInitialEnrollmentTest = PsmHelperTest;
-
 TEST_P(PsmHelperInitialEnrollmentTest, PsmSucceedAndStateRetrievalSucceed) {
-  InSequence sequence;
-
-  const bool kExpectedMembershipResult = GetExpectedMembershipResult();
+  const bool kExpectedMembershipResult = true;
   const base::TimeDelta kOneSecondTimeDelta = base::Seconds(1);
   const base::Time kExpectedPsmDeterminationTimestamp =
       base::Time::NowFromSystemTime() + kOneSecondTimeDelta;
@@ -2250,10 +1783,6 @@
   // Advance the time forward one second.
   task_environment_.FastForwardBy(kOneSecondTimeDelta);
 
-  // Succeed for both PSM RLWE requests.
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillReplyWithPsmQueryResponse();
-
   // Succeed for DeviceInitialEnrollmentStateRequest if the device has a
   // server-backed state.
   if (kExpectedMembershipResult) {
@@ -2264,26 +1793,24 @@
         em::DeviceInitialEnrollmentStateResponse::CHROME_ENTERPRISE);
   }
 
+  PsmWillReplyWith(PsmResult::kSuccessfulDetermination,
+                   kExpectedMembershipResult,
+                   kExpectedPsmDeterminationTimestamp);
+
   client()->Start();
   base::RunLoop().RunUntilIdle();
 
   // Verify PSM result.
   EXPECT_EQ(GetStateDiscoveryResult(),
-            GetExpectedMembershipResult()
+            kExpectedMembershipResult
                 ? StateDiscoveryResult::kSuccessHasServerSideState
                 : StateDiscoveryResult::kSuccessNoServerSideState);
   EXPECT_EQ(
       GetPsmExecutionResult(),
-      GetExpectedMembershipResult()
+      kExpectedMembershipResult
           ? em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITH_STATE
           : em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
   EXPECT_EQ(kExpectedPsmDeterminationTimestamp, GetPsmDeterminationTimestamp());
-  ExpectPsmHistograms(PsmResult::kSuccessfulDetermination,
-                      /*success_time_recorded=*/true);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/2);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
 
   // Verify initial enrollment state retrieval.
   if (kExpectedMembershipResult) {
@@ -2298,9 +1825,7 @@
 }
 
 TEST_P(PsmHelperInitialEnrollmentTest, PsmSucceedAndStateRetrievalFailed) {
-  InSequence sequence;
-
-  const bool kExpectedMembershipResult = GetExpectedMembershipResult();
+  const bool kExpectedMembershipResult = true;
   const base::TimeDelta kOneSecondTimeDelta = base::Seconds(1);
   const base::Time kExpectedPsmDeterminationTimestamp =
       base::Time::NowFromSystemTime() + kOneSecondTimeDelta;
@@ -2308,35 +1833,28 @@
   // Advance the time forward one second.
   task_environment_.FastForwardBy(kOneSecondTimeDelta);
 
-  // Succeed for both PSM RLWE requests.
-  ServerWillReplyWithPsmOprfResponse();
-  ServerWillReplyWithPsmQueryResponse();
-
   // Fail for DeviceInitialEnrollmentStateRequest if the device has a
   // server-backed state.
-  if (kExpectedMembershipResult)
-    ServerWillFail(net::OK, DeviceManagementService::kServiceUnavailable);
+  ServerWillFail(net::OK, DeviceManagementService::kServiceUnavailable);
+
+  PsmWillReplyWith(PsmResult::kSuccessfulDetermination,
+                   kExpectedMembershipResult,
+                   kExpectedPsmDeterminationTimestamp);
 
   client()->Start();
   base::RunLoop().RunUntilIdle();
 
   // Verify PSM result.
   EXPECT_EQ(GetStateDiscoveryResult(),
-            GetExpectedMembershipResult()
+            kExpectedMembershipResult
                 ? StateDiscoveryResult::kSuccessHasServerSideState
                 : StateDiscoveryResult::kSuccessNoServerSideState);
   EXPECT_EQ(
       GetPsmExecutionResult(),
-      GetExpectedMembershipResult()
+      kExpectedMembershipResult
           ? em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITH_STATE
           : em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
   EXPECT_EQ(kExpectedPsmDeterminationTimestamp, GetPsmDeterminationTimestamp());
-  ExpectPsmHistograms(PsmResult::kSuccessfulDetermination,
-                      /*success_time_recorded=*/true);
-  ExpectPsmRequestStatusHistogram(DM_STATUS_SUCCESS,
-                                  /*dm_status_count=*/2);
-  VerifyPsmRlweQueryRequest();
-  VerifyPsmLastRequestJobType();
 
   // Verify initial enrollment state retrieval.
   if (kExpectedMembershipResult) {
@@ -2348,15 +1866,13 @@
 }
 
 // PSM is enabled to test initial enrollment case extensively only.
-// Note that: PSM is running only for initial enrollment, and Hash dance for FRE
-// use case.
-INSTANTIATE_TEST_SUITE_P(
-    PsmForInitialEnrollment,
-    PsmHelperInitialEnrollmentTest,
-    testing::Combine(testing::Values(AutoEnrollmentClientImplTestState(
-                         AutoEnrollmentProtocol::kInitialEnrollment,
-                         PsmState::kEnabled)),
-                     ::testing::Range(0, kNumberOfPsmTestCases)));
+// Note that: PSM is running only for initial enrollment, and Hash dance for
+// FRE use case.
+INSTANTIATE_TEST_SUITE_P(PsmForInitialEnrollment,
+                         PsmHelperInitialEnrollmentTest,
+                         testing::Values(AutoEnrollmentClientImplTestState(
+                             AutoEnrollmentProtocol::kInitialEnrollment,
+                             PsmState::kEnabled)));
 
 }  // namespace
 }  // namespace policy
diff --git a/chrome/browser/ash/policy/enrollment/private_membership/fake_private_membership_rlwe_client.cc b/chrome/browser/ash/policy/enrollment/private_membership/fake_private_membership_rlwe_client.cc
index 3be632f..cfe47fc 100644
--- a/chrome/browser/ash/policy/enrollment/private_membership/fake_private_membership_rlwe_client.cc
+++ b/chrome/browser/ash/policy/enrollment/private_membership/fake_private_membership_rlwe_client.cc
@@ -9,7 +9,6 @@
 
 #include "base/check.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client.h"
-#include "third_party/private_membership/src/membership_response_map.h"
 #include "third_party/private_membership/src/private_membership_rlwe.pb.h"
 #include "third_party/shell-encryption/src/statusor.h"
 
diff --git a/chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client_impl.cc b/chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client_impl.cc
index 14f71302..1028c9d 100644
--- a/chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client_impl.cc
+++ b/chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client_impl.cc
@@ -11,7 +11,6 @@
 
 #include "base/check.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client.h"
-#include "third_party/private_membership/src/membership_response_map.h"
 #include "third_party/private_membership/src/private_membership_rlwe.pb.h"
 #include "third_party/private_membership/src/private_membership_rlwe_client.h"
 #include "third_party/shell-encryption/src/statusor.h"
diff --git a/chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h b/chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h
index 2dc67cc..3bbd9a4e 100644
--- a/chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h
+++ b/chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h
@@ -21,7 +21,6 @@
 #include "components/policy/core/common/cloud/enterprise_metrics.h"
 #include "components/prefs/pref_service.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/private_membership/src/membership_response_map.h"
 #include "third_party/private_membership/src/private_membership_rlwe.pb.h"
 
 namespace enterprise_management {
diff --git a/chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.cc b/chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.cc
index 250cde6..b6a9d36 100644
--- a/chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.cc
+++ b/chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.cc
@@ -12,7 +12,6 @@
 #include "base/check.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/private_membership/src/membership_response_map.h"
 #include "third_party/private_membership/src/private_membership_rlwe.pb.h"
 #include "third_party/private_membership/src/private_membership_rlwe_client.h"
 #include "third_party/shell-encryption/src/statusor.h"
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
index b29b43bc..51357dac 100644
--- a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
@@ -642,6 +642,20 @@
   RunTest(test_code);
 }
 
+IN_PROC_BROWSER_TEST_F(CrosWindowBrowserTest, CrosAcceleratorEventIdl) {
+  const char test_code[] = R"(
+async function cros_test() {
+  assert_true(chromeos.CrosAcceleratorEvent !== undefined, 'event');
+  let accelerator_event = new chromeos.CrosAcceleratorEvent();
+  assert_equals(accelerator_event.type, 'acceleratordown', 'event type');
+  assert_true(accelerator_event.bubbles, 'bubbles');
+  assert_false(accelerator_event.cancelable, 'cancelable');
+}
+  )";
+
+  RunTest(test_code);
+}
+
 IN_PROC_BROWSER_TEST_F(CrosWindowExtensionBrowserTest, StartEvent) {
   auto* provider = SystemExtensionsProvider::Get(browser()->profile());
   auto& install_manager = provider->install_manager();
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_system_app_delegate.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_system_app_delegate.cc
index 5ed1bf9d..e990438 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_system_app_delegate.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_system_app_delegate.cc
@@ -37,13 +37,44 @@
           ? l10n_util::GetStringUTF16(
                 IDS_PERSONALIZATION_APP_PERSONALIZATION_HUB_TITLE)
           : l10n_util::GetStringUTF16(IDS_PERSONALIZATION_APP_WALLPAPER_LABEL);
-  std::initializer_list<web_app::IconResourceInfo> icons = {
-      {"app_icon_192.png", 192, IDR_ASH_PERSONALIZATION_APP_ICON_192_PNG}};
   if (ash::features::IsPersonalizationHubEnabled()) {
-    icons = {{"app_hub_icon_192.png", 192,
-              IDR_ASH_PERSONALIZATION_APP_HUB_ICON_192_PNG}};
+    web_app::CreateIconInfoForSystemWebApp(
+        info->start_url,
+        {
+            {
+                "app_hub_icon_64.png",
+                64,
+                IDR_ASH_PERSONALIZATION_APP_HUB_ICON_64_PNG,
+            },
+            {
+                "app_hub_icon_128.png",
+                128,
+                IDR_ASH_PERSONALIZATION_APP_HUB_ICON_128_PNG,
+            },
+            {
+                "app_hub_icon_192.png",
+                192,
+                IDR_ASH_PERSONALIZATION_APP_HUB_ICON_192_PNG,
+            },
+            {
+                "app_hub_icon_256.png",
+                256,
+                IDR_ASH_PERSONALIZATION_APP_HUB_ICON_256_PNG,
+            },
+        },
+        *info);
+  } else {
+    web_app::CreateIconInfoForSystemWebApp(
+        info->start_url,
+        {
+            {
+                "app_icon_192.png",
+                192,
+                IDR_ASH_PERSONALIZATION_APP_ICON_192_PNG,
+            },
+        },
+        *info);
   }
-  web_app::CreateIconInfoForSystemWebApp(info->start_url, icons, *info);
   info->display_mode = blink::mojom::DisplayMode::kStandalone;
   info->user_display_mode = web_app::UserDisplayMode::kStandalone;
 
diff --git a/chrome/browser/autofill_assistant/common_dependencies_chrome.cc b/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
index 6bbf03b932..abf9247f 100644
--- a/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
+++ b/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
@@ -18,6 +18,7 @@
 #include "components/autofill_assistant/content/browser/annotate_dom_model_service.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/tribool.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
 
@@ -56,10 +57,11 @@
 }
 
 std::string CommonDependenciesChrome::GetSignedInEmail(
-    WebContents* web_contents) const {
+    content::BrowserContext* browser_context) const {
+  DCHECK(browser_context);
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(
-          Profile::FromBrowserContext(web_contents->GetBrowserContext()));
+          Profile::FromBrowserContext(browser_context));
   if (!identity_manager) {
     return std::string();
   }
@@ -67,6 +69,23 @@
       .email;
 }
 
+bool CommonDependenciesChrome::IsSupervisedUser(
+    content::BrowserContext* browser_context) const {
+  DCHECK(browser_context);
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(
+          Profile::FromBrowserContext(browser_context));
+  if (!identity_manager) {
+    return false;
+  }
+
+  std::string gaia_id =
+      identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync).gaia;
+  return identity_manager->FindExtendedAccountInfoByGaiaId(gaia_id)
+             .capabilities.is_subject_to_parental_controls() ==
+         signin::Tribool::kTrue;
+}
+
 AnnotateDomModelService*
 CommonDependenciesChrome::GetOrCreateAnnotateDomModelService(
     content::BrowserContext* browser_context) const {
diff --git a/chrome/browser/autofill_assistant/common_dependencies_chrome.h b/chrome/browser/autofill_assistant/common_dependencies_chrome.h
index 8148a211..df27dc66 100644
--- a/chrome/browser/autofill_assistant/common_dependencies_chrome.h
+++ b/chrome/browser/autofill_assistant/common_dependencies_chrome.h
@@ -36,7 +36,10 @@
       content::WebContents* web_contents) const override;
 
   std::string GetSignedInEmail(
-      content::WebContents* web_contents) const override;
+      content::BrowserContext* browser_context) const override;
+
+  bool IsSupervisedUser(
+      content::BrowserContext* browser_context) const override;
 
   // The AnnotateDomModelService is a KeyedService. There is only one per
   // BrowserContext.
diff --git a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
index 5ae01533..3884318 100644
--- a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
+++ b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
@@ -64,6 +64,16 @@
   Stop();
 }
 
+void ApcClientImpl::OnHidden() {
+  // The side panel was hidden, so we need to destroy it.
+  side_panel_coordinator_.reset();
+
+  // TODO(crbug.com/1324089): Destroy the ApcExternalAction delegate and decide
+  // whether to log any data about the shutdown.
+
+  Stop();
+}
+
 std::unique_ptr<ApcOnboardingCoordinator>
 ApcClientImpl::CreateOnboardingCoordinator() {
   return ApcOnboardingCoordinator::Create(&GetWebContents());
diff --git a/chrome/browser/autofill_assistant/password_change/apc_client_impl.h b/chrome/browser/autofill_assistant/password_change/apc_client_impl.h
index 7ef0a6bc..7c5c857 100644
--- a/chrome/browser/autofill_assistant/password_change/apc_client_impl.h
+++ b/chrome/browser/autofill_assistant/password_change/apc_client_impl.h
@@ -12,6 +12,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator.h"
+#include "chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "url/gurl.h"
@@ -22,7 +23,8 @@
 // Implementation of the ApcClient interface that attaches itself to a
 // `WebContents`.
 class ApcClientImpl : public content::WebContentsUserData<ApcClientImpl>,
-                      public ApcClient {
+                      public ApcClient,
+                      public AssistantSidePanelCoordinator::Observer {
  public:
   ~ApcClientImpl() override;
 
@@ -54,6 +56,9 @@
   // Registers when a run is complete. Used in callbacks.
   void OnRunComplete();
 
+  // AssistantSidePanelCoordinator::Observer:
+  void OnHidden() override;
+
   // The state of the `ApcClient` to avoid that a run is started while
   // another is already ongoing in the tab.
   bool is_running_ = false;
@@ -62,6 +67,9 @@
   // previously.
   std::unique_ptr<ApcOnboardingCoordinator> onboarding_coordinator_;
 
+  // The coordinator for the side panel.
+  std::unique_ptr<AssistantSidePanelCoordinator> side_panel_coordinator_;
+
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
diff --git a/chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator_impl.cc b/chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator_impl.cc
index a6cf213..0ff09b1 100644
--- a/chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator_impl.cc
+++ b/chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator_impl.cc
@@ -65,13 +65,14 @@
 std::unique_ptr<AssistantOnboardingController>
 ApcOnboardingCoordinatorImpl::CreateOnboardingController(
     const AssistantOnboardingInformation& onboarding_information) {
-  return AssistantOnboardingController::Create(onboarding_information);
+  return AssistantOnboardingController::Create(onboarding_information,
+                                               web_contents_);
 }
 
 base::WeakPtr<AssistantOnboardingPrompt>
 ApcOnboardingCoordinatorImpl::CreateOnboardingPrompt(
     base::WeakPtr<AssistantOnboardingController> controller) {
-  return AssistantOnboardingPrompt::Create(controller, web_contents_);
+  return AssistantOnboardingPrompt::Create(controller);
 }
 
 bool ApcOnboardingCoordinatorImpl::IsOnboardingAlreadyAccepted() {
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index b74c38a..ea1c896 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -583,212 +583,6 @@
   ]
 
   sources = [
-    "../ash/camera_detector.cc",
-    "../ash/camera_detector.h",
-    "../ash/camera_mic/vm_camera_mic_manager.cc",
-    "../ash/camera_mic/vm_camera_mic_manager.h",
-    "../ash/camera_presence_notifier.cc",
-    "../ash/camera_presence_notifier.h",
-    "../ash/cert_provisioning/cert_provisioning_common.cc",
-    "../ash/cert_provisioning/cert_provisioning_common.h",
-    "../ash/cert_provisioning/cert_provisioning_invalidator.cc",
-    "../ash/cert_provisioning/cert_provisioning_invalidator.h",
-    "../ash/cert_provisioning/cert_provisioning_metrics.cc",
-    "../ash/cert_provisioning/cert_provisioning_metrics.h",
-    "../ash/cert_provisioning/cert_provisioning_platform_keys_helpers.cc",
-    "../ash/cert_provisioning/cert_provisioning_platform_keys_helpers.h",
-    "../ash/cert_provisioning/cert_provisioning_scheduler.cc",
-    "../ash/cert_provisioning/cert_provisioning_scheduler.h",
-    "../ash/cert_provisioning/cert_provisioning_scheduler_user_service.cc",
-    "../ash/cert_provisioning/cert_provisioning_scheduler_user_service.h",
-    "../ash/cert_provisioning/cert_provisioning_serializer.cc",
-    "../ash/cert_provisioning/cert_provisioning_serializer.h",
-    "../ash/cert_provisioning/cert_provisioning_worker.cc",
-    "../ash/cert_provisioning/cert_provisioning_worker.h",
-    "../ash/certificate_provider/certificate_info.cc",
-    "../ash/certificate_provider/certificate_info.h",
-    "../ash/certificate_provider/certificate_provider.h",
-    "../ash/certificate_provider/certificate_provider_service.cc",
-    "../ash/certificate_provider/certificate_provider_service.h",
-    "../ash/certificate_provider/certificate_provider_service_factory.cc",
-    "../ash/certificate_provider/certificate_provider_service_factory.h",
-    "../ash/certificate_provider/certificate_requests.cc",
-    "../ash/certificate_provider/certificate_requests.h",
-    "../ash/certificate_provider/pin_dialog_manager.cc",
-    "../ash/certificate_provider/pin_dialog_manager.h",
-    "../ash/certificate_provider/security_token_pin_dialog_host.h",
-    "../ash/certificate_provider/security_token_pin_dialog_host_popup_impl.cc",
-    "../ash/certificate_provider/security_token_pin_dialog_host_popup_impl.h",
-    "../ash/certificate_provider/sign_requests.cc",
-    "../ash/certificate_provider/sign_requests.h",
-    "../ash/certificate_provider/thread_safe_certificate_map.cc",
-    "../ash/certificate_provider/thread_safe_certificate_map.h",
-    "../ash/child_accounts/child_policy_observer.cc",
-    "../ash/child_accounts/child_policy_observer.h",
-    "../ash/child_accounts/child_status_reporting_service.cc",
-    "../ash/child_accounts/child_status_reporting_service.h",
-    "../ash/child_accounts/child_status_reporting_service_factory.cc",
-    "../ash/child_accounts/child_status_reporting_service_factory.h",
-    "../ash/child_accounts/child_user_service.cc",
-    "../ash/child_accounts/child_user_service.h",
-    "../ash/child_accounts/child_user_service_factory.cc",
-    "../ash/child_accounts/child_user_service_factory.h",
-    "../ash/child_accounts/edu_coexistence_tos_store_utils.cc",
-    "../ash/child_accounts/edu_coexistence_tos_store_utils.h",
-    "../ash/child_accounts/event_based_status_reporting_service.cc",
-    "../ash/child_accounts/event_based_status_reporting_service.h",
-    "../ash/child_accounts/event_based_status_reporting_service_factory.cc",
-    "../ash/child_accounts/event_based_status_reporting_service_factory.h",
-    "../ash/child_accounts/family_features.cc",
-    "../ash/child_accounts/family_features.h",
-    "../ash/child_accounts/family_user_app_metrics.cc",
-    "../ash/child_accounts/family_user_app_metrics.h",
-    "../ash/child_accounts/family_user_chrome_activity_metrics.cc",
-    "../ash/child_accounts/family_user_chrome_activity_metrics.h",
-    "../ash/child_accounts/family_user_device_metrics.cc",
-    "../ash/child_accounts/family_user_device_metrics.h",
-    "../ash/child_accounts/family_user_metrics_service.cc",
-    "../ash/child_accounts/family_user_metrics_service.h",
-    "../ash/child_accounts/family_user_metrics_service_factory.cc",
-    "../ash/child_accounts/family_user_metrics_service_factory.h",
-    "../ash/child_accounts/family_user_parental_control_metrics.cc",
-    "../ash/child_accounts/family_user_parental_control_metrics.h",
-    "../ash/child_accounts/family_user_session_metrics.cc",
-    "../ash/child_accounts/family_user_session_metrics.h",
-    "../ash/child_accounts/parent_access_code/authenticator.cc",
-    "../ash/child_accounts/parent_access_code/authenticator.h",
-    "../ash/child_accounts/parent_access_code/config_source.cc",
-    "../ash/child_accounts/parent_access_code/config_source.h",
-    "../ash/child_accounts/parent_access_code/parent_access_service.cc",
-    "../ash/child_accounts/parent_access_code/parent_access_service.h",
-    "../ash/child_accounts/screen_time_controller.cc",
-    "../ash/child_accounts/screen_time_controller.h",
-    "../ash/child_accounts/screen_time_controller_factory.cc",
-    "../ash/child_accounts/screen_time_controller_factory.h",
-    "../ash/child_accounts/time_limit_notifier.cc",
-    "../ash/child_accounts/time_limit_notifier.h",
-    "../ash/child_accounts/time_limit_override.cc",
-    "../ash/child_accounts/time_limit_override.h",
-    "../ash/child_accounts/time_limits/app_activity_registry.cc",
-    "../ash/child_accounts/time_limits/app_activity_registry.h",
-    "../ash/child_accounts/time_limits/app_activity_report_interface.cc",
-    "../ash/child_accounts/time_limits/app_activity_report_interface.h",
-    "../ash/child_accounts/time_limits/app_service_wrapper.cc",
-    "../ash/child_accounts/time_limits/app_service_wrapper.h",
-    "../ash/child_accounts/time_limits/app_time_controller.cc",
-    "../ash/child_accounts/time_limits/app_time_controller.h",
-    "../ash/child_accounts/time_limits/app_time_limit_interface.cc",
-    "../ash/child_accounts/time_limits/app_time_limit_interface.h",
-    "../ash/child_accounts/time_limits/app_time_limit_utils.cc",
-    "../ash/child_accounts/time_limits/app_time_limit_utils.h",
-    "../ash/child_accounts/time_limits/app_time_limits_allowlist_policy_wrapper.cc",
-    "../ash/child_accounts/time_limits/app_time_limits_allowlist_policy_wrapper.h",
-    "../ash/child_accounts/time_limits/app_time_notification_delegate.h",
-    "../ash/child_accounts/time_limits/app_time_policy_helpers.cc",
-    "../ash/child_accounts/time_limits/app_time_policy_helpers.h",
-    "../ash/child_accounts/time_limits/app_types.cc",
-    "../ash/child_accounts/time_limits/app_types.h",
-    "../ash/child_accounts/time_limits/persisted_app_info.cc",
-    "../ash/child_accounts/time_limits/persisted_app_info.h",
-    "../ash/child_accounts/time_limits/web_time_activity_provider.cc",
-    "../ash/child_accounts/time_limits/web_time_activity_provider.h",
-    "../ash/child_accounts/time_limits/web_time_limit_enforcer.cc",
-    "../ash/child_accounts/time_limits/web_time_limit_enforcer.h",
-    "../ash/child_accounts/time_limits/web_time_limit_navigation_throttle.cc",
-    "../ash/child_accounts/time_limits/web_time_limit_navigation_throttle.h",
-    "../ash/child_accounts/time_limits/web_time_navigation_observer.cc",
-    "../ash/child_accounts/time_limits/web_time_navigation_observer.h",
-    "../ash/child_accounts/usage_time_limit_processor.cc",
-    "../ash/child_accounts/usage_time_limit_processor.h",
-    "../ash/child_accounts/usage_time_state_notifier.cc",
-    "../ash/child_accounts/usage_time_state_notifier.h",
-    "../ash/child_accounts/website_approval_notifier.cc",
-    "../ash/child_accounts/website_approval_notifier.h",
-    "../ash/chrome_browser_main_parts_ash.cc",
-    "../ash/chrome_browser_main_parts_ash.h",
-    "../ash/concierge_helper_service.cc",
-    "../ash/concierge_helper_service.h",
-    "../ash/crostini/ansible/ansible_management_service.cc",
-    "../ash/crostini/ansible/ansible_management_service.h",
-    "../ash/crostini/ansible/ansible_management_service_factory.cc",
-    "../ash/crostini/ansible/ansible_management_service_factory.h",
-    "../ash/crostini/crostini_capabilities.cc",
-    "../ash/crostini/crostini_capabilities.h",
-    "../ash/crostini/crostini_disk.cc",
-    "../ash/crostini/crostini_disk.h",
-    "../ash/crostini/crostini_engagement_metrics_service.cc",
-    "../ash/crostini/crostini_engagement_metrics_service.h",
-    "../ash/crostini/crostini_export_import.cc",
-    "../ash/crostini/crostini_export_import.h",
-    "../ash/crostini/crostini_export_import_notification_controller.cc",
-    "../ash/crostini/crostini_export_import_notification_controller.h",
-    "../ash/crostini/crostini_export_import_status_tracker.cc",
-    "../ash/crostini/crostini_export_import_status_tracker.h",
-    "../ash/crostini/crostini_features.cc",
-    "../ash/crostini/crostini_features.h",
-    "../ash/crostini/crostini_force_close_watcher.cc",
-    "../ash/crostini/crostini_force_close_watcher.h",
-    "../ash/crostini/crostini_installer.cc",
-    "../ash/crostini/crostini_installer.h",
-    "../ash/crostini/crostini_installer_ui_delegate.h",
-    "../ash/crostini/crostini_low_disk_notification.cc",
-    "../ash/crostini/crostini_low_disk_notification.h",
-    "../ash/crostini/crostini_manager.cc",
-    "../ash/crostini/crostini_manager.h",
-    "../ash/crostini/crostini_manager_factory.cc",
-    "../ash/crostini/crostini_manager_factory.h",
-    "../ash/crostini/crostini_package_notification.cc",
-    "../ash/crostini/crostini_package_notification.h",
-    "../ash/crostini/crostini_package_operation_status.h",
-    "../ash/crostini/crostini_package_service.cc",
-    "../ash/crostini/crostini_package_service.h",
-    "../ash/crostini/crostini_port_forwarder.cc",
-    "../ash/crostini/crostini_port_forwarder.h",
-    "../ash/crostini/crostini_pref_names.cc",
-    "../ash/crostini/crostini_pref_names.h",
-    "../ash/crostini/crostini_remover.cc",
-    "../ash/crostini/crostini_remover.h",
-    "../ash/crostini/crostini_reporting_util.cc",
-    "../ash/crostini/crostini_reporting_util.h",
-    "../ash/crostini/crostini_shelf_utils.cc",
-    "../ash/crostini/crostini_shelf_utils.h",
-    "../ash/crostini/crostini_simple_types.cc",
-    "../ash/crostini/crostini_simple_types.h",
-    "../ash/crostini/crostini_sshfs.cc",
-    "../ash/crostini/crostini_sshfs.h",
-    "../ash/crostini/crostini_terminal.cc",
-    "../ash/crostini/crostini_terminal.h",
-    "../ash/crostini/crostini_unsupported_action_notifier.cc",
-    "../ash/crostini/crostini_unsupported_action_notifier.h",
-    "../ash/crostini/crostini_upgrade_available_notification.cc",
-    "../ash/crostini/crostini_upgrade_available_notification.h",
-    "../ash/crostini/crostini_upgrader.cc",
-    "../ash/crostini/crostini_upgrader.h",
-    "../ash/crostini/crostini_upgrader_ui_delegate.h",
-    "../ash/crostini/crostini_util.cc",
-    "../ash/crostini/crostini_util.h",
-    "../ash/crostini/fake_crostini_installer_ui_delegate.cc",
-    "../ash/crostini/fake_crostini_installer_ui_delegate.h",
-    "../ash/crostini/termina_installer.cc",
-    "../ash/crostini/termina_installer.h",
-    "../ash/crostini/throttle/crostini_active_window_throttle_observer.cc",
-    "../ash/crostini/throttle/crostini_active_window_throttle_observer.h",
-    "../ash/crostini/throttle/crostini_throttle.cc",
-    "../ash/crostini/throttle/crostini_throttle.h",
-    "../ash/cryptauth/client_app_metadata_provider_service.cc",
-    "../ash/cryptauth/client_app_metadata_provider_service.h",
-    "../ash/cryptauth/client_app_metadata_provider_service_factory.cc",
-    "../ash/cryptauth/client_app_metadata_provider_service_factory.h",
-    "../ash/cryptauth/cryptauth_device_id_provider_impl.cc",
-    "../ash/cryptauth/cryptauth_device_id_provider_impl.h",
-    "../ash/cryptauth/gcm_device_info_provider_impl.cc",
-    "../ash/cryptauth/gcm_device_info_provider_impl.h",
-    "../ash/customization/customization_document.cc",
-    "../ash/customization/customization_document.h",
-    "../ash/customization/customization_wallpaper_downloader.cc",
-    "../ash/customization/customization_wallpaper_downloader.h",
-    "../ash/customization/customization_wallpaper_util.cc",
-    "../ash/customization/customization_wallpaper_util.h",
     "../ash/dbus/ash_dbus_helper.cc",
     "../ash/dbus/ash_dbus_helper.h",
     "../ash/dbus/chrome_features_service_provider.cc",
@@ -3274,8 +3068,6 @@
     "../ash/borealis/testing/apps.cc",
     "../ash/borealis/testing/apps.h",
     "../ash/borealis/testing/callback_factory.h",
-    "../ash/borealis/testing/dbus.cc",
-    "../ash/borealis/testing/dbus.h",
     "../ash/borealis/testing/features.cc",
     "../ash/borealis/testing/features.h",
     "../ash/borealis/testing/widgets.cc",
@@ -3302,6 +3094,8 @@
     "../ash/drive/drivefs_test_support.h",
     "../ash/file_manager/mount_test_util.cc",
     "../ash/file_manager/mount_test_util.h",
+    "../ash/guest_os/dbus_test_helper.cc",
+    "../ash/guest_os/dbus_test_helper.h",
     "../ash/input_method/stub_input_method_engine_observer.h",
     "../ash/lock_screen_apps/fake_lock_screen_profile_creator.cc",
     "../ash/lock_screen_apps/fake_lock_screen_profile_creator.h",
diff --git a/chrome/browser/chromeos/OWNERS b/chrome/browser/chromeos/OWNERS
index 9fca8d6..6d0a775 100644
--- a/chrome/browser/chromeos/OWNERS
+++ b/chrome/browser/chromeos/OWNERS
@@ -5,10 +5,10 @@
 achuith@chromium.org
 afakhry@chromium.org
 alemate@chromium.org
+hidehiko@chromium.org
 jamescook@chromium.org
 khorimoto@chromium.org
 oshima@chromium.org
-satorux@chromium.org
 xiyuan@chromium.org
 per-file *active_directory*=file://chrome/browser/ash/authpolicy/OWNERS
 per-file note_taking*=glenrob@chromium.org
diff --git a/chrome/browser/chromeos/extensions/install_limiter_factory.cc b/chrome/browser/chromeos/extensions/install_limiter_factory.cc
index aeb869b..52b9e14 100644
--- a/chrome/browser/chromeos/extensions/install_limiter_factory.cc
+++ b/chrome/browser/chromeos/extensions/install_limiter_factory.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/extensions/install_limiter_factory.h"
 
 #include "chrome/browser/chromeos/extensions/install_limiter.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "extensions/browser/extension_system_provider.h"
@@ -38,4 +39,19 @@
   return new InstallLimiter();
 }
 
+content::BrowserContext* InstallLimiterFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  Profile* const profile = Profile::FromBrowserContext(context);
+  if (!profile) {
+    return nullptr;
+  }
+  // Use OTR profile for Guest Session.
+  if (profile->IsGuestSession() && profile->IsOffTheRecord()) {
+    return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+  }
+#endif
+  return BrowserContextKeyedServiceFactory::GetBrowserContextToUse(context);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/install_limiter_factory.h b/chrome/browser/chromeos/extensions/install_limiter_factory.h
index 2e7acb1..4b0af00 100644
--- a/chrome/browser/chromeos/extensions/install_limiter_factory.h
+++ b/chrome/browser/chromeos/extensions/install_limiter_factory.h
@@ -33,6 +33,8 @@
   // BrowserContextKeyedServiceFactory overrides:
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc
index 3823a33d..c10561b 100644
--- a/chrome/browser/extensions/extension_service_test_base.cc
+++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -91,6 +91,10 @@
 #endif
   }
 
+  if (params.profile_is_guest) {
+    profile_builder.SetGuestSession();
+  }
+
   if (params.enable_bookmark_model) {
     profile_builder.AddTestingFactory(
         BookmarkModelFactory::GetInstance(),
@@ -189,11 +193,11 @@
   CreateExtensionService(params);
 
   extensions_install_dir_ = params.extensions_install_dir;
-  registry_ = ExtensionRegistry::Get(profile_.get());
+  registry_ = ExtensionRegistry::Get(profile());
 
   // Garbage collector is typically NULL during tests, so give it a build.
   ExtensionGarbageCollectorFactory::GetInstance()->SetTestingFactoryAndUse(
-      profile_.get(),
+      profile(),
       base::BindRepeating(&ExtensionGarbageCollectorFactory::BuildInstanceFor));
 }
 
@@ -203,7 +207,8 @@
 
 void ExtensionServiceTestBase::InitializeInstalledExtensionService(
     const base::FilePath& prefs_file,
-    const base::FilePath& source_install_dir) {
+    const base::FilePath& source_install_dir,
+    const ExtensionServiceInitParams& additional_params) {
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   base::FilePath path = temp_dir_.GetPath();
 
@@ -222,7 +227,7 @@
   ASSERT_TRUE(
       base::CopyDirectory(source_install_dir, extensions_install_dir, true));
 
-  ExtensionServiceInitParams params;
+  ExtensionServiceInitParams params = additional_params;
   params.profile_path = path;
   params.pref_file = temp_prefs;
   params.extensions_install_dir = extensions_install_dir;
@@ -349,7 +354,7 @@
 void ExtensionServiceTestBase::TearDown() {
   if (profile_) {
     content::StoragePartitionConfig default_storage_partition_config =
-        content::StoragePartitionConfig::CreateDefault(profile_.get());
+        content::StoragePartitionConfig::CreateDefault(profile());
     auto* partition = profile_->GetStoragePartition(
         default_storage_partition_config, /*can_create=*/false);
     if (partition)
@@ -366,10 +371,15 @@
 // These are declared in the .cc so that all inheritors don't need to know
 // that TestingProfile derives Profile derives BrowserContext.
 content::BrowserContext* ExtensionServiceTestBase::browser_context() {
-  return profile_.get();
+  return profile();
 }
 
 Profile* ExtensionServiceTestBase::profile() {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  if (profile_->IsGuestSession())
+    return profile_->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
   return profile_.get();
 }
 
@@ -381,9 +391,9 @@
 void ExtensionServiceTestBase::CreateExtensionService(
     const ExtensionServiceInitParams& params) {
   TestExtensionSystem* system =
-      static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get()));
+      static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()));
   if (!params.is_first_run)
-    ExtensionPrefs::Get(profile_.get())->SetAlertSystemFirstRun();
+    ExtensionPrefs::Get(profile())->SetAlertSystemFirstRun();
 
   service_ = system->CreateExtensionService(
       base::CommandLine::ForCurrentProcess(), params.extensions_install_dir,
@@ -402,7 +412,7 @@
                                 service_->shared_module_service());
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  InstallLimiter::Get(profile_.get())->DisableForTest();
+  InstallLimiter::Get(profile())->DisableForTest();
 #endif
 }
 
diff --git a/chrome/browser/extensions/extension_service_test_base.h b/chrome/browser/extensions/extension_service_test_base.h
index 84b3b7e..ff00127 100644
--- a/chrome/browser/extensions/extension_service_test_base.h
+++ b/chrome/browser/extensions/extension_service_test_base.h
@@ -68,6 +68,7 @@
     bool extensions_enabled = true;
     bool is_first_run = true;
     bool profile_is_supervised = false;
+    bool profile_is_guest = false;
     bool enable_bookmark_model = false;
 
     raw_ptr<policy::PolicyService> policy_service = nullptr;
@@ -111,7 +112,9 @@
   // |source_install_dir|.
   void InitializeInstalledExtensionService(
       const base::FilePath& prefs_file,
-      const base::FilePath& source_install_dir);
+      const base::FilePath& source_install_dir,
+      const ExtensionServiceInitParams& additional_params =
+          ExtensionServiceInitParams{});
 
   // Initialize an ExtensionService with a few already-installed extensions.
   void InitializeGoodInstalledExtensionService();
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/CredentialManagerLauncherFactory.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/CredentialManagerLauncherFactory.java
index 93daaf0e..1b0391e 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/CredentialManagerLauncherFactory.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/CredentialManagerLauncherFactory.java
@@ -33,4 +33,14 @@
     public CredentialManagerLauncher createLauncher() {
         return null;
     }
+
+    /**
+     * Returns whether the downstream implementation has the required versions of the
+     * dependency it relies on.
+     *
+     * @return True if the required dependency version is available, false otherwise.
+     */
+    public boolean isBackendVersionSupported() {
+        return false;
+    }
 }
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelperFactory.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelperFactory.java
index a79da7b3..3fe095d 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelperFactory.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelperFactory.java
@@ -24,4 +24,14 @@
     public PasswordCheckupClientHelper createHelper() {
         return null;
     }
+
+    /**
+     * Returns whether the downstream implementation has the required versions of the
+     * dependency it relies on.
+     *
+     * @return True if the required dependency version is available, false otherwise.
+     */
+    public boolean isBackendVersionSupported() {
+        return false;
+    }
 }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index d738a1e..21545b8 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -565,13 +565,21 @@
         .SetTimeToSuccessfulLogin(
             ukm::GetExponentialBucketMinForUserTiming(delta.InMilliseconds()))
         .Record(ukm::UkmRecorder::Get());
-  }
 
-  username_filled_by_touch_to_fill_.reset();
+    base::UmaHistogramBoolean(
+        "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true);
+    username_filled_by_touch_to_fill_.reset();
+  } else {
+    ResetSubmissionTrackingAfterTouchToFill();
+  }
 }
 
 void ChromePasswordManagerClient::ResetSubmissionTrackingAfterTouchToFill() {
-  username_filled_by_touch_to_fill_.reset();
+  if (username_filled_by_touch_to_fill_.has_value()) {
+    base::UmaHistogramBoolean(
+        "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false);
+    username_filled_by_touch_to_fill_.reset();
+  }
 }
 #endif  // BUILDFLAG(IS_ANDROID)
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index c38c34d..f54e80e 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -1094,45 +1094,73 @@
 }
 
 TEST_F(ChromePasswordManagerClientAndroidTest,
-       FormSubmissionTrackingAfterTouchToLogin) {
-  base::HistogramTester uma_recorder;
-
+       FormSubmissionTrackingAfterTouchToLogin_NotStarted) {
   // As tracking is not started yet, no metric reports are expected.
+  base::HistogramTester uma_recorder;
   GetClient()->NotifyOnSuccessfulLogin(u"username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
+  uma_recorder.ExpectTotalCount(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", 0);
+}
 
-  // As tracking was reset, no metric reports are expected.
+TEST_F(ChromePasswordManagerClientAndroidTest,
+       FormSubmissionTrackingAfterTouchToLogin_Resetted) {
+  // Tracking started, but was reset before a successful login (e.g. a user
+  // manually edited a field).
+  base::HistogramTester uma_recorder;
   GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
   GetClient()->ResetSubmissionTrackingAfterTouchToFill();
   GetClient()->NotifyOnSuccessfulLogin(u"username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
+  uma_recorder.ExpectUniqueSample(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
+}
 
-  // Tracking started but a successful login was observed for a wrong username.
-  // No reports are expected.
+TEST_F(ChromePasswordManagerClientAndroidTest,
+       FormSubmissionTrackingAfterTouchToLogin_AnotherUsername) {
+  // Tracking started but a successful login was observed for a wrong
+  // username.
+  base::HistogramTester uma_recorder;
   GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
   GetClient()->NotifyOnSuccessfulLogin(u"another_username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
+  uma_recorder.ExpectUniqueSample(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
+}
 
+TEST_F(ChromePasswordManagerClientAndroidTest,
+       FormSubmissionTrackingAfterTouchToLogin_StaleTracking) {
   // Tracking started too long ago, ignore a successful login.
+  base::HistogramTester uma_recorder;
   GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
   AdvanceClock(base::Minutes(2));
   GetClient()->NotifyOnSuccessfulLogin(u"username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
+  uma_recorder.ExpectUniqueSample(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
+}
 
+TEST_F(ChromePasswordManagerClientAndroidTest,
+       FormSubmissionTrackingAfterTouchToLogin_Succeeded) {
   // Tracking started and a successful login was observed for the correct
   // username recently, expect a metric report.
+  base::HistogramTester uma_recorder;
   GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
   GetClient()->NotifyOnSuccessfulLogin(u"username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 1);
+  uma_recorder.ExpectUniqueSample(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true, 1);
   // Should be reported only once.
   GetClient()->NotifyOnSuccessfulLogin(u"username");
   uma_recorder.ExpectTotalCount(
       "PasswordManager.TouchToFill.TimeToSuccessfulLogin", 1);
+  uma_recorder.ExpectUniqueSample(
+      "PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true, 1);
 }
 
 TEST_F(ChromePasswordManagerClientAndroidTest,
diff --git a/chrome/browser/privacy_budget/identifiability_study_state.cc b/chrome/browser/privacy_budget/identifiability_study_state.cc
index fff1ed9..15f8d98 100644
--- a/chrome/browser/privacy_budget/identifiability_study_state.cc
+++ b/chrome/browser/privacy_budget/identifiability_study_state.cc
@@ -80,6 +80,10 @@
   if (LIKELY(!settings_.enabled()))
     return false;
 
+  // We always record surfaces of type zero.
+  if (surface.GetType() == blink::IdentifiableSurface::Type::kReservedInternal)
+    return true;
+
   if (base::Contains(active_surfaces_, surface))
     return true;
 
@@ -577,6 +581,12 @@
           blink::IdentifiableSurface::Type::kMeasuredSurface)) {
     return false;
   }
+
+  if (surface.GetType() ==
+      blink::IdentifiableSurface::Type::kReservedInternal) {
+    return false;
+  }
+
   return surface_encounters_.IsNewEncounter(source_id,
                                             surface.ToUkmMetricHash());
 }
diff --git a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc
index edc27fe..10ec320 100644
--- a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc
+++ b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc
@@ -723,6 +723,90 @@
   EXPECT_LE(selected_surfaces, kMaxSelectedSurfaces);
 }
 
+TEST(IdentifiabilityStudyStateStandaloneTest,
+     AlwaysSampleReservedInternalRandom) {
+  test::ScopedPrivacyBudgetConfig::Parameters parameters;
+  parameters.active_surface_budget = kTestingActiveSurfaceBudget;
+  parameters.expected_surface_count = 20;
+  parameters.allowed_random_types = {
+      blink::IdentifiableSurface::Type::kWebFeature};
+  test::ScopedPrivacyBudgetConfig config(parameters);
+
+  TestingPrefServiceSimple pref_service;
+  prefs::RegisterPrivacyBudgetPrefs(pref_service.registry());
+  test_utils::InspectableIdentifiabilityStudyState state(&pref_service);
+
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsCrossOriginFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsCrossSiteFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsMainFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_NavigationSourceId))));
+}
+
+TEST(IdentifiabilityStudyStateStandaloneTest,
+     AlwaysSampleReservedInternalBlock) {
+  const int kTestGroupCount = 80;
+  const int kSurfacesInGroup = 40;
+
+  test::ScopedPrivacyBudgetConfig::Parameters parameters;
+  for (int group_index = 0; group_index < kTestGroupCount; ++group_index) {
+    parameters.blocks.emplace_back(
+        CreateSurfaceList(kSurfacesInGroup, kSurfacesInGroup * group_index));
+  }
+
+  parameters.block_weights.assign(kTestGroupCount, 1.0);
+  parameters.active_surface_budget = kSurfacesInGroup;
+  test::ScopedPrivacyBudgetConfig config(parameters);
+
+  TestingPrefServiceSimple pref_service;
+  prefs::RegisterPrivacyBudgetPrefs(pref_service.registry());
+  test_utils::InspectableIdentifiabilityStudyState state(&pref_service);
+
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsCrossOriginFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsCrossSiteFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_IsMainFrame))));
+  EXPECT_TRUE(
+      state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken(
+          blink::IdentifiableSurface::Type::kReservedInternal,
+          blink::IdentifiableToken(
+              blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                  kDocumentCreated_NavigationSourceId))));
+}
+
 TEST(IdentifiabilityStudyStateStandaloneTest, NoAllowedTypes) {
   constexpr auto kExpectedSurfaceCount = 20;
 
diff --git a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
index 47bd50c..e4e47f0 100644
--- a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
+++ b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
@@ -245,14 +245,22 @@
 
   auto merged_entries = recorder().GetMergedEntriesByName(
       ukm::builders::Identifiability::kEntryName);
-  // Shouldn't be more than one source here. If this changes, then we'd need to
-  // adjust this test to deal.
-  ASSERT_EQ(1u, merged_entries.size());
+  // There are 2 entries here (3 on Android) generated by the two navigations
+  // from the test. All entries contain the document created event surfaces of
+  // type zero, but only one entry contains the web feature metrics.
+  ASSERT_GE(merged_entries.size(), 2u);
 
-  // All of the following features should be included in the list of returned
-  // metrics here. The exact values depend on the test host.
+  // We collect all metrics together and check that there is one that contains
+  // the web feature metrics.
+  auto it = merged_entries.begin();
+  auto metrics = it->second->metrics;
+
+  for (auto& it : merged_entries) {
+    metrics.insert(it.second->metrics.begin(), it.second->metrics.end());
+  }
+
   EXPECT_THAT(
-      merged_entries.begin()->second->metrics,
+      metrics,
       IsSupersetOf({
           Key(HashFeature(
               blink::mojom::WebFeature::kV8Screen_Height_AttributeGetter)),
@@ -268,6 +276,75 @@
 }
 
 IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithTestRecorder,
+                       EveryNavigationRecordsDocumentCreatedMetrics) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  content::DOMMessageQueue messages(web_contents());
+  base::RunLoop run_loop;
+
+  recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName,
+                                   run_loop.QuitClosure());
+
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents(), embedded_test_server()->GetURL(
+                          "/privacy_budget/samples_screen_attributes.html")));
+
+  // The document calls a bunch of instrumented functions and sends a message
+  // back to the test. Receipt of the message indicates that the script
+  // successfully completed.
+  std::string screen_scrape;
+  ASSERT_TRUE(messages.WaitForMessage(&screen_scrape));
+
+  // The contents of the received message isn't used for anything other than
+  // diagnostics.
+  SCOPED_TRACE(screen_scrape);
+
+  // Navigating away from the test page causes the document to be unloaded. That
+  // will cause any buffered metrics to be flushed.
+  content::NavigateToURLBlockUntilNavigationsComplete(web_contents(),
+                                                      GURL("about:blank"), 1);
+
+  // Wait for the metrics to come down the pipe.
+  run_loop.Run();
+
+  auto merged_entries = recorder().GetMergedEntriesByName(
+      ukm::builders::Identifiability::kEntryName);
+  // There are 2 entries here (3 on Android) generated by the two navigations
+  // from the test. All entries contain the document created event surfaces of
+  // type zero.
+  ASSERT_GE(merged_entries.size(), 2u);
+
+  // Each entry in merged_entries (except the initial navigation to about:blank)
+  // corresponds to a committed navigation and they all should contain the
+  // document created metrics.
+  for (auto& it : merged_entries) {
+    EXPECT_THAT(it.second->metrics,
+                IsSupersetOf({
+                    Key(blink::IdentifiableSurface::FromTypeAndToken(
+                            blink::IdentifiableSurface::Type::kReservedInternal,
+                            blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                                kDocumentCreated_IsMainFrame)
+                            .ToUkmMetricHash()),
+                    Key(blink::IdentifiableSurface::FromTypeAndToken(
+                            blink::IdentifiableSurface::Type::kReservedInternal,
+                            blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                                kDocumentCreated_IsCrossOriginFrame)
+                            .ToUkmMetricHash()),
+                    Key(blink::IdentifiableSurface::FromTypeAndToken(
+                            blink::IdentifiableSurface::Type::kReservedInternal,
+                            blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                                kDocumentCreated_IsCrossSiteFrame)
+                            .ToUkmMetricHash()),
+                    Key(blink::IdentifiableSurface::FromTypeAndToken(
+                            blink::IdentifiableSurface::Type::kReservedInternal,
+                            blink::IdentifiableSurface::ReservedSurfaceMetrics::
+                                kDocumentCreated_NavigationSourceId)
+                            .ToUkmMetricHash()),
+                }));
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithTestRecorder,
                        CallsCanvasToBlob) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
@@ -299,14 +376,25 @@
 
   auto merged_entries = recorder().GetMergedEntriesByName(
       ukm::builders::Identifiability::kEntryName);
-  // Shouldn't be more than one source here. If this changes, then we'd need to
-  // adjust this test to deal.
-  ASSERT_EQ(1u, merged_entries.size());
+  // There are 2 entries here (3 on android) generated by the two navigations
+  // from the test. All entries contain the document created event surfaces of
+  // type zero, but only one entry contains the canvas readback metric.
+  ASSERT_GE(merged_entries.size(), 2u);
 
   // toBlob() is called on a context-less canvas, hence -1, which is the value
   // of blink::CanvasRenderingContext::CanvasRenderingAPI::kUnknown.
   constexpr uint64_t input_digest = -1;
-  EXPECT_THAT(merged_entries.begin()->second->metrics,
+
+  // We collect all metrics together and check that there is one that contains
+  // the canvas readback metrics.
+  auto it = merged_entries.begin();
+  auto metrics = it->second->metrics;
+
+  for (auto& it : merged_entries) {
+    metrics.insert(it.second->metrics.begin(), it.second->metrics.end());
+  }
+
+  EXPECT_THAT(metrics,
               IsSupersetOf({
                   Key(blink::IdentifiableSurface::FromTypeAndToken(
                           blink::IdentifiableSurface::Type::kCanvasReadback,
@@ -354,17 +442,25 @@
 
   auto merged_entries = recorder().GetMergedEntriesByName(
       ukm::builders::Identifiability::kEntryName);
-  // Shouldn't be more than one source here. If this changes, then we'd need to
-  // adjust this test to deal.
-  ASSERT_EQ(1u, merged_entries.size());
-
-  auto& metrics = merged_entries.begin()->second->metrics;
+  // There are 2 entries here (3 on Android) generated by the two navigations
+  // from the test. All entries contain the document created event surfaces of
+  // type zero, but only one entry contains the canvas readback metric.
+  ASSERT_GE(merged_entries.size(), 2u);
 
   // (kCanvasReadback | input_digest << kTypeBits) = one of the merged_entries
   // If the value of the relevant merged entry changes, input_digest needs to
   // change. The new input_digest can be calculated by:
-  // new_input_digest = new_ukm_entry >> kTypeBits
+  // new_input_digest = new_ukm_entry >> kTypeBits;
   constexpr uint64_t input_digest = UINT64_C(33457614533296512);
+  // We collect all metrics together and check that there is one that contains
+  // the canvas readback metrics.
+  auto it = merged_entries.begin();
+  auto metrics = it->second->metrics;
+
+  for (auto& it : merged_entries) {
+    metrics.insert(it.second->metrics.begin(), it.second->metrics.end());
+  }
+
   EXPECT_THAT(metrics,
               IsSupersetOf({
                   Key(blink::IdentifiableSurface::FromTypeAndToken(
@@ -430,7 +526,6 @@
 }
 
 namespace {
-
 class PrivacyBudgetGroupConfigBrowserTest : public PlatformBrowserTest {
  public:
   PrivacyBudgetGroupConfigBrowserTest() {
diff --git a/chrome/browser/resources/chromeos/OWNERS b/chrome/browser/resources/chromeos/OWNERS
index b0e991e..fe165b27 100644
--- a/chrome/browser/resources/chromeos/OWNERS
+++ b/chrome/browser/resources/chromeos/OWNERS
@@ -1,8 +1,8 @@
 achuith@chromium.org
 alemate@chromium.org
+hidehiko@chromium.org
 khorimoto@chromium.org
 michaelpg@chromium.org
-satorux@chromium.org
 xiyuan@chromium.org
 
 per-file drive_internals*=file://ui/file_manager/OWNERS
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
index 3d69e989..e4b5a1b9 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -28,7 +28,6 @@
   "../common/key_code.js",
   "../common/string_util.js",
   "../common/tree_walker.js",
-  "background/automation_object_constructor_installer.js",
   "background/braille/cursor_dots.js",
   "background/braille/liblouis.js",
   "background/braille/pan_strategy.js",
@@ -76,6 +75,7 @@
 chromevox_es6_modules = [
   "../common/event_generator.js",
   "../common/instance_checker.js",
+  "background/automation_object_constructor_installer.js",
   "background/auto_scroll_handler.js",
   "background/background.js",
   "background/base_automation_handler.js",
@@ -110,6 +110,7 @@
   "background/keyboard_handler.js",
   "background/live_regions.js",
   "background/logging/event_stream_logger.js",
+  "background/logging/log_url_watcher.js",
   "background/math_handler.js",
   "background/media_automation_handler.js",
   "background/page_load_sound_handler.js",
@@ -448,6 +449,7 @@
       "background/logging/log_store_test.js",
       "background/output/output_test.js",
       "background/panel/i_search_test.js",
+      "background/panel/panel_node_menu_background_test.js",
       "background/portals_test.js",
       "background/settings_test.js",
       "background/smart_sticky_mode_test.js",
@@ -467,6 +469,7 @@
       "../common/testing/accessibility_test_base.js",
       "../common/testing/assert_additions.js",
       "../common/testing/callback_helper.js",
+      "../common/testing/documents.js",
       "../common/testing/e2e_test_base.js",
       "testing/chromevox_e2e_test_base.js",
       "testing/chromevox_next_e2e_test_base.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/automation_object_constructor_installer.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/automation_object_constructor_installer.js
index f7f63fe2..079455e 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/automation_object_constructor_installer.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/automation_object_constructor_installer.js
@@ -10,30 +10,30 @@
  * of that object, we can save its constructor for future use.
  */
 
-goog.provide('AutomationObjectConstructorInstaller');
+const AutomationNode = chrome.automation.AutomationNode;
+const AutomationEvent = chrome.automation.AutomationEvent;
 
-/**
- * Installs the AutomationNode and AutomationEvent classes based on an
- * AutomationNode instance.
- * @param {chrome.automation.AutomationNode} node
- * @param {function()} callback Called when installation finishes.
- */
-AutomationObjectConstructorInstaller.init = async (node) => {
-  return new Promise(resolve => {
-    chrome.automation.AutomationNode =
-        /** @type {function (new:chrome.automation.AutomationNode)} */ (
-            node.constructor);
-    node.addEventListener(
-        chrome.automation.EventType.CHILDREN_CHANGED,
-        function installAutomationEvent(e) {
-          chrome.automation.AutomationEvent =
-              /** @type {function (new:chrome.automation.AutomationEvent)} */ (
-                  e.constructor);
-          node.removeEventListener(
-              chrome.automation.EventType.CHILDREN_CHANGED,
-              installAutomationEvent, true);
-          resolve();
-        },
-        true);
-  });
+export const AutomationObjectConstructorInstaller = {
+  /**
+   * Installs the AutomationNode and AutomationEvent classes based on an
+   * AutomationNode instance.
+   * @param {AutomationNode} node
+   */
+  async init(node) {
+    return new Promise(resolve => {
+      chrome.automation.AutomationNode =
+          /** @type {function (new:AutomationNode)} */ (node.constructor);
+      node.addEventListener(
+          chrome.automation.EventType.CHILDREN_CHANGED,
+          function installAutomationEvent(e) {
+            chrome.automation.AutomationEvent =
+                /** @type {function (new:AutomationEvent)} */ (e.constructor);
+            node.removeEventListener(
+                chrome.automation.EventType.CHILDREN_CHANGED,
+                installAutomationEvent, true);
+            resolve();
+          },
+          true);
+    });
+  }
 };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
index bd5aa99..6cb17d57 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -70,15 +70,6 @@
       get: () => this.earcons_,
     });
 
-    Object.defineProperty(ChromeVox, 'typingEcho', {
-      get() {
-        return parseInt(localStorage['typingEcho'], 10) || 0;
-      },
-      set(value) {
-        localStorage['typingEcho'] = value;
-      }
-    });
-
     chrome.clipboard.onClipboardDataChanged.addListener(() => {
       this.onClipboardDataChanged_();
     });
@@ -183,6 +174,16 @@
     this.pageSel_ = newPageSel;
   }
 
+  /** @override */
+  get typingEcho() {
+    return parseInt(localStorage['typingEcho'], 10) || 0;
+  }
+
+  /** @override */
+  set typingEcho(newTypingEcho) {
+    localStorage['typingEcho'] = value;
+  }
+
   /**
    * Navigate to the given range - it both sets the range and outputs it.
    * @param {!cursors.Range} range The new range.
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/liblouis.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/liblouis.js
index 70ae619..6fc64fd 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/liblouis.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/liblouis.js
@@ -9,9 +9,7 @@
 goog.provide('LibLouis');
 goog.provide('LibLouis.FormType');
 
-/**
- * Encapsulates a liblouis Web Assembly instance in the page.
- */
+/** Encapsulates a liblouis Web Assembly instance in the page. */
 LibLouis = class {
   /**
    * @param {string} wasmPath Path to .wasm file for the module.
@@ -72,14 +70,14 @@
       // TODO: save last callback.
       return;
     }
-    this.rpc_('CheckTable', {'table_names': tableNames}, function(reply) {
+    this.rpc_('CheckTable', {'table_names': tableNames}, reply => {
       if (reply['success']) {
         const translator = new LibLouis.Translator(this, tableNames);
         callback(translator);
       } else {
         callback(null /* translator */);
       }
-    }.bind(this));
+    });
   }
 
   /**
@@ -155,9 +153,9 @@
   loadOrReload_(opt_loadCallback) {
     this.worker_ = new Worker(this.wasmPath_);
     this.worker_.addEventListener(
-        'message', this.onInstanceMessage_.bind(this), false /* useCapture */);
+        'message', e => this.onInstanceMessage_(e), false /* useCapture */);
     this.worker_.addEventListener(
-        'error', this.onInstanceError_.bind(this), false /* useCapture */);
+        'error', e => this.onInstanceError_(e), false /* useCapture */);
     this.rpc_('load', {}, () => {
       this.isLoaded_ = true;
       opt_loadCallback && opt_loadCallback(this);
@@ -218,8 +216,7 @@
    *     Callback for result.  Takes 3 parameters: the resulting cells,
    *     mapping from text to braille positions and mapping from braille to
    *     text positions.  If translation fails for any reason, all parameters
-   * are
-   *     {@code null}.
+   *     are {@code null}.
    */
   translate(text, formTypeMap, callback) {
     if (!this.instance_.worker_) {
@@ -231,7 +228,7 @@
       text,
       form_type_map: formTypeMap
     };
-    this.instance_.rpc_('Translate', message, function(reply) {
+    this.instance_.rpc_('Translate', message, reply => {
       let cells = null;
       let textToBraille = null;
       let brailleToText = null;
@@ -273,7 +270,7 @@
       'table_names': this.tableNames_,
       'cells': LibLouis.Translator.encodeHexString_(cells)
     };
-    this.instance_.rpc_('BackTranslate', message, function(reply) {
+    this.instance_.rpc_('BackTranslate', message, reply => {
       if (reply['success'] && goog.isString(reply['text'])) {
         callback(reply['text']);
       } else {
@@ -309,8 +306,7 @@
   static encodeHexString_(arrayBuffer) {
     const array = new Uint8Array(arrayBuffer);
     let hex = '';
-    for (let i = 0; i < array.length; i++) {
-      const b = array[i];
+    for (const b of array) {
       hex += (b < 0x10 ? '0' : '') + b.toString(16);
     }
     return hex;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js
index b640ce7d..caf7f59e 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js
@@ -6,12 +6,6 @@
  * @fileoverview Defines a global object.
  */
 
-// Forward declare.
-goog.addDependency('../common/abstract_earcons.js', ['AbstractEarcons'], []);
-goog.addDependency(
-    '../common/braille/braille_interface.js', ['BrailleInterface'], []);
-goog.addDependency('../common/tts_interface.js', ['TtsInterface'], []);
-
 goog.provide('ChromeVox');
 
 goog.require('AbstractEarcons');
@@ -63,10 +57,6 @@
  */
 ChromeVox.stickyOverride = null;
 /**
- * @type {number}
- */
-ChromeVox.typingEcho = 0;
-/**
  * @type {Object<string, constants.Point>}
  */
 ChromeVox.position = {};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_state.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_state.js
index 19f262b..eb2038cb9 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_state.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_state.js
@@ -94,6 +94,12 @@
   /** @param {cursors.Range} */
   set pageSel(newPageSel) {},
 
+  /** @return {number} */
+  get typingEcho() {},
+
+  /** @param {number} newTypingEcho */
+  set typingEcho(newTypingEcho) {},
+
   /**
    * Navigate to the given range - it both sets the range and outputs it.
    * @param {!cursors.Range} range The new range.
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
index 642e01c..9bfb20b 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -194,9 +194,10 @@
       }
         return false;
       case 'cycleTypingEcho': {
-        ChromeVox.typingEcho = TypingEcho.cycle(ChromeVox.typingEcho);
+        ChromeVoxState.instance.typingEcho =
+            TypingEcho.cycle(ChromeVoxState.instance.typingEcho);
         let announce = '';
-        switch (ChromeVox.typingEcho) {
+        switch (ChromeVoxState.instance.typingEcho) {
           case TypingEcho.CHARACTER:
             announce = Msgs.getMsg('character_echo');
             break;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js
index 898a7ec..fbe7fe7 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js
@@ -6,6 +6,7 @@
  * @fileoverview Handles automation from a desktop automation node.
  */
 import {AutoScrollHandler} from '/chromevox/background/auto_scroll_handler.js';
+import {AutomationObjectConstructorInstaller} from '/chromevox/background/automation_object_constructor_installer.js';
 import {DesktopAutomationInterface} from '/chromevox/background/desktop_automation_interface.js';
 import {TextEditHandler} from '/chromevox/background/editing/editing.js';
 import {ChromeVoxEvent, CustomAutomationEvent} from '/chromevox/common/custom_automation_event.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
index 12cd7fe..a197b19 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
@@ -10,7 +10,6 @@
 goog.require('AutomationPredicate');
 goog.require('AutomationTreeWalker');
 goog.require('AutomationUtil');
-goog.require('AutomationObjectConstructorInstaller');
 goog.require('BrailleDisplayState');
 goog.require('BrailleInterface');
 goog.require('BrailleKeyCommand');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_store.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_store.js
index 9545d9f2..09a107f 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_store.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_store.js
@@ -24,6 +24,9 @@
      */
     this.logs_ = Array(LogStore.LOG_LIMIT);
 
+    /** @private {boolean} */
+    this.shouldSkipOutput_ = false;
+
     /*
      * this.logs_ is implemented as a ring buffer which starts
      * from this.startIndex_ and ends at this.startIndex_-1
@@ -80,7 +83,7 @@
    * @param {!LogType} logType
    */
   writeTextLog(logContent, logType) {
-    if (this.shouldSkipOutput_()) {
+    if (this.shouldSkipOutput_) {
       return;
     }
 
@@ -93,7 +96,7 @@
    * @param {!TreeDumper} logContent
    */
   writeTreeLog(logContent) {
-    if (this.shouldSkipOutput_()) {
+    if (this.shouldSkipOutput_) {
       return;
     }
 
@@ -106,7 +109,7 @@
    * @param {!BaseLog} log
    */
   writeLog(log) {
-    if (this.shouldSkipOutput_()) {
+    if (this.shouldSkipOutput_) {
       return;
     }
 
@@ -126,17 +129,9 @@
     this.startIndex_ = 0;
   }
 
-  /** @private @return {boolean} */
-  shouldSkipOutput_() {
-    if (ChromeVoxState.instance && ChromeVoxState.instance.currentRange &&
-        ChromeVoxState.instance.currentRange.start &&
-        ChromeVoxState.instance.currentRange.start.node &&
-        ChromeVoxState.instance.currentRange.start.node.root) {
-      return ChromeVoxState.instance.currentRange.start.node.root.docUrl
-                 .indexOf(chrome.extension.getURL(
-                     'chromevox/log_page/log.html')) === 0;
-    }
-    return false;
+  /** @param {boolean} newValue */
+  set shouldSkipOutput(newValue) {
+    this.shouldSkipOutput_ = newValue;
   }
 
   /**
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_url_watcher.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_url_watcher.js
new file mode 100644
index 0000000..15695d1e
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/logging/log_url_watcher.js
@@ -0,0 +1,45 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Watches the currently focused URL to verify if logging should
+ * occur.
+ */
+
+/** @implements {ChromeVoxStateObserver} */
+export class LogUrlWatcher {
+  static create() {
+    if (LogUrlWatcher.instance) {
+      return;
+    }
+    LogUrlWatcher.instance = new LogUrlWatcher();
+    ChromeVoxState.addObserver(LogUrlWatcher.instance);
+    // Initialize using the current range.
+    if (ChromeVoxState.instance) {
+      this.onCurrentRangeChanged(ChromeVoxState.instance.currentRange);
+    }
+  }
+
+  static destroy() {
+    if (!LogUrlWatcher.instance) {
+      return;
+    }
+    ChromeVoxState.removeObserver(LogUrlWatcher.instance);
+    LogUrlWatcher.instance = null;
+  }
+
+  /** @override */
+  onCurrentRangeChanged(range, opt_fromEditing) {
+    if (range && range.start && range.start.node && range.start.node.root) {
+      LogStore.shouldSkipOutput =
+          range.start.node.root.docUrl.indexOf(
+              chrome.extension.getURL('chromevox/log_page/log.html')) === 0;
+    } else {
+      LogStore.shouldSkipOutput = false;
+    }
+  }
+}
+
+/** @type {LogUrlWatcher} */
+LogUrlWatcher.instance;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js
new file mode 100644
index 0000000..47e1cc3
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js
@@ -0,0 +1,308 @@
+// 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.
+
+GEN_INCLUDE([
+  '../../../common/testing/documents.js',
+  '../../testing/chromevox_next_e2e_test_base.js',
+]);
+
+// Fake Msgs object.
+const Msgs = {
+  getMsg: () => 'None'
+};
+
+// Fake PanelBridge.
+const PanelBridge = {
+  addMenuItem: (item, id) => PanelBridge.calls.append({item, id}),
+  calls: [],
+};
+
+/** Test fixture for PanelNodeMenuBackground. */
+ChromeVoxPanelNodeMenuBackgroundTest = class extends ChromeVoxNextE2ETest {
+  /** @override */
+  async setUpDeferred() {
+    await super.setUpDeferred();
+    await importModule(
+        'PanelBackground', '/chromevox/background/panel/panel_background.js');
+    await importModule(
+        'PanelNodeMenuBackground',
+        '/chromevox/background/panel/panel_node_menu_background.js');
+  }
+
+  assertMenuItemIndicatesNoNodesFound(item) {
+    assertNotNullNorUndefined(item);
+    assertEquals('None', item.title);
+    assertEquals(-1, item.callbackId);
+    assertFalse(item.isActive);
+  }
+
+  assertItemMatches(expectedName, item, opt_isActive) {
+    assertEquals(expectedName, item.title);
+    assertTrue(
+        item.callbackId >= 0 &&
+        item.callbackId < PanelNodeMenuBackground.callbackNodes_.length);
+    assertEquals(
+        expectedName,
+        PanelNodeMenuBackground.callbackNodes_[item.callbackId].name);
+    if (opt_isActive) {
+      assertTrue(item.isActive);
+    } else {
+      assertFalse(item.isActive);
+    }
+  }
+
+  assertMenusHaveNoNodesFoundExcept(id) {
+    for (const menu of PanelNodeMenuData.ALL_NODE_MENUS) {
+      if (menu.menuId === id) {
+        continue;
+      }
+      const call = PanelBridge.calls.find(args => args.id === menu.menuId);
+      assertNotNullNorUndefined(call);
+      this.assertMenuItemIndicatesNoNodesFound(call.item);
+    }
+  }
+
+  createAllNodeMenuBackgrounds(opt_activateMenu) {
+    PanelBridge.calls = [];
+    PanelBackground.instance.createAllNodeMenuBackgrounds_();
+  }
+
+  isFormControl(args) {
+    return args.id === PanelNodeMenuId.FORM_CONTROL;
+  }
+
+  isHeading(args) {
+    return args.id === PanelNodeMenuId.HEADING;
+  }
+
+  isLandmark(args) {
+    return args.id === PanelNodeMenuId.LANDMARK;
+  }
+
+  isLink(args) {
+    return args.id === PanelNodeMenuId.LINK;
+  }
+
+  isTable(args) {
+    return args.id === PanelNodeMenuId.TABLE;
+  }
+
+  get formControlsDoc() {
+    return [
+      Documents.button,
+      Documents.textInput,
+      Documents.textarea,
+      `<p>Static text</p>`,
+      Documents.checkbox,
+      Documents.color,
+      Documents.slider,
+      Documents.switch,
+      Documents.tab,
+      Documents.tree,
+      `<script>
+          document.getElementById('tree').focus();
+        </script>`
+    ].join('\n');
+  }
+
+  get headingsDoc() {
+    return `<h1>Heading 1</h1>
+        <h2>Heading 2</h2>
+        <h3>Heading 3</h3>`;
+  }
+
+  get landmarksDoc() {
+    return [
+      Documents.application,
+      Documents.banner,
+      Documents.complementary,
+      Documents.form,
+      Documents.main,
+      Documents.navigation,
+      Documents.region,
+      Documents.search
+    ].join('\n');
+  }
+
+  get linksDoc() {
+    return `<a href="#a">Link 1</a>
+        <a href="#b">Link 2</a>
+        <a href="#c">Link 3</a>
+        <a href="#d">Link 4</a>
+        <p>Not a link</p>`;
+  }
+
+  get mixedDoc() {
+    return [
+      Documents.button,
+      Documents.table,
+      Documents.region,
+      Documents.link,
+      Documents.header
+    ].join('\n');
+  }
+
+  get tablesDoc() {
+    return [
+        Documents.grid,
+        Documents.table
+    ].join('\n');
+  }
+};
+
+TEST_F(
+    'ChromeVoxPanelNodeMenuBackgroundTest', 'EmptyDocument', async function() {
+      await this.runWithLoadedTree('');
+      this.createAllNodeMenuBackgrounds();
+
+      // Expect that one element is added per menu, specifying that no nodes
+      // of that type are found.
+      assertEquals(
+          PanelNodeMenuData.ALL_NODE_MENUS.length, PanelBridge.calls.length);
+      // Assert all menus have a no nodes found element.
+      this.assertMenusHaveNoNodesFoundExcept(null);
+    });
+
+TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Headings', async function() {
+  await this.runWithLoadedTree(this.headingsDoc);
+  this.createAllNodeMenuBackgrounds();
+
+  // Check that there are the correct number of calls (one for each menu, plus
+  // two extra for the additional headings found).
+  assertEquals(
+      PanelNodeMenuData.ALL_NODE_MENUS_.length + 2, PanelBridge.calls.length);
+
+  // Expect that the three items are added to the headings menu
+  const headingItems =
+      PanelBridge.calls.findAll(this.isHeading).map(args => args.item);
+  assertEquals(3, headingItems.length);
+
+  this.assertItemMatches('Heading 1', headingItems.unshift());
+  this.assertItemMatches('Heading 2', headingItems.unshift());
+  this.assertItemMatches('Heading 3', headingItems.unshift());
+
+  this.assertMenusHaveNoNodesFoundExcept(PanelNodeMenuId.HEADING);
+});
+
+TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Landmarks', async function() {
+  await this.runWithLoadedTree(this.landmarksDoc);
+  this.createAllNodeMenuBackgrounds();
+
+  // Check that there are the correct number of calls (one for each menu, plus
+  // seven extra for the additional landmarks found).
+  assertEquals(
+      PanelNodeMenuData.ALL_NODE_MENUS_.length + 7, PanelBridge.calls.length);
+
+  // Verify that eight items were added to the landmarks menu.
+  const landmarkItems =
+      PanelBridge.calls.findAll(this.isLandmark).map(args => args.item);
+  assertEquals(8, landmarkItems.length);
+
+  this.assertItemMatches('application', landmarkItems.unshift());
+  this.assertItemMatches('banner', landmarkItems.unshift());
+  this.assertItemMatches('complementary', landmarkItems.unshift());
+  this.assertItemMatches('form', landmarkItems.unshift());
+  this.assertItemMatches('main', landmarkItems.unshift());
+  this.assertItemMatches('navigation', landmarkItems.unshift());
+  this.assertItemMatches('region', landmarkItems.unshift());
+  this.assertItemMatches('search', landmarkItems.unshift());
+
+  this.assertMenusHaveNoNodesFoundExcept(PanelNodeMenuId.LANDMARK);
+});
+
+TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Links', async function() {
+  await this.runWithLoadedTree(this.linksDoc);
+  this.createAllNodeMenuBackgrounds();
+
+  // Check that there are the correct number of calls (one for each menu, plus
+  // three extra for the additional links found).
+  assertEquals(
+      PanelNodeMenuData.ALL_NODE_MENUS_.length + 3, PanelBridge.calls.length);
+
+  // Verify that four items were added to the links menu.
+  const linkItems =
+      PanelBridge.calls.findAll(this.isLink).map(args => args.item);
+  assertEquals(4, linkItems.length);
+
+  this.assertItemMatches('Link 1', linkItems.unshift());
+  this.assertItemMatches('Link 2', linkItems.unshift());
+  this.assertItemMatches('Link 3', linkItems.unshift());
+  this.assertItemMatches('Link 4', linkItems.unshift());
+
+  this.assertMenusHaveNoNodesFoundExcept(PanelNodeMenuId.LINK);
+});
+
+TEST_F(
+    'ChromeVoxPanelNodeMenuBackgroundTest', 'FormControls', async function() {
+      await this.runWithLoadedTree(this.formControlsDoc);
+      this.createAllNodeMenuBackgrounds('panel_menu_form_controls');
+
+      // Check that there are the correct number of calls (one for each menu,
+      // plus eight extra for the additional form controls found).
+      assertEquals(
+          PanelNodeMenuData.ALL_NODE_MENUS_.length + 8,
+          PanelBridge.calls.length);
+
+      // Verify that nine items were added to the form controls menu.
+      const formItems =
+          PanelBridge.calls.findAll(this.isFormControl).map(args => args.item);
+      assertEquals(9, formItems.length);
+
+      this.assertItemMatches('button', formItems.unshift());
+      this.assertItemMatches('textInput', formItems.unshift());
+      this.assertItemMatches('textarea', formItems.unshift());
+      this.assertItemMatches('checkbox', formItems.unshift());
+      this.assertItemMatches('color', formItems.unshift());
+      this.assertItemMatches('slider', formItems.unshift());
+      this.assertItemMatches('switch', formItems.unshift());
+      this.assertItemMatches('tab', formItems.unshift());
+      this.assertItemMatches('tree', formItems.unshift(), /* isActive= */ true);
+
+      this.assertMenusHaveNoNodesFoundExcept(PanelNodeMenuId.FORM_CONTROL);
+    });
+
+TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Tables', async function() {
+  await this.runWithLoadedTree(this.tablesDoc);
+  this.createAllNodeMenuBackgrounds();
+
+  // Check that there are the correct number of calls (one for each menu, plus
+  // one extra for the additional links found).
+  assertEquals(
+      PanelNodeMenuData.ALL_NODE_MENUS_.length + 1, PanelBridge.calls.length);
+
+  // Verify that two items were added to the tables menu.
+  const tableItems =
+      PanelBridge.calls.findAll(this.isTable).map(args => args.item);
+  assertEquals(2, tableItems.length);
+
+  this.assertItemMatches('grid', tableItems.unshift());
+  this.assertItemMatches('table', tableItems.unshift());
+
+  this.assertMenusHaveNoNodesFoundExcept(PanelNodeMenuId.TABLE);
+});
+
+TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'MixedData', async function() {
+  await this.runWithLoadedTree(this.mixedDoc);
+  this.createAllNodeMenuBackgrounds();
+
+  // Check that there are the correct number of calls (one for each menu).
+  assertEquals(
+      PanelNodeMenuData.ALL_NODE_MENUS_.length, PanelBridge.calls.length);
+
+  // Check that each item was added to the correct menu.
+  const formItem = PanelBridge.calls.find(this.isFormControl).item;
+  this.assertItemMatches('button', formItem);
+
+  const headingItem = PanelBridge.calls.find(this.isHeading).item;
+  this.assertItemMatches('header', headingItem);
+
+  const landmarkItem = PanelBridge.calls.find(this.isLandmark).item;
+  this.assertItemMatches('region', landmarkItem);
+
+  const linkItem = PanelBridge.calls.find(this.isLink).item;
+  this.assertItemMatches('link', linkItem);
+
+  const tableItem = PanelBridge.calls.find(this.isTable).item;
+  this.assertItemMatches('table', tableItem);
+});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
index f398d46..592355a 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
@@ -9,6 +9,7 @@
  */
 import {ConsoleTts} from '/chromevox/background/console_tts.js';
 import {EventStreamLogger} from '/chromevox/background/logging/event_stream_logger.js';
+import {LogUrlWatcher} from '/chromevox/background/logging/log_url_watcher.js';
 
 /**
  * This object has default values of preferences and contains the common
@@ -55,6 +56,7 @@
         localStorage[pref] = ChromeVoxPrefs.DEFAULT_PREFS[pref];
       }
     }
+    this.enableOrDisableLogUrlWatcher_();
   }
 
   /**
@@ -94,6 +96,17 @@
     } else if (key === 'enableEventStreamLogging') {
       EventStreamLogger.instance.notifyEventStreamFilterChangedAll(value);
     }
+    this.enableOrDisableLogUrlWatcher_();
+  }
+
+  enableOrDisableLogUrlWatcher_() {
+    for (const pref of Object.values(ChromeVoxPrefs.loggingPrefs)) {
+      if (localStorage[pref]) {
+        LogUrlWatcher.create();
+        return;
+      }
+    }
+    LogUrlWatcher.destroy();
   }
 }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js
index 9460bf76..0e7b9e32 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base.js
@@ -356,8 +356,9 @@
       if (this.start + 1 === evt.start && this.end === this.value.length &&
           evt.end === this.value.length) {
         // Autocomplete: the user typed one character of autocompleted text.
-        if (ChromeVox.typingEcho === TypingEcho.CHARACTER ||
-            ChromeVox.typingEcho === TypingEcho.CHARACTER_AND_WORD) {
+        if (ChromeVoxState.instance.typingEcho === TypingEcho.CHARACTER ||
+            ChromeVoxState.instance.typingEcho ===
+                TypingEcho.CHARACTER_AND_WORD) {
           this.speak(this.value.substr(this.start, 1), evt.triggeredByUser);
         }
         this.speak(this.value.substr(evt.start));
@@ -577,8 +578,9 @@
       }
       utterance = inserted;
     } else if (insertedLen === 1) {
-      if ((ChromeVox.typingEcho === TypingEcho.WORD ||
-           ChromeVox.typingEcho === TypingEcho.CHARACTER_AND_WORD) &&
+      if ((ChromeVoxState.instance.typingEcho === TypingEcho.WORD ||
+           ChromeVoxState.instance.typingEcho ===
+               TypingEcho.CHARACTER_AND_WORD) &&
           this.isWordBreakChar(inserted) && prefixLen > 0 &&
           !this.isWordBreakChar(evt.value.substr(prefixLen - 1, 1))) {
         // Speak previous word.
@@ -593,8 +595,9 @@
           triggeredByUser = false;  // Implies QUEUE_MODE_QUEUE.
         }
       } else if (
-          ChromeVox.typingEcho === TypingEcho.CHARACTER ||
-          ChromeVox.typingEcho === TypingEcho.CHARACTER_AND_WORD) {
+          ChromeVoxState.instance.typingEcho === TypingEcho.CHARACTER ||
+          ChromeVoxState.instance.typingEcho ===
+              TypingEcho.CHARACTER_AND_WORD) {
         utterance = inserted;
       }
     } else if (deletedLen > 1 && !autocompleteSuffix) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js
index 05b1d9f..ee55ae2 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/editable_text_base_test.js
@@ -96,7 +96,7 @@
     // TODO: These tests are all assuming we used the IBeam cursor.
     // We need to add coverage for block cursor.
     ChromeVoxEditableTextBase.useIBeamCursor = true;
-    ChromeVox.typingEcho = TypingEcho.CHARACTER_AND_WORD;
+    ChromeVoxState.instance.typingEcho = TypingEcho.CHARACTER_AND_WORD;
     ChromeVoxEditableTextBase.eventTypingEcho = false;
     ChromeVoxEditableTextBase.shouldSpeakInsertions = true;
     ChromeVox.braille = new TestBraille();
@@ -340,7 +340,7 @@
 
 /** Tests character echo. */
 TEST_F('ChromeVoxEditableTextUnitTest', 'CharacterEcho', function() {
-  ChromeVox.typingEcho = TypingEcho.CHARACTER;
+  ChromeVoxState.instance.typingEcho = TypingEcho.CHARACTER;
   var tts = new TestTts();
   var obj = new ChromeVoxEditableTextBase('', 0, 0, false, tts);
   obj.changed(new TextChangeEvent('H', 1, 1));
@@ -371,13 +371,13 @@
   // This simulates a user typing into an auto complete text field one character
   // at a time. The selection is the completion and we toggle between various
   // typing echo options.
-  ChromeVox.typingEcho = TypingEcho.CHARACTER;
+  ChromeVoxState.instance.typingEcho = TypingEcho.CHARACTER;
   obj.changed(new TextChangeEvent(url, 2, 13));
-  ChromeVox.typingEcho = TypingEcho.NONE;
+  ChromeVoxState.instance.typingEcho = TypingEcho.NONE;
   obj.changed(new TextChangeEvent(url, 3, 13));
-  ChromeVox.typingEcho = TypingEcho.CHARACTER_AND_WORD;
+  ChromeVoxState.instance.typingEcho = TypingEcho.CHARACTER_AND_WORD;
   obj.changed(new TextChangeEvent(url, 4, 13));
-  ChromeVox.typingEcho = TypingEcho.WORD;
+  ChromeVoxState.instance.typingEcho = TypingEcho.WORD;
   obj.changed(new TextChangeEvent(url, 5, 13));
 
   // The characters should only be read for the typing echo modes containing a
@@ -395,7 +395,7 @@
 
 /** Tests word echo. */
 TEST_F('ChromeVoxEditableTextUnitTest', 'WordEcho', function() {
-  ChromeVox.typingEcho = TypingEcho.WORD;
+  ChromeVoxState.instance.typingEcho = TypingEcho.WORD;
   var tts = new TestTts();
   var obj = new ChromeVoxEditableTextBase('', 0, 0, false, tts);
   obj.changed(new TextChangeEvent('H', 1, 1));
@@ -417,7 +417,7 @@
 
 /** Tests no echo. */
 TEST_F('ChromeVoxEditableTextUnitTest', 'NoEcho', function() {
-  ChromeVox.typingEcho = TypingEcho.NONE;
+  ChromeVoxState.instance.typingEcho = TypingEcho.NONE;
   var tts = new TestTts();
   var obj = new ChromeVoxEditableTextBase('', 0, 0, false, tts);
   obj.changed(new TextChangeEvent('H', 1, 1));
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js b/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js
new file mode 100644
index 0000000..ee0b8062
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js
@@ -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.
+
+/**
+ * @fileoverview A collection of document fragments to allow for easier test
+ * creation.
+ */
+
+const Documents = {
+  application: `<div role="application" id="application">application</div>`,
+  banner: `<div role="banner" id="banner">banner</div>`,
+  button: `<button id="button">button</button>`,
+  checkbox: `<input type="checkbox" id="checkbox"></input>
+      <label for="checkbox">checkbox</label>`,
+  color: `<input type="color" id="color"></input>
+      <label for="color">color</label>`,
+  complementary:
+      `<div role="complementary" id="complementary">Complementary</div>`,
+  form: `<form aria-label="form" id="form"></form>`,
+  grid: `<div role="grid" id="grid">grid</div>`,
+  header: `<h1 id="header">header</header>`,
+  link: `<a href="#link" id="link">link</a>`,
+  main: `<div role="main" id="main">main</div>`,
+  navigation: `<nav id="navigation">navigation</nav>`,
+  region: `<div role="region" id="region">region</div>`,
+  search: `<input type="text" role="search" id="search"></input>
+      <label for="search">search</label>`,
+  slider: `<input type="range" id="slider"></input>
+      <label for="slider">slider</label>`,
+  switch: `<button role="switch" id="switch" aria-checked=true>switch</button>
+    <script>
+        const switchElement = document.getElementById("switch");
+        switchElement.onclick =
+            () => switchElement.ariaChecked = !switchElement.ariaChecked;
+    </script>`,
+  tab: `<div role="tab" id="tab">tab</div>`,
+  table: `<table id="table" aria-label="table"></table>`,
+  textarea: `<textarea aria-label="textarea" id="textarea"></textarea>`,
+  textInput:
+      `<input type="text" aria-label="textInput" id="textInput"></input>`,
+  tree: `<div role="tree" id="tree">tree</div>`,
+};
diff --git a/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.ts b/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.ts
index 9139e9eb..fe4d822 100644
--- a/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_move_multiple_passwords_to_account_dialog.ts
@@ -78,9 +78,6 @@
       }
     });
     PasswordManagerImpl.getInstance().movePasswordsToAccount(selectedPasswords);
-    chrome.metricsPrivate.recordSmallCount(
-        'PasswordManager.AccountStorage.MoveToAccountStorePasswordsCount',
-        selectedPasswords.length);
     this.$.dialog.close();
   }
 
diff --git a/chrome/browser/resources/settings/autofill_page/password_view.ts b/chrome/browser/resources/settings/autofill_page/password_view.ts
index 4e98490..6a3b113f 100644
--- a/chrome/browser/resources/settings/autofill_page/password_view.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_view.ts
@@ -154,12 +154,9 @@
       return;
     }
 
-    const username = queryParameters.get(PasswordViewPageUrlParams.USERNAME);
-    if (!username) {
-      return;
-    }
+    this.username =
+        queryParameters.get(PasswordViewPageUrlParams.USERNAME) || '';
     this.site = site;
-    this.username = username;
   }
 
   override onPasswordRemoveDialogPasswordsRemoved(
@@ -325,7 +322,7 @@
     this.credential = null;
     this.password_ = '';
     this.isPasswordVisible_ = false;
-    if (!this.savedPasswords.length || !this.site || !this.username) {
+    if (!this.savedPasswords.length || !this.site) {
       return;
     }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index b94afd9..310da7d8 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -2095,12 +2095,6 @@
   // Navigate away without interacting with the page.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2116,8 +2110,6 @@
   // Navigate to about:blank to "flush" metrics, if any.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 0);
 }
 
 // Close the tab while a user interaction observer is attached to the tab. It
@@ -2128,12 +2120,6 @@
   chrome::NewTab(browser());
   NavigateAndAssertNoInterstitial();
   chrome::CloseTab(browser());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2165,11 +2151,6 @@
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
 
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnKeypress, 1);
   histograms.ExpectUniqueTimeSample(kDelayedWarningsTimeOnPageHistogram,
                                     base::Seconds(kTimeOnPage), 1);
 }
@@ -2263,12 +2244,6 @@
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2299,12 +2274,6 @@
   // navigation.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2340,12 +2309,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnKeypress, 1);
 }
 
 // Similar to KeyPress_ESC_WarningNotShown, but a character key is pressed after
@@ -2372,9 +2335,6 @@
       ->ForwardKeyboardEvent(event);
   base::RunLoop().RunUntilIdle();
   AssertNoInterstitial(browser(), false);
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
 
   // Now type something. The interstitial should be shown.
   EXPECT_TRUE(TypeAndWaitForInterstitial(browser()));
@@ -2385,12 +2345,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnKeypress, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2410,13 +2364,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kWarningShownOnFullscreenAttempt, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2436,12 +2383,6 @@
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
 
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kWarningShownOnPermissionRequest, 1);
   histograms.ExpectTotalCount("Permissions.Action.Notifications", 1);
   histograms.ExpectBucketCount(
       "Permissions.Action.Notifications",
@@ -2469,13 +2410,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kWarningShownOnJavaScriptDialog, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2496,13 +2430,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kWarningShownOnDesktopCaptureRequest, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2521,11 +2448,6 @@
   menu->ExecuteCommand(IDC_CONTENT_CONTEXT_PASTE, 0);
   observer.WaitForNavigationFinished();
   EXPECT_TRUE(WaitForReady(browser()));
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnPaste, 1);
 }
 
 // The user clicks on the page. Feature isn't configured to show a warning on
@@ -2547,15 +2469,6 @@
   // Navigate away to "flush" the metrics.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 3);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kWarningNotTriggeredOnMouseClick, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2577,13 +2490,6 @@
                 ->tab_strip_model()
                 ->GetActiveWebContents()
                 ->GetLastCommittedURL());
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnMouseClick,
-                               1);
 }
 
 // This test initiates a download when a warning is delayed. The download should
@@ -2599,14 +2505,6 @@
   // Navigate away to "flush" the metrics.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 3);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kDownloadCancelled, 1);
 }
 
 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest,
@@ -2623,12 +2521,6 @@
   // Navigate away to "flush" the metrics.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningShownOnKeypress, 1);
 }
 
 // This test navigates to a page with password form and submits a password. The
@@ -2663,14 +2555,6 @@
   // Navigate away to "flush" the metrics.
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 3);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
-  histograms.ExpectBucketCount(
-      kDelayedWarningsHistogram,
-      DelayedWarningEvent::kPasswordSaveOrAutofillDenied, 1);
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -3290,16 +3174,8 @@
   GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
   prerender_helper().AddPrerender(prerender_url);
 
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 1);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kPageLoaded, 1);
-
   // Activating the prerendered page causes "flush" metrics.
   prerender_helper().NavigatePrimaryPage(prerender_url);
-
-  histograms.ExpectTotalCount(kDelayedWarningsHistogram, 2);
-  histograms.ExpectBucketCount(kDelayedWarningsHistogram,
-                               DelayedWarningEvent::kWarningNotShown, 1);
 }
 
 class SafeBrowsingFencedFrameBrowserTest
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc
index 93c936a..29ffa579 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.cc
+++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -33,7 +33,6 @@
 
 namespace safe_browsing {
 
-const char kDelayedWarningsHistogram[] = "SafeBrowsing.DelayedWarnings.Event";
 const char kDelayedWarningsTimeOnPageHistogram[] =
     "SafeBrowsing.DelayedWarnings.TimeOnPage";
 
@@ -102,7 +101,6 @@
   if (permission_request_manager) {
     permission_request_manager->AddObserver(this);
   }
-  RecordUMA(DelayedWarningEvent::kPageLoaded);
 }
 
 SafeBrowsingUserInteractionObserver::~SafeBrowsingUserInteractionObserver() {
@@ -193,7 +191,6 @@
   // result, the page should remain unchanged on downloads. Record a metric and
   // ignore this cancelled navigation.
   if (handle->IsDownload()) {
-    RecordUMA(DelayedWarningEvent::kDownloadCancelled);
     return;
   }
   // Now ignore other kinds of navigations that don't commit (e.g. 204 response
@@ -206,9 +203,6 @@
 }
 
 void SafeBrowsingUserInteractionObserver::Detach() {
-  if (!interstitial_shown_) {
-    RecordUMA(DelayedWarningEvent::kWarningNotShown);
-  }
   base::TimeDelta time_on_page = clock_->Now() - creation_time_;
   if (IsUrlElisionDisabled(
           Profile::FromBrowserContext(web_contents()->GetBrowserContext()),
@@ -274,7 +268,6 @@
     return;
   }
   password_save_or_autofill_denied_metric_recorded_ = true;
-  RecordUMA(DelayedWarningEvent::kPasswordSaveOrAutofillDenied);
 }
 
 void SafeBrowsingUserInteractionObserver::OnDesktopCaptureRequest() {
@@ -304,14 +297,6 @@
   return creation_time_;
 }
 
-void SafeBrowsingUserInteractionObserver::RecordUMA(DelayedWarningEvent event) {
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-  if (!IsUrlElisionDisabled(profile, suspicious_site_reporter_extension_id_)) {
-    base::UmaHistogramEnumeration(kDelayedWarningsHistogram, event);
-  }
-}
-
 bool IsAllowedModifier(const content::NativeWebKeyboardEvent& event) {
   const int key_modifiers =
       event.GetModifiers() & blink::WebInputEvent::kKeyModifiers;
@@ -351,7 +336,6 @@
   // the user clicks.
   if (!kDelayedWarningsEnableMouseClicks.Get()) {
     if (!mouse_click_with_no_warning_recorded_) {
-      RecordUMA(DelayedWarningEvent::kWarningNotTriggeredOnMouseClick);
       mouse_click_with_no_warning_recorded_ = true;
     }
     return false;
@@ -367,7 +351,6 @@
   DCHECK(!interstitial_shown_);
   interstitial_shown_ = true;
   CleanUp();
-  RecordUMA(event);
   ui_manager_->StartDisplayingBlockingPage(resource_);
   Detach();
   // DO NOT add code past this point. |this| is destroyed.
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.h b/chrome/browser/safe_browsing/user_interaction_observer.h
index 1f16e79..ccc0136 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.h
+++ b/chrome/browser/safe_browsing/user_interaction_observer.h
@@ -62,7 +62,6 @@
 // Name of the recorded histograms when the user did not disable URL elision via
 // "Always Show Full URLs" menu option or by installing Suspicious Site Reporter
 // extension.
-extern const char kDelayedWarningsHistogram[];
 extern const char kDelayedWarningsTimeOnPageHistogram[];
 
 // Same as above but only recorded if the user disabled URL elision.
@@ -132,8 +131,6 @@
       bool is_main_frame,
       scoped_refptr<SafeBrowsingUIManager> ui_manager);
 
-  void RecordUMA(DelayedWarningEvent event);
-
   bool HandleKeyPress(const content::NativeWebKeyboardEvent& event);
   bool HandleMouseEvent(const blink::WebMouseEvent& event);
 
diff --git a/chrome/browser/sharing/OWNERS b/chrome/browser/sharing/OWNERS
index d20898a..f32124f 100644
--- a/chrome/browser/sharing/OWNERS
+++ b/chrome/browser/sharing/OWNERS
@@ -1,3 +1,3 @@
-knollr@chromium.org
 mvanouwerkerk@chromium.org
 peter@chromium.org
+rushans@google.com
diff --git a/chrome/browser/thumbnail/DEPS b/chrome/browser/thumbnail/DEPS
index 00f797e..02be6da0 100644
--- a/chrome/browser/thumbnail/DEPS
+++ b/chrome/browser/thumbnail/DEPS
@@ -26,7 +26,6 @@
   "+skia",
   "+testing/gmock",
   "+testing/gtest",
-  "+third_party/abseil-cpp/absl",
   "+third_party/android_opengl/etc1",
   "+third_party/skia/include",
   "+ui",
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc
index f7316a98..a5ae7bb 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc
@@ -98,9 +98,12 @@
   if (ash::ProfileHelper::IsSigninProfile(profile))
     return nullptr;
 
-  // Use profile as-is for guest session.
-  if (profile->IsGuestSession())
-    return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+  // Use OTR profile for Guest Session.
+  if (profile->IsGuestSession()) {
+    return profile->IsOffTheRecord()
+               ? chrome::GetBrowserContextOwnInstanceInIncognito(context)
+               : nullptr;
+  }
 
   // This matches the logic in ExtensionSyncServiceFactory, which uses the
   // orginal browser context.
diff --git a/chrome/browser/ui/app_list/app_list_test_util.cc b/chrome/browser/ui/app_list/app_list_test_util.cc
index 94cb5d6..7eee25e 100644
--- a/chrome/browser/ui/app_list/app_list_test_util.cc
+++ b/chrome/browser/ui/app_list/app_list_test_util.cc
@@ -29,6 +29,10 @@
 AppListTestBase::~AppListTestBase() {}
 
 void AppListTestBase::SetUp() {
+  SetUp(/*guest_mode=*/false);
+}
+
+void AppListTestBase::SetUp(bool guest_mode) {
   extensions::ExtensionServiceTestBase::SetUp();
 
   // Load "app_list" extensions test profile.
@@ -40,7 +44,9 @@
       data_dir().AppendASCII("app_list").AppendASCII("Extensions");
   base::FilePath pref_path =
       source_install_dir.DirName().Append(chrome::kPreferencesFilename);
-  InitializeInstalledExtensionService(pref_path, source_install_dir);
+  ExtensionServiceInitParams params;
+  params.profile_is_guest = guest_mode;
+  InitializeInstalledExtensionService(pref_path, source_install_dir, params);
   service_->Init();
 
   ConfigureWebAppProvider();
@@ -53,19 +59,20 @@
 }
 
 void AppListTestBase::ConfigureWebAppProvider() {
-  Profile* const profile = testing_profile();
+  Profile* testing_profile = profile();
 
   auto url_loader = std::make_unique<web_app::TestWebAppUrlLoader>();
   url_loader_ = url_loader.get();
 
   auto externally_managed_app_manager =
-      std::make_unique<web_app::ExternallyManagedAppManagerImpl>(profile);
+      std::make_unique<web_app::ExternallyManagedAppManagerImpl>(
+          testing_profile);
   externally_managed_app_manager->SetUrlLoaderForTesting(std::move(url_loader));
 
-  auto* const provider = web_app::FakeWebAppProvider::Get(profile);
+  auto* const provider = web_app::FakeWebAppProvider::Get(testing_profile);
   provider->SetExternallyManagedAppManager(
       std::move(externally_managed_app_manager));
-  web_app::test::AwaitStartWebAppProviderAndSubsystems(profile);
+  web_app::test::AwaitStartWebAppProviderAndSubsystems(testing_profile);
 }
 
 // Test util constants ---------------------------------------------------------
diff --git a/chrome/browser/ui/app_list/app_list_test_util.h b/chrome/browser/ui/app_list/app_list_test_util.h
index 2bb200f8..972b76c 100644
--- a/chrome/browser/ui/app_list/app_list_test_util.h
+++ b/chrome/browser/ui/app_list/app_list_test_util.h
@@ -24,6 +24,7 @@
   ~AppListTestBase() override;
 
   void SetUp() override;
+  void SetUp(bool guest_mode);
 
   web_app::TestWebAppUrlLoader& url_loader() { return *url_loader_; }
 
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
index 6aee17ee..246c862 100644
--- a/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
@@ -225,7 +225,7 @@
 
     app_service_test_.UninstallAllApps(profile());
     testing_profile()->SetGuestSession(guest_mode);
-    app_service_test_.SetUp(testing_profile());
+    app_service_test_.SetUp(profile());
     model_updater_ = std::make_unique<FakeAppListModelUpdater>(
         /*profile=*/nullptr, /*reorder_delegate=*/nullptr);
     controller_ = std::make_unique<test::TestAppListControllerDelegate>();
@@ -233,7 +233,7 @@
     scoped_callback_ = std::make_unique<
         AppServiceAppModelBuilder::ScopedAppPositionInitCallbackForTest>(
         builder_.get(), base::BindRepeating(&InitAppPosition));
-    builder_->Initialize(nullptr, testing_profile(), model_updater_.get());
+    builder_->Initialize(nullptr, profile(), model_updater_.get());
   }
 
   apps::AppServiceTest app_service_test_;
@@ -248,12 +248,17 @@
 };
 
 class BuiltInAppTest : public AppServiceAppModelBuilderTest {
+ public:
+  // Don't call AppListTestBase::SetUp() - it's called from CreateBuilder().
+  void SetUp() override {}
+
  protected:
-  // Creates a new builder, destroying any existing one.
+  // Creates a new builder. Should be called only once for each test.
+  // Calls `AppListTestBase::SetUp()`.
   void CreateBuilder(bool guest_mode) {
+    AppListTestBase::SetUp(guest_mode);
     AppServiceAppModelBuilderTest::CreateBuilder(guest_mode);
-    RemoveApps(apps::AppType::kBuiltIn, testing_profile(),
-               model_updater_.get());
+    RemoveApps(apps::AppType::kBuiltIn, profile(), model_updater_.get());
   }
 };
 
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
index fa97f518..aaf85c06a 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -2860,8 +2860,7 @@
 
 // Verify that the in-app shelf should be shown when the app icon receives
 // the accessibility focus.
-// TODO(https://crbug.com/1299759): Re-enable once flaky timeouts are fixed.
-IN_PROC_BROWSER_TEST_F(HotseatShelfAppBrowserTest, DISABLED_EnableChromeVox) {
+IN_PROC_BROWSER_TEST_F(HotseatShelfAppBrowserTest, EnableChromeVox) {
   ash::Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
   ash::test::SpeechMonitor speech_monitor;
 
@@ -2881,6 +2880,11 @@
     content::ExecuteScriptAsync(host->host_contents(), script);
   });
 
+  // Wait for an utterance from the browser before the test starts traversal
+  // through shelf to ensure that the browser does not show mid shelf traversal,
+  // and causes the a11y focus to unexpectedly switch to the omnibox mid test.
+  speech_monitor.ExpectSpeech("about:blank");
+
   ash::RootWindowController* controller =
       ash::Shell::GetRootWindowControllerWithDisplayId(
           display::Screen::GetScreen()->GetPrimaryDisplay().id());
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h
index fb30c553..40bf065 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h
@@ -12,6 +12,10 @@
 #include "base/memory/weak_ptr.h"
 #include "url/gurl.h"
 
+namespace content {
+class WebContents;
+}  // namespace content
+
 class AssistantOnboardingPrompt;
 
 // Holds information for the consent dialog.
@@ -52,7 +56,8 @@
   // Factory function to create controller that is defined in the file
   // `assistant_onboarding_controller_impl.cc`.
   static std::unique_ptr<AssistantOnboardingController> Create(
-      const AssistantOnboardingInformation& onboarding_information);
+      const AssistantOnboardingInformation& onboarding_information,
+      content::WebContents* web_contents);
 
   AssistantOnboardingController() = default;
   virtual ~AssistantOnboardingController() = default;
@@ -72,6 +77,9 @@
   // closing a sidepanel, etc.
   virtual void OnClose() = 0;
 
+  // Navigates to the website that contains more information about Assistant.
+  virtual void OnLearnMoreClicked() = 0;
+
   // Provides the "model" behind the controller by returning a struct
   // specifying the consent text.
   virtual const AssistantOnboardingInformation& GetOnboardingInformation() = 0;
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.cc b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.cc
index 1ca2d08..c057803 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.cc
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.cc
@@ -7,12 +7,20 @@
 #include <utility>
 
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h"
 #include "chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_navigator_params.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/base/page_transition_types.h"
+#include "ui/base/window_open_disposition.h"
 
 AssistantOnboardingControllerImpl::AssistantOnboardingControllerImpl(
-    const AssistantOnboardingInformation& onboarding_information)
-    : onboarding_information_(onboarding_information) {}
+    const AssistantOnboardingInformation& onboarding_information,
+    content::WebContents* web_contents)
+    : onboarding_information_(onboarding_information),
+      web_contents_(web_contents) {}
 
 AssistantOnboardingControllerImpl::~AssistantOnboardingControllerImpl() {
   ClosePrompt();
@@ -26,7 +34,7 @@
 
   callback_ = std::move(callback);
   prompt_ = prompt;
-  prompt_->Show();
+  prompt_->Show(web_contents_);
 }
 
 void AssistantOnboardingControllerImpl::OnAccept() {
@@ -50,6 +58,15 @@
   }
 }
 
+void AssistantOnboardingControllerImpl::OnLearnMoreClicked() {
+  NavigateParams params(
+      Profile::FromBrowserContext(web_contents_->GetBrowserContext()),
+      GetOnboardingInformation().learn_more_url,
+      ui::PageTransition::PAGE_TRANSITION_LINK);
+  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
+  Navigate(&params);
+}
+
 const AssistantOnboardingInformation&
 AssistantOnboardingControllerImpl::GetOnboardingInformation() {
   return onboarding_information_;
@@ -71,7 +88,8 @@
 // static
 std::unique_ptr<AssistantOnboardingController>
 AssistantOnboardingController::Create(
-    const AssistantOnboardingInformation& onboarding_information) {
+    const AssistantOnboardingInformation& onboarding_information,
+    content::WebContents* web_contents) {
   return std::make_unique<AssistantOnboardingControllerImpl>(
-      onboarding_information);
+      onboarding_information, web_contents);
 }
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.h b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.h
index 0bfef50..8b6760d 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.h
@@ -11,6 +11,10 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 
+namespace content {
+class WebContents;
+}  // namespace content
+
 class OnboardingPrompt;
 
 // Implementation of the `AssistantOnboardingController` interface that keeps
@@ -18,7 +22,8 @@
 class AssistantOnboardingControllerImpl : public AssistantOnboardingController {
  public:
   explicit AssistantOnboardingControllerImpl(
-      const AssistantOnboardingInformation& onboarding_information);
+      const AssistantOnboardingInformation& onboarding_information,
+      content::WebContents* web_contents);
   ~AssistantOnboardingControllerImpl() override;
 
   // OnboardingController:
@@ -29,6 +34,7 @@
   void OnAccept() override;
   void OnCancel() override;
   void OnClose() override;
+  void OnLearnMoreClicked() override;
   const AssistantOnboardingInformation& GetOnboardingInformation() override;
   base::WeakPtr<AssistantOnboardingController> GetWeakPtr() override;
 
@@ -43,7 +49,11 @@
   // Callback triggered when dialog is accepted, canceled or closed.
   Callback callback_;
 
-  // A weak pointer to the view implementing the `OnboardingPrompt` interface.
+  // The `WebContents` for which the dialog is supposed to show.
+  content::WebContents* web_contents_;
+
+  // A weak pointer to the view implementing the `OnboardingPrompt`
+  // interface.
   base::WeakPtr<AssistantOnboardingPrompt> prompt_ = nullptr;
 
   // A factory for weak pointers to the controller.
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_browsertest.cc b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_browsertest.cc
new file mode 100644
index 0000000..67fa145
--- /dev/null
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_browsertest.cc
@@ -0,0 +1,46 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller.h"
+#include "chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "url/gurl.h"
+
+constexpr char kUrl[] = "https://www.google.com/example_page";
+
+class AssistantOnboardingControllerImplBrowserTest
+    : public InProcessBrowserTest {
+ public:
+  AssistantOnboardingControllerImplBrowserTest() {
+    model_.learn_more_url = GURL(kUrl);
+  }
+  ~AssistantOnboardingControllerImplBrowserTest() override = default;
+
+  content::WebContents* web_contents() {
+    return chrome_test_utils::GetActiveWebContents(this);
+  }
+  const AssistantOnboardingInformation& model() { return model_; }
+
+ private:
+  AssistantOnboardingInformation model_;
+};
+
+IN_PROC_BROWSER_TEST_F(AssistantOnboardingControllerImplBrowserTest,
+                       NavigateToLearnMorePage) {
+  // Create the controller here to ensure that the BrowserTest is all set up.
+  std::unique_ptr<AssistantOnboardingController> controller =
+      AssistantOnboardingController::Create(model(), web_contents());
+  content::TestNavigationObserver navigation_observer(model().learn_more_url);
+  navigation_observer.StartWatchingNewWebContents();
+  controller->OnLearnMoreClicked();
+  navigation_observer.Wait();
+  EXPECT_EQ(web_contents()->GetLastCommittedURL(), model().learn_more_url);
+}
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_unittest.cc b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_unittest.cc
index e6db129..2678782a 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_unittest.cc
@@ -17,8 +17,10 @@
 class AssistantOnboardingControllerImplTest : public ::testing::Test {
  public:
   AssistantOnboardingControllerImplTest() {
-    controller_ =
-        AssistantOnboardingController::Create(AssistantOnboardingInformation());
+    // Create controller without `WebContents` here - the version with
+    // `WebContents` is tested in the browsertest.
+    controller_ = AssistantOnboardingController::Create(
+        AssistantOnboardingInformation(), /*web_contents=*/nullptr);
   }
   ~AssistantOnboardingControllerImplTest() override = default;
 
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h
index a8070fc0..6e25731 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h
@@ -20,14 +20,13 @@
   // Factory function to create onboarding prompts on desktop platforms. The
   // actual implementation is in the `assistant_onboarding_view.cc` file.
   static base::WeakPtr<AssistantOnboardingPrompt> Create(
-      base::WeakPtr<AssistantOnboardingController> controller,
-      content::WebContents* web_contents);
+      base::WeakPtr<AssistantOnboardingController> controller);
 
   AssistantOnboardingPrompt() = default;
   virtual ~AssistantOnboardingPrompt() = default;
 
   // Shows the view of the prompt.
-  virtual void Show() = 0;
+  virtual void Show(content::WebContents* web_contents) = 0;
 
   // Notifies that view that the controller was destroyed so that the view can
   // close.
diff --git a/chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h b/chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h
index 5cdf487..0061f82 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h
@@ -7,48 +7,42 @@
 
 #include <memory>
 
+#include "base/observer_list_types.h"
+#include "chrome/browser/ui/autofill_assistant/password_change/assistant_display_delegate.h"
+
 namespace content {
 class WebContents;
 }  // namespace content
 
-namespace views {
-class View;
-}  // namespace views
-
-class SidePanelEntryObserver;
-
 // Abstract interface for interactions with the Assistant side panel.
 // Whoever owns an instance of it is responsible for destroying it
 // and therefore effectively removing its entry from the unified side panel.
-// The |WebContents| provided during creation must always outlive
+// The `WebContents` provided during creation must always outlive
 // implementations of this interface.
-class AssistantSidePanelCoordinator {
+class AssistantSidePanelCoordinator : public AssistantDisplayDelegate {
  public:
-  // If not already registered, registers an Assistant Side Panel entry in the
-  // specified |webContents| and returns and instance of
-  // AssistantSidePanelCoordinator. Otherwise returns nullptr
+  class Observer : public base::CheckedObserver {
+   public:
+    ~Observer() override = default;
+
+    // Called when the side panel is hidden.
+    virtual void OnHidden() {}
+  };
+
+  // If not already registered, registers an Assistant side panel entry in the
+  // specified `WebContents` and returns and instance of
+  // AssistantSidePanelCoordinator. Otherwise returns `nullptr`.
   static std::unique_ptr<AssistantSidePanelCoordinator> Create(
       content::WebContents* web_contents);
 
-  virtual ~AssistantSidePanelCoordinator() = default;
-
-  // Returns true if a side panel entry is shown false otherwise.
+  // Returns `true` if a side panel entry is shown and `false` otherwise.
   virtual bool Shown() = 0;
 
-  // Sets the assistant side panel view.
-  // This method takes ownership of the view, returning a pointer to it
-  // which can be used for later updates.
-  virtual views::View* SetView(std::unique_ptr<views::View> view) = 0;
-
-  // Gets the current view rendered in the side panel. Returns null if the side
-  // panel is hidden or no view has been set.
-  virtual views::View* GetView() = 0;
-
-  // Removes the current view rendered in the side panel and destroys it.
-  virtual void RemoveView() = 0;
-
   // Add an observer to the assistant side panel. Useful for listening to the
   // side panel being hidden.
-  virtual void AddObserver(SidePanelEntryObserver* observer) = 0;
+  virtual void AddObserver(Observer* observer) = 0;
+
+  // Removes an observer of the assistant side panel.
+  virtual void RemoveObserver(Observer* observer) = 0;
 };
 #endif  // CHROME_BROWSER_UI_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_ASSISTANT_SIDE_PANEL_COORDINATOR_H_
diff --git a/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_controller.h b/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_controller.h
index ed690f68..56d8f5e 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_controller.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_controller.h
@@ -22,6 +22,7 @@
   MOCK_METHOD(void, OnAccept, (), (override));
   MOCK_METHOD(void, OnCancel, (), (override));
   MOCK_METHOD(void, OnClose, (), (override));
+  MOCK_METHOD(void, OnLearnMoreClicked, (), (override));
   MOCK_METHOD(const AssistantOnboardingInformation&,
               GetOnboardingInformation,
               (),
diff --git a/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_prompt.h b/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_prompt.h
index bf103ee0..65f0affc 100644
--- a/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_prompt.h
+++ b/chrome/browser/ui/autofill_assistant/password_change/mock_assistant_onboarding_prompt.h
@@ -9,13 +9,17 @@
 #include "chrome/browser/ui/autofill_assistant/password_change/assistant_onboarding_prompt.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
+namespace content {
+class WebContents;
+}  // namespace content
+
 // Mocked AssistantOnboardingPrompt used in unit tests.
 class MockAssistantOnboardingPrompt : public AssistantOnboardingPrompt {
  public:
   MockAssistantOnboardingPrompt();
   ~MockAssistantOnboardingPrompt() override;
 
-  MOCK_METHOD(void, Show, (), (override));
+  MOCK_METHOD(void, Show, (content::WebContents*), (override));
   MOCK_METHOD(void, OnControllerGone, (), (override));
 
   base::WeakPtr<AssistantOnboardingPrompt> GetWeakPtr() {
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.cc b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.cc
index 23702f2..ff5f69f4 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.cc
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.cc
@@ -27,6 +27,10 @@
 #include "ui/views/style/typography.h"
 #include "ui/views/view_class_properties.h"
 
+namespace content {
+class WebContents;
+}  // namespace content
+
 namespace {
 
 // Ratios of element width and dialog width.
@@ -42,26 +46,24 @@
 
 // Factory function to create onboarding prompts on desktop platforms.
 base::WeakPtr<AssistantOnboardingPrompt> AssistantOnboardingPrompt::Create(
-    base::WeakPtr<AssistantOnboardingController> controller,
-    content::WebContents* web_contents) {
-  return (new AssistantOnboardingView(controller, web_contents))->GetWeakPtr();
+    base::WeakPtr<AssistantOnboardingController> controller) {
+  return (new AssistantOnboardingView(controller))->GetWeakPtr();
 }
 
 AssistantOnboardingView::AssistantOnboardingView(
-    base::WeakPtr<AssistantOnboardingController> controller,
-    content::WebContents* web_contents)
-    : controller_(controller), web_contents_(web_contents) {
+    base::WeakPtr<AssistantOnboardingController> controller)
+    : controller_(controller) {
   DCHECK(controller_);
 }
 
 AssistantOnboardingView::~AssistantOnboardingView() = default;
 
-void AssistantOnboardingView::Show() {
+void AssistantOnboardingView::Show(content::WebContents* web_contents) {
   DCHECK(controller_);
 
   InitDelegate();
   InitDialog();
-  constrained_window::ShowWebModalDialogViews(this, web_contents_);
+  constrained_window::ShowWebModalDialogViews(this, web_contents);
 }
 
 void AssistantOnboardingView::OnControllerGone() {
@@ -169,10 +171,9 @@
   std::u16string consent_text = base::ReplaceStringPlaceholders(
       controller_->GetOnboardingInformation().consent_text,
       controller_->GetOnboardingInformation().learn_more_title, &offset);
-  // TODO(crbug.com/1322387): Add proper callback to controller.
   views::StyledLabel::RangeStyleInfo link_style =
-      views::StyledLabel::RangeStyleInfo::CreateForLink(
-          base::DoNothingAs<void()>());
+      views::StyledLabel::RangeStyleInfo::CreateForLink(base::BindRepeating(
+          &AssistantOnboardingController::OnLearnMoreClicked, controller_));
 
   // The actual consent text with the "Learn more" link.
   AddChildView(
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.h b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.h
index cfaa016..edb1f60 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.h
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view.h
@@ -40,16 +40,15 @@
     CONSENT_TEXT,
   };
 
-  AssistantOnboardingView(
-      base::WeakPtr<AssistantOnboardingController> controller,
-      content::WebContents* web_contents);
+  explicit AssistantOnboardingView(
+      base::WeakPtr<AssistantOnboardingController> controller);
   ~AssistantOnboardingView() override;
 
   AssistantOnboardingView(const AssistantOnboardingView&) = delete;
   AssistantOnboardingView& operator=(const AssistantOnboardingView&) = delete;
 
   // AssistantOnboardingPrompt:
-  void Show() override;
+  void Show(content::WebContents* web_contents) override;
   void OnControllerGone() override;
 
   // Returns a weak pointer to itself.
@@ -65,9 +64,6 @@
   // The controller belonging to this view.
   base::WeakPtr<AssistantOnboardingController> controller_;
 
-  // The `WebContents` for which the dialog is supposed to show.
-  raw_ptr<content::WebContents> web_contents_;
-
   // Factory for weak pointers to this view.
   base::WeakPtrFactory<AssistantOnboardingView> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view_browsertest.cc b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view_browsertest.cc
index 551571a..b331305 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view_browsertest.cc
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_onboarding_view_browsertest.cc
@@ -61,12 +61,11 @@
 
   // Creates controller and view and calls their `Show()` method.
   void ShowUi(const std::string& name) override {
-    controller_ = AssistantOnboardingController::Create(model_);
+    controller_ = AssistantOnboardingController::Create(
+        model_, browser()->tab_strip_model()->GetActiveWebContents());
     // We do not use the factory function here to test `AssistantOnboardingView`
     // directly.
-    view_ = new AssistantOnboardingView(
-        controller()->GetWeakPtr(),
-        browser()->tab_strip_model()->GetActiveWebContents());
+    view_ = new AssistantOnboardingView(controller()->GetWeakPtr());
     controller()->Show(prompt(), callback().Get());
   }
 
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.cc b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.cc
index 00c67729..f93275b 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.cc
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.cc
@@ -36,7 +36,12 @@
           base::BindRepeating(
               &AssistantSidePanelCoordinatorImpl::CreateSidePanelView,
               base::Unretained(this))));
-  AddObserver(this);
+
+  // Listen to `OnEntryHidden` events to be able to propagate them outside.
+  GetSidePanelRegistry()
+      ->GetEntryForId(SidePanelEntry::Id::kAssistant)
+      ->AddObserver(this);
+
   GetSidePanelCoordinator()->Show(SidePanelEntry::Id::kAssistant);
 }
 
@@ -83,15 +88,19 @@
   side_panel_view_host_->RemoveAllChildViews();
 }
 
-void AssistantSidePanelCoordinatorImpl::AddObserver(
-    SidePanelEntryObserver* observer) {
-  GetSidePanelRegistry()
-      ->GetEntryForId(SidePanelEntry::Id::kAssistant)
-      ->AddObserver(observer);
+void AssistantSidePanelCoordinatorImpl::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void AssistantSidePanelCoordinatorImpl::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
 }
 
 void AssistantSidePanelCoordinatorImpl::OnEntryHidden(SidePanelEntry* entry) {
   side_panel_view_host_ = nullptr;
+
+  for (Observer& observer : observers_)
+    observer.OnHidden();
 }
 
 std::unique_ptr<views::View>
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.h b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.h
index 4ff29c6..ded144c 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.h
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_ASSISTANT_SIDE_PANEL_COORDINATOR_IMPL_H_
 
 #include "base/memory/raw_ptr.h"
+#include "base/observer_list.h"
 #include "chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h"
 
@@ -23,14 +24,22 @@
       const AssistantSidePanelCoordinatorImpl&) = delete;
   ~AssistantSidePanelCoordinatorImpl() override;
 
-  // AssistantSidePanelCoordinator
-  bool Shown() override;
+  // AssistantDisplayDelegate:
+  // Sets the Assistant side panel view. This method takes ownership of the view
+  // and returns a pointer to it, which can be used for later updates.
   views::View* SetView(std::unique_ptr<views::View> view) override;
+  // Gets the current view rendered in the side panel. Returns `nullptr` if the
+  // side panel is hidden or no view has been set.
   views::View* GetView() override;
+  // Removes the current view rendered in the side panel and destroys it.
   void RemoveView() override;
-  void AddObserver(SidePanelEntryObserver* observer) override;
 
-  // SidePanelEntryObserver
+  // AssistantSidePanelCoordinator:
+  bool Shown() override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+
+  // SidePanelEntryObserver:
   void OnEntryHidden(SidePanelEntry* entry) override;
 
  private:
@@ -44,6 +53,9 @@
   std::unique_ptr<views::View> side_panel_view_child_ = nullptr;
 
   raw_ptr<content::WebContents> web_contents_;
+
+  // List of observers to the side panel.
+  base::ObserverList<Observer> observers_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_ASSISTANT_SIDE_PANEL_COORDINATOR_IMPL_H_
diff --git a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl_unittest.cc b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl_unittest.cc
index 1729c9c5..efc1a0d 100644
--- a/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl_unittest.cc
+++ b/chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl_unittest.cc
@@ -4,15 +4,28 @@
 
 #include "chrome/browser/ui/views/autofill_assistant/password_change/assistant_side_panel_coordinator_impl.h"
 
+#include <memory>
+
 #include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
+#include "chrome/browser/ui/autofill_assistant/password_change/assistant_side_panel_coordinator.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
 #include "content/public/browser/web_contents.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+class MockAssistantSidePanelObserver
+    : public AssistantSidePanelCoordinator::Observer {
+ public:
+  MockAssistantSidePanelObserver() = default;
+  ~MockAssistantSidePanelObserver() override = default;
+
+  MOCK_METHOD(void, OnHidden, (), (override));
+};
+
 class AssistantSidePanelCoordinatorImplTest : public TestWithBrowserView {
  public:
   void SetUp() override {
@@ -75,3 +88,22 @@
           browser_view()->GetActiveWebContents());
   EXPECT_EQ(nullptr, coordinator);
 }
+
+TEST_F(AssistantSidePanelCoordinatorImplTest,
+       AssistantSidePanelPropagatesOnHidden) {
+  // Since we are testing the implementation here, we can safely perform this
+  // cast.
+  AssistantSidePanelCoordinatorImpl* coordinator =
+      static_cast<AssistantSidePanelCoordinatorImpl*>(
+          assistant_side_panel_coordinator());
+  auto observer = std::make_unique<MockAssistantSidePanelObserver>();
+  coordinator->AddObserver(observer.get());
+
+  // Only a total of 1 call is expected.
+  EXPECT_CALL(*observer, OnHidden).Times(1);
+  coordinator->OnEntryHidden(nullptr);
+
+  coordinator->RemoveObserver(observer.get());
+  // This call does not get registered.
+  coordinator->OnEntryHidden(nullptr);
+}
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 865ac29..eabfda08 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -16,6 +16,7 @@
 #include "ash/public/cpp/style/scoped_light_mode_as_default.h"
 #include "ash/public/cpp/tablet_mode.h"
 #include "base/feature_list.h"
+#include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
@@ -399,8 +400,13 @@
     // as |default_path| (crbug.com/178013 #9-#11). In such a case, we use the
     // last selected directory as a workaround. Real fix is tracked at
     // crbug.com/110119.
+    base::FilePath base_name = default_path.BaseName();
     if (!file_manager::util::ConvertAbsoluteFilePathToFileSystemUrl(
-            profile, fallback_path.Append(default_path.BaseName()),
+            profile,
+            // If the base_name is absolute (happens for default_path '/') it's
+            // not usable in Append.
+            base_name.IsAbsolute() ? fallback_path
+                                   : fallback_path.Append(base_name),
             file_manager::util::GetFileManagerURL(), &selection_url)) {
       DVLOG(1) << "Unable to resolve the selection URL.";
     }
diff --git a/chrome/browser/ui/webui/chromeos/OWNERS b/chrome/browser/ui/webui/chromeos/OWNERS
index fc87c56..0647ada 100644
--- a/chrome/browser/ui/webui/chromeos/OWNERS
+++ b/chrome/browser/ui/webui/chromeos/OWNERS
@@ -1,7 +1,7 @@
 achuith@chromium.org
+hidehiko@chromium.org
 khorimoto@chromium.org
 michaelpg@chromium.org
-satorux@chromium.org
 xiyuan@chromium.org
 
 per-file *bluetooth*=file://ui/webui/resources/cr_components/chromeos/bluetooth/OWNERS
diff --git a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler.cc b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler.cc
index 82d40ea..3b0c864 100644
--- a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler.cc
+++ b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler.cc
@@ -24,7 +24,9 @@
 #include "chrome/browser/ui/webui/management/management_ui_handler.h"
 #include "chrome/browser/ui/webui/signin/signin_utils.h"
 #include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
+#include "chrome/grit/google_chrome_strings.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
index 20120b5f..02572cd 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -243,6 +243,7 @@
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   std::string remove_warning_profile = l10n_util::GetStringFUTF8(
       IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_LACROS,
+      ui::GetChromeOSDeviceName(),
       l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE),
       l10n_util::GetStringUTF16(IDS_OS_SETTINGS_PEOPLE_V2));
   html_source->AddString("removeWarningProfileLacros", remove_warning_profile);
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
index 5018b41..f5c56f4 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
@@ -513,8 +513,16 @@
 }
 
 TEST_F(PreinstalledWebAppManagerTest, GuestUser) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // App service is available for OTR profile in Guest mode.
+  auto primary_profile = CreateGuestProfileAndLogin();
+  auto* otr_profile =
+      primary_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+  VerifySetOfApps(otr_profile, {GURL(kAppAllUrl), GURL(kAppGuestUrl)});
+#else
   VerifySetOfApps(CreateGuestProfileAndLogin().get(),
                   {GURL(kAppAllUrl), GURL(kAppGuestUrl)});
+#endif
 }
 
 TEST_F(PreinstalledWebAppManagerTest, UnmanagedUser) {
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc
index f85e875b..b1d7e351 100644
--- a/chrome/browser/web_applications/web_app_provider.cc
+++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -120,9 +120,15 @@
 
 WebAppProvider::WebAppProvider(Profile* profile) : profile_(profile) {
   DCHECK(AreWebAppsEnabled(profile_));
+
   // WebApp System must have only one instance in original profile.
   // Exclude secondary off-the-record profiles.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  if (!profile_->IsGuestSession())
+    DCHECK(!profile_->IsOffTheRecord());
+#else
   DCHECK(!profile_->IsOffTheRecord());
+#endif
 
   CreateSubsystems(profile_);
 }
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index 5b7c85a2..3f0288b 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -143,7 +143,17 @@
     return nullptr;
   }
   Profile* original_profile = profile->GetOriginalProfile();
-  return AreWebAppsEnabled(original_profile) ? original_profile : nullptr;
+  if (!AreWebAppsEnabled(original_profile))
+    return nullptr;
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Use OTR profile for Guest Session.
+  if (profile->IsGuestSession()) {
+    return profile->IsOffTheRecord() ? profile : nullptr;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+  return original_profile;
 }
 
 content::BrowserContext* GetBrowserContextForWebAppMetrics(
diff --git a/chrome/browser/web_applications/web_app_utils_unittest.cc b/chrome/browser/web_applications/web_app_utils_unittest.cc
index 3a21662..267e551 100644
--- a/chrome/browser/web_applications/web_app_utils_unittest.cc
+++ b/chrome/browser/web_applications/web_app_utils_unittest.cc
@@ -176,6 +176,10 @@
   ASSERT_TRUE(profile_manager.SetUp());
 
   Profile* guest_profile = profile_manager.CreateGuestProfile();
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  guest_profile =
+      guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   EXPECT_EQ(guest_profile, GetBrowserContextForWebApps(guest_profile));
   EXPECT_EQ(guest_profile,
             GetBrowserContextForWebApps(guest_profile->GetPrimaryOTRProfile(
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 11afd79..3a4ca25 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1653328714-4906953a7ad7d9c52bc1f006772753e140aa6704.profdata
+chrome-linux-main-1653372000-369d2b350746f8de30ff0da2a9920fb5618ebce4.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 8f70f46..8b91df6 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1653350081-1c0a98e421257f7c4776ea641a9b422055b0f269.profdata
+chrome-mac-arm-main-1653372000-1fb762fde777b1a811cbad5b1ca2e7a823969ab2.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 65c17a80..09f91110 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1653350081-aa26db6ceda32af91f980cc1855a3bae8404b862.profdata
+chrome-mac-main-1653372000-62b6aaf954233d89b297dbfb37a01c67c0246d1d.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index c81c1d4..da01270d 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1653339533-1ba2d0b528c52342f22d0b2fd1b953b262a2f221.profdata
+chrome-win32-main-1653382738-742a60945714f64ef266750d3991ab1380356c5e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 12371159..31b0144 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1653339533-7331fa8c301cbd38c5bf96f212974548681fca3d.profdata
+chrome-win64-main-1653382738-168df4e4d69e2d379efc58f09a14452741d8c013.profdata
diff --git a/chrome/chrome_cleaner/DEPS b/chrome/chrome_cleaner/DEPS
index 034833c..f69b764 100644
--- a/chrome/chrome_cleaner/DEPS
+++ b/chrome/chrome_cleaner/DEPS
@@ -9,7 +9,6 @@
   "+mojo/public",
   "+sandbox/win/src",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/protobuf/src/google/protobuf",
   "+url",
 ]
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 14a132b..14eddaff 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -803,7 +803,7 @@
     "PrerenderFallbackToPreconnect", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kPrivacyGuide{"PrivacyGuide",
-                                  base::FEATURE_DISABLED_BY_DEFAULT};
+                                  base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kPrivacyGuide2{"PrivacyGuide2",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9c00f3e9..1f9c6d40 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2069,6 +2069,7 @@
       "../browser/ui/autofill/payments/save_card_bubble_controller_impl_browsertest.cc",
       "../browser/ui/autofill/payments/save_upi_bubble_controller_impl_browsertest.cc",
       "../browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc",
+      "../browser/ui/autofill_assistant/password_change/assistant_onboarding_controller_impl_browsertest.cc",
       "../browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc",
       "../browser/ui/blocked_content/popup_tracker_browsertest.cc",
       "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 61dcbea5..c1dac0fa 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -877,11 +877,21 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 policy::ProfilePolicyConnector* TestingProfile::GetProfilePolicyConnector() {
+  // This matches OffTheRecordProfileImpl::GetProfilePolicyConnector()
+  // implementation.
+  if (IsOffTheRecord())
+    return original_profile_->GetProfilePolicyConnector();
+
   return profile_policy_connector_.get();
 }
 
 const policy::ProfilePolicyConnector*
 TestingProfile::GetProfilePolicyConnector() const {
+  // This matches OffTheRecordProfileImpl::GetProfilePolicyConnector()
+  // implementation.
+  if (IsOffTheRecord())
+    return original_profile_->GetProfilePolicyConnector();
+
   return profile_policy_connector_.get();
 }
 
diff --git a/chrome/test/data/extensions/api_test/tab_capture/constraints/constraints.js b/chrome/test/data/extensions/api_test/tab_capture/constraints/constraints.js
index 5bfa3ed..11f0b49c 100644
--- a/chrome/test/data/extensions/api_test/tab_capture/constraints/constraints.js
+++ b/chrome/test/data/extensions/api_test/tab_capture/constraints/constraints.js
@@ -48,7 +48,7 @@
     });
   },
 
-  function rejectsInvalidConstraints() {
+  function ignoresInvalidConstraints() {
     chrome.tabCapture.capture({
       video: true,
       audio: true,
@@ -58,21 +58,10 @@
         }
       }
     }, function(stream) {
-      assertBindingsPassedWebKitErrorMessage();
-      chrome.test.assertTrue(!stream);
-
-      chrome.tabCapture.capture({
-        audio: true,
-        audioConstraints: {
-          mandatory: {
-            notValid: '123'
-          }
-        }
-      }, function(stream) {
-        assertBindingsPassedWebKitErrorMessage();
-        chrome.test.assertTrue(!stream);
-        chrome.test.succeed();
-      });
+      chrome.test.assertTrue(!!stream);
+      stream.getVideoTracks()[0].stop();
+      stream.getAudioTracks()[0].stop();
+      chrome.test.succeed();
     });
   }
 ]);
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_landing_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_landing_page_test.js
index 62bc7492..af6b662 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_landing_page_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_landing_page_test.js
@@ -175,18 +175,18 @@
         component.shadowRoot.querySelector('#dialogBody').textContent.trim());
   });
 
-  test('OnBoardingPageCancelButtonDispatchesCancelEvent', async () => {
+  test('OnBoardingPageExitButtonDispatchesExitEvent', async () => {
     await initializeLandingPage();
 
-    let cancelButtonEventFired = false;
-    component.addEventListener('click-cancel-button', (e) => {
-      cancelButtonEventFired = true;
+    let exitButtonEventFired = false;
+    component.addEventListener('click-exit-button', (e) => {
+      exitButtonEventFired = true;
     });
 
-    await clickButton('#landingCancel');
+    await clickButton('#landingExit');
     await flushTasks();
 
-    assertTrue(cancelButtonEventFired);
+    assertTrue(exitButtonEventFired);
   });
 
   test(
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_calibration_failed_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_calibration_failed_page_test.js
index 153e2895..2e30e36 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/reimaging_calibration_failed_page_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/reimaging_calibration_failed_page_test.js
@@ -142,7 +142,7 @@
         CalibrationStatus.kCalibrationSkip, getComponentsList()[0].status);
   });
 
-  test('CancelButtonTriggersCalibrationComplete', async () => {
+  test('ExitButtonTriggersCalibrationComplete', async () => {
     const resolver = new PromiseResolver();
     await initializeCalibrationPage(fakeCalibrationComponentsWithoutFails);
     let startCalibrationCalls = 0;
@@ -158,7 +158,7 @@
 
     const expectedResult = {foo: 'bar'};
     let savedResult;
-    component.onCancelButtonClick().then((result) => savedResult = result);
+    component.onExitButtonClick().then((result) => savedResult = result);
     // Resolve to a distinct result to confirm it was not modified.
     resolver.resolve(expectedResult);
     await flushTasks();
@@ -215,7 +215,7 @@
     await initializeCalibrationPage(fakeCalibrationComponentsWithFails);
 
     let wasPromiseRejected = false;
-    component.onCancelButtonClick()
+    component.onExitButtonClick()
         .then(() => assertNotReached('Do not proceed with failed components'))
         .catch(() => {
           wasPromiseRejected = true;
@@ -235,7 +235,7 @@
       return resolver.promise;
     };
 
-    component.onCancelButtonClick().catch(() => {});
+    component.onExitButtonClick().catch(() => {});
 
     await flushTasks();
     assertEquals(0, startCalibrationCalls);
@@ -259,7 +259,7 @@
       return resolver.promise;
     };
 
-    component.onCancelButtonClick().catch(() => {});
+    component.onExitButtonClick().catch(() => {});
 
     await flushTasks();
     assertEquals(0, startCalibrationCalls);
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
index c6f173d..8b93d1f 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
@@ -63,10 +63,10 @@
    */
   function assertNavButtons() {
     const nextButton = component.shadowRoot.querySelector('#next');
-    const prevButton = component.shadowRoot.querySelector('#cancel');
+    const exitButton = component.shadowRoot.querySelector('#exit');
     const backButton = component.shadowRoot.querySelector('#back');
     assertTrue(!!nextButton);
-    assertTrue(!!prevButton);
+    assertTrue(!!exitButton);
     assertTrue(!!backButton);
   }
 
@@ -96,12 +96,12 @@
   }
 
   /**
-   * Utility function to click cancel button
+   * Utility function to click exit button
    * @return {Promise}
    */
-  function clickCancel() {
-    const cancelButton = component.shadowRoot.querySelector('#cancel');
-    cancelButton.click();
+  function clickExit() {
+    const exitButton = component.shadowRoot.querySelector('#exit');
+    exitButton.click();
     return flushTasks();
   }
 
@@ -114,9 +114,9 @@
     await initializeShimlessRMAApp(fakeStates, fakeChromeVersion[0]);
 
     const prevButton = component.shadowRoot.querySelector('#back');
-    const cancelButton = component.shadowRoot.querySelector('#cancel');
+    const exitButton = component.shadowRoot.querySelector('#exit');
     assertTrue(!!prevButton);
-    assertTrue(!!cancelButton);
+    assertTrue(!!exitButton);
 
     const initialPage =
         component.shadowRoot.querySelector('onboarding-landing-page');
@@ -124,7 +124,7 @@
     assertFalse(initialPage.hidden);
     assertFalse(initialPage.allButtonsDisabled);
     assertTrue(prevButton.hidden);
-    assertTrue(cancelButton.hidden);
+    assertTrue(exitButton.hidden);
 
     // This enables the next button on the landing page.
     service.triggerHardwareVerificationStatusObserver(true, '', 0);
@@ -138,7 +138,7 @@
     assertTrue(!!initialPage);
     assertTrue(initialPage.hidden);
     assertFalse(prevButton.hidden);
-    assertFalse(cancelButton.hidden);
+    assertFalse(exitButton.hidden);
 
     prevButton.click();
     await flushTasks();
@@ -148,10 +148,10 @@
     assertTrue(selectNetworkPage.hidden);
     assertFalse(initialPage.hidden);
     assertTrue(prevButton.hidden);
-    assertTrue(cancelButton.hidden);
+    assertTrue(exitButton.hidden);
   });
 
-  test('ShimlessRMACancellation', async () => {
+  test('ShimlessRMAExit', async () => {
     await initializeShimlessRMAApp(fakeStates, fakeChromeVersion[0]);
     let abortRmaCount = 0;
     service.abortRma = () => {
@@ -160,10 +160,10 @@
     };
     const initialPage =
         component.shadowRoot.querySelector('onboarding-landing-page');
-    const cancelButton = component.shadowRoot.querySelector('#cancel');
+    const exitButton = component.shadowRoot.querySelector('#exit');
 
     assertFalse(initialPage.allButtonsDisabled);
-    cancelButton.click();
+    exitButton.click();
     await flushTasks();
 
     assertEquals(1, abortRmaCount);
@@ -270,27 +270,27 @@
         component.shadowRoot.querySelector('#nextButtonSpinner');
     const backButtonSpinner =
         component.shadowRoot.querySelector('#backButtonSpinner');
-    const cancelButtonSpinner =
-        component.shadowRoot.querySelector('#cancelButtonSpinner');
+    const exitButtonSpinner =
+        component.shadowRoot.querySelector('#exitButtonSpinner');
 
     // Next spinner
     const nextResolver = new PromiseResolver();
     initialPage.onNextButtonClick = () => nextResolver.promise;
     assertTrue(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
 
     await clickNext();
     assertFalse(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
 
     nextResolver.resolve({state: State.kUpdateOs, error: RmadErrorCode.kOk});
     await flushTasks();
 
     assertTrue(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
   });
 
   test('BackButtonSpinner', async () => {
@@ -311,8 +311,8 @@
         component.shadowRoot.querySelector('#nextButtonSpinner');
     const backButtonSpinner =
         component.shadowRoot.querySelector('#backButtonSpinner');
-    const cancelButtonSpinner =
-        component.shadowRoot.querySelector('#cancelButtonSpinner');
+    const exitButtonSpinner =
+        component.shadowRoot.querySelector('#exitButtonSpinner');
 
     // Back spinner
     const backResolver = new PromiseResolver();
@@ -322,16 +322,16 @@
     await clickBack();
     assertTrue(nextButtonSpinner.hidden);
     assertFalse(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
 
     backResolver.resolve({state: State.kUpdateOs, error: RmadErrorCode.kOk});
     await flushTasks();
     assertTrue(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
   });
 
-  test('CancelButtonSpinner', async () => {
+  test('ExitButtonSpinner', async () => {
     await initializeShimlessRMAApp(
         [{
           state: State.kSelectComponents,
@@ -349,24 +349,24 @@
         component.shadowRoot.querySelector('#nextButtonSpinner');
     const backButtonSpinner =
         component.shadowRoot.querySelector('#backButtonSpinner');
-    const cancelButtonSpinner =
-        component.shadowRoot.querySelector('#cancelButtonSpinner');
+    const exitButtonSpinner =
+        component.shadowRoot.querySelector('#exitButtonSpinner');
 
-    // Cancel spinner
-    const cancelResolver = new PromiseResolver();
+    // Exit spinner
+    const exitResolver = new PromiseResolver();
     service.abortRma = () => {
-      return cancelResolver.promise;
+      return exitResolver.promise;
     };
-    await clickCancel();
+    await clickExit();
     assertTrue(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertFalse(cancelButtonSpinner.hidden);
+    assertFalse(exitButtonSpinner.hidden);
 
-    cancelResolver.resolve({state: State.kUpdateOs, error: RmadErrorCode.kOk});
+    exitResolver.resolve({state: State.kUpdateOs, error: RmadErrorCode.kOk});
     await flushTasks();
     assertTrue(nextButtonSpinner.hidden);
     assertTrue(backButtonSpinner.hidden);
-    assertTrue(cancelButtonSpinner.hidden);
+    assertTrue(exitButtonSpinner.hidden);
   });
 
   test('AllButtonsDisabled', async () => {
@@ -374,18 +374,18 @@
 
     const nextButton = component.shadowRoot.querySelector('#next');
     const backButton = component.shadowRoot.querySelector('#back');
-    const cancelButton = component.shadowRoot.querySelector('#cancel');
+    const exitButton = component.shadowRoot.querySelector('#exit');
     const busyStateOverlay = /** @type {!HTMLElement} */ (
         component.shadowRoot.querySelector('#busyStateOverlay'));
 
     assertFalse(nextButton.disabled);
     assertFalse(backButton.disabled);
-    assertFalse(cancelButton.disabled);
+    assertFalse(exitButton.disabled);
 
     disableAllButtons(component, /*showBusyStateOverlay=*/ false);
     assertTrue(nextButton.disabled);
     assertTrue(backButton.disabled);
-    assertTrue(cancelButton.disabled);
+    assertTrue(exitButton.disabled);
     assertFalse(isVisible(busyStateOverlay));
 
     disableAllButtons(component, /*showBusyStateOverlay=*/ true);
@@ -394,11 +394,11 @@
     enableAllButtons(component);
     assertFalse(nextButton.disabled);
     assertFalse(backButton.disabled);
-    assertFalse(cancelButton.disabled);
+    assertFalse(exitButton.disabled);
     assertFalse(isVisible(busyStateOverlay));
   });
 
-  test('CancelButtonClickEventIsHandled', async () => {
+  test('ExitButtonClickEventIsHandled', async () => {
     const resolver = new PromiseResolver();
 
     await initializeShimlessRMAApp(
@@ -417,7 +417,7 @@
     };
 
     component.dispatchEvent(new CustomEvent(
-        'click-cancel-button',
+        'click-exit-button',
         {bubbles: true, composed: true},
         ));
 
diff --git a/chrome/test/data/webui/settings/password_view_test.ts b/chrome/test/data/webui/settings/password_view_test.ts
index 89a68f90..3ea2af1 100644
--- a/chrome/test/data/webui/settings/password_view_test.ts
+++ b/chrome/test/data/webui/settings/password_view_test.ts
@@ -75,24 +75,26 @@
     PasswordManagerImpl.setInstance(passwordManager);
   });
 
-  test('Valid site and username displays an entry', async function() {
-    const passwordList = [
-      createPasswordEntry({url: SITE, username: USERNAME, id: ID}),
-    ];
+  [{url: SITE, username: USERNAME}, {url: SITE, username: ''}].forEach(
+      item =>
+          test('Valid site and username displays an entry', async function() {
+            const passwordList = [
+              createPasswordEntry(
+                  {url: item.url, username: item.username, id: ID}),
+            ];
 
-    passwordManager.setPlaintextPassword(PASSWORD);
-    passwordManager.data.passwords = passwordList;
-    const page = document.createElement('password-view');
-    document.body.appendChild(page);
-    const params = new URLSearchParams({
-      username: USERNAME,
-      site: SITE,
-    });
-    Router.getInstance().navigateTo(routes.PASSWORD_VIEW, params);
+            passwordManager.data.passwords = passwordList;
+            const page = document.createElement('password-view');
+            document.body.appendChild(page);
+            const params = new URLSearchParams({
+              username: item.username,
+              site: item.url,
+            });
+            Router.getInstance().navigateTo(routes.PASSWORD_VIEW, params);
 
-    await flushTasks();
-    assertVisibilityOfPageElements(page, /*visibility=*/ true);
-  });
+            await flushTasks();
+            assertVisibilityOfPageElements(page, /*visibility=*/ true);
+          }));
 
   test(
       'Invalid site and username does not display an entry ' +
diff --git a/chromeos/ash/components/dbus/DEPS b/chromeos/ash/components/dbus/DEPS
index ca7d39f..6e1f8ee2 100644
--- a/chromeos/ash/components/dbus/DEPS
+++ b/chromeos/ash/components/dbus/DEPS
@@ -7,7 +7,6 @@
   "+components/policy/proto",
   "+dbus",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
 
   # TODO(crbug.com/1164001): Remove after chromeos/dbus migration is done.
diff --git a/chromeos/ash/components/network/DEPS b/chromeos/ash/components/network/DEPS
index 8a79fee..478fcd0 100644
--- a/chromeos/ash/components/network/DEPS
+++ b/chromeos/ash/components/network/DEPS
@@ -13,6 +13,7 @@
   "+chromeos/components/feature_usage",
   "+chromeos/components/onc",
   "+chromeos/login/login_state",
+  "+chromeos/network",
   "+chromeos/services/network_config/public",
   "+components/account_id",
   "+components/certificate_matching",
@@ -29,7 +30,6 @@
   "+net",
   "+services/preferences/public/cpp",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
   "+url",
 ]
diff --git a/chromeos/ash/components/network/metrics/BUILD.gn b/chromeos/ash/components/network/metrics/BUILD.gn
new file mode 100644
index 0000000..8783043
--- /dev/null
+++ b/chromeos/ash/components/network/metrics/BUILD.gn
@@ -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.
+
+import("//build/config/chromeos/ui_mode.gni")
+
+assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //chromeos/ash")
+
+source_set("metrics") {
+  # Due to circular dependency, others should depend on via chromeos/network.
+  visibility = [ "//chromeos/network" ]
+
+  configs += [ "//chromeos/network:network_config" ]
+  deps = [
+    "//base",
+    "//chromeos/login/login_state",
+    "//chromeos/services/network_config/public/mojom",
+  ]
+  sources = [
+    "connection_info_metrics_logger.cc",
+    "connection_info_metrics_logger.h",
+    "connection_results.cc",
+    "connection_results.h",
+    "esim_policy_login_metrics_logger.cc",
+    "esim_policy_login_metrics_logger.h",
+    "network_metrics_helper.cc",
+    "network_metrics_helper.h",
+    "vpn_network_metrics_helper.cc",
+    "vpn_network_metrics_helper.h",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  deps = [
+    "//ash/constants",
+    "//base",
+    "//base/test:test_support",
+    "//chromeos/dbus/shill",
+    "//chromeos/login/login_state",
+    "//chromeos/network",
+    "//chromeos/network:test_support",
+    "//components/prefs",
+    "//components/prefs:test_support",
+    "//testing/gtest",
+  ]
+  sources = [
+    "connection_info_metrics_logger_unittest.cc",
+    "esim_policy_login_metrics_logger_unittest.cc",
+    "network_metrics_helper_unittest.cc",
+    "vpn_network_metrics_helper_unittest.cc",
+  ]
+}
diff --git a/chromeos/network/metrics/connection_info_metrics_logger.cc b/chromeos/ash/components/network/metrics/connection_info_metrics_logger.cc
similarity index 97%
rename from chromeos/network/metrics/connection_info_metrics_logger.cc
rename to chromeos/ash/components/network/metrics/connection_info_metrics_logger.cc
index fb24364d..de4fb0d 100644
--- a/chromeos/network/metrics/connection_info_metrics_logger.cc
+++ b/chromeos/ash/components/network/metrics/connection_info_metrics_logger.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/connection_info_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/connection_info_metrics_logger.h"
 
 #include "base/containers/contains.h"
 #include "base/containers/flat_set.h"
-#include "chromeos/network/metrics/network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 #include "chromeos/network/network_connection_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
diff --git a/chromeos/network/metrics/connection_info_metrics_logger.h b/chromeos/ash/components/network/metrics/connection_info_metrics_logger.h
similarity index 92%
rename from chromeos/network/metrics/connection_info_metrics_logger.h
rename to chromeos/ash/components/network/metrics/connection_info_metrics_logger.h
index 25024ec..094afb5 100644
--- a/chromeos/network/metrics/connection_info_metrics_logger.h
+++ b/chromeos/ash/components/network/metrics/connection_info_metrics_logger.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
-#define CHROMEOS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
 
 #include "base/component_export.h"
 #include "base/containers/flat_map.h"
@@ -97,4 +97,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_INFO_METRICS_LOGGER_H_
diff --git a/chromeos/network/metrics/connection_info_metrics_logger_unittest.cc b/chromeos/ash/components/network/metrics/connection_info_metrics_logger_unittest.cc
similarity index 97%
rename from chromeos/network/metrics/connection_info_metrics_logger_unittest.cc
rename to chromeos/ash/components/network/metrics/connection_info_metrics_logger_unittest.cc
index 44b3355..fdf3064 100644
--- a/chromeos/network/metrics/connection_info_metrics_logger_unittest.cc
+++ b/chromeos/ash/components/network/metrics/connection_info_metrics_logger_unittest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/connection_info_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/connection_info_metrics_logger.h"
 
 #include <memory>
 
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
+#include "chromeos/ash/components/network/metrics/connection_results.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
-#include "chromeos/network/metrics/connection_results.h"
-#include "chromeos/network/metrics/network_metrics_helper.h"
 #include "chromeos/network/network_connection_handler.h"
 #include "chromeos/network/network_handler_test_helper.h"
 #include "chromeos/network/network_state_handler.h"
diff --git a/chromeos/network/metrics/connection_results.cc b/chromeos/ash/components/network/metrics/connection_results.cc
similarity index 98%
rename from chromeos/network/metrics/connection_results.cc
rename to chromeos/ash/components/network/metrics/connection_results.cc
index 655db4b..b6341bec 100644
--- a/chromeos/network/metrics/connection_results.cc
+++ b/chromeos/ash/components/network/metrics/connection_results.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/connection_results.h"
+#include "chromeos/ash/components/network/metrics/connection_results.h"
 
 #include "chromeos/network/network_connection_handler.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/chromeos/network/metrics/connection_results.h b/chromeos/ash/components/network/metrics/connection_results.h
similarity index 94%
rename from chromeos/network/metrics/connection_results.h
rename to chromeos/ash/components/network/metrics/connection_results.h
index 62c27fed..d3ce89a 100644
--- a/chromeos/network/metrics/connection_results.h
+++ b/chromeos/ash/components/network/metrics/connection_results.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_NETWORK_METRICS_CONNECTION_RESULTS_H_
-#define CHROMEOS_NETWORK_METRICS_CONNECTION_RESULTS_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_RESULTS_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_RESULTS_H_
 
 #include <string>
 
@@ -133,4 +133,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_NETWORK_METRICS_CONNECTION_RESULTS_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_CONNECTION_RESULTS_H_
diff --git a/chromeos/network/metrics/esim_policy_login_metrics_logger.cc b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.cc
similarity index 98%
rename from chromeos/network/metrics/esim_policy_login_metrics_logger.cc
rename to chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.cc
index c424e632..4435c3d 100644
--- a/chromeos/network/metrics/esim_policy_login_metrics_logger.cc
+++ b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/esim_policy_login_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h"
 
 #include "base/metrics/histogram_macros.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
diff --git a/chromeos/network/metrics/esim_policy_login_metrics_logger.h b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h
similarity index 94%
rename from chromeos/network/metrics/esim_policy_login_metrics_logger.h
rename to chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h
index 1ea2fd4..e9c8937 100644
--- a/chromeos/network/metrics/esim_policy_login_metrics_logger.h
+++ b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
-#define CHROMEOS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
 
 #include "base/component_export.h"
 #include "base/gtest_prod_util.h"
@@ -115,4 +115,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_ESIM_POLICY_LOGIN_METRICS_LOGGER_H_
diff --git a/chromeos/network/metrics/esim_policy_login_metrics_logger_unittest.cc b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger_unittest.cc
similarity index 98%
rename from chromeos/network/metrics/esim_policy_login_metrics_logger_unittest.cc
rename to chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger_unittest.cc
index d7d10af2..bc57ae89 100644
--- a/chromeos/network/metrics/esim_policy_login_metrics_logger_unittest.cc
+++ b/chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/esim_policy_login_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/run_loop.h"
diff --git a/chromeos/network/metrics/network_metrics_helper.cc b/chromeos/ash/components/network/metrics/network_metrics_helper.cc
similarity index 98%
rename from chromeos/network/metrics/network_metrics_helper.cc
rename to chromeos/ash/components/network/metrics/network_metrics_helper.cc
index 37d25e4d..aa394dc 100644
--- a/chromeos/network/metrics/network_metrics_helper.cc
+++ b/chromeos/ash/components/network/metrics/network_metrics_helper.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 
 #include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
-#include "chromeos/network/metrics/connection_results.h"
+#include "chromeos/ash/components/network/metrics/connection_results.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
diff --git a/chromeos/network/metrics/network_metrics_helper.h b/chromeos/ash/components/network/metrics/network_metrics_helper.h
similarity index 90%
rename from chromeos/network/metrics/network_metrics_helper.h
rename to chromeos/ash/components/network/metrics/network_metrics_helper.h
index d8f398f..482de9a 100644
--- a/chromeos/network/metrics/network_metrics_helper.h
+++ b/chromeos/ash/components/network/metrics/network_metrics_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
-#define CHROMEOS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
 
 #include "base/component_export.h"
 #include "chromeos/network/network_state_handler.h"
@@ -61,4 +61,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_NETWORK_METRICS_HELPER_H_
diff --git a/chromeos/network/metrics/network_metrics_helper_unittest.cc b/chromeos/ash/components/network/metrics/network_metrics_helper_unittest.cc
similarity index 99%
rename from chromeos/network/metrics/network_metrics_helper_unittest.cc
rename to chromeos/ash/components/network/metrics/network_metrics_helper_unittest.cc
index d8b0521..798ad8e 100644
--- a/chromeos/network/metrics/network_metrics_helper_unittest.cc
+++ b/chromeos/ash/components/network/metrics/network_metrics_helper_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 
 #include <memory>
 
diff --git a/chromeos/network/metrics/vpn_network_metrics_helper.cc b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper.cc
similarity index 95%
rename from chromeos/network/metrics/vpn_network_metrics_helper.cc
rename to chromeos/ash/components/network/metrics/vpn_network_metrics_helper.cc
index 94e429b..b88e309 100644
--- a/chromeos/network/metrics/vpn_network_metrics_helper.cc
+++ b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/vpn_network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h"
 
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
-#include "chromeos/network/metrics/network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
diff --git a/chromeos/network/metrics/vpn_network_metrics_helper.h b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h
similarity index 88%
rename from chromeos/network/metrics/vpn_network_metrics_helper.h
rename to chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h
index 27c448a..ef99aba7 100644
--- a/chromeos/network/metrics/vpn_network_metrics_helper.h
+++ b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
-#define CHROMEOS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
+#define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
 
 #include <string>
 
@@ -50,4 +50,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_VPN_NETWORK_METRICS_HELPER_H_
diff --git a/chromeos/network/metrics/vpn_network_metrics_helper_unittest.cc b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper_unittest.cc
similarity index 98%
rename from chromeos/network/metrics/vpn_network_metrics_helper_unittest.cc
rename to chromeos/ash/components/network/metrics/vpn_network_metrics_helper_unittest.cc
index e5bae2d..c424bfb 100644
--- a/chromeos/network/metrics/vpn_network_metrics_helper_unittest.cc
+++ b/chromeos/ash/components/network/metrics/vpn_network_metrics_helper_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/metrics/vpn_network_metrics_helper.h"
+#include "chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h"
 
 #include <memory>
 #include <utility>
diff --git a/chromeos/components/onc/DEPS b/chromeos/components/onc/DEPS
index d858bd02..8567161 100644
--- a/chromeos/components/onc/DEPS
+++ b/chromeos/components/onc/DEPS
@@ -8,5 +8,4 @@
   "+crypto",
   "+net",
   "+testing",
-  "+third_party/abseil-cpp/absl",
 ]
diff --git a/chromeos/dbus/DEPS b/chromeos/dbus/DEPS
index 1712b665..5a5179f 100644
--- a/chromeos/dbus/DEPS
+++ b/chromeos/dbus/DEPS
@@ -9,7 +9,6 @@
   "+dbus",
   "+net",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
   "+url",
 ]
diff --git a/chromeos/dbus/audio/OWNERS b/chromeos/dbus/audio/OWNERS
index e71cb32..806624d 100644
--- a/chromeos/dbus/audio/OWNERS
+++ b/chromeos/dbus/audio/OWNERS
@@ -1,2 +1 @@
-jennyz@chromium.org
 hychao@chromium.org
diff --git a/chromeos/network/BUILD.gn b/chromeos/network/BUILD.gn
index 14c1018..ca35ad8 100644
--- a/chromeos/network/BUILD.gn
+++ b/chromeos/network/BUILD.gn
@@ -8,8 +8,13 @@
 
 assert(is_chromeos, "Non-Chrome-OS builds must not depend on //chromeos")
 
-component("network") {
+config("network_config") {
   defines = [ "IS_CHROMEOS_NETWORK_IMPL" ]
+}
+
+component("network") {
+  configs += [ ":network_config" ]
+  public_deps = [ "//chromeos/ash/components/network/metrics" ]
   deps = [
     "//ash/constants",
     "//base",
@@ -39,6 +44,10 @@
     "//skia",
     "//url",
   ]
+
+  # Allow circular dependency from sub-directories of
+  # chromeos/ash/components/network.
+  allow_circular_includes_from = [ "//chromeos/ash/components/network/metrics" ]
   sources = [
     "auto_connect_handler.cc",
     "auto_connect_handler.h",
@@ -86,16 +95,6 @@
     "managed_network_configuration_handler_impl.h",
     "managed_state.cc",
     "managed_state.h",
-    "metrics/connection_info_metrics_logger.cc",
-    "metrics/connection_info_metrics_logger.h",
-    "metrics/connection_results.cc",
-    "metrics/connection_results.h",
-    "metrics/esim_policy_login_metrics_logger.cc",
-    "metrics/esim_policy_login_metrics_logger.h",
-    "metrics/network_metrics_helper.cc",
-    "metrics/network_metrics_helper.h",
-    "metrics/vpn_network_metrics_helper.cc",
-    "metrics/vpn_network_metrics_helper.h",
     "network_activation_handler.h",
     "network_activation_handler_impl.cc",
     "network_activation_handler_impl.h",
@@ -267,6 +266,7 @@
     "//base:i18n",
     "//base/test:test_support",
     "//chromeos:test_utils",
+    "//chromeos/ash/components/network/metrics:unit_tests",
     "//chromeos/components/feature_usage",
     "//chromeos/components/onc",
     "//chromeos/components/onc:test_support",
@@ -309,10 +309,6 @@
     "geolocation_handler_unittest.cc",
     "managed_cellular_pref_handler_unittest.cc",
     "managed_network_configuration_handler_unittest.cc",
-    "metrics/connection_info_metrics_logger_unittest.cc",
-    "metrics/esim_policy_login_metrics_logger_unittest.cc",
-    "metrics/network_metrics_helper_unittest.cc",
-    "metrics/vpn_network_metrics_helper_unittest.cc",
     "network_cert_loader_unittest.cc",
     "network_cert_migrator_unittest.cc",
     "network_configuration_handler_unittest.cc",
diff --git a/chromeos/network/DEPS b/chromeos/network/DEPS
index f178ce4..ed3628d 100644
--- a/chromeos/network/DEPS
+++ b/chromeos/network/DEPS
@@ -8,6 +8,7 @@
   "+ash/constants",
   "+base",
   "+base/component_export.h",
+  "+chromeos/ash/components/network",
   "+chromeos/test",
   "+chromeos/dbus",
   "+chromeos/components/feature_usage",
@@ -29,7 +30,6 @@
   "+net",
   "+services/preferences/public/cpp",
   "+testing",
-  "+third_party/abseil-cpp/absl",
   "+third_party/cros_system_api",
   "+url",
 ]
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc
index 2d5c16d7..4aec9e04 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.cc
+++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -19,6 +19,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
+#include "chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h"
 #include "chromeos/components/onc/onc_signature.h"
 #include "chromeos/components/onc/onc_utils.h"
 #include "chromeos/components/onc/onc_validator.h"
@@ -26,7 +27,6 @@
 #include "chromeos/dbus/shill/shill_profile_client.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "chromeos/network/device_state.h"
-#include "chromeos/network/metrics/esim_policy_login_metrics_logger.h"
 #include "chromeos/network/network_configuration_handler.h"
 #include "chromeos/network/network_device_handler.h"
 #include "chromeos/network/network_event_log.h"
diff --git a/chromeos/network/network_handler.cc b/chromeos/network/network_handler.cc
index 3be0dca..aa502373 100644
--- a/chromeos/network/network_handler.cc
+++ b/chromeos/network/network_handler.cc
@@ -6,6 +6,9 @@
 
 #include "ash/constants/ash_features.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "chromeos/ash/components/network/metrics/connection_info_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h"
+#include "chromeos/ash/components/network/metrics/vpn_network_metrics_helper.h"
 #include "chromeos/network/auto_connect_handler.h"
 #include "chromeos/network/cellular_connection_handler.h"
 #include "chromeos/network/cellular_esim_installer.h"
@@ -18,9 +21,6 @@
 #include "chromeos/network/geolocation_handler.h"
 #include "chromeos/network/managed_cellular_pref_handler.h"
 #include "chromeos/network/managed_network_configuration_handler_impl.h"
-#include "chromeos/network/metrics/connection_info_metrics_logger.h"
-#include "chromeos/network/metrics/esim_policy_login_metrics_logger.h"
-#include "chromeos/network/metrics/vpn_network_metrics_helper.h"
 #include "chromeos/network/network_activation_handler_impl.h"
 #include "chromeos/network/network_cert_loader.h"
 #include "chromeos/network/network_cert_migrator.h"
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc
index 45de35fc..65dbf4859 100644
--- a/chromeos/network/shill_property_handler.cc
+++ b/chromeos/network/shill_property_handler.cc
@@ -16,12 +16,12 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
+#include "chromeos/ash/components/network/metrics/network_metrics_helper.h"
 #include "chromeos/dbus/shill/shill_device_client.h"
 #include "chromeos/dbus/shill/shill_ipconfig_client.h"
 #include "chromeos/dbus/shill/shill_manager_client.h"
 #include "chromeos/dbus/shill/shill_profile_client.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
-#include "chromeos/network/metrics/network_metrics_helper.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_state.h"
 #include "dbus/object_path.h"
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index 405dd08b..523aa6ce 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -223,6 +223,9 @@
   # https://crbug.com/1327171
   "policy.PopupsForURLCheck.default",
 
+  # https://crbug.com/1327345
+  "policy.ChromePolicyPageStatusTimestamps.ash",
+
   # https://crbug.com/1327361
   "policy.FullscreenAllowed",
 ]
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 1af3ef0..96d77e96 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -5101,7 +5101,10 @@
   EXPECT_EQ(std::u16string(), response_data.fields[4].value);
 }
 
-// Verify when no complete number can be found, we do best-effort filling.
+// Verify that phone number fields annotated with the autocomplete attribute
+// are filled best-effort.
+// Phone number local heuristics only succeed if a PHONE_HOME_NUMBER field is
+// present.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_BestEfforFilling) {
   AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
diff --git a/components/autofill/core/browser/data_model/phone_number.cc b/components/autofill/core/browser/data_model/phone_number.cc
index 451200f..7a9cefb 100644
--- a/components/autofill/core/browser/data_model/phone_number.cc
+++ b/components/autofill/core/browser/data_model/phone_number.cc
@@ -270,18 +270,22 @@
   if (number_.empty())
     return true;
 
-  // Store a formatted (i.e., pretty printed) version of the number if either
-  // the number doesn't contain formatting marks.
+  // `SetRawInfoWithVerificationStatus()` invalidated `cached_parsed_phone_` and
+  // calling `UpdateCacheIfNeeded()` will thus try parsing the `number_` here.
   UpdateCacheIfNeeded(app_locale);
+  // If the number invalid, setting fails and `GetRawInfo()` and `GetInfo()`
+  // should return an empty string. Clear both representations of the number.
+  if (!cached_parsed_phone_.IsValidNumber()) {
+    number_.clear();
+    cached_parsed_phone_ = i18n::PhoneObject();
+    return false;
+  }
+  // Store a formatted (i.e., pretty printed) version of the number if it
+  // doesn't contain formatting marks.
   if (base::ContainsOnlyChars(number_, u"+0123456789")) {
     number_ = cached_parsed_phone_.GetFormattedNumber();
-  } else if (i18n::NormalizePhoneNumber(number_,
-                                        GetRegion(*profile_, app_locale))
-                 .empty()) {
-    // The number doesn't make sense for this region; clear it.
-    number_.clear();
   }
-  return !number_.empty();
+  return true;
 }
 
 void PhoneNumber::UpdateCacheIfNeeded(const std::string& app_locale) const {
diff --git a/components/autofill/core/browser/data_model/phone_number_unittest.cc b/components/autofill/core/browser/data_model/phone_number_unittest.cc
index b7dd49c5..1a43db6 100644
--- a/components/autofill/core/browser/data_model/phone_number_unittest.cc
+++ b/components/autofill/core/browser/data_model/phone_number_unittest.cc
@@ -115,51 +115,54 @@
        {u"01741234567", {PHONE_HOME_CITY_AND_NUMBER}}});
 }
 
-// Verify that PhoneNumber::SetInfo() correctly formats the incoming number.
+// Verify that `PhoneNumber::SetInfo()` correctly formats the incoming number.
 TEST(PhoneNumberTest, SetInfo) {
   AutofillProfile profile;
   profile.SetRawInfo(ADDRESS_HOME_COUNTRY, u"US");
+  const char kLocale[] = "US";  // Irrelevant, as `profile` has a country.
 
   PhoneNumber phone(&profile);
-  EXPECT_EQ(std::u16string(), phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  EXPECT_TRUE(phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER).empty());
+  EXPECT_TRUE(phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale).empty());
 
   // Set the formatted info directly.
-  EXPECT_TRUE(phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
-                            u"(650) 234-5678", "US"));
+  EXPECT_TRUE(
+      phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"(650) 234-5678", kLocale));
   EXPECT_EQ(u"(650) 234-5678", phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  EXPECT_EQ(u"6502345678", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale));
 
   // Unformatted numbers should be formatted.
-  EXPECT_TRUE(phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
-                            u"8887776666", "US"));
+  EXPECT_TRUE(phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"8887776666", kLocale));
   EXPECT_EQ(u"(888) 777-6666", phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
-  EXPECT_TRUE(phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
-                            u"+18887776666", "US"));
+  EXPECT_EQ(u"8887776666", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale));
+
+  EXPECT_TRUE(phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"+18887776666", kLocale));
   EXPECT_EQ(u"1 888-777-6666", phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  EXPECT_EQ(u"18887776666", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale));
 
   // Differently formatted numbers should be left alone.
-  EXPECT_TRUE(phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
-                            u"800-432-8765", "US"));
+  EXPECT_TRUE(phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"800-432-8765", kLocale));
   EXPECT_EQ(u"800-432-8765", phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  EXPECT_EQ(u"8004328765", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale));
 
   // SetRawInfo should not try to format.
   phone.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"8004328765");
   EXPECT_EQ(u"8004328765", phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
 
-  // Invalid numbers should not be stored.  In the US, phone numbers cannot
-  // start with the digit '1'.
-  EXPECT_FALSE(
-      phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), u"650111111", "US"));
-  EXPECT_EQ(std::u16string(), phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  // Invalid numbers should not be stored. In the US, phone numbers cannot start
+  // with the digit '1'.
+  EXPECT_FALSE(phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"650111111", kLocale));
+  EXPECT_TRUE(phone.GetRawInfo(PHONE_HOME_WHOLE_NUMBER).empty());
+  EXPECT_TRUE(phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale).empty());
 
-  // If the stored number is invalid due to metadata mismatch(non-existing
+  // If the stored number is invalid due to metadata mismatch (non-existing
   // carrier code for example), but otherwise is a possible number and can be
   // parsed into different components, we should respond to queries with best
   // effort as if it is a valid number.
-  EXPECT_TRUE(phone.SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
-                            u"5141231234", "US"));
-  EXPECT_EQ(u"5141231234", phone.GetInfo(PHONE_HOME_CITY_AND_NUMBER, "CA"));
-  EXPECT_EQ(u"5141231234", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, "CA"));
-  EXPECT_EQ(u"514", phone.GetInfo(PHONE_HOME_CITY_CODE, "CA"));
+  EXPECT_TRUE(phone.SetInfo(PHONE_HOME_WHOLE_NUMBER, u"5141231234", kLocale));
+  EXPECT_EQ(u"5141231234", phone.GetInfo(PHONE_HOME_CITY_AND_NUMBER, kLocale));
+  EXPECT_EQ(u"5141231234", phone.GetInfo(PHONE_HOME_WHOLE_NUMBER, kLocale));
+  EXPECT_EQ(u"514", phone.GetInfo(PHONE_HOME_CITY_CODE, kLocale));
 }
 
 // Test that cached phone numbers are correctly invalidated and updated.
diff --git a/components/autofill/core/browser/form_parsing/phone_field.cc b/components/autofill/core/browser/form_parsing/phone_field.cc
index a20aa065..a5f3040 100644
--- a/components/autofill/core/browser/form_parsing/phone_field.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field.cc
@@ -4,13 +4,14 @@
 
 #include "components/autofill/core/browser/form_parsing/phone_field.h"
 
-#include <string.h>
-
+#include <algorithm>
 #include <memory>
 #include <string>
 #include <utility>
 
 #include "base/check.h"
+#include "base/memory/ptr_util.h"
+#include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
@@ -51,11 +52,8 @@
 
 }  // namespace
 
-PhoneField::~PhoneField() {}
-
-// Phone field grammars - first matched grammar will be parsed. Grammars are
-// separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are
-// parsed separately unless they are necessary parts of the match.
+// Phone field grammars - first matched grammar will be parsed. Suffix and
+// extension are parsed separately unless they are necessary parts of the match.
 // The following notation is used to describe the patterns:
 // <cc> - country code field.
 // <ac> - area code field.
@@ -64,90 +62,72 @@
 // <ext> - extension.
 // :N means field is limited to N characters, otherwise it is unlimited.
 // (pattern <field>)? means pattern is optional and matched separately.
-const PhoneField::Parser PhoneField::kPhoneFieldGrammars[] = {
-    // Country code: <cc> Area Code: <ac> Phone: <phone> (- <suffix>
-    // (Ext: <ext>)?)?
-    {REGEX_COUNTRY, FIELD_COUNTRY_CODE, 0},
-    {REGEX_AREA, FIELD_AREA_CODE, 0},
-    {REGEX_PHONE, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // \( <ac> \) <phone>:3 <suffix>:4 (Ext: <ext>)?
-    {REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 3},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
-    {REGEX_PHONE, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc> <ac>:3 - <phone>:3 - <suffix>:4 (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 0},
-    {REGEX_PHONE, FIELD_AREA_CODE, 3},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
-    {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc>:3 <ac>:3 <phone>:3 <suffix>:4 (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 3},
-    {REGEX_PHONE, FIELD_AREA_CODE, 3},
-    {REGEX_PHONE, FIELD_PHONE, 3},
-    {REGEX_PHONE, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Area Code: <ac> Phone: <phone> (- <suffix> (Ext: <ext>)?)?
-    {REGEX_AREA, FIELD_AREA_CODE, 0},
-    {REGEX_PHONE, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <ac> <phone>:3 <suffix>:4 (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_AREA_CODE, 0},
-    {REGEX_PHONE, FIELD_PHONE, 3},
-    {REGEX_PHONE, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc> \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 0},
-    {REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 0},
-    {REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc> - <ac> - <phone> - <suffix> (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0},
-    {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Area code: <ac>:3 Prefix: <prefix>:3 Suffix: <suffix>:4 (Ext: <ext>)?
-    {REGEX_AREA, FIELD_AREA_CODE, 3},
-    {REGEX_PREFIX, FIELD_PHONE, 3},
-    {REGEX_SUFFIX, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <ac> Prefix: <phone> Suffix: <suffix> (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_AREA_CODE, 0},
-    {REGEX_PREFIX, FIELD_PHONE, 0},
-    {REGEX_SUFFIX, FIELD_SUFFIX, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <ac> - <phone>:3 - <suffix>:4 (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_AREA_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
-    {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc> - <ac> - <phone> (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 0},
-    {REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE, 0},
-    {REGEX_SUFFIX_SEPARATOR, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <ac> - <phone> (Ext: <ext>)?
-    {REGEX_AREA, FIELD_AREA_CODE, 0},
-    {REGEX_PHONE, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <cc>:3 - <phone> (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_COUNTRY_CODE, 3},
-    {REGEX_PHONE, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Ext: <ext>
-    {REGEX_EXTENSION, FIELD_EXTENSION, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-    // Phone: <phone> (Ext: <ext>)?
-    {REGEX_PHONE, FIELD_PHONE, 0},
-    {REGEX_SEPARATOR, FIELD_NONE, 0},
-};
+// static
+const std::vector<PhoneField::PhoneGrammar>& PhoneField::GetPhoneGrammars() {
+  static const base::NoDestructor<std::vector<PhoneGrammar>> grammars({
+      // Country code: <cc> Area Code: <ac> Phone: <phone> (- <suffix>
+      // (Ext: <ext>)?)?
+      {{REGEX_COUNTRY, FIELD_COUNTRY_CODE},
+       {REGEX_AREA, FIELD_AREA_CODE},
+       {REGEX_PHONE, FIELD_PHONE}},
+      // \( <ac> \) <phone>:3 <suffix>:4 (Ext: <ext>)?
+      {{REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 3},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
+       {REGEX_PHONE, FIELD_SUFFIX, 4}},
+      // Phone: <cc> <ac>:3 - <phone>:3 - <suffix>:4 (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE},
+       {REGEX_PHONE, FIELD_AREA_CODE, 3},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
+       {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4}},
+      // Phone: <cc>:3 <ac>:3 <phone>:3 <suffix>:4 (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE, 3},
+       {REGEX_PHONE, FIELD_AREA_CODE, 3},
+       {REGEX_PHONE, FIELD_PHONE, 3},
+       {REGEX_PHONE, FIELD_SUFFIX, 4}},
+      // Area Code: <ac> Phone: <phone> (- <suffix> (Ext: <ext>)?)?
+      {{REGEX_AREA, FIELD_AREA_CODE}, {REGEX_PHONE, FIELD_PHONE}},
+      // Phone: <ac> <phone>:3 <suffix>:4 (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_AREA_CODE},
+       {REGEX_PHONE, FIELD_PHONE, 3},
+       {REGEX_PHONE, FIELD_SUFFIX, 4}},
+      // Phone: <cc> \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE},
+       {REGEX_AREA_NOTEXT, FIELD_AREA_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE}},
+      // Phone: \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE},
+       {REGEX_AREA_NOTEXT, FIELD_AREA_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE}},
+      // Phone: <cc> - <ac> - <phone> - <suffix> (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE},
+       {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX}},
+      // Area code: <ac>:3 Prefix: <prefix>:3 Suffix: <suffix>:4 (Ext: <ext>)?
+      {{REGEX_AREA, FIELD_AREA_CODE, 3},
+       {REGEX_PREFIX, FIELD_PHONE, 3},
+       {REGEX_SUFFIX, FIELD_SUFFIX, 4}},
+      // Phone: <ac> Prefix: <phone> Suffix: <suffix> (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_AREA_CODE},
+       {REGEX_PREFIX, FIELD_PHONE},
+       {REGEX_SUFFIX, FIELD_SUFFIX}},
+      // Phone: <ac> - <phone>:3 - <suffix>:4 (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_AREA_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3},
+       {REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4}},
+      // Phone: <cc> - <ac> - <phone> (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE},
+       {REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE},
+       {REGEX_SUFFIX_SEPARATOR, FIELD_PHONE}},
+      // Phone: <ac> - <phone> (Ext: <ext>)?
+      {{REGEX_AREA, FIELD_AREA_CODE}, {REGEX_PHONE, FIELD_PHONE}},
+      // Phone: <cc>:3 - <phone> (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_COUNTRY_CODE, 3}, {REGEX_PHONE, FIELD_PHONE}},
+      // Phone: <phone> (Ext: <ext>)?
+      {{REGEX_PHONE, FIELD_PHONE}},
+  });
+  return *grammars;
+}
 
 // static
 bool PhoneField::LikelyAugmentedPhoneCountryCode(
@@ -209,6 +189,39 @@
 }
 
 // static
+bool PhoneField::ParseGrammar(const PhoneGrammar& grammar,
+                              ParsedPhoneFields& parsed_fields,
+                              AutofillScanner* scanner,
+                              const LanguageCode& page_language,
+                              PatternSource pattern_source,
+                              LogManager* log_manager) {
+  for (const auto& rule : grammar) {
+    const bool is_country_code_field = rule.phone_part == FIELD_COUNTRY_CODE;
+
+    // The field length comparison with |rule.max_size| is not required in case
+    // of the selection boxes that are of phone country code type.
+    if (is_country_code_field &&
+        LikelyAugmentedPhoneCountryCode(scanner,
+                                        &parsed_fields[FIELD_COUNTRY_CODE])) {
+      continue;
+    }
+
+    if (!ParsePhoneField(
+            scanner, GetRegExp(rule.regex), &parsed_fields[rule.phone_part],
+            {log_manager, GetRegExpName(rule.regex)}, is_country_code_field,
+            GetJSONFieldType(rule.regex), page_language, pattern_source)) {
+      return false;
+    }
+    if (rule.max_size != 0 &&
+        (parsed_fields[rule.phone_part]->max_length == 0 ||
+         rule.max_size < parsed_fields[rule.phone_part]->max_length)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// static
 std::unique_ptr<FormField> PhoneField::Parse(AutofillScanner* scanner,
                                              const LanguageCode& page_language,
                                              PatternSource pattern_source,
@@ -217,101 +230,45 @@
     return nullptr;
 
   size_t start_cursor = scanner->SaveCursor();
+  ParsedPhoneFields parsed_fields;
 
-  // The form owns the following variables, so they should not be deleted.
-  AutofillField* parsed_fields[FIELD_MAX];
-
-  for (size_t i = 0; i < std::size(kPhoneFieldGrammars); ++i) {
-    memset(parsed_fields, 0, sizeof(parsed_fields));
-    size_t saved_cursor = scanner->SaveCursor();
-
-    // Attempt to parse according to the next grammar.
-    for (; i < std::size(kPhoneFieldGrammars) &&
-           kPhoneFieldGrammars[i].regex != REGEX_SEPARATOR;
-         ++i) {
-      const bool is_country_code_field =
-          kPhoneFieldGrammars[i].phone_part == FIELD_COUNTRY_CODE;
-
-      // The field length comparison with |kPhoneFieldGrammars[i].max_size| is
-      // not required in case of the selection boxes that are of phone country
-      // code type.
-      if (is_country_code_field &&
-          LikelyAugmentedPhoneCountryCode(scanner,
-                                          &parsed_fields[FIELD_COUNTRY_CODE]))
-        continue;
-
-      if (!ParsePhoneField(
-              scanner, GetRegExp(kPhoneFieldGrammars[i].regex),
-              &parsed_fields[kPhoneFieldGrammars[i].phone_part],
-              {log_manager, GetRegExpName(kPhoneFieldGrammars[i].regex)},
-              is_country_code_field,
-              GetJSONFieldType(kPhoneFieldGrammars[i].regex), page_language,
-              pattern_source)) {
-        break;
-      }
-      if (kPhoneFieldGrammars[i].max_size &&
-          (!parsed_fields[kPhoneFieldGrammars[i].phone_part]->max_length ||
-           kPhoneFieldGrammars[i].max_size <
-               parsed_fields[kPhoneFieldGrammars[i].phone_part]->max_length)) {
-        break;
-      }
+  // Find the first matching grammar.
+  bool found_matching_grammar = false;
+  for (const PhoneGrammar& grammar : GetPhoneGrammars()) {
+    std::fill(parsed_fields.begin(), parsed_fields.end(), nullptr);
+    if (ParseGrammar(grammar, parsed_fields, scanner, page_language,
+                     pattern_source, log_manager)) {
+      found_matching_grammar = true;
+      break;
     }
-
-    if (i >= std::size(kPhoneFieldGrammars)) {
-      scanner->RewindTo(saved_cursor);
-      return nullptr;  // Parsing failed.
-    }
-    if (kPhoneFieldGrammars[i].regex == REGEX_SEPARATOR)
-      break;  // Parsing succeeded.
-
-    // Proceed to the next grammar.
-    do {
-      ++i;
-    } while (i < std::size(kPhoneFieldGrammars) &&
-             kPhoneFieldGrammars[i].regex != REGEX_SEPARATOR);
-
-    scanner->RewindTo(saved_cursor);
-    if (i + 1 == std::size(kPhoneFieldGrammars)) {
-      return nullptr;  // Tried through all the possibilities - did not match.
-    }
-  }
-
-  if (!parsed_fields[FIELD_PHONE]) {
     scanner->RewindTo(start_cursor);
+  }
+  if (!found_matching_grammar)
     return nullptr;
+  // No grammar without FIELD_PHONE should be defined.
+  DCHECK(parsed_fields[FIELD_PHONE] != nullptr);
+
+  // Look for a suffix field using two different regex.
+  if (!parsed_fields[FIELD_SUFFIX]) {
+    ParsePhoneField(scanner, kPhoneSuffixRe, &parsed_fields[FIELD_SUFFIX],
+                    {log_manager, "kPhoneSuffixRe"},
+                    /*is_country_code_field=*/false, "PHONE_SUFFIX",
+                    page_language, pattern_source) ||
+        ParsePhoneField(
+            scanner, kPhoneSuffixSeparatorRe, &parsed_fields[FIELD_SUFFIX],
+            {log_manager, "kPhoneSuffixSeparatorRe"},
+            /*is_country_code_field=*/false, "PHONE_SUFFIX_SEPARATOR",
+            page_language, pattern_source);
   }
-
-  std::unique_ptr<PhoneField> phone_field(new PhoneField);
-  for (int i = 0; i < FIELD_MAX; ++i)
-    phone_field->parsed_phone_fields_[i] = parsed_fields[i];
-
-  // Look for optional fields.
-
-  // Look for a third text box.
-  if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) {
-    if (!ParsePhoneField(scanner, kPhoneSuffixRe,
-                         &phone_field->parsed_phone_fields_[FIELD_SUFFIX],
-                         {log_manager, "kPhoneSuffixRe"},
-                         /*is_country_code_field=*/false, "PHONE_SUFFIX",
-                         page_language, pattern_source)) {
-      ParsePhoneField(scanner, kPhoneSuffixSeparatorRe,
-                      &phone_field->parsed_phone_fields_[FIELD_SUFFIX],
-                      {log_manager, "kPhoneSuffixSeparatorRe"},
-                      /*is_country_code_field=*/false, "PHONE_SUFFIX_SEPARATOR",
-                      page_language, pattern_source);
-    }
-  }
-
   // Now look for an extension.
   // The extension is not actually used, so this just eats the field so other
   // parsers do not mistaken it for something else.
-  ParsePhoneField(scanner, kPhoneExtensionRe,
-                  &phone_field->parsed_phone_fields_[FIELD_EXTENSION],
+  ParsePhoneField(scanner, kPhoneExtensionRe, &parsed_fields[FIELD_EXTENSION],
                   {log_manager, "kPhoneExtensionRe"},
                   /*is_country_code_field=*/false, "PHONE_EXTENSION",
                   page_language, pattern_source);
 
-  return std::move(phone_field);
+  return base::WrapUnique(new PhoneField(std::move(parsed_fields)));
 }
 
 void PhoneField::AddClassifications(
@@ -369,9 +326,8 @@
   }
 }
 
-PhoneField::PhoneField() {
-  memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_));
-}
+PhoneField::PhoneField(ParsedPhoneFields fields)
+    : parsed_phone_fields_(std::move(fields)) {}
 
 // static
 std::u16string PhoneField::GetRegExp(RegexType regex_id) {
diff --git a/components/autofill/core/browser/form_parsing/phone_field.h b/components/autofill/core/browser/form_parsing/phone_field.h
index 1dfc0d3..121e5efc 100644
--- a/components/autofill/core/browser/form_parsing/phone_field.h
+++ b/components/autofill/core/browser/form_parsing/phone_field.h
@@ -5,8 +5,7 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_PHONE_FIELD_H_
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_PHONE_FIELD_H_
 
-#include <stddef.h>
-
+#include <array>
 #include <memory>
 #include <string>
 
@@ -30,7 +29,6 @@
 // - number
 class PhoneField : public FormField {
  public:
-  ~PhoneField() override;
   PhoneField(const PhoneField&) = delete;
   PhoneField& operator=(const PhoneField&) = delete;
 
@@ -63,32 +61,30 @@
     REGEX_SUFFIX_SEPARATOR,
     REGEX_SUFFIX,
     REGEX_EXTENSION,
-
-    // Separates regexps in grammar.
-    REGEX_SEPARATOR,
   };
 
   // Parsed fields.
   enum PhonePart {
-    FIELD_NONE = -1,
     FIELD_COUNTRY_CODE,
     FIELD_AREA_CODE,
     FIELD_PHONE,
     FIELD_SUFFIX,
     FIELD_EXTENSION,
-
     FIELD_MAX,
   };
+  using ParsedPhoneFields = std::array<AutofillField*, FIELD_MAX>;
 
-  struct Parser {
-    RegexType regex;       // Field matching reg-ex.
-    PhonePart phone_part;  // Index of the field.
-    size_t max_size;       // Max size of the field to match. 0 means any.
+  explicit PhoneField(ParsedPhoneFields fields);
+
+  struct Rule {
+    RegexType regex;       // The regex used to match this `phone_part`.
+    PhonePart phone_part;  // The type/index of the field.
+    size_t max_size = 0;   // Max size of the field to match. 0 means any.
   };
+  using PhoneGrammar = std::vector<Rule>;
 
-  static const Parser kPhoneFieldGrammars[];
-
-  PhoneField();
+  // Returns all the `PhoneGrammar`s used for parsing.
+  static const std::vector<PhoneGrammar>& GetPhoneGrammars();
 
   // Returns the regular expression string corresponding to |regex_id|
   static std::u16string GetRegExp(RegexType regex_id);
@@ -111,6 +107,15 @@
                               const LanguageCode& page_language,
                               PatternSource pattern_source);
 
+  // Tries parsing the given `grammar` into `parsed_fields` and returns true
+  // if it succeeded.
+  static bool ParseGrammar(const PhoneGrammar& grammar,
+                           ParsedPhoneFields& parsed_fields,
+                           AutofillScanner* scanner,
+                           const LanguageCode& page_language,
+                           PatternSource pattern_source,
+                           LogManager* log_manager);
+
   // Returns true if |scanner| points to a <select> field that appears to be the
   // phone country code by looking at its option contents.
   // "Augmented" refers to the fact that we are looking for select options that
@@ -120,7 +125,7 @@
 
   // FIELD_PHONE is always present; holds suffix if prefix is present.
   // The rest could be NULL.
-  AutofillField* parsed_phone_fields_[FIELD_MAX];
+  ParsedPhoneFields parsed_phone_fields_;
 };
 
 }  // namespace autofill
diff --git a/components/autofill_assistant/browser/android/client_android.cc b/components/autofill_assistant/browser/android/client_android.cc
index 14dec88..9709e066 100644
--- a/components/autofill_assistant/browser/android/client_android.cc
+++ b/components/autofill_assistant/browser/android/client_android.cc
@@ -98,6 +98,9 @@
     : content::WebContentsUserData<ClientAndroid>(*web_contents),
       dependencies_(
           DependenciesAndroid::CreateFromJavaDependencies(jdependencies)),
+      annotate_dom_model_service_(dependencies_->GetCommonDependencies()
+                                      ->GetOrCreateAnnotateDomModelService(
+                                          web_contents->GetBrowserContext())),
       jdependencies_(jdependencies),
       java_object_(Java_AutofillAssistantClient_Constructor(
           AttachCurrentThread(),
@@ -129,7 +132,7 @@
          ui_controller_android_->IsAttached();
 }
 
-bool ClientAndroid::Start(
+void ClientAndroid::Start(
     const GURL& url,
     std::unique_ptr<TriggerContext> trigger_context,
     std::unique_ptr<Service> test_service_to_inject,
@@ -176,7 +179,7 @@
       DVLOG(2) << "\t\t" << param.name() << ": " << param.value();
     }
   }
-  return controller_->Start(url, std::move(trigger_context));
+  controller_->Start(url, std::move(trigger_context));
 }
 
 void ClientAndroid::OnJavaDestroyUI(
@@ -465,7 +468,7 @@
 
 std::string ClientAndroid::GetSignedInEmail() const {
   return dependencies_->GetCommonDependencies()->GetSignedInEmail(
-      GetWebContents());
+      GetWebContents()->GetBrowserContext());
 }
 
 absl::optional<std::pair<int, int>> ClientAndroid::GetWindowSize() const {
@@ -600,6 +603,31 @@
   return dependencies_->GetCommonDependencies()->IsWebLayer();
 }
 
+void ClientAndroid::GetAnnotateDomModelVersion(
+    base::OnceCallback<void(absl::optional<int64_t>)> callback) const {
+  if (!annotate_dom_model_service_) {
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+
+  auto model_version = annotate_dom_model_service_->GetModelVersion();
+  if (model_version.has_value()) {
+    std::move(callback).Run(model_version);
+    return;
+  }
+
+  annotate_dom_model_service_->NotifyOnModelFileAvailable(
+      base::BindOnce(&ClientAndroid::OnAnnotateDomModelFileAvailable,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void ClientAndroid::OnAnnotateDomModelFileAvailable(
+    base::OnceCallback<void(absl::optional<int64_t>)> callback,
+    bool available) {
+  DCHECK(annotate_dom_model_service_);
+  std::move(callback).Run(annotate_dom_model_service_->GetModelVersion());
+}
+
 void ClientAndroid::Shutdown(Metrics::DropOutReason reason) {
   if (!controller_)
     return;
@@ -673,10 +701,7 @@
       GetWebContents(), /* client= */ this,
       base::DefaultTickClock::GetInstance(),
       RuntimeManager::GetForWebContents(GetWebContents())->GetWeakPtr(),
-      std::move(service), ukm::UkmRecorder::Get(),
-      dependencies_->GetCommonDependencies()
-          ->GetOrCreateAnnotateDomModelService(
-              GetWebContents()->GetBrowserContext()));
+      std::move(service), ukm::UkmRecorder::Get(), annotate_dom_model_service_);
   ui_controller_ = std::make_unique<UiController>(
       /* client= */ this, controller_.get(), std::move(tts_controller));
   ui_controller_->StartListening();
diff --git a/components/autofill_assistant/browser/android/client_android.h b/components/autofill_assistant/browser/android/client_android.h
index 8315ff8..36c5914 100644
--- a/components/autofill_assistant/browser/android/client_android.h
+++ b/components/autofill_assistant/browser/android/client_android.h
@@ -58,7 +58,7 @@
   // Returns whether UI is currently being displayed to the user.
   bool IsVisible() const;
 
-  bool Start(const GURL& url,
+  void Start(const GURL& url,
              std::unique_ptr<TriggerContext> trigger_context,
              std::unique_ptr<Service> test_service_to_inject,
              const base::android::JavaRef<jobject>& joverlay_coordinator,
@@ -143,6 +143,9 @@
   bool HasHadUI() const override;
   ScriptExecutorUiDelegate* GetScriptExecutorUiDelegate() override;
   bool MustUseBackendData() const override;
+  void GetAnnotateDomModelVersion(
+      base::OnceCallback<void(absl::optional<int64_t>)> callback)
+      const override;
 
   // Overrides AccessTokenFetcher
   void FetchAccessToken(
@@ -176,10 +179,15 @@
   // UiDelegate::PerformUserAction() or -1 if not found.
   int FindDirectAction(const std::string& action_name);
 
+  void OnAnnotateDomModelFileAvailable(
+      base::OnceCallback<void(absl::optional<int64_t>)> callback,
+      bool available);
+
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
   // Contains AssistantStaticDependencies which do not change.
   const std::unique_ptr<const DependenciesAndroid> dependencies_;
+  const raw_ptr<AnnotateDomModelService> annotate_dom_model_service_;
   // Can change based on activity attachment.
   const base::android::ScopedJavaGlobalRef<jobject> jdependencies_;
 
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.cc b/components/autofill_assistant/browser/android/starter_delegate_android.cc
index eb0f569a..77661db 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.cc
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.cc
@@ -56,12 +56,11 @@
     : content::WebContentsUserData<StarterDelegateAndroid>(*web_contents),
       dependencies_(std::move(dependencies)),
       website_login_manager_(std::make_unique<WebsiteLoginManagerImpl>(
-          dependencies_->GetCommonDependencies()->GetPasswordManagerClient(
-              web_contents),
+          GetCommonDependencies()->GetPasswordManagerClient(web_contents),
           web_contents)) {
   // Create the AnnotateDomModelService when the browser starts, such that it
   // starts listening to model changes early enough.
-  dependencies_->GetCommonDependencies()->GetOrCreateAnnotateDomModelService(
+  GetCommonDependencies()->GetOrCreateAnnotateDomModelService(
       web_contents->GetBrowserContext());
 }
 
@@ -249,18 +248,23 @@
 }
 
 bool StarterDelegateAndroid::GetIsLoggedIn() {
-  return !dependencies_->GetCommonDependencies()
-              ->GetSignedInEmail(&GetWebContents())
+  return !GetCommonDependencies()
+              ->GetSignedInEmail(GetWebContents().GetBrowserContext())
               .empty();
 }
 
+bool StarterDelegateAndroid::GetIsSupervisedUser() {
+  return GetCommonDependencies()->IsSupervisedUser(
+      GetWebContents().GetBrowserContext());
+}
+
 bool StarterDelegateAndroid::GetIsCustomTab() const {
   return dependencies_->GetPlatformDependencies()->IsCustomTab(
       GetWebContents());
 }
 
 bool StarterDelegateAndroid::GetIsWebLayer() const {
-  return dependencies_->GetCommonDependencies()->IsWebLayer();
+  return GetCommonDependencies()->IsWebLayer();
 }
 
 bool StarterDelegateAndroid::GetIsTabCreatedByGSA() const {
@@ -349,18 +353,20 @@
 
 std::unique_ptr<AssistantFieldTrialUtil>
 StarterDelegateAndroid::CreateFieldTrialUtil() {
-  return dependencies_->GetCommonDependencies()->CreateFieldTrialUtil();
+  return GetCommonDependencies()->CreateFieldTrialUtil();
 }
 
 bool StarterDelegateAndroid::IsAttached() {
   return !!java_object_;
 }
 
-const CommonDependencies* StarterDelegateAndroid::GetCommonDependencies() {
+const CommonDependencies* StarterDelegateAndroid::GetCommonDependencies()
+    const {
   return dependencies_->GetCommonDependencies();
 }
 
-const PlatformDependencies* StarterDelegateAndroid::GetPlatformDependencies() {
+const PlatformDependencies* StarterDelegateAndroid::GetPlatformDependencies()
+    const {
   return dependencies_->GetPlatformDependencies();
 }
 
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.h b/components/autofill_assistant/browser/android/starter_delegate_android.h
index 86a4bef..4b44ed6 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.h
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.h
@@ -78,13 +78,14 @@
   void SetProactiveHelpSettingEnabled(bool enabled) override;
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
+  bool GetIsSupervisedUser() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
   std::unique_ptr<AssistantFieldTrialUtil> CreateFieldTrialUtil() override;
   bool IsAttached() override;
-  const CommonDependencies* GetCommonDependencies() override;
-  const PlatformDependencies* GetPlatformDependencies() override;
+  const CommonDependencies* GetCommonDependencies() const override;
+  const PlatformDependencies* GetPlatformDependencies() const override;
   base::WeakPtr<StarterPlatformDelegate> GetWeakPtr() override;
 
   // Called by Java to start an autofill-assistant flow for an incoming intent.
diff --git a/components/autofill_assistant/browser/client.h b/components/autofill_assistant/browser/client.h
index 213af70..8e597c1d 100644
--- a/components/autofill_assistant/browser/client.h
+++ b/components/autofill_assistant/browser/client.h
@@ -126,6 +126,10 @@
   // backend endpoint to query data.
   virtual bool MustUseBackendData() const = 0;
 
+  // Return the annotate DOM model version, if available.
+  virtual void GetAnnotateDomModelVersion(
+      base::OnceCallback<void(absl::optional<int64_t>)> callback) const = 0;
+
  protected:
   Client() = default;
 };
diff --git a/components/autofill_assistant/browser/client_context.cc b/components/autofill_assistant/browser/client_context.cc
index e0ba1e7f..aa36888f 100644
--- a/components/autofill_assistant/browser/client_context.cc
+++ b/components/autofill_assistant/browser/client_context.cc
@@ -86,6 +86,10 @@
   proto_.set_screen_orientation(client_->GetScreenOrientation());
 }
 
+void ClientContextImpl::UpdateAnnotateDomModelContext(int64_t model_version) {
+  proto_.mutable_annotate_dom_model_context()->set_model_version(model_version);
+}
+
 ClientContextProto ClientContextImpl::AsProto() const {
   return proto_;
 }
diff --git a/components/autofill_assistant/browser/client_context.h b/components/autofill_assistant/browser/client_context.h
index e6cede8..03664c7 100644
--- a/components/autofill_assistant/browser/client_context.h
+++ b/components/autofill_assistant/browser/client_context.h
@@ -18,6 +18,8 @@
   virtual ~ClientContext() = default;
   // Updates the client context based on the current state of the client.
   virtual void Update(const TriggerContext& trigger_context) = 0;
+  // Updates the annotate DOM model context.
+  virtual void UpdateAnnotateDomModelContext(int64_t model_version) {}
   // Returns the proto representation of this client context.
   virtual ClientContextProto AsProto() const = 0;
 };
@@ -29,6 +31,7 @@
   ClientContextImpl(const Client* client);
   ~ClientContextImpl() override = default;
   void Update(const TriggerContext& trigger_context) override;
+  void UpdateAnnotateDomModelContext(int64_t model_version) override;
   ClientContextProto AsProto() const override;
 
  private:
diff --git a/components/autofill_assistant/browser/client_context_unittest.cc b/components/autofill_assistant/browser/client_context_unittest.cc
index b719386..613bc95c 100644
--- a/components/autofill_assistant/browser/client_context_unittest.cc
+++ b/components/autofill_assistant/browser/client_context_unittest.cc
@@ -83,7 +83,7 @@
   EXPECT_THAT(actual_device_context.model(), Eq("model"));
 }
 
-TEST_F(ClientContextTest, UpdateWithTriggerContext) {
+TEST_F(ClientContextTest, UpdatesToClientContext) {
   // Calls expected when the constructor is called.
   EXPECT_CALL(mock_client_, IsAccessibilityEnabled()).WillOnce(Return(false));
   EXPECT_CALL(mock_client_, GetSignedInEmail())
@@ -102,16 +102,16 @@
       .WillOnce(Return(std::pair<int, int>(1080, 1920)));
   EXPECT_CALL(mock_client_, GetScreenOrientation())
       .WillOnce(Return(ClientContextProto::LANDSCAPE));
+
   client_context.Update({std::make_unique<ScriptParameters>(
                              base::flat_map<std::string, std::string>{
                                  {"USER_EMAIL", "example@chromium.org"}}),
-                         /* exp = */ "1,2,3",
+                         /* experiment_ids = */ "1,2,3",
                          /* is_cct = */ true,
                          /* onboarding_shown = */ true,
                          /* is_direct_action = */ true,
                          /* initial_url = */ "https://www.example.com",
                          /* is_in_chrome_triggered = */ true});
-
   auto actual_client_context = client_context.AsProto();
   EXPECT_THAT(actual_client_context.experiment_ids(), Eq("1,2,3"));
   EXPECT_THAT(actual_client_context.is_cct(), Eq(true));
@@ -128,6 +128,13 @@
   EXPECT_THAT(actual_client_context.window_size().height_pixels(), Eq(1920));
   EXPECT_THAT(actual_client_context.screen_orientation(),
               ClientContextProto::LANDSCAPE);
+  EXPECT_FALSE(actual_client_context.has_annotate_dom_model_context());
+
+  client_context.UpdateAnnotateDomModelContext(123456);
+  actual_client_context = client_context.AsProto();
+  EXPECT_THAT(
+      actual_client_context.annotate_dom_model_context().model_version(),
+      123456);
 }
 
 TEST_F(ClientContextTest, WindowSizeIsClearedIfNoLongerAvailable) {
diff --git a/components/autofill_assistant/browser/common_dependencies.h b/components/autofill_assistant/browser/common_dependencies.h
index 71423d3..518c4db1 100644
--- a/components/autofill_assistant/browser/common_dependencies.h
+++ b/components/autofill_assistant/browser/common_dependencies.h
@@ -56,7 +56,10 @@
       content::WebContents* web_contents) const = 0;
 
   virtual std::string GetSignedInEmail(
-      content::WebContents* web_contents) const = 0;
+      content::BrowserContext* browser_context) const = 0;
+
+  virtual bool IsSupervisedUser(
+      content::BrowserContext* browser_context) const = 0;
 
   virtual AnnotateDomModelService* GetOrCreateAnnotateDomModelService(
       content::BrowserContext* browser_context) const = 0;
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index 7655498f..d994fd995 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -412,16 +412,44 @@
 #else
     VLOG(2) << "GetScripts for " << script_url_.host();
 #endif
-
-    GetService()->GetScriptsForUrl(
-        url, *trigger_context_,
-        base::BindOnce(&Controller::OnGetScripts, base::Unretained(this), url));
+    MaybeUpdateClientContextAndGetScriptsForUrl(url);
   } else {
     script_tracker()->CheckScripts();
     StartPeriodicScriptChecks();
   }
 }
 
+void Controller::MaybeUpdateClientContextAndGetScriptsForUrl(const GURL& url) {
+  DCHECK(trigger_context_);
+  if (!trigger_context_->GetScriptParameters()
+           .GetSendAnnotateDomModelVersion()
+           .value_or(false)) {
+    GetScriptsForUrl(url);
+    return;
+  }
+
+  DCHECK(client_);
+  client_->GetAnnotateDomModelVersion(
+      base::BindOnce(&Controller::OnGetAnnotateDomModelVersionForGetScripts,
+                     weak_ptr_factory_.GetWeakPtr(), url));
+}
+
+void Controller::OnGetAnnotateDomModelVersionForGetScripts(
+    const GURL& url,
+    absl::optional<int64_t> model_version) {
+  if (model_version) {
+    GetService()->UpdateAnnotateDomModelContext(*model_version);
+  }
+  GetScriptsForUrl(url);
+}
+
+void Controller::GetScriptsForUrl(const GURL& url) {
+  GetService()->GetScriptsForUrl(
+      url, *trigger_context_,
+      base::BindOnce(&Controller::OnGetScripts, weak_ptr_factory_.GetWeakPtr(),
+                     url));
+}
+
 void Controller::StartPeriodicScriptChecks() {
   periodic_script_check_count_ = settings_.periodic_script_check_count;
   // If periodic checks are running, setting periodic_script_check_count_ keeps
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h
index 64d141d9f..7fc4fd8 100644
--- a/components/autofill_assistant/browser/controller.h
+++ b/components/autofill_assistant/browser/controller.h
@@ -299,6 +299,12 @@
   // Sets the semantic selector in the DOM annotation service.
   void SetSemanticSelectorPolicy(SemanticSelectorPolicy policy);
 
+  void MaybeUpdateClientContextAndGetScriptsForUrl(const GURL& url);
+  void OnGetAnnotateDomModelVersionForGetScripts(
+      const GURL& url,
+      absl::optional<int64_t> model_version);
+  void GetScriptsForUrl(const GURL& url);
+
   ClientSettings settings_;
   const raw_ptr<Client> client_;
   const raw_ptr<const base::TickClock> tick_clock_;
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc
index 2ddc770..b36eaa1 100644
--- a/components/autofill_assistant/browser/controller_unittest.cc
+++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -2328,4 +2328,50 @@
   EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
 }
 
+TEST_F(ControllerTest, SkipModelVersionIfParameterNotSpecified) {
+  EXPECT_CALL(mock_client_, GetAnnotateDomModelVersion).Times(0);
+  EXPECT_CALL(*mock_service_, UpdateAnnotateDomModelContext).Times(0);
+  EXPECT_CALL(*mock_service_, GetScriptsForUrl)
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "",
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  controller_->Start(GURL("https://www.example.com"),
+                     std::make_unique<TriggerContext>(
+                         /* parameters = */ std::make_unique<ScriptParameters>(
+                             base::flat_map<std::string, std::string>{{}}),
+                         TriggerContext::Options()));
+}
+
+TEST_F(ControllerTest, AttachesAvailableModelVersionOnStart) {
+  EXPECT_CALL(mock_client_, GetAnnotateDomModelVersion)
+      .WillOnce(RunOnceCallback<0>(123456));
+  EXPECT_CALL(*mock_service_, UpdateAnnotateDomModelContext(123456));
+  EXPECT_CALL(*mock_service_, GetScriptsForUrl)
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "",
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  controller_->Start(GURL("https://www.example.com"),
+                     std::make_unique<TriggerContext>(
+                         /* parameters = */ std::make_unique<ScriptParameters>(
+                             base::flat_map<std::string, std::string>{
+                                 {"SEND_ANNOTATE_DOM_MODEL_VERSION", "true"}}),
+                         TriggerContext::Options()));
+}
+
+TEST_F(ControllerTest, DoesNotAttachUnavailableModelVersionOnStart) {
+  EXPECT_CALL(mock_client_, GetAnnotateDomModelVersion)
+      .WillOnce(RunOnceCallback<0>(absl::nullopt));
+  EXPECT_CALL(*mock_service_, UpdateAnnotateDomModelContext).Times(0);
+  EXPECT_CALL(*mock_service_, GetScriptsForUrl)
+      .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "",
+                                   ServiceRequestSender::ResponseInfo{}));
+
+  controller_->Start(GURL("https://www.example.com"),
+                     std::make_unique<TriggerContext>(
+                         /* parameters = */ std::make_unique<ScriptParameters>(
+                             base::flat_map<std::string, std::string>{
+                                 {"SEND_ANNOTATE_DOM_MODEL_VERSION", "true"}}),
+                         TriggerContext::Options()));
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
index 25f41df..12f126d1 100644
--- a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
+++ b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
@@ -98,8 +98,14 @@
 }
 
 bool StarterDelegateDesktop::GetIsLoggedIn() {
-  // Only relevant for trigger scripts, which don't exist in headless.
-  return false;
+  return !common_dependencies_
+              ->GetSignedInEmail(GetWebContents().GetBrowserContext())
+              .empty();
+}
+
+bool StarterDelegateDesktop::GetIsSupervisedUser() {
+  return common_dependencies_->IsSupervisedUser(
+      GetWebContents().GetBrowserContext());
 }
 
 bool StarterDelegateDesktop::GetIsCustomTab() const {
@@ -140,11 +146,13 @@
   return true;
 }
 
-const CommonDependencies* StarterDelegateDesktop::GetCommonDependencies() {
+const CommonDependencies* StarterDelegateDesktop::GetCommonDependencies()
+    const {
   return common_dependencies_.get();
 }
 
-const PlatformDependencies* StarterDelegateDesktop::GetPlatformDependencies() {
+const PlatformDependencies* StarterDelegateDesktop::GetPlatformDependencies()
+    const {
   return platform_dependencies_.get();
 }
 
diff --git a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
index ff14262..f2abd050 100644
--- a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
+++ b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
@@ -62,13 +62,14 @@
   void SetProactiveHelpSettingEnabled(bool enabled) override;
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
+  bool GetIsSupervisedUser() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
   std::unique_ptr<AssistantFieldTrialUtil> CreateFieldTrialUtil() override;
   bool IsAttached() override;
-  const CommonDependencies* GetCommonDependencies() override;
-  const PlatformDependencies* GetPlatformDependencies() override;
+  const CommonDependencies* GetCommonDependencies() const override;
+  const PlatformDependencies* GetPlatformDependencies() const override;
   base::WeakPtr<StarterPlatformDelegate> GetWeakPtr() override;
 
  private:
diff --git a/components/autofill_assistant/browser/fake_script_executor_ui_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_ui_delegate.cc
index 57eb6937..61f539b 100644
--- a/components/autofill_assistant/browser/fake_script_executor_ui_delegate.cc
+++ b/components/autofill_assistant/browser/fake_script_executor_ui_delegate.cc
@@ -165,7 +165,7 @@
     bool show_feedback_chip) {}
 
 bool FakeScriptExecutorUiDelegate::SupportsExternalActions() {
-  return false;
+  return true;
 }
 
 void FakeScriptExecutorUiDelegate::ExecuteExternalAction(
diff --git a/components/autofill_assistant/browser/fake_starter_platform_delegate.cc b/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
index 627ed6c5..28b9938 100644
--- a/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
+++ b/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
@@ -107,6 +107,10 @@
   return is_logged_in_;
 }
 
+bool FakeStarterPlatformDelegate::GetIsSupervisedUser() {
+  return is_supervised_user_;
+}
+
 bool FakeStarterPlatformDelegate::GetIsCustomTab() const {
   return is_custom_tab_;
 }
@@ -131,12 +135,13 @@
   return is_attached_;
 }
 
-const CommonDependencies* FakeStarterPlatformDelegate::GetCommonDependencies() {
+const CommonDependencies* FakeStarterPlatformDelegate::GetCommonDependencies()
+    const {
   return nullptr;
 }
 
 const PlatformDependencies*
-FakeStarterPlatformDelegate::GetPlatformDependencies() {
+FakeStarterPlatformDelegate::GetPlatformDependencies() const {
   return nullptr;
 }
 
diff --git a/components/autofill_assistant/browser/fake_starter_platform_delegate.h b/components/autofill_assistant/browser/fake_starter_platform_delegate.h
index ad71a43..70884dd 100644
--- a/components/autofill_assistant/browser/fake_starter_platform_delegate.h
+++ b/components/autofill_assistant/browser/fake_starter_platform_delegate.h
@@ -50,13 +50,14 @@
   void SetProactiveHelpSettingEnabled(bool enabled) override;
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
+  bool GetIsSupervisedUser() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
   std::unique_ptr<AssistantFieldTrialUtil> CreateFieldTrialUtil() override;
   bool IsAttached() override;
-  const CommonDependencies* GetCommonDependencies() override;
-  const PlatformDependencies* GetPlatformDependencies() override;
+  const CommonDependencies* GetCommonDependencies() const override;
+  const PlatformDependencies* GetPlatformDependencies() const override;
   base::WeakPtr<StarterPlatformDelegate> GetWeakPtr() override;
 
   // Intentionally public to give tests direct access.
@@ -78,6 +79,7 @@
   bool proactive_help_enabled_ = true;
   bool msbb_enabled_ = true;
   bool is_logged_in_ = true;
+  bool is_supervised_user_ = false;
   bool is_custom_tab_ = true;
   bool is_web_layer_ = true;
   bool is_tab_created_by_gsa_ = true;
diff --git a/components/autofill_assistant/browser/headless/client_headless.cc b/components/autofill_assistant/browser/headless/client_headless.cc
index 5766cf9..d34cfca 100644
--- a/components/autofill_assistant/browser/headless/client_headless.cc
+++ b/components/autofill_assistant/browser/headless/client_headless.cc
@@ -94,7 +94,8 @@
 }
 
 std::string ClientHeadless::GetSignedInEmail() const {
-  return common_dependencies_->GetSignedInEmail(GetWebContents());
+  return common_dependencies_->GetSignedInEmail(
+      GetWebContents()->GetBrowserContext());
 }
 
 absl::optional<std::pair<int, int>> ClientHeadless::GetWindowSize() const {
@@ -170,6 +171,11 @@
   return false;
 }
 
+void ClientHeadless::GetAnnotateDomModelVersion(
+    base::OnceCallback<void(absl::optional<int64_t>)> callback) const {
+  std::move(callback).Run(absl::nullopt);
+}
+
 void ClientHeadless::Shutdown(Metrics::DropOutReason reason) {}
 
 void ClientHeadless::FetchAccessToken(
diff --git a/components/autofill_assistant/browser/headless/client_headless.h b/components/autofill_assistant/browser/headless/client_headless.h
index cba8590..f39f16a3 100644
--- a/components/autofill_assistant/browser/headless/client_headless.h
+++ b/components/autofill_assistant/browser/headless/client_headless.h
@@ -70,6 +70,9 @@
   bool HasHadUI() const override;
   ScriptExecutorUiDelegate* GetScriptExecutorUiDelegate() override;
   bool MustUseBackendData() const override;
+  void GetAnnotateDomModelVersion(
+      base::OnceCallback<void(absl::optional<int64_t>)> callback)
+      const override;
 
   // Overrides AccessTokenFetcher
   void FetchAccessToken(
diff --git a/components/autofill_assistant/browser/mock_client.h b/components/autofill_assistant/browser/mock_client.h
index fdf1b26a..04c316d0 100644
--- a/components/autofill_assistant/browser/mock_client.h
+++ b/components/autofill_assistant/browser/mock_client.h
@@ -56,6 +56,8 @@
                void(base::OnceCallback<void(const std::string&)>));
   MOCK_METHOD0(GetScriptExecutorUiDelegate, ScriptExecutorUiDelegate*());
   MOCK_CONST_METHOD0(MustUseBackendData, bool());
+  MOCK_CONST_METHOD1(GetAnnotateDomModelVersion,
+                     void(base::OnceCallback<void(absl::optional<int64_t>)>));
 
  private:
   std::unique_ptr<MockPersonalDataManager> mock_personal_data_manager_;
diff --git a/components/autofill_assistant/browser/mock_client_context.h b/components/autofill_assistant/browser/mock_client_context.h
index cc9a593c..2827a9a 100644
--- a/components/autofill_assistant/browser/mock_client_context.h
+++ b/components/autofill_assistant/browser/mock_client_context.h
@@ -19,6 +19,7 @@
   ~MockClientContext() override;
 
   MOCK_METHOD1(Update, void(const TriggerContext& trigger_context));
+  MOCK_METHOD1(UpdateAnnotateDomModelContext, void(int64_t model_version));
   MOCK_CONST_METHOD0(AsProto, ClientContextProto());
 };
 
diff --git a/components/autofill_assistant/browser/mock_common_dependencies.h b/components/autofill_assistant/browser/mock_common_dependencies.h
index 6a6f8531..a500b44 100644
--- a/components/autofill_assistant/browser/mock_common_dependencies.h
+++ b/components/autofill_assistant/browser/mock_common_dependencies.h
@@ -32,7 +32,11 @@
               (const override));
   MOCK_METHOD(std::string,
               GetSignedInEmail,
-              (content::WebContents*),
+              (content::BrowserContext*),
+              (const override));
+  MOCK_METHOD(bool,
+              IsSupervisedUser,
+              (content::BrowserContext*),
               (const override));
   MOCK_METHOD(AnnotateDomModelService*,
               GetOrCreateAnnotateDomModelService,
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc
index 43ef4458..ce28fb3 100644
--- a/components/autofill_assistant/browser/script_executor_unittest.cc
+++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -214,7 +214,7 @@
                 {{"additional_param", "additional_param_value"},
                  {"param", "value"}})));
 
-        std::move(callback).Run(net::HTTP_OK, "",
+        std::move(callback).Run(net::HTTP_OK, /* response= */ "",
                                 ServiceRequestSender::ResponseInfo{});
       });
 
@@ -235,7 +235,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(AllOf(Field(&ScriptExecutor::Result::success, true),
@@ -269,7 +269,7 @@
                              ServiceRequestSender::ResponseInfo{})))
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions2_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -307,7 +307,7 @@
           Delay(&task_environment_, 600),
           RunOnceCallback<6>(net::HTTP_OK, Serialize(next_actions_response),
                              ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -342,7 +342,7 @@
           Delay(&task_environment_, 600),
           RunOnceCallback<6>(net::HTTP_OK, Serialize(next_actions_response),
                              ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -379,7 +379,7 @@
           Delay(&task_environment_, 600),
           RunOnceCallback<6>(net::HTTP_OK, Serialize(next_actions_response),
                              ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -415,7 +415,7 @@
           Delay(&task_environment_, 600),
           RunOnceCallback<6>(net::HTTP_OK, Serialize(next_actions_response),
                              ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -450,7 +450,7 @@
           Delay(&task_environment_, 600),
           RunOnceCallback<6>(net::HTTP_OK, Serialize(initial_actions_response),
                              ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -478,7 +478,7 @@
                                    ServiceRequestSender::ResponseInfo{}))
       .WillOnce(
           DoAll(Delay(&task_environment_, 600),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -532,7 +532,7 @@
       .WillOnce(DoAll(Delay(&task_environment_, 600),
                       RunOnceCallback<6>(net::HTTP_OK, Serialize(tell3),
                                          ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -684,7 +684,7 @@
       .WillOnce(DoAll(Delay(&task_environment_, 600),
                       RunOnceCallback<6>(net::HTTP_OK, Serialize(tell3),
                                          ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -745,7 +745,7 @@
       .WillOnce(DoAll(Delay(&task_environment_, 600),
                       RunOnceCallback<6>(net::HTTP_OK, Serialize(tell3),
                                          ServiceRequestSender::ResponseInfo{})))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -771,7 +771,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -790,7 +790,7 @@
                                    ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(AllOf(Field(&ScriptExecutor::Result::success, true),
@@ -812,7 +812,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(AllOf(Field(&ScriptExecutor::Result::success, true),
@@ -848,7 +848,7 @@
       // response.
       .WillOnce(
           DoAll(SaveArg<3>(&third_response_processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(AllOf(Field(&ScriptExecutor::Result::success, true),
@@ -891,7 +891,7 @@
                              ServiceRequestSender::ResponseInfo{})))
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions2_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -922,7 +922,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // executor_callback_.Run() not expected to be run just yet, as the action is
@@ -949,7 +949,7 @@
       .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response),
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -972,7 +972,7 @@
       .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response),
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
   EXPECT_CALL(executor_callback_,
               Run(Field(&ScriptExecutor::Result::success, true)));
@@ -1064,7 +1064,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // First check does not find the element, wait for dom waits 1s, then the
@@ -1097,11 +1097,11 @@
   std::vector<ProcessedActionProto> processed_actions2_capture;
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(DoAll(SaveArg<3>(&processed_actions1_capture),
-                      RunOnceCallback<6>(net::HTTP_OK, "",
+                      RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{})))
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions2_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   EXPECT_CALL(executor_callback_,
@@ -1134,15 +1134,15 @@
     testing::InSequence seq;
     EXPECT_CALL(mock_service_,
                 GetNextActions(_, _, "payload for interrupt1", _, _, _, _))
-        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                      ServiceRequestSender::ResponseInfo{}));
     EXPECT_CALL(mock_service_,
                 GetNextActions(_, _, "payload for interrupt2", _, _, _, _))
-        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                      ServiceRequestSender::ResponseInfo{}));
     EXPECT_CALL(mock_service_,
                 GetNextActions(_, _, "main script payload", _, _, _, _))
-        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+        .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                      ServiceRequestSender::ResponseInfo{}));
   }
 
@@ -1176,7 +1176,7 @@
 
   // All scripts succeed with no more actions.
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1263,7 +1263,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   EXPECT_CALL(executor_callback_,
@@ -1297,7 +1297,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   EXPECT_CALL(executor_callback_,
@@ -1356,7 +1356,7 @@
   // action.
   EXPECT_CALL(mock_service_, GetNextActions)
       .Times(2)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1420,7 +1420,7 @@
       }));
 
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1534,7 +1534,7 @@
       }));
 
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1576,7 +1576,7 @@
       .WillOnce(RunOnceCallback<6>(net::HTTP_OK,
                                    Serialize(next_actions_response),
                                    ServiceRequestSender::ResponseInfo{}))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1609,7 +1609,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(RunOnceCallback<6>(net::HTTP_OK, Serialize(actions_response),
                                    ServiceRequestSender::ResponseInfo{}))
-      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillOnce(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1649,7 +1649,7 @@
       .Times(3)
       .WillOnce(RunOnceCallback<6>(net::HTTP_OK, Serialize(interrupt_actions),
                                    ServiceRequestSender::ResponseInfo{}))
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1684,7 +1684,7 @@
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1708,7 +1708,7 @@
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(mock_service_, GetNextActions)
-      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, "",
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{}));
 
   EXPECT_CALL(executor_callback_,
@@ -1740,7 +1740,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // First check does not find the element, wait for dom waits 1s.
@@ -1784,7 +1784,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // Navigation starts before WaitForDom starts. WaitForDom does not wait and
@@ -1824,11 +1824,11 @@
   std::vector<ProcessedActionProto> processed_actions2_capture;
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(DoAll(SaveArg<3>(&processed_actions1_capture),
-                      RunOnceCallback<6>(net::HTTP_OK, "",
+                      RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                          ServiceRequestSender::ResponseInfo{})))
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions2_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   EXPECT_CALL(executor_callback_, Run(_));
@@ -1850,7 +1850,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ true);
@@ -1877,7 +1877,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // WaitForDom does NOT wait for navigation to end, it immediately checks for
@@ -1926,7 +1926,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // As the element doesn't exist, WaitForDom returns and waits for 1s.
@@ -1973,7 +1973,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // As the element doesn't exist, WaitForDom returns and waits for 1s.
@@ -2011,7 +2011,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // WaitForNavigation returns immediately
@@ -2034,7 +2034,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // WaitForNavigation waits for navigation to start after expect_navigation
@@ -2062,7 +2062,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // The first wait_for_navigation waits for the navigation to happen. After
@@ -2091,7 +2091,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false);
@@ -2128,7 +2128,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<3>(&processed_actions_capture),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   // WaitForNavigation waits for navigation to start after expect_navigation
@@ -2182,7 +2182,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<4>(&timing_stats),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
   executor_->Run(&user_data_, executor_callback_.Get());
   EXPECT_TRUE(task_environment_.NextTaskIsDelayed());
@@ -2212,7 +2212,7 @@
   EXPECT_CALL(mock_service_, GetNextActions)
       .WillOnce(
           DoAll(SaveArg<5>(&captured_network_stats),
-                RunOnceCallback<6>(net::HTTP_OK, "",
+                RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
                                    ServiceRequestSender::ResponseInfo{})));
 
   EXPECT_CALL(executor_callback_,
@@ -2294,5 +2294,91 @@
   EXPECT_FALSE(executor_->MustUseBackendData());
 }
 
+TEST_F(ScriptExecutorTest, ExternalActionDoesNotApplyTouchableArea) {
+  ActionsResponseProto actions_response;
+  ElementAreaProto area = MakeElementAreaProto("#area");
+  *actions_response.add_actions()
+       ->mutable_set_touchable_area()
+       ->mutable_element_area() = area;
+  actions_response.add_actions()->mutable_external_action()->mutable_info();
+
+  EXPECT_CALL(mock_service_, GetActions)
+      .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response),
+                                   ServiceRequestSender::ResponseInfo{}));
+  EXPECT_CALL(mock_service_, GetNextActions)
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
+                                         ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+
+  executor_->Run(&user_data_, executor_callback_.Get());
+  // The touchable area was never applied.
+  EXPECT_THAT(delegate_.GetTouchableElementAreaHistory(), IsEmpty());
+  // The delegate never entered prompt.
+  EXPECT_THAT(delegate_.GetStateHistory(), IsEmpty());
+}
+
+TEST_F(ScriptExecutorTest, ExternalActionDoesNotConsumeTouchableArea) {
+  ActionsResponseProto actions_response;
+  ElementAreaProto area = MakeElementAreaProto("#area");
+  *actions_response.add_actions()
+       ->mutable_set_touchable_area()
+       ->mutable_element_area() = area;
+  actions_response.add_actions()->mutable_external_action()->mutable_info();
+  auto* prompt_action = actions_response.add_actions()->mutable_prompt();
+  *prompt_action->add_choices()->mutable_auto_select_when()->mutable_match() =
+      ToSelectorProto("end_prompt");
+
+  EXPECT_CALL(mock_service_, GetActions)
+      .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response),
+                                   ServiceRequestSender::ResponseInfo{}));
+  EXPECT_CALL(mock_service_, GetNextActions)
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
+                                         ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  EXPECT_CALL(mock_web_controller_, FindElement(Selector({"end_prompt"}), _, _))
+      .WillOnce(RunOnceCallback<2>(OkClientStatus(),
+                                   std::make_unique<ElementFinderResult>()));
+  executor_->Run(&user_data_, executor_callback_.Get());
+  // Since the ExternalAction did not consume the touchable area, the following
+  // prompt action was able to apply it.
+  EXPECT_THAT(delegate_.GetTouchableElementAreaHistory(),
+              ElementsAre(area, ElementAreaProto::default_instance()));
+}
+
+TEST_F(ScriptExecutorTest, ExternalActionAppliesAndRestoresTouchableArea) {
+  ActionsResponseProto actions_response;
+  ElementAreaProto area = MakeElementAreaProto("#area");
+  *actions_response.add_actions()
+       ->mutable_set_touchable_area()
+       ->mutable_element_area() = area;
+  auto* external_action =
+      actions_response.add_actions()->mutable_external_action();
+  external_action->mutable_info();
+  external_action->set_show_touchable_area(true);
+
+  EXPECT_CALL(mock_service_, GetActions)
+      .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response),
+                                   ServiceRequestSender::ResponseInfo{}));
+  EXPECT_CALL(mock_service_, GetNextActions)
+      .WillRepeatedly(RunOnceCallback<6>(net::HTTP_OK, /* response= */ "",
+                                         ServiceRequestSender::ResponseInfo{}));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+
+  executor_->Run(&user_data_, executor_callback_.Get());
+  // The touchable area was applied at the start of the ExternalAction and
+  // restored at the end of it.
+  EXPECT_THAT(delegate_.GetTouchableElementAreaHistory(),
+              ElementsAre(area, ElementAreaProto::default_instance()));
+  EXPECT_THAT(delegate_.GetStateHistory(),
+              ElementsAre(AutofillAssistantState::PROMPT,
+                          AutofillAssistantState::RUNNING));
+}
+
 }  // namespace
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_parameters.cc b/components/autofill_assistant/browser/script_parameters.cc
index 238b1d6a0..99bab29 100644
--- a/components/autofill_assistant/browser/script_parameters.cc
+++ b/components/autofill_assistant/browser/script_parameters.cc
@@ -110,6 +110,10 @@
 // Parameter to disable CUP RPC signing. Intended for internal use only.
 const char kDisableRpcSigningParamaterName[] = "DISABLE_RPC_SIGNING";
 
+// Parameter to send the annotate DOM model version. Should only be used if we
+// expect the model to be used.
+const char kSendAnnotateDomModelVersion[] = "SEND_ANNOTATE_DOM_MODEL_VERSION";
+
 // 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
@@ -284,6 +288,10 @@
   return GetTypedParameter<bool>(parameters_, kDisableRpcSigningParamaterName);
 }
 
+absl::optional<bool> ScriptParameters::GetSendAnnotateDomModelVersion() const {
+  return GetTypedParameter<bool>(parameters_, kSendAnnotateDomModelVersion);
+}
+
 absl::optional<bool> ScriptParameters::GetDetailsShowInitial() const {
   return GetTypedParameter<bool>(parameters_, kDetailsShowInitialParameterName);
 }
diff --git a/components/autofill_assistant/browser/script_parameters.h b/components/autofill_assistant/browser/script_parameters.h
index 51815e4d3..a87c2c7 100644
--- a/components/autofill_assistant/browser/script_parameters.h
+++ b/components/autofill_assistant/browser/script_parameters.h
@@ -66,6 +66,7 @@
   absl::optional<int> GetSource() const;
   std::vector<std::string> GetExperiments() const;
   absl::optional<bool> GetDisableRpcSigning() const;
+  absl::optional<bool> GetSendAnnotateDomModelVersion() const;
 
   // Details parameters.
   absl::optional<bool> GetDetailsShowInitial() const;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 6cb4065d..2f014780 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -28,7 +28,7 @@
 }
 
 // Context contains client environment details.
-// Next ID: 21
+// Next ID: 22
 message ClientContextProto {
   message Chrome {
     optional string chrome_version = 1;
@@ -137,7 +137,13 @@
   }
   optional PlatformType platform_type = 20;
 
-  reserved 19;
+  // The model for semantic dom annotation.
+  message AnnotateDomModelContextProto {
+    optional int64 model_version = 1;
+  }
+  optional AnnotateDomModelContextProto annotate_dom_model_context = 22;
+
+  reserved 19, 21;
 }
 
 // Get the list of scripts that can potentially be run on a url.
diff --git a/components/autofill_assistant/browser/service/mock_service.h b/components/autofill_assistant/browser/service/mock_service.h
index 23c0e5a..abc4cd2 100644
--- a/components/autofill_assistant/browser/service/mock_service.h
+++ b/components/autofill_assistant/browser/service/mock_service.h
@@ -59,6 +59,10 @@
               SetDisableRpcSigning,
               (bool disable_rpc_signing),
               (override));
+  MOCK_METHOD(void,
+              UpdateAnnotateDomModelContext,
+              (int64_t model_version),
+              (override));
 };
 
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service.h b/components/autofill_assistant/browser/service/service.h
index 8da6be7..c0154c0d 100644
--- a/components/autofill_assistant/browser/service/service.h
+++ b/components/autofill_assistant/browser/service/service.h
@@ -60,6 +60,8 @@
 
   virtual void SetDisableRpcSigning(bool disable_rpc_signing) {}
 
+  virtual void UpdateAnnotateDomModelContext(int64_t model_version) {}
+
  protected:
   Service() = default;
 };
diff --git a/components/autofill_assistant/browser/service/service_impl.cc b/components/autofill_assistant/browser/service/service_impl.cc
index f46d5e1d..d713e03 100644
--- a/components/autofill_assistant/browser/service/service_impl.cc
+++ b/components/autofill_assistant/browser/service/service_impl.cc
@@ -183,10 +183,6 @@
       preexisting_payment_instrument_ids, std::move(callback), std::string());
 }
 
-void ServiceImpl::SetDisableRpcSigning(bool disable_rpc_signing) {
-  request_sender_->SetDisableRpcSigning(disable_rpc_signing);
-}
-
 void ServiceImpl::SendUserDataRequest(
     uint64_t run_id,
     bool request_name,
@@ -210,4 +206,12 @@
       RpcType::GET_USER_DATA);
 }
 
+void ServiceImpl::SetDisableRpcSigning(bool disable_rpc_signing) {
+  request_sender_->SetDisableRpcSigning(disable_rpc_signing);
+}
+
+void ServiceImpl::UpdateAnnotateDomModelContext(int64_t model_version) {
+  client_context_->UpdateAnnotateDomModelContext(model_version);
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service_impl.h b/components/autofill_assistant/browser/service/service_impl.h
index 8bc6015..d83fcb5 100644
--- a/components/autofill_assistant/browser/service/service_impl.h
+++ b/components/autofill_assistant/browser/service/service_impl.h
@@ -93,6 +93,8 @@
 
   void SetDisableRpcSigning(bool disable_rpc_signing) override;
 
+  void UpdateAnnotateDomModelContext(int64_t model_version) override;
+
  private:
   void SendUserDataRequest(
       uint64_t run_id,
diff --git a/components/autofill_assistant/browser/service/service_impl_unittest.cc b/components/autofill_assistant/browser/service/service_impl_unittest.cc
index 4498656..f2504a6e 100644
--- a/components/autofill_assistant/browser/service/service_impl_unittest.cc
+++ b/components/autofill_assistant/browser/service/service_impl_unittest.cc
@@ -254,5 +254,10 @@
                         mock_response_callback_.Get());
 }
 
+TEST_F(ServiceImplTest, UpdateAnnotateDomModelService) {
+  EXPECT_CALL(*mock_client_context_, UpdateAnnotateDomModelContext(123456));
+  service_->UpdateAnnotateDomModelContext(123456);
+}
+
 }  // namespace
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/starter.cc b/components/autofill_assistant/browser/starter.cc
index 02a1eaf..a1bc80a 100644
--- a/components/autofill_assistant/browser/starter.cc
+++ b/components/autofill_assistant/browser/starter.cc
@@ -470,7 +470,13 @@
   CancelPendingStartup(Metrics::TriggerScriptFinishedState::CANCELED);
   pending_trigger_context_ = std::move(trigger_context);
   if (!platform_delegate_->IsAttached()) {
-    OnStartDone(/* start_regular_script = */ false);
+    OnStartDone(/* start_script= */ false);
+    return;
+  }
+
+  if (platform_delegate_->GetIsSupervisedUser()) {
+    OnStartDone(/* start_script= */ false);
+    return;
   }
 
   if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
diff --git a/components/autofill_assistant/browser/starter_platform_delegate.h b/components/autofill_assistant/browser/starter_platform_delegate.h
index 1a4a554..8c91b2bc 100644
--- a/components/autofill_assistant/browser/starter_platform_delegate.h
+++ b/components/autofill_assistant/browser/starter_platform_delegate.h
@@ -89,6 +89,8 @@
   virtual bool GetMakeSearchesAndBrowsingBetterEnabled() const = 0;
   // Returns whether the user is logged in or not.
   virtual bool GetIsLoggedIn() = 0;
+  // Returns whether the user is restricted to any supervision.
+  virtual bool GetIsSupervisedUser() = 0;
   // Returns whether this is a custom tab or not.
   virtual bool GetIsCustomTab() const = 0;
   // Returns whether this is running in WebLayer or not.
@@ -102,9 +104,9 @@
   // as it might not be able to perform its functions while detached.
   virtual bool IsAttached() = 0;
   // Returns the common dependencies.
-  virtual const CommonDependencies* GetCommonDependencies() = 0;
+  virtual const CommonDependencies* GetCommonDependencies() const = 0;
   // Returns the platform dependencies.
-  virtual const PlatformDependencies* GetPlatformDependencies() = 0;
+  virtual const PlatformDependencies* GetPlatformDependencies() const = 0;
 
   virtual base::WeakPtr<StarterPlatformDelegate> GetWeakPtr() = 0;
 };
diff --git a/components/autofill_assistant/browser/starter_unittest.cc b/components/autofill_assistant/browser/starter_unittest.cc
index 389a31d..b1534fc 100644
--- a/components/autofill_assistant/browser/starter_unittest.cc
+++ b/components/autofill_assistant/browser/starter_unittest.cc
@@ -2386,4 +2386,39 @@
                      Metrics::AutofillAssistantExperiment::NO_EXPERIMENT}}})));
 }
 
+TEST_F(StarterTest, RegularStartupFailsForSupervisedUser) {
+  SetupPlatformDelegateForFirstTimeUser();
+  fake_platform_delegate_.is_supervised_user_ = true;
+
+  base::flat_map<std::string, std::string> script_parameters = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  TriggerContext::Options options;
+  options.initial_url = "https://redirect.com/to/www/example/com";
+  EXPECT_CALL(mock_start_regular_script_callback_, Run).Times(0);
+
+  starter_->Start(std::make_unique<TriggerContext>(
+      std::make_unique<ScriptParameters>(script_parameters), options));
+}
+
+TEST_F(StarterTest, RpcTriggerScriptStartupFailsForSupervisedUser) {
+  SetupPlatformDelegateForReturningUser();
+  fake_platform_delegate_.is_supervised_user_ = true;
+
+  base::flat_map<std::string, std::string> script_parameters = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "false"},
+      {"REQUEST_TRIGGER_SCRIPT", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  EXPECT_CALL(*mock_trigger_script_ui_delegate_, Attach).Times(0);
+  EXPECT_CALL(*mock_trigger_script_service_request_sender_, OnSendRequest)
+      .Times(0);
+  EXPECT_CALL(mock_start_regular_script_callback_, Run).Times(0);
+
+  starter_->Start(std::make_unique<TriggerContext>(
+      std::make_unique<ScriptParameters>(script_parameters),
+      TriggerContext::Options()));
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/browser/annotate_dom_model_service.cc b/components/autofill_assistant/content/browser/annotate_dom_model_service.cc
index bdaf61ad..37efddb 100644
--- a/components/autofill_assistant/content/browser/annotate_dom_model_service.cc
+++ b/components/autofill_assistant/content/browser/annotate_dom_model_service.cc
@@ -59,12 +59,11 @@
   // This and the optimization guide are keyed services, currently optimization
   // guide is a BrowserContextKeyedService, it will be cleaned first so removing
   // the observer should not be performed.
-  if (annotate_dom_model_file_) {
+  if (model_file_) {
     // If the model file is already loaded, it should be closed on a
     // background thread.
     background_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&CloseModelFile, std::move(*annotate_dom_model_file_)));
+        FROM_HERE, base::BindOnce(&CloseModelFile, std::move(*model_file_)));
   }
   for (auto& pending_request : pending_model_requests_) {
     // Clear any pending requests, no model file is acceptable as |Shutdown| is
@@ -85,23 +84,24 @@
   background_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(&LoadModelFile, model_info.GetModelFilePath()),
       base::BindOnce(&AnnotateDomModelService::OnModelFileLoaded,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr(), model_info.GetVersion()));
 }
 
-void AnnotateDomModelService::OnModelFileLoaded(base::File model_file) {
+void AnnotateDomModelService::OnModelFileLoaded(int64_t model_version,
+                                                base::File model_file) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!model_file.IsValid()) {
     return;
   }
 
-  if (annotate_dom_model_file_) {
+  if (model_file_) {
     // If the model file is already loaded, it should be closed on a background
     // thread.
     background_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&CloseModelFile, std::move(*annotate_dom_model_file_)));
+        FROM_HERE, base::BindOnce(&CloseModelFile, std::move(*model_file_)));
   }
-  annotate_dom_model_file_ = std::move(model_file);
+  model_file_ = std::move(model_file);
+  model_version_ = model_version;
   for (auto& pending_request : pending_model_requests_) {
     if (!pending_request) {
       continue;
@@ -111,13 +111,17 @@
   pending_model_requests_.clear();
 }
 
-absl::optional<base::File> AnnotateDomModelService::GetModelFile() {
-  if (!annotate_dom_model_file_) {
+absl::optional<base::File> AnnotateDomModelService::GetModelFile() const {
+  if (!model_file_) {
     return absl::nullopt;
   }
   // The model must be valid at this point.
-  DCHECK(annotate_dom_model_file_->IsValid());
-  return annotate_dom_model_file_->Duplicate();
+  DCHECK(model_file_->IsValid());
+  return model_file_->Duplicate();
+}
+
+absl::optional<int64_t> AnnotateDomModelService::GetModelVersion() const {
+  return model_version_;
 }
 
 std::string AnnotateDomModelService::GetOverridesPolicy() const {
@@ -131,7 +135,7 @@
 
 void AnnotateDomModelService::NotifyOnModelFileAvailable(
     NotifyModelAvailableCallback callback) {
-  DCHECK(!annotate_dom_model_file_);
+  DCHECK(!model_file_);
   if (pending_model_requests_.size() < kMaxPendingRequestsAllowed) {
     pending_model_requests_.emplace_back(std::move(callback));
     return;
@@ -140,7 +144,7 @@
 }
 
 void AnnotateDomModelService::SetModelFileForTest(base::File model_file) {
-  annotate_dom_model_file_ = std::move(model_file);
+  model_file_ = std::move(model_file);
   for (auto& pending_request : pending_model_requests_) {
     std::move(pending_request).Run(true);
   }
diff --git a/components/autofill_assistant/content/browser/annotate_dom_model_service.h b/components/autofill_assistant/content/browser/annotate_dom_model_service.h
index fbb0b81..8590808 100644
--- a/components/autofill_assistant/content/browser/annotate_dom_model_service.h
+++ b/components/autofill_assistant/content/browser/annotate_dom_model_service.h
@@ -46,10 +46,15 @@
       optimization_guide::proto::OptimizationTarget optimization_target,
       const optimization_guide::ModelInfo& model_info) override;
 
-  // Returns the annotate dom model file, should only be called when the model
-  // file is already available. See the |NotifyOnModelFileAvailable| for an
-  // asynchronous notification of the model being available.
-  absl::optional<base::File> GetModelFile();
+  // Returns the annotate dom model file. If this returns a nullopt, see the
+  // |NotifyOnModelFileAvailable| for an asynchronous notification of the model
+  // being available.
+  absl::optional<base::File> GetModelFile() const;
+
+  // Returns the model of the version. If this returns a nullopt, see the
+  // |NotifyOnModelFileAvailable| for an asynchronous notification of the model
+  // being available.
+  absl::optional<int64_t> GetModelVersion() const;
 
   // Returns the overrides policy as a serialized binary proto representation
   // that will be passed to renderer processes.
@@ -67,7 +72,7 @@
   void SetModelFileForTest(base::File model_file);
 
  private:
-  void OnModelFileLoaded(base::File model_file);
+  void OnModelFileLoaded(int64_t model_version, base::File model_file);
 
   // Optimization Guide Service that provides model files for this service.
   raw_ptr<optimization_guide::OptimizationGuideModelProvider> opt_guide_ =
@@ -76,7 +81,9 @@
   // The file that contains the annotate DOM model. Available when the
   // file path has been provided by the Optimization Guide and has been
   // successfully loaded.
-  absl::optional<base::File> annotate_dom_model_file_;
+  absl::optional<base::File> model_file_;
+  // The version of the current model.
+  absl::optional<int64_t> model_version_;
 
   // A serialized binary representation of a SemanticSelectorPolicy proto.
   std::string overrides_policy_binary_proto_;
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn
index d881deb..0b39a710 100644
--- a/components/history/core/browser/BUILD.gn
+++ b/components/history/core/browser/BUILD.gn
@@ -58,6 +58,8 @@
     "sync/history_delete_directives_model_type_controller.h",
     "sync/history_model_type_controller_helper.cc",
     "sync/history_model_type_controller_helper.h",
+    "sync/history_sync_metadata_database.cc",
+    "sync/history_sync_metadata_database.h",
     "sync/typed_url_model_type_controller.cc",
     "sync/typed_url_model_type_controller.h",
     "sync/typed_url_sync_bridge.cc",
@@ -218,6 +220,7 @@
     "history_service_unittest.cc",
     "history_types_unittest.cc",
     "sync/delete_directive_handler_unittest.cc",
+    "sync/history_sync_metadata_database_unittest.cc",
     "sync/typed_url_sync_bridge_unittest.cc",
     "sync/typed_url_sync_metadata_database_unittest.cc",
     "top_sites_database_unittest.cc",
diff --git a/components/history/core/browser/sync/history_sync_metadata_database.cc b/components/history/core/browser/sync/history_sync_metadata_database.cc
new file mode 100644
index 0000000..8cfa42bf
--- /dev/null
+++ b/components/history/core/browser/sync/history_sync_metadata_database.cc
@@ -0,0 +1,184 @@
+// 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/history/core/browser/sync/history_sync_metadata_database.h"
+
+#include <memory>
+
+#include "base/big_endian.h"
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "components/sync/model/metadata_batch.h"
+#include "components/sync/protocol/entity_metadata.pb.h"
+#include "sql/meta_table.h"
+#include "sql/statement.h"
+
+namespace history {
+
+namespace {
+
+// Key in sql::MetaTable, the value is a serialization of syner::ModelTypeState,
+// which tracks the overall sync state of the history datatype.
+const char kHistoryModelTypeStateKey[] = "history_model_type_state";
+
+}  // namespace
+
+// Description of database table:
+//
+// history_sync_metadata
+//   storage_key      The visit_time of an entry in the visits table (in
+//                    microseconds since the windows epoch, serialized into a
+//                    string in big-endian order), used to look up native data
+//                    with sync metadata records.
+//   value            Serialized sync EntityMetadata, which tracks the sync
+//                    state of each history entity.
+
+HistorySyncMetadataDatabase::HistorySyncMetadataDatabase() = default;
+HistorySyncMetadataDatabase::~HistorySyncMetadataDatabase() = default;
+
+bool HistorySyncMetadataDatabase::GetAllSyncMetadata(
+    syncer::MetadataBatch* metadata_batch) {
+  DCHECK(metadata_batch);
+  if (!GetAllEntityMetadata(metadata_batch)) {
+    return false;
+  }
+
+  sync_pb::ModelTypeState model_type_state;
+  if (!GetModelTypeState(&model_type_state)) {
+    return false;
+  }
+
+  metadata_batch->SetModelTypeState(model_type_state);
+  return true;
+}
+
+bool HistorySyncMetadataDatabase::UpdateSyncMetadata(
+    syncer::ModelType model_type,
+    const std::string& storage_key,
+    const sync_pb::EntityMetadata& metadata) {
+  DCHECK_EQ(model_type, syncer::HISTORY)
+      << "Only the HISTORY model type is supported";
+  DCHECK(!storage_key.empty());
+
+  sql::Statement s(
+      GetDB().GetUniqueStatement("INSERT OR REPLACE INTO history_sync_metadata "
+                                 "(storage_key, value) VALUES(?, ?)"));
+  s.BindInt64(0, StorageKeyToMicrosSinceWindowsEpoch(storage_key));
+  s.BindString(1, metadata.SerializeAsString());
+
+  return s.Run();
+}
+
+bool HistorySyncMetadataDatabase::ClearSyncMetadata(
+    syncer::ModelType model_type,
+    const std::string& storage_key) {
+  DCHECK_EQ(model_type, syncer::HISTORY)
+      << "Only the HISTORY model type is supported";
+  DCHECK(!storage_key.empty());
+
+  sql::Statement s(GetDB().GetUniqueStatement(
+      "DELETE FROM history_sync_metadata WHERE storage_key=?"));
+  s.BindInt64(0, StorageKeyToMicrosSinceWindowsEpoch(storage_key));
+
+  return s.Run();
+}
+
+bool HistorySyncMetadataDatabase::UpdateModelTypeState(
+    syncer::ModelType model_type,
+    const sync_pb::ModelTypeState& model_type_state) {
+  DCHECK_EQ(model_type, syncer::HISTORY)
+      << "Only the HISTORY model type is supported";
+  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
+
+  std::string serialized_state = model_type_state.SerializeAsString();
+  return GetMetaTable().SetValue(kHistoryModelTypeStateKey, serialized_state);
+}
+
+bool HistorySyncMetadataDatabase::ClearModelTypeState(
+    syncer::ModelType model_type) {
+  DCHECK_EQ(model_type, syncer::HISTORY)
+      << "Only the HISTORY model type is supported";
+  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
+  return GetMetaTable().DeleteKey(kHistoryModelTypeStateKey);
+}
+
+// static
+uint64_t HistorySyncMetadataDatabase::StorageKeyToMicrosSinceWindowsEpoch(
+    const std::string& storage_key) {
+  uint64_t microseconds_since_windows_epoch = 0;
+  DCHECK_EQ(storage_key.size(), sizeof(microseconds_since_windows_epoch));
+  base::ReadBigEndian(reinterpret_cast<const uint8_t*>(storage_key.data()),
+                      &microseconds_since_windows_epoch);
+  // Make sure microseconds_since_windows_epoch is set.
+  DCHECK_NE(microseconds_since_windows_epoch, 0u);
+  return microseconds_since_windows_epoch;
+}
+
+// static
+std::string HistorySyncMetadataDatabase::StorageKeyFromMicrosSinceWindowsEpoch(
+    uint64_t micros) {
+  std::string storage_key(sizeof(uint64_t), 0);
+  base::WriteBigEndian<uint64_t>(storage_key.data(), micros);
+  return storage_key;
+}
+
+// static
+base::Time HistorySyncMetadataDatabase::StorageKeyToVisitTime(
+    const std::string& storage_key) {
+  return base::Time::FromDeltaSinceWindowsEpoch(
+      base::Microseconds(StorageKeyToMicrosSinceWindowsEpoch(storage_key)));
+}
+
+// static
+std::string HistorySyncMetadataDatabase::StorageKeyFromVisitTime(
+    base::Time visit_time) {
+  return StorageKeyFromMicrosSinceWindowsEpoch(
+      visit_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+}
+
+bool HistorySyncMetadataDatabase::InitHistoryMetadataTable() {
+  if (!GetDB().DoesTableExist("history_sync_metadata")) {
+    if (!GetDB().Execute(
+            "CREATE TABLE history_sync_metadata "
+            "(storage_key INTEGER PRIMARY KEY NOT NULL, value BLOB)")) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool HistorySyncMetadataDatabase::GetAllEntityMetadata(
+    syncer::MetadataBatch* metadata_batch) {
+  DCHECK(metadata_batch);
+  sql::Statement s(GetDB().GetUniqueStatement(
+      "SELECT storage_key, value FROM history_sync_metadata"));
+
+  while (s.Step()) {
+    std::string storage_key =
+        StorageKeyFromMicrosSinceWindowsEpoch(s.ColumnInt64(0));
+    std::string serialized_metadata = s.ColumnString(1);
+    auto entity_metadata = std::make_unique<sync_pb::EntityMetadata>();
+    if (!entity_metadata->ParseFromString(serialized_metadata)) {
+      DLOG(WARNING) << "Failed to deserialize HISTORY model type "
+                       "sync_pb::EntityMetadata.";
+      return false;
+    }
+    metadata_batch->AddMetadata(storage_key, std::move(entity_metadata));
+  }
+  return true;
+}
+
+bool HistorySyncMetadataDatabase::GetModelTypeState(
+    sync_pb::ModelTypeState* state) {
+  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
+  std::string serialized_state;
+  if (!GetMetaTable().GetValue(kHistoryModelTypeStateKey, &serialized_state)) {
+    *state = sync_pb::ModelTypeState();
+    return true;
+  }
+
+  return state->ParseFromString(serialized_state);
+}
+
+}  // namespace history
diff --git a/components/history/core/browser/sync/history_sync_metadata_database.h b/components/history/core/browser/sync/history_sync_metadata_database.h
new file mode 100644
index 0000000..3c92537
--- /dev/null
+++ b/components/history/core/browser/sync/history_sync_metadata_database.h
@@ -0,0 +1,89 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_HISTORY_CORE_BROWSER_SYNC_HISTORY_SYNC_METADATA_DATABASE_H_
+#define COMPONENTS_HISTORY_CORE_BROWSER_SYNC_HISTORY_SYNC_METADATA_DATABASE_H_
+
+#include <string>
+
+#include "components/sync/base/model_type.h"
+#include "components/sync/model/sync_metadata_store.h"
+
+namespace base {
+class Time;
+}
+
+namespace sql {
+class Database;
+class MetaTable;
+}  // namespace sql
+
+namespace syncer {
+class MetadataBatch;
+}
+
+namespace history {
+
+// A sync metadata database maintains two things: the entity metadata table and
+// the datatype state, stored in the MetaTable. The entity metadata table
+// contains metadata (sync states) for each entity. The datatype state is the
+// overall state of the history sync datatype.
+class HistorySyncMetadataDatabase : public syncer::SyncMetadataStore {
+ public:
+  // After construction, subclasses must call InitHistoryMetadataTable() before
+  // doing anything else to make sure the database is initialized.
+  HistorySyncMetadataDatabase();
+
+  HistorySyncMetadataDatabase(const HistorySyncMetadataDatabase&) = delete;
+  HistorySyncMetadataDatabase& operator=(const HistorySyncMetadataDatabase&) =
+      delete;
+
+  ~HistorySyncMetadataDatabase() override;
+
+  // Reads all stored metadata for History and fills `metadata_batch` with it.
+  bool GetAllSyncMetadata(syncer::MetadataBatch* metadata_batch);
+
+  // syncer::SyncMetadataStore implementation.
+  bool UpdateSyncMetadata(syncer::ModelType model_type,
+                          const std::string& storage_key,
+                          const sync_pb::EntityMetadata& metadata) override;
+  bool ClearSyncMetadata(syncer::ModelType model_type,
+                         const std::string& storage_key) override;
+  bool UpdateModelTypeState(
+      syncer::ModelType model_type,
+      const sync_pb::ModelTypeState& model_type_state) override;
+  bool ClearModelTypeState(syncer::ModelType model_type) override;
+
+  // Conversion between timestamps and storage keys, exposed so that the bridge
+  // (and tests) can access this.
+  static uint64_t StorageKeyToMicrosSinceWindowsEpoch(
+      const std::string& storage_key);
+  static std::string StorageKeyFromMicrosSinceWindowsEpoch(uint64_t micros);
+
+  static base::Time StorageKeyToVisitTime(const std::string& storage_key);
+  static std::string StorageKeyFromVisitTime(base::Time visit_time);
+
+ protected:
+  // Called by derived classes on initialization to make sure the tables and
+  // indices are properly set up. Must be called before anything else.
+  bool InitHistoryMetadataTable();
+
+  // Returns the underlying database to be used.
+  virtual sql::Database& GetDB() = 0;
+
+  // Returns the database's MetaTable, where the ModelTypeState will be stored.
+  virtual sql::MetaTable& GetMetaTable() = 0;
+
+ private:
+  // Reads all sync_pb::EntityMetadata for History and fills `metadata_batch`
+  // with it.
+  bool GetAllEntityMetadata(syncer::MetadataBatch* metadata_batch);
+
+  // Reads sync_pb::ModelTypeState for History and fills `state` with it.
+  bool GetModelTypeState(sync_pb::ModelTypeState* state);
+};
+
+}  // namespace history
+
+#endif  // COMPONENTS_HISTORY_CORE_BROWSER_SYNC_HISTORY_SYNC_METADATA_DATABASE_H_
diff --git a/components/history/core/browser/sync/history_sync_metadata_database_unittest.cc b/components/history/core/browser/sync/history_sync_metadata_database_unittest.cc
new file mode 100644
index 0000000..9a129a2f3
--- /dev/null
+++ b/components/history/core/browser/sync/history_sync_metadata_database_unittest.cc
@@ -0,0 +1,215 @@
+// 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/history/core/browser/sync/history_sync_metadata_database.h"
+
+#include "base/big_endian.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "components/history/core/browser/url_row.h"
+#include "components/sync/model/metadata_batch.h"
+#include "components/sync/protocol/entity_metadata.pb.h"
+#include "components/sync/protocol/model_type_state.pb.h"
+#include "sql/meta_table.h"
+#include "sql/statement.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using sync_pb::EntityMetadata;
+using sync_pb::ModelTypeState;
+using syncer::EntityMetadataMap;
+using syncer::MetadataBatch;
+
+namespace history {
+
+namespace {
+
+// Some arbitrary timestamps (which happen to map to 20 May 2022).
+constexpr base::Time kVisitTime1 = base::Time::FromDeltaSinceWindowsEpoch(
+    base::Microseconds(13297523045341512ull));
+constexpr base::Time kVisitTime2 = base::Time::FromDeltaSinceWindowsEpoch(
+    base::Microseconds(13297523047664774ull));
+
+// Test implementation of HistorySyncMetadataDatabase that's backed by an
+// in-memory database.
+class TestHistorySyncMetadataDatabase : public HistorySyncMetadataDatabase {
+ public:
+  TestHistorySyncMetadataDatabase() {
+    EXPECT_TRUE(db_.OpenInMemory());
+    EXPECT_TRUE(
+        meta_table_.Init(&db_, /*version=*/1, /*compatible_version=*/1));
+
+    InitHistoryMetadataTable();
+  }
+  ~TestHistorySyncMetadataDatabase() override { db_.Close(); }
+
+  TestHistorySyncMetadataDatabase(const TestHistorySyncMetadataDatabase&) =
+      delete;
+  TestHistorySyncMetadataDatabase& operator=(
+      const TestHistorySyncMetadataDatabase&) = delete;
+
+  sql::Database& GetDB() override { return db_; }
+  sql::MetaTable& GetMetaTable() override { return meta_table_; }
+
+ private:
+  sql::Database db_;
+  sql::MetaTable meta_table_;
+};
+
+class HistorySyncMetadataDatabaseTest : public testing::Test {
+ public:
+  HistorySyncMetadataDatabaseTest() = default;
+
+  HistorySyncMetadataDatabaseTest(const HistorySyncMetadataDatabaseTest&) =
+      delete;
+  HistorySyncMetadataDatabaseTest& operator=(
+      const HistorySyncMetadataDatabaseTest&) = delete;
+
+  ~HistorySyncMetadataDatabaseTest() override = default;
+
+  TestHistorySyncMetadataDatabase* db() { return &metadata_db_; }
+
+ private:
+  TestHistorySyncMetadataDatabase metadata_db_;
+};
+
+TEST_F(HistorySyncMetadataDatabaseTest,
+       ConvertsBetweenStorageKeysAndTimestamps) {
+  ASSERT_NE(kVisitTime1, kVisitTime2);
+
+  const std::string storage_key1 =
+      HistorySyncMetadataDatabase::StorageKeyFromVisitTime(kVisitTime1);
+  const std::string storage_key2 =
+      HistorySyncMetadataDatabase::StorageKeyFromVisitTime(kVisitTime2);
+
+  // Different timestamps should result in different storage keys.
+  EXPECT_NE(storage_key1, storage_key2);
+
+  // StorageKeyFromMicros and StorageKeyFromVisitTime should be equivalent.
+  EXPECT_EQ(storage_key1,
+            HistorySyncMetadataDatabase::StorageKeyFromMicrosSinceWindowsEpoch(
+                kVisitTime1.ToDeltaSinceWindowsEpoch().InMicroseconds()));
+  EXPECT_EQ(storage_key2,
+            HistorySyncMetadataDatabase::StorageKeyFromMicrosSinceWindowsEpoch(
+                kVisitTime2.ToDeltaSinceWindowsEpoch().InMicroseconds()));
+
+  // Conversion from storage key back to base::Time should be lossless.
+  EXPECT_EQ(kVisitTime1,
+            HistorySyncMetadataDatabase::StorageKeyToVisitTime(storage_key1));
+  EXPECT_EQ(kVisitTime2,
+            HistorySyncMetadataDatabase::StorageKeyToVisitTime(storage_key2));
+}
+
+TEST_F(HistorySyncMetadataDatabaseTest, EmptyStateIsValid) {
+  MetadataBatch metadata_batch;
+  EXPECT_TRUE(db()->GetAllSyncMetadata(&metadata_batch));
+  EXPECT_EQ(0u, metadata_batch.TakeAllMetadata().size());
+  EXPECT_EQ(ModelTypeState().SerializeAsString(),
+            metadata_batch.GetModelTypeState().SerializeAsString());
+}
+
+TEST_F(HistorySyncMetadataDatabaseTest, StoresAndReturnsMetadata) {
+  const std::string storage_key1 =
+      HistorySyncMetadataDatabase::StorageKeyFromVisitTime(kVisitTime1);
+  const std::string storage_key2 =
+      HistorySyncMetadataDatabase::StorageKeyFromVisitTime(kVisitTime2);
+
+  // Store some data - both entity metadata and model type state.
+  EntityMetadata metadata1;
+  metadata1.set_sequence_number(1);
+  metadata1.set_client_tag_hash("client_hash1");
+  ASSERT_TRUE(
+      db()->UpdateSyncMetadata(syncer::HISTORY, storage_key1, metadata1));
+
+  ModelTypeState model_type_state;
+  model_type_state.set_initial_sync_done(true);
+  ASSERT_TRUE(db()->UpdateModelTypeState(syncer::HISTORY, model_type_state));
+
+  EntityMetadata metadata2;
+  metadata2.set_sequence_number(2);
+  metadata2.set_client_tag_hash("client_hash2");
+  ASSERT_TRUE(
+      db()->UpdateSyncMetadata(syncer::HISTORY, storage_key2, metadata2));
+
+  // Read the metadata and make sure it matches what we wrote.
+  MetadataBatch metadata_batch;
+  EXPECT_TRUE(db()->GetAllSyncMetadata(&metadata_batch));
+
+  EXPECT_TRUE(metadata_batch.GetModelTypeState().initial_sync_done());
+
+  EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
+  EXPECT_EQ(metadata_records.size(), 2u);
+  EXPECT_EQ(metadata_records[storage_key1]->sequence_number(), 1);
+  EXPECT_EQ(metadata_records[storage_key1]->client_tag_hash(), "client_hash1");
+  EXPECT_EQ(metadata_records[storage_key2]->sequence_number(), 2);
+  EXPECT_EQ(metadata_records[storage_key2]->client_tag_hash(), "client_hash2");
+
+  // Now check that an entity update and a model type state update replace the
+  // old values.
+  metadata1.set_sequence_number(2);
+  ASSERT_TRUE(
+      db()->UpdateSyncMetadata(syncer::HISTORY, storage_key1, metadata1));
+  model_type_state.set_initial_sync_done(false);
+  ASSERT_TRUE(db()->UpdateModelTypeState(syncer::HISTORY, model_type_state));
+
+  MetadataBatch metadata_batch2;
+  ASSERT_TRUE(db()->GetAllSyncMetadata(&metadata_batch2));
+  EXPECT_FALSE(metadata_batch2.GetModelTypeState().initial_sync_done());
+
+  EntityMetadataMap metadata_records2 = metadata_batch2.TakeAllMetadata();
+  EXPECT_EQ(metadata_records2.size(), 2u);
+  EXPECT_EQ(metadata_records2[storage_key1]->sequence_number(), 2);
+}
+
+TEST_F(HistorySyncMetadataDatabaseTest, DeletesSyncMetadata) {
+  const std::string storage_key =
+      HistorySyncMetadataDatabase::StorageKeyFromVisitTime(kVisitTime1);
+
+  // Write some data into the store.
+  ModelTypeState model_type_state;
+  model_type_state.set_initial_sync_done(true);
+  ASSERT_TRUE(db()->UpdateModelTypeState(syncer::HISTORY, model_type_state));
+
+  EntityMetadata metadata;
+  metadata.set_client_tag_hash("client_hash");
+  ASSERT_TRUE(db()->UpdateSyncMetadata(syncer::HISTORY, storage_key, metadata));
+
+  // Delete the data we just wrote.
+  ASSERT_TRUE(db()->ClearSyncMetadata(syncer::HISTORY, storage_key));
+
+  // It shouldn't be there anymore.
+  MetadataBatch metadata_batch;
+  ASSERT_TRUE(db()->GetAllSyncMetadata(&metadata_batch));
+  EXPECT_EQ(metadata_batch.GetAllMetadata().size(), 0u);
+
+  // Now delete the model type state and make sure it's gone.
+  ASSERT_NE(ModelTypeState().SerializeAsString(),
+            metadata_batch.GetModelTypeState().SerializeAsString());
+  ASSERT_TRUE(db()->ClearModelTypeState(syncer::HISTORY));
+  ASSERT_TRUE(db()->GetAllSyncMetadata(&metadata_batch));
+  EXPECT_EQ(ModelTypeState().SerializeAsString(),
+            metadata_batch.GetModelTypeState().SerializeAsString());
+}
+
+TEST_F(HistorySyncMetadataDatabaseTest, FailsToReadCorruptSyncMetadata) {
+  // Manually insert some corrupt data into the underlying sql DB.
+  sql::Statement s(db()->GetDB().GetUniqueStatement(
+      "INSERT OR REPLACE INTO history_sync_metadata (storage_key, value) "
+      "VALUES(1, 'unparseable')"));
+  ASSERT_TRUE(s.Run());
+
+  MetadataBatch metadata_batch;
+  EXPECT_FALSE(db()->GetAllSyncMetadata(&metadata_batch));
+}
+
+TEST_F(HistorySyncMetadataDatabaseTest, FailsToReadCorruptModelTypeState) {
+  // Insert some corrupt data into the meta table.
+  db()->GetMetaTable().SetValue("history_model_type_state", "unparseable");
+
+  MetadataBatch metadata_batch;
+  EXPECT_FALSE(db()->GetAllSyncMetadata(&metadata_batch));
+}
+
+}  // namespace
+
+}  // namespace history
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
index d7b3d963..e34aaad 100644
--- a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
+++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -39,8 +39,6 @@
     std::unique_ptr<SafeBrowsingApiHandler::URLCheckCallbackMeta> callback,
     SBThreatType threat_type,
     const ThreatMetadata& metadata) {
-  CHECK(callback);              // Remove after fixing crbug.com/889972
-  CHECK(!callback->is_null());  // Remove after fixing crbug.com/889972
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE, base::BindOnce(std::move(*callback), threat_type, metadata));
 }
@@ -126,17 +124,12 @@
 
   std::unique_ptr<SafeBrowsingApiHandler::URLCheckCallbackMeta> callback =
       std::move((*pending_callbacks)[callback_id]);
-  CHECK(callback);  // Remove after fixing crbug.com/889972
   pending_callbacks->erase(callback_id);
 
   if (result_status != RESULT_STATUS_SUCCESS) {
     if (result_status == RESULT_STATUS_TIMEOUT) {
-      CHECK(!callback->is_null());  // Remove after fixing crbug.com/889972
-
       ReportUmaResult(UMA_STATUS_TIMEOUT);
     } else {
-      CHECK(!callback->is_null());  // Remove after fixing crbug.com/889972
-
       DCHECK_EQ(result_status, RESULT_STATUS_INTERNAL_ERROR);
       ReportUmaResult(UMA_STATUS_INTERNAL_ERROR);
     }
@@ -146,13 +139,9 @@
 
   // Shortcut for safe, so we don't have to parse JSON.
   if (metadata == "{}") {
-    CHECK(!callback->is_null());  // Remove after fixing crbug.com/889972
-
     ReportUmaResult(UMA_STATUS_SAFE);
     std::move(*callback).Run(SB_THREAT_TYPE_SAFE, ThreatMetadata());
   } else {
-    CHECK(!callback->is_null());  // Remove after fixing crbug.com/889972
-
     // Unsafe, assuming we can parse the JSON.
     SBThreatType worst_threat;
     ThreatMetadata threat_metadata;
diff --git a/components/signin/internal/identity_manager/account_tracker_service.cc b/components/signin/internal/identity_manager/account_tracker_service.cc
index 01b00a21..3aab443 100644
--- a/components/signin/internal/identity_manager/account_tracker_service.cc
+++ b/components/signin/internal/identity_manager/account_tracker_service.cc
@@ -247,18 +247,16 @@
   return AccountInfo();
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 AccountTrackerService::AccountIdMigrationState
 AccountTrackerService::GetMigrationState() const {
   return GetMigrationState(pref_service_);
 }
 
 void AccountTrackerService::SetMigrationDone() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   SetMigrationState(MIGRATION_DONE);
-#else
-  NOTREACHED() << "Migration cannot be in progress on this platform";
-#endif
 }
+#endif
 
 void AccountTrackerService::NotifyAccountUpdated(
     const AccountInfo& account_info) {
@@ -491,19 +489,14 @@
   DCHECK(state != MIGRATION_DONE || AreAllAccountsMigrated());
   pref_service_->SetInteger(prefs::kAccountIdMigrationState, state);
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // static
 AccountTrackerService::AccountIdMigrationState
 AccountTrackerService::GetMigrationState(const PrefService* pref_service) {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   return static_cast<AccountTrackerService::AccountIdMigrationState>(
       pref_service->GetInteger(prefs::kAccountIdMigrationState));
-#else
-  // Migration is now done on all other platforms
-  return AccountIdMigrationState::MIGRATION_DONE;
-#endif
 }
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 base::FilePath AccountTrackerService::GetImagePathFor(
     const CoreAccountId& account_id) {
@@ -699,12 +692,12 @@
     }
   }
   DCHECK(GetMigrationState() != MIGRATION_DONE || AreAllAccountsMigrated());
-#else
-  DCHECK(AreAllAccountsMigrated());
-#endif
 
   UMA_HISTOGRAM_ENUMERATION("Signin.AccountTracker.GaiaIdMigrationState",
                             GetMigrationState(), NUM_MIGRATION_STATES);
+#else
+  DCHECK(AreAllAccountsMigrated());
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   UMA_HISTOGRAM_COUNTS_100("Signin.AccountTracker.CountOfLoadedAccounts",
                            accounts_.size());
@@ -783,6 +776,7 @@
     const PrefService* pref_service,
     const std::string& gaia,
     const std::string& email) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   DCHECK(!gaia.empty() ||
          GetMigrationState(pref_service) == MIGRATION_NOT_STARTED);
   DCHECK(!email.empty());
@@ -796,6 +790,9 @@
       NOTREACHED();
       return CoreAccountId::FromString(email);
   }
+#else
+  return CoreAccountId::FromGaiaId(gaia);
+#endif
 }
 
 CoreAccountId AccountTrackerService::SeedAccountInfo(const std::string& gaia,
diff --git a/components/signin/internal/identity_manager/account_tracker_service.h b/components/signin/internal/identity_manager/account_tracker_service.h
index 0063ce8..c3bd96d 100644
--- a/components/signin/internal/identity_manager/account_tracker_service.h
+++ b/components/signin/internal/identity_manager/account_tracker_service.h
@@ -60,6 +60,7 @@
   typedef base::RepeatingCallback<void(const AccountInfo& info)>
       AccountInfoCallback;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Possible values for the kAccountIdMigrationState preference.
   // Keep in sync with OAuth2LoginAccountRevokedMigrationState histogram enum.
   // These values are persisted to logs. Entries should not be renumbered and
@@ -70,6 +71,7 @@
     MIGRATION_DONE = 2,
     NUM_MIGRATION_STATES
   };
+#endif
 
   AccountTrackerService();
 
@@ -122,8 +124,10 @@
 
   void RemoveAccount(const CoreAccountId& account_id);
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   AccountIdMigrationState GetMigrationState() const;
   void SetMigrationDone();
+#endif
 
 #if BUILDFLAG(IS_ANDROID)
   // Returns a reference to the corresponding Java AccountTrackerService object.
@@ -208,17 +212,15 @@
                              bool success);
   void RemoveAccountImageFromDisk(const CoreAccountId& account_id);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Migrate accounts to be keyed by gaia id instead of normalized email.
-  // Requires that the migration state is set to MIGRATION_IN_PROGRESS.
-  void MigrateToGaiaId();
-#endif
-
   // Returns whether the accounts are all keyed by gaia id. This should
   // be the case when the migration state is set to MIGRATION_DONE.
   bool AreAllAccountsMigrated() const;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Migrate accounts to be keyed by gaia id instead of normalized email.
+  // Requires that the migration state is set to MIGRATION_IN_PROGRESS.
+  void MigrateToGaiaId();
+
   // Computes the new migration state. The state is saved to preference
   // before performing the migration in order to support resuming the
   // migration if necessary during the next load.
@@ -226,11 +228,11 @@
 
   // Updates the migration state in the preferences.
   void SetMigrationState(AccountIdMigrationState state);
-#endif
 
   // Returns the saved migration state in the preferences.
   static AccountIdMigrationState GetMigrationState(
       const PrefService* pref_service);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   raw_ptr<PrefService> pref_service_ = nullptr;  // Not owned.
   std::map<CoreAccountId, AccountInfo> accounts_;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
index 4d5dc82..332053c 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -474,8 +474,6 @@
 
     VLOG(1) << "MutablePO2TS::LoadAllCredentialsIntoMemory; "
             << db_tokens.size() << " Credential(s).";
-    AccountTrackerService::AccountIdMigrationState migration_state =
-        account_tracker_service_->GetMigrationState();
     for (auto iter = db_tokens.begin(); iter != db_tokens.end(); ++iter) {
       std::string prefixed_account_id = iter->first;
       std::string refresh_token = iter->second;
@@ -492,55 +490,9 @@
       } else {
         DCHECK(!refresh_token.empty());
         CoreAccountId account_id = RemoveAccountIdPrefix(prefixed_account_id);
-
-        switch (migration_state) {
-          case AccountTrackerService::MIGRATION_IN_PROGRESS: {
-            // Migrate to gaia-ids.
-            AccountInfo account_info =
-                account_tracker_service_->FindAccountInfoByEmail(
-                    account_id.ToString());
-            // |account_info| can be empty if |account_id| was already migrated.
-            // This could happen if the chrome was closed in the middle of the
-            // account id migration.
-            if (!account_info.IsEmpty()) {
-              ClearPersistedCredentials(account_id);
-              account_id = account_info.account_id;
-              PersistCredentials(account_id, refresh_token);
-            }
-
-            // Skip duplicate accounts, this could happen if migration was
-            // crashed in the middle.
-            if (refresh_tokens_.count(account_id) != 0)
-              continue;
-            break;
-          }
-          case AccountTrackerService::MIGRATION_NOT_STARTED:
-            // If the account_id is an email address, then canonicalize it. This
-            // is to support legacy account_ids, and will not be needed after
-            // switching to gaia-ids.
-            if (account_id.ToString().find('@') != std::string::npos) {
-              // If the canonical account id is not the same as the loaded
-              // account id, make sure not to overwrite a refresh token from
-              // a canonical version.  If no canonical version was loaded, then
-              // re-persist this refresh token with the canonical account id.
-              CoreAccountId canon_account_id = CoreAccountId::FromEmail(
-                  gaia::CanonicalizeEmail(account_id.ToString()));
-              if (canon_account_id != account_id) {
-                ClearPersistedCredentials(account_id);
-                if (db_tokens.count(
-                        ApplyAccountIdPrefix(canon_account_id.ToString())) == 0)
-                  PersistCredentials(canon_account_id, refresh_token);
-              }
-              account_id = canon_account_id;
-            }
-            break;
-          case AccountTrackerService::MIGRATION_DONE:
-            DCHECK_EQ(std::string::npos, account_id.ToString().find('@'));
-            break;
-          case AccountTrackerService::NUM_MIGRATION_STATES:
-            NOTREACHED();
-            break;
-        }
+        DCHECK(!account_id.IsEmail())
+            << "Expecting a Gaia ID as account id [ account_id = " << account_id
+            << "]";
 
         // Only load secondary accounts when account consistency is enabled.
         bool load_account =
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc
index c65305fa..0f5f38b 100644
--- a/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -87,6 +87,7 @@
                                     !pref_account_id.empty());
   }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!pref_account_id.empty()) {
     if (account_tracker_service_->GetMigrationState() ==
         AccountTrackerService::MIGRATION_IN_PROGRESS) {
@@ -100,6 +101,7 @@
       }
     }
   }
+#endif
 
   bool consented =
       client_->GetPrefs()->GetBoolean(prefs::kGoogleServicesConsentedToSync);
@@ -365,10 +367,12 @@
 void PrimaryAccountManager::OnRefreshTokensLoaded() {
   token_service_->RemoveObserver(this);
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (account_tracker_service_->GetMigrationState() ==
       AccountTrackerService::MIGRATION_IN_PROGRESS) {
     account_tracker_service_->SetMigrationDone();
   }
+#endif
 
   // Remove account information from the account tracker service if needed.
   if (token_service_->HasLoadCredentialsFinishedWithNoErrors()) {
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
index 31283be..010b083f 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
@@ -160,20 +160,6 @@
           env, reinterpret_cast<intptr_t>(this),
           account_tracker_service_->GetJavaObject());
   java_ref_.Reset(env, local_java_ref.obj());
-
-  if (account_tracker_service_->GetMigrationState() ==
-      AccountTrackerService::MIGRATION_IN_PROGRESS) {
-    std::vector<CoreAccountId> accounts = GetAccounts();
-    std::vector<CoreAccountId> accounts_id;
-    for (auto account_name : accounts) {
-      std::string email = account_name.ToString();
-      AccountInfo account_info =
-          account_tracker_service_->FindAccountInfoByEmail(email);
-      DCHECK(!account_info.gaia.empty());
-      accounts_id.push_back(CoreAccountId::FromGaiaId(account_info.gaia));
-    }
-    SetAccounts(accounts_id);
-  }
 }
 
 ProfileOAuth2TokenServiceDelegateAndroid::
@@ -365,14 +351,6 @@
     if (!base::Contains(curr_ids, info.account_id))
       account_tracker_service_->RemoveAccount(info.account_id);
   }
-
-  // No need to wait for PrimaryAccountManager to finish migration if not signed
-  // in.
-  if (account_tracker_service_->GetMigrationState() ==
-          AccountTrackerService::MIGRATION_IN_PROGRESS &&
-      !signed_in_account_id.has_value()) {
-    account_tracker_service_->SetMigrationDone();
-  }
 }
 
 bool ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc
index 4fbf6f23..f3875d1 100644
--- a/components/signin/public/identity_manager/identity_manager.cc
+++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -426,8 +426,12 @@
 
 IdentityManager::AccountIdMigrationState
 IdentityManager::GetAccountIdMigrationState() const {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   return static_cast<IdentityManager::AccountIdMigrationState>(
       account_tracker_service_->GetMigrationState());
+#else
+  return IdentityManager::AccountIdMigrationState::MIGRATION_DONE;
+#endif
 }
 
 CoreAccountId IdentityManager::PickAccountIdForAccount(
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 1e2eca9..6d6fba2 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -84,6 +84,10 @@
 constexpr int kMaxScreencastFramesInFlight = 2;
 constexpr char kCommandIsOnlyAvailableAtTopTarget[] =
     "Command can only be executed on top-level targets";
+constexpr char kErrorNotAttached[] = "Not attached to a page";
+constexpr char kErrorInactivePage[] = "Not attached to an active page";
+constexpr char kErrorNonTopLevelFrames[] =
+    "This is only supported for top-level frames";
 
 Binary EncodeImage(const gfx::Image& image,
                    const std::string& format,
@@ -394,7 +398,7 @@
 Response PageHandler::Crash() {
   WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
   if (!web_contents)
-    return Response::ServerError("Not attached to a page");
+    return Response::ServerError(kErrorNotAttached);
   if (web_contents->IsCrashed())
     return Response::ServerError("The target has already crashed");
   if (host_->frame_tree_node()->navigation_request())
@@ -404,7 +408,7 @@
 
 Response PageHandler::Close() {
   if (!host_)
-    return Response::ServerError("Not attached to a page");
+    return Response::ServerError(kErrorNotAttached);
 
   if (!host_->IsOutermostMainFrame())
     return Response::ServerError(kCommandIsOnlyAvailableAtTopTarget);
@@ -418,7 +422,7 @@
                          Maybe<std::string> script_to_evaluate_on_load,
                          std::unique_ptr<ReloadCallback> callback) {
   if (!host_) {
-    callback->sendFailure(Response::ServerError("Not attached to a page"));
+    callback->sendFailure(Response::ServerError(kErrorNotAttached));
     return;
   }
 
@@ -994,9 +998,9 @@
 
 Response PageHandler::HandleJavaScriptDialog(bool accept,
                                              Maybe<std::string> prompt_text) {
-  WebContentsImpl* web_contents = GetWebContents();
-  if (!web_contents)
-    return Response::InternalError();
+  Response response = AssureTopLevelActiveFrame();
+  if (response.IsError())
+    return response;
 
   if (pending_dialog_.is_null())
     return Response::InvalidParams("No dialog is showing");
@@ -1007,6 +1011,7 @@
   std::move(pending_dialog_).Run(accept, prompt_override);
 
   // Clean up the dialog UI if any.
+  WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
   if (web_contents->GetDelegate()) {
     JavaScriptDialogManager* manager =
         web_contents->GetDelegate()->GetJavaScriptDialogManager(web_contents);
@@ -1074,6 +1079,19 @@
          !(++frame_counter_ % capture_every_nth_frame_);
 }
 
+Response PageHandler::AssureTopLevelActiveFrame() {
+  if (!host_)
+    return Response::ServerError(kErrorNotAttached);
+
+  if (!host_->IsActive())
+    return Response::ServerError(kErrorInactivePage);
+
+  if (host_->GetParentOrOuterDocument())
+    return Response::ServerError(kErrorNonTopLevelFrames);
+
+  return Response::Success();
+}
+
 void PageHandler::InnerSwapCompositorFrame() {
   if (!host_)
     return;
@@ -1277,16 +1295,11 @@
 }
 
 Response PageHandler::SetWebLifecycleState(const std::string& state) {
-  if (!host_)
-    return Response::ServerError("Not attached to a page");
-
   // Inactive pages(e.g., a prerendered or back-forward cached page) should not
   // affect the state.
-  if (!host_->IsActive())
-    return Response::ServerError("Not attached to an active page");
-
-  if (host_->GetParentOrOuterDocument())
-    return Response::ServerError("This is only supported for top-level frames");
+  Response response = AssureTopLevelActiveFrame();
+  if (response.IsError())
+    return response;
 
   WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
   if (state == Page::SetWebLifecycleState::StateEnum::Frozen) {
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h
index d74a47e..065763b 100644
--- a/content/browser/devtools/protocol/page_handler.h
+++ b/content/browser/devtools/protocol/page_handler.h
@@ -184,6 +184,7 @@
   enum EncodingFormat { PNG, JPEG };
 
   bool ShouldCaptureNextScreencastFrame();
+  Response AssureTopLevelActiveFrame();
   void NotifyScreencastVisibility(bool visible);
   void InnerSwapCompositorFrame();
   void OnFrameFromVideoConsumer(scoped_refptr<media::VideoFrame> frame);
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index c93548b2..c91c101 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -7165,7 +7165,8 @@
   if (coop_value ==
           network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep &&
       !CompatibleWithCrossOriginIsolated(
-          policies.cross_origin_embedder_policy)) {
+          policies.cross_origin_embedder_policy) &&
+      !anonymous_) {
     NOTREACHED();
     base::debug::DumpWithoutCrashing();
     return false;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index b41b617..0af88f1e 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -231,6 +231,8 @@
 #include "third_party/blink/public/common/permissions/permission_utils.h"
 #include "third_party/blink/public/common/permissions_policy/document_policy.h"
 #include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
 #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/broadcastchannel/broadcast_channel.mojom.h"
@@ -1119,6 +1121,25 @@
       std::move(callback));
 }
 
+// Records the identifiable surface metric associated with a document created
+// event when the identifiability study is active.
+void RecordIdentifiabilityDocumentCreatedMetrics(
+    const ukm::SourceId document_ukm_source_id,
+    ukm::UkmRecorder* ukm_recorder,
+    ukm::SourceId navigation_source_id,
+    bool is_cross_origin_frame,
+    bool is_cross_site_frame,
+    bool is_main_frame) {
+  if (blink::IdentifiabilityStudySettings::Get()->IsActive()) {
+    blink::IdentifiabilityStudyDocumentCreated(document_ukm_source_id)
+        .SetNavigationSourceId(navigation_source_id)
+        .SetIsMainFrame(is_main_frame)
+        .SetIsCrossOriginFrame(is_cross_origin_frame)
+        .SetIsCrossSiteFrame(is_cross_site_frame)
+        .Record(ukm_recorder);
+  }
+}
+
 }  // namespace
 
 class RenderFrameHostImpl::SubresourceLoaderFactoriesConfig {
@@ -13312,6 +13333,10 @@
       .SetIsCrossOriginFrame(is_cross_origin_frame)
       .SetIsCrossSiteFrame(is_cross_site_frame)
       .Record(ukm_recorder);
+
+  RecordIdentifiabilityDocumentCreatedMetrics(
+      document_ukm_source_id, ukm_recorder, GetPageUkmSourceId(),
+      is_cross_origin_frame, is_cross_site_frame, IsOutermostMainFrame());
 }
 
 void RenderFrameHostImpl::BindReportingObserver(
diff --git a/extensions/browser/task_queue_util.cc b/extensions/browser/task_queue_util.cc
index 5ab77e6..8dd5ec6 100644
--- a/extensions/browser/task_queue_util.cc
+++ b/extensions/browser/task_queue_util.cc
@@ -19,6 +19,20 @@
 
 namespace {
 
+#if DCHECK_IS_ON()
+// Whether the task queue is allowed to be created for OTR profile.
+bool IsOffTheRecordContextAllowed(content::BrowserContext* browser_context) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // In Guest mode on Chrome OS we want to create a task queue for OTR profile.
+  if (ExtensionsBrowserClient::Get()->IsGuestSession(browser_context))
+    return true;
+#endif
+
+  // In other cases don't create a task queue for OTR profile.
+  return false;
+}
+#endif  // DCHECK_IS_ON()
+
 // Get the ServiceWorkerTaskQueue instance for the BrowserContext.
 //
 ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForBrowserContext(
@@ -73,6 +87,11 @@
 void DoTaskQueueFunction(content::BrowserContext* browser_context,
                          const Extension* extension,
                          TaskQueueFunction function) {
+#if DCHECK_IS_ON()
+  DCHECK(IsOffTheRecordContextAllowed(browser_context) ||
+         !browser_context->IsOffTheRecord());
+#endif  // DCHECK_IS_ON()
+
   // This is only necessary for service worker-based extensions.
   if (!BackgroundInfo::IsServiceWorkerBased(extension))
     return;
@@ -113,14 +132,12 @@
 
 void ActivateTaskQueueForExtension(content::BrowserContext* browser_context,
                                    const Extension* extension) {
-  DCHECK(!browser_context->IsOffTheRecord());
   DoTaskQueueFunction(browser_context, extension,
                       &ServiceWorkerTaskQueue::ActivateExtension);
 }
 
 void DeactivateTaskQueueForExtension(content::BrowserContext* browser_context,
                                      const Extension* extension) {
-  DCHECK(!browser_context->IsOffTheRecord());
   DoTaskQueueFunction(browser_context, extension,
                       &ServiceWorkerTaskQueue::DeactivateExtension);
 }
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index 96bea634..08eca74 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -64,6 +64,7 @@
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/ui/image_util",
     "//ios/chrome/browser/ui/util",
+    "//ios/chrome/browser/ui/util:util_swift",
     "//ios/chrome/browser/webdata_services",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/elements:form_input_accessory",
diff --git a/ios/chrome/browser/autofill/DEPS b/ios/chrome/browser/autofill/DEPS
index 4b25f80..8d01a10 100644
--- a/ios/chrome/browser/autofill/DEPS
+++ b/ios/chrome/browser/autofill/DEPS
@@ -22,6 +22,8 @@
   ],
   "^form_suggestion_view.mm": [
     "+ios/chrome/browser/ui/util/rtl_geometry.h",
+    "+ios/chrome/browser/ui/util/layout_guide_names.h",
+    "+ios/chrome/browser/ui/util/util_swift.h",
     "+ios/chrome/common/ui/util/constraints_ui_util.h",
   ],
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
index f67f177..6622b67c 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
@@ -19,7 +19,7 @@
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
 #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_consumer.h"
 #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h"
-#include "ios/chrome/browser/ui/bubble/bubble_features.h"
+#import "ios/chrome/browser/ui/bubble/bubble_features.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/test/fakes/fake_navigation_context.h"
@@ -156,8 +156,7 @@
 class FormSuggestionControllerTest : public PlatformTest {
  public:
   FormSuggestionControllerTest()
-      : test_form_activity_tab_helper_(&fake_web_state_),
-        call_to_animate_suggestion_label_counter_(0) {}
+      : test_form_activity_tab_helper_(&fake_web_state_) {}
 
   FormSuggestionControllerTest(const FormSuggestionControllerTest&) = delete;
   FormSuggestionControllerTest& operator=(const FormSuggestionControllerTest&) =
@@ -194,11 +193,6 @@
     [[[mock_consumer stub] andDo:mockShow]
         showAccessorySuggestions:[OCMArg any]];
 
-    // Mock the consumer to check call on |animateSuggestionLabel|.
-    void (^mockCallAnimate)(NSInvocation*) = ^(NSInvocation* invocation) {
-      call_to_animate_suggestion_label_counter_ += 1;
-    };
-    [[[mock_consumer stub] andDo:mockCallAnimate] animateSuggestionLabel];
     id mock_window = OCMClassMock([UIWindow class]);
 
     id mock_web_state_view = OCMClassMock([UIView class]);
@@ -234,6 +228,11 @@
   // Accessory view controller.
   FormInputAccessoryMediator* accessory_mediator_;
 
+  // The scoped feature list to enable/disable features. This needs to be placed
+  // before task_environment_, as per
+  // https://source.chromium.org/chromium/chromium/src/+/main:base/test/scoped_feature_list.h;l=37-41;drc=fe05104cfedb627fa99f218d7d1af6862871566c.
+  base::test::ScopedFeatureList scoped_feature_list_;
+
   // The associated test Web Threads.
   web::WebTaskEnvironment task_environment_;
 
@@ -243,9 +242,6 @@
   // The fake form tracker to simulate form events.
   autofill::TestFormActivityTabHelper test_form_activity_tab_helper_;
 
-  // Counter to track consumer call on |animateSuggestionLabel|.
-  NSInteger call_to_animate_suggestion_label_counter_;
-
   // Mock FormInputAccessoryMediatorHandler for verifying interactions.
   id mock_handler_;
 };
@@ -466,41 +462,11 @@
   EXPECT_NSEQ(suggestions[0], [provider suggestion]);
 }
 
-// Tests that the password suggestion highlight is disabled if the flag is
-// disabled.
-TEST_F(FormSuggestionControllerTest, SuggestionHighlightNoFlag) {
-  NSArray* suggestions = @[
-    [FormSuggestion suggestionWithValue:@"foo"
-                     displayDescription:nil
-                                   icon:@""
-                             identifier:0
-                         requiresReauth:NO],
-  ];
-  TestSuggestionProvider* provider =
-      [[TestSuggestionProvider alloc] initWithSuggestions:suggestions];
-  SetUpController(@[ provider ]);
-  GURL url("http://foo.com");
-  fake_web_state_.SetCurrentURL(url);
-  auto main_frame = web::FakeWebFrame::CreateMainWebFrame(url);
-
-  autofill::FormActivityParams params;
-  params.form_name = "form";
-  params.field_identifier = "field_id";
-  params.field_type = "password";
-  params.type = "type";
-  params.value = "value";
-  params.frame_id = "frame_id";
-  params.input_missing = false;
-  test_form_activity_tab_helper_.FormActivityRegistered(main_frame.get(),
-                                                        params);
-  EXPECT_EQ(call_to_animate_suggestion_label_counter_, 0);
-}
-
-// Tests that the suggestion highlight is enabled when suggesting a password.
-TEST_F(FormSuggestionControllerTest, PasswordSuggestionHighlight) {
-  // Enable the feature flag for password suggestion highlight.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(kBubbleRichIPH);
+// Tests that the password suggestion IPH is not shown, but the event logged,
+// when the feature is not enabled,
+TEST_F(FormSuggestionControllerTest, PasswordSuggestionNoFeatureNoIPH) {
+  // Disable the feature flag for password suggestion IPH.
+  scoped_feature_list_.InitAndDisableFeature(kBubbleRichIPH);
 
   NSArray* suggestions = @[
     [FormSuggestion suggestionWithValue:@"foo"
@@ -518,20 +484,46 @@
   auto main_frame = web::FakeWebFrame::CreateMainWebFrame(url);
   autofill::FormActivityParams params;
 
+  [[mock_handler_ reject] showPasswordSuggestionIPHIfNeeded];
   OCMExpect([mock_handler_ notifyPasswordSuggestionsShown]);
   test_form_activity_tab_helper_.FormActivityRegistered(main_frame.get(),
                                                         params);
-
-  EXPECT_EQ(call_to_animate_suggestion_label_counter_, 1);
   [mock_handler_ verify];
 }
 
-// Tests that the suggestion highlight is disabled when not suggesting a
+// Tests that the password suggestion IPH is enabled when suggesting a password.
+TEST_F(FormSuggestionControllerTest, PasswordSuggestionIPH) {
+  // Enable the feature flag for password suggestion IPH.
+  scoped_feature_list_.InitAndEnableFeature(kBubbleRichIPH);
+
+  NSArray* suggestions = @[
+    [FormSuggestion suggestionWithValue:@"foo"
+                     displayDescription:nil
+                                   icon:@""
+                             identifier:0
+                         requiresReauth:NO],
+  ];
+  TestSuggestionProvider* provider =
+      [[TestSuggestionProvider alloc] initWithSuggestions:suggestions];
+  provider.type = SuggestionProviderTypePassword;
+  SetUpController(@[ provider ]);
+  GURL url("http://foo.com");
+  fake_web_state_.SetCurrentURL(url);
+  auto main_frame = web::FakeWebFrame::CreateMainWebFrame(url);
+  autofill::FormActivityParams params;
+
+  OCMExpect([mock_handler_ showPasswordSuggestionIPHIfNeeded]);
+  [[mock_handler_ reject] notifyPasswordSuggestionsShown];
+  test_form_activity_tab_helper_.FormActivityRegistered(main_frame.get(),
+                                                        params);
+  [mock_handler_ verify];
+}
+
+// Tests that the password suggestion iph is disabled when not suggesting a
 // password.
-TEST_F(FormSuggestionControllerTest, NonPasswordSuggestionNoHighlight) {
-  // Enable the feature flag for password suggestion highlight.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(kBubbleRichIPH);
+TEST_F(FormSuggestionControllerTest, NonPasswordSuggestionNoIPH) {
+  // Enable the feature flag for password suggestion iph.
+  scoped_feature_list_.InitAndEnableFeature(kBubbleRichIPH);
 
   NSArray* suggestions = @[
     [FormSuggestion suggestionWithValue:@"foo"
@@ -548,11 +540,10 @@
   auto main_frame = web::FakeWebFrame::CreateMainWebFrame(url);
   autofill::FormActivityParams params;
 
+  [[mock_handler_ reject] showPasswordSuggestionIPHIfNeeded];
   [[mock_handler_ reject] notifyPasswordSuggestionsShown];
   test_form_activity_tab_helper_.FormActivityRegistered(main_frame.get(),
                                                         params);
-
-  EXPECT_EQ(call_to_animate_suggestion_label_counter_, 0);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/autofill/form_suggestion_view.h b/ios/chrome/browser/autofill/form_suggestion_view.h
index ca16ef05..c430ebd 100644
--- a/ios/chrome/browser/autofill/form_suggestion_view.h
+++ b/ios/chrome/browser/autofill/form_suggestion_view.h
@@ -10,6 +10,7 @@
 @class FormSuggestion;
 @protocol FormSuggestionClient;
 @class FormSuggestionView;
+@class LayoutGuideCenter;
 
 @protocol FormSuggestionViewDelegate <NSObject>
 
@@ -37,6 +38,9 @@
 // A view added at the end of the current suggestions.
 @property(nonatomic, strong) UIView* trailingView;
 
+// The layout guide center to use to refer to the first suggestion label.
+@property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter;
+
 // Updates with |suggestions|.
 - (void)updateSuggestions:(NSArray<FormSuggestion*>*)suggestions;
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_view.mm b/ios/chrome/browser/autofill/form_suggestion_view.mm
index ebc48a57..4c18feb 100644
--- a/ios/chrome/browser/autofill/form_suggestion_view.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_view.mm
@@ -12,7 +12,9 @@
 #import "ios/chrome/browser/autofill/form_suggestion_client.h"
 #import "ios/chrome/browser/autofill/form_suggestion_constants.h"
 #import "ios/chrome/browser/autofill/form_suggestion_label.h"
+#import "ios/chrome/browser/ui/util/layout_guide_names.h"
 #include "ios/chrome/browser/ui/util/rtl_geometry.h"
+#import "ios/chrome/browser/ui/util/util_swift.h"
 #include "ios/chrome/common/ui/util/constraints_ui_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -159,6 +161,12 @@
                                          numSuggestions:[self.suggestions count]
                                                delegate:self];
     [self.stackView addArrangedSubview:label];
+
+    // Track the first element.
+    if (idx == 0) {
+      [self.layoutGuideCenter referenceView:label
+                                  underName:kAutofillFirstSuggestionGuide];
+    }
   };
   [self.suggestions enumerateObjectsUsingBlock:setupBlock];
   if (self.trailingView) {
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 27fc539..55bdf27 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -321,11 +321,11 @@
 };
 
 const FeatureEntry::FeatureParam kFREDefaultPromoTestingDefaultDelay[] = {
-    {kFREDefaultPromoTestingDefaultDelayParam, "true"}};
+    {kFREDefaultBrowserPromoParam, kFREDefaultBrowserPromoDefaultDelayParam}};
 const FeatureEntry::FeatureParam kFREDefaultPromoTestingOnly[] = {
-    {kFREDefaultPromoTestingOnlyParam, "true"}};
+    {kFREDefaultBrowserPromoParam, kFREDefaultBrowserPromoFirstRunOnlyParam}};
 const FeatureEntry::FeatureParam kFREDefaultPromoTestingShortDelay[] = {
-    {kFREDefaultPromoTestingShortDelayParam, "true"}};
+    {kFREDefaultBrowserPromoParam, kFREDefaultBrowserPromoShortDelayParam}};
 const FeatureEntry::FeatureVariation kFREDefaultPromoTestingVariations[] = {
     {"Wait 14 days after FRE default browser promo",
      kFREDefaultPromoTestingDefaultDelay,
@@ -526,7 +526,7 @@
      flags_ui::kOsIos,
      FEATURE_WITH_PARAMS_VALUE_TYPE(signin::kNewMobileIdentityConsistencyFRE,
                                     kNewMobileIdentityConsistencyFREVariations,
-                                    "NewMobileIdentityConsistencyFRE")},
+                                    kIOSMICeAndDefaultBrowserTrialName)},
     {"enable-long-message-duration",
      flag_descriptions::kEnableLongMessageDurationName,
      flag_descriptions::kEnableLongMessageDurationDescription, flags_ui::kOsIos,
@@ -727,7 +727,7 @@
      flags_ui::kOsIos,
      FEATURE_WITH_PARAMS_VALUE_TYPE(kEnableFREDefaultBrowserScreenTesting,
                                     kFREDefaultPromoTestingVariations,
-                                    "EnableFREDefaultBrowserScreenTesting")},
+                                    kIOSMICeAndDefaultBrowserTrialName)},
     {"enable-discover-feed-shorter-cache",
      flag_descriptions::kEnableDiscoverFeedShorterCacheName,
      flag_descriptions::kEnableDiscoverFeedShorterCacheDescription,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index cea05c9..6614c5bf 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -114,7 +114,9 @@
 extern const char kBubbleRichIPHName[] = "Bubble rich IPH";
 extern const char kBubbleRichIPHDescription[] =
     "When enabled, displays a rich description (ex: title, image, etc..) of "
-    "the feature presented in the bubble view.";
+    "the feature presented in the bubble. Also enables password suggestion "
+    "highlight IPH. When enabled with no option, uses the default bubble "
+    "style.";
 
 extern const char kCalendarExperienceKitName[] = "Experience Kit Calendar";
 extern const char kCalendarExperienceKitDescription[] =
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn b/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
index c5ddec3..dcd667a 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
@@ -26,7 +26,7 @@
     "//components/password_manager/ios",
     "//components/strings:components_strings_grit",
     "//ios/chrome/app/application_delegate:app_state_header",
-    "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/app/strings",
     "//ios/chrome/browser/autofill:autofill",
     "//ios/chrome/browser/autofill:autofill_shared",
     "//ios/chrome/browser/autofill/manual_fill",
@@ -38,12 +38,16 @@
     "//ios/chrome/browser/ui/alert_coordinator",
     "//ios/chrome/browser/ui/autofill/manual_fill",
     "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui",
+    "//ios/chrome/browser/ui/autofill/resources:password_suggestion_icon",
+    "//ios/chrome/browser/ui/bubble",
     "//ios/chrome/browser/ui/bubble:features",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/default_promo:utils",
+    "//ios/chrome/browser/ui/main:layout_guide_scene_agent",
     "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/util",
+    "//ios/chrome/browser/ui/util:util_swift",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/common/ui/elements:form_input_accessory",
     "//ios/chrome/common/ui/reauthentication",
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
index 17928f10..71531f92 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
@@ -36,17 +36,23 @@
 #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_all_password_coordinator.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_coordinator.h"
+#import "ios/chrome/browser/ui/bubble/bubble_features.h"
+#import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_coordinator_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/commands/security_alert_commands.h"
+#import "ios/chrome/browser/ui/main/layout_guide_scene_agent.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/util/layout_guide_names.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/browser/ui/util/util_swift.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
+#include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/web_state.h"
 #include "ui/base/device_form_factor.h"
@@ -56,6 +62,32 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+// Delay between the time the view is shown, and the time the password
+// suggestion tip is shown.
+const NSTimeInterval kPasswordSuggestionTipDelay = 1.5f;
+
+// Additional vertical offset for the IPH, so that it doesn't appear below the
+// Autofill strip at the top of the keyboard.
+const CGFloat kIPHVerticalOffset = -5;
+
+// Returns BubbleViewType param from kBubbleRichIPH feature flag.
+BubbleViewType BubbleTypeFromFeature() {
+  DCHECK(base::FeatureList::IsEnabled(kBubbleRichIPH));
+  std::string bubbleTypeName = base::GetFieldTrialParamValueByFeature(
+      kBubbleRichIPH, kBubbleRichIPHParameterName);
+  if (bubbleTypeName == kBubbleRichIPHParameterExplicitDismissal) {
+    return BubbleViewTypeWithClose;
+  } else if (bubbleTypeName == kBubbleRichIPHParameterRich) {
+    return BubbleViewTypeRich;
+  } else if (bubbleTypeName == kBubbleRichIPHParameterRichWithSnooze) {
+    return BubbleViewTypeRichWithSnooze;
+  } else {
+    return BubbleViewTypeDefault;
+  }
+}
+}  // namespace
+
 @interface FormInputAccessoryCoordinator () <
     AddressCoordinatorDelegate,
     CardCoordinatorDelegate,
@@ -89,6 +121,17 @@
 // Active Form Input View Controller.
 @property(nonatomic, strong) UIViewController* formInputViewController;
 
+// Bubble view controller presenter for password suggestion tip.
+@property(nonatomic, strong) BubbleViewControllerPresenter* bubblePresenter;
+
+// UI tap recognizer used to dismiss bubble presenter.
+@property(nonatomic, strong)
+    UITapGestureRecognizer* formInputAccessoryTapRecognizer;
+
+// The layout guide installed in the base view controller on which to anchor the
+// potential IPH bubble.
+@property(nonatomic, strong) UILayoutGuide* layoutGuide;
+
 @end
 
 @implementation FormInputAccessoryCoordinator
@@ -107,6 +150,10 @@
           initWithWebStateList:browser->GetWebStateList()
           securityAlertHandler:securityAlertHandler
         reauthenticationModule:_reauthenticationModule];
+    _formInputAccessoryTapRecognizer = [[UITapGestureRecognizer alloc]
+        initWithTarget:self
+                action:@selector(tapInsideRecognized:)];
+    _formInputAccessoryTapRecognizer.cancelsTouchesInView = NO;
   }
   return self;
 }
@@ -115,6 +162,8 @@
   self.formInputAccessoryViewController =
       [[FormInputAccessoryViewController alloc]
           initWithManualFillAccessoryViewControllerDelegate:self];
+  self.formInputAccessoryViewController.layoutGuideCenter =
+      [self layoutGuideCenter];
 
   auto passwordStore = IOSChromePasswordStoreFactory::GetForBrowserState(
       self.browser->GetBrowserState(), ServiceAccessType::EXPLICIT_ACCESS);
@@ -137,10 +186,18 @@
       reauthenticationModule:self.reauthenticationModule];
   self.formInputAccessoryViewController.formSuggestionClient =
       self.formInputAccessoryMediator;
+  [self.formInputAccessoryViewController.view
+      addGestureRecognizer:self.formInputAccessoryTapRecognizer];
+
+  self.layoutGuide = [[self layoutGuideCenter]
+      makeLayoutGuideNamed:kAutofillFirstSuggestionGuide];
+  [self.baseViewController.view addLayoutGuide:self.layoutGuide];
 }
 
 - (void)stop {
   [self stopChildren];
+  [self.formInputAccessoryTapRecognizer.view
+      removeGestureRecognizer:self.formInputAccessoryTapRecognizer];
   self.formInputAccessoryViewController = nil;
   self.formInputViewController = nil;
   [GetFirstResponder() reloadInputViews];
@@ -150,6 +207,9 @@
 
   [self.allPasswordCoordinator stop];
   self.allPasswordCoordinator = nil;
+
+  [self.layoutGuide.owningView removeLayoutGuide:self.layoutGuide];
+  self.layoutGuide = nil;
 }
 
 - (void)reset {
@@ -226,6 +286,13 @@
   [self.childCoordinators addObject:addressCoordinator];
 }
 
+#pragma mark - Actions
+
+- (void)tapInsideRecognized:(id)sender {
+  [self.bubblePresenter dismissAnimated:YES];
+  self.bubblePresenter = nil;
+}
+
 #pragma mark - FormInputAccessoryMediatorHandler
 
 - (void)resetFormInputView {
@@ -254,6 +321,65 @@
       feature_engagement::events::kPasswordSuggestionSelected);
 }
 
+- (void)showPasswordSuggestionIPHIfNeeded {
+  DCHECK(base::FeatureList::IsEnabled(kBubbleRichIPH));
+  if (self.bubblePresenter) {
+    // Already showing a bubble.
+    return;
+  }
+
+  // At this point, `self.layoutGuide` is usually not yet updated, since the
+  // view it matches has just been added to the hierarchy. Wait for it to be
+  // updated.
+  dispatch_after(
+      dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)),
+      dispatch_get_main_queue(), ^{
+        self.bubblePresenter = [self newBubbleViewControllerPresenter];
+
+        // Get the anchor point for the bubble.
+        CGRect anchorFrame = self.layoutGuide.layoutFrame;
+        CGPoint anchorPoint =
+            CGPointMake(CGRectGetMidX(anchorFrame),
+                        CGRectGetMinY(anchorFrame) + kIPHVerticalOffset);
+
+        // Discard if it doesn't fit in the view as it is currently shown.
+        if (![self.bubblePresenter canPresentInView:self.baseViewController.view
+                                        anchorPoint:anchorPoint]) {
+          self.bubblePresenter = nil;
+          return;
+        }
+
+        // Early return if the engagement tracker won't display the IPH.
+        const base::Feature& feature =
+            feature_engagement::kIPHPasswordSuggestionsFeature;
+        if (!feature_engagement::TrackerFactory::GetForBrowserState(
+                 self.browser->GetBrowserState())
+                 ->ShouldTriggerHelpUI(feature)) {
+          self.bubblePresenter = nil;
+          return;
+        }
+
+        // Show the highlight suggestion.
+        [self.formInputAccessoryViewController animateSuggestionLabel];
+
+        // Present the bubble.
+        __weak __typeof(self) weakSelf = self;
+        dispatch_after(
+            dispatch_time(
+                DISPATCH_TIME_NOW,
+                (int64_t)(kPasswordSuggestionTipDelay * NSEC_PER_SEC)),
+            dispatch_get_main_queue(), ^{
+              __typeof(self) strongSelf = weakSelf;
+              if (strongSelf) {
+                [strongSelf.bubblePresenter
+                    presentInViewController:strongSelf.baseViewController
+                                       view:strongSelf.baseViewController.view
+                                anchorPoint:anchorPoint];
+              }
+            });
+      });
+}
+
 #pragma mark - ManualFillAccessoryViewControllerDelegate
 
 - (void)keyboardButtonPressed {
@@ -464,4 +590,48 @@
   [self.allPasswordCoordinator start];
 }
 
+// Returns a new bubble view controller presenter for password suggestion tip.
+- (BubbleViewControllerPresenter*)newBubbleViewControllerPresenter {
+  NSString* text = l10n_util::GetNSString(IDS_IOS_PASSWORD_SUGGESTIONS_TIP);
+  NSString* title =
+      l10n_util::GetNSString(IDS_IOS_PASSWORD_SUGGESTIONS_TIP_TITLE);
+  UIImage* image = [UIImage imageNamed:@"password_suggestion_icon"];
+  BubbleViewType bubbleType = BubbleTypeFromFeature();
+  const base::Feature& feature =
+      feature_engagement::kIPHPasswordSuggestionsFeature;
+  __weak __typeof(self) weakSelf = self;
+  ProceduralBlockWithSnoozeAction dismissalCallback =
+      ^(feature_engagement::Tracker::SnoozeAction snoozeAction) {
+        __typeof(self) strongSelf = weakSelf;
+        if (strongSelf) {
+          feature_engagement::TrackerFactory::GetForBrowserState(
+              strongSelf.browser->GetBrowserState())
+              ->DismissedWithSnooze(feature, snoozeAction);
+        }
+      };
+  BubbleViewControllerPresenter* bubbleViewControllerPresenter =
+      [[BubbleViewControllerPresenter alloc]
+               initWithText:text
+                      title:title
+                      image:image
+             arrowDirection:BubbleArrowDirectionDown
+                  alignment:BubbleAlignmentLeading
+                 bubbleType:bubbleType
+          dismissalCallback:dismissalCallback];
+  return bubbleViewControllerPresenter;
+}
+
+// Returns the layout guide center to use to coordinate views.
+- (LayoutGuideCenter*)layoutGuideCenter {
+  SceneState* sceneState =
+      SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState();
+  LayoutGuideSceneAgent* layoutGuideSceneAgent =
+      [LayoutGuideSceneAgent agentFromScene:sceneState];
+  if (self.browser->GetBrowserState()->IsOffTheRecord()) {
+    return layoutGuideSceneAgent.incognitoLayoutGuideCenter;
+  } else {
+    return layoutGuideSceneAgent.layoutGuideCenter;
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
index 43766b3..386df6dd 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h
@@ -41,6 +41,9 @@
 // The mediator notifies that a password suggestion has been selected.
 - (void)notifyPasswordSuggestionSelected;
 
+// The mediator shows password suggestion tip if needed.
+- (void)showPasswordSuggestionIPHIfNeeded;
+
 @end
 
 // This class contains all the logic to get and provide keyboard input accessory
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
index 998847a..b98e189 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/browser/passwords/password_generation_utils.h"
 #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_chromium_text_data.h"
 #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_consumer.h"
-#include "ios/chrome/browser/ui/bubble/bubble_features.h"
+#import "ios/chrome/browser/ui/bubble/bubble_features.h"
 #import "ios/chrome/browser/ui/commands/security_alert_commands.h"
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 #import "ios/chrome/browser/ui/default_promo/default_browser_utils.h"
@@ -532,9 +532,10 @@
       LogLikelyInterestedDefaultBrowserUserActivity(DefaultPromoTypeMadeForIOS);
     }
     if (provider.type == SuggestionProviderTypePassword) {
-      [self.handler notifyPasswordSuggestionsShown];
       if (base::FeatureList::IsEnabled(kBubbleRichIPH)) {
-        [self.consumer animateSuggestionLabel];
+        [self.handler showPasswordSuggestionIPHIfNeeded];
+      } else {
+        [self.handler notifyPasswordSuggestionsShown];
       }
     }
   }
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.h b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.h
index c4c4223..21bcda4 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.h
@@ -10,6 +10,7 @@
 #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_consumer.h"
 
 @protocol FormSuggestionClient;
+@class LayoutGuideCenter;
 @class ManualFillAccessoryViewController;
 @protocol ManualFillAccessoryViewControllerDelegate;
 
@@ -21,6 +22,9 @@
 // Client in charge of handling actions in suggestions.
 @property(nonatomic, weak) id<FormSuggestionClient> formSuggestionClient;
 
+// The layout guide center to use to refer to the first suggestion label.
+@property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter;
+
 // Shows the manual fallback icons as the first option in the suggestions bar,
 // and locks them in that position.
 - (void)lockManualFallbackView;
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
index 1f83166..8cbe81a 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
@@ -176,6 +176,7 @@
   if (!self.formSuggestionView) {
     self.formSuggestionView = [[FormSuggestionView alloc] init];
     self.formSuggestionView.formSuggestionViewDelegate = self;
+    self.formSuggestionView.layoutGuideCenter = self.layoutGuideCenter;
   }
 }
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address+AutofillProfile_unittest.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address+AutofillProfile_unittest.mm
index c9744a6..a0fb3c22 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address+AutofillProfile_unittest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address+AutofillProfile_unittest.mm
@@ -44,7 +44,7 @@
   NSString* city = @"Springfield";
   NSString* state = @"State";
   NSString* country = @"US";
-  NSString* phoneNumber = @"123-456-789";
+  NSString* phoneNumber = @"6502345678";
   NSString* emailAddress = @"john@doe";
 
   autofill::CountryNames::SetLocaleString("en-US");
@@ -95,7 +95,7 @@
   NSString* city = @"Springfield";
   NSString* state = @"State";
   NSString* country = @"US";
-  NSString* phoneNumber = @"123-456-789";
+  NSString* phoneNumber = @"6502345678";
   NSString* emailAddress = @"john@doe";
 
   autofill::CountryNames::SetLocaleString("en-US");
diff --git a/ios/chrome/browser/ui/bubble/bubble_features.h b/ios/chrome/browser/ui/bubble/bubble_features.h
index 5b58b41..c41fe1f 100644
--- a/ios/chrome/browser/ui/bubble/bubble_features.h
+++ b/ios/chrome/browser/ui/bubble/bubble_features.h
@@ -10,10 +10,11 @@
 // Feature flag to enable rich IPH on bubbles.
 extern const base::Feature kBubbleRichIPH;
 
-// Feature parameters for rich IPH on bubbles.
+// Feature parameters for rich IPH on bubbles. If no parameter is set, the
+// default bubble style will be used.
 extern const char kBubbleRichIPHParameterName[];
 
-// Wide bubble view with explicit dismissal.
+// Default bubble view.
 extern const char kBubbleRichIPHParameterTargetHighlight[];
 // Wide bubble view with explicit dismissal.
 extern const char kBubbleRichIPHParameterExplicitDismissal[];
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_utils.mm b/ios/chrome/browser/ui/default_promo/default_browser_utils.mm
index 21f962e..f81b390 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_utils.mm
+++ b/ios/chrome/browser/ui/default_promo/default_browser_utils.mm
@@ -177,8 +177,8 @@
   // should be set only one time, so after the first run promo there is a short
   // cool down before the next promo and after it goes back to normal.
   if (DisplayedPromoCount() < 2 &&
-      fre_field_trial::
-          IsInFirstRunDefaultBrowserAndSmallDelayBeforeOtherPromosGroup() &&
+      fre_field_trial::GetFREDefaultBrowserScreenPromoFRE() ==
+          NewDefaultBrowserPromoFRE::kShortDelay &&
       HasUserInteractedWithFirstRunPromoBefore() &&
       !HasUserOpenedSettingsFromFirstRunPromo()) {
     return kPromosShortCoolDown;
diff --git a/ios/chrome/browser/ui/first_run/first_run_screen_provider.mm b/ios/chrome/browser/ui/first_run/first_run_screen_provider.mm
index b1723ba..34bec0e 100644
--- a/ios/chrome/browser/ui/first_run/first_run_screen_provider.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_screen_provider.mm
@@ -36,7 +36,8 @@
       break;
   }
 
-  if (fre_field_trial::IsFREDefaultBrowserScreenEnabled()) {
+  if (fre_field_trial::GetFREDefaultBrowserScreenPromoFRE() !=
+      NewDefaultBrowserPromoFRE::kDisabled) {
     [screens addObject:@(kDefaultBrowserPromo)];
   }
 
diff --git a/ios/chrome/browser/ui/first_run/fre_field_trial.cc b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
index fee985af..7c48023e 100644
--- a/ios/chrome/browser/ui/first_run/fre_field_trial.cc
+++ b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
@@ -17,10 +17,16 @@
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
 #include "ios/chrome/common/channel_info.h"
 
-const char kFREDefaultPromoTestingDefaultDelayParam[] =
+const char kIOSMICeAndDefaultBrowserTrialName[] =
+    "IOSTrialMICeAndDefaultBrowser";
+
+// Parameters for new Default Browser Promo FRE.
+const char kFREDefaultBrowserPromoParam[] = "variant_default_browser";
+const char kFREDefaultBrowserPromoDefaultDelayParam[] =
     "variant_default_delay_enabled";
-const char kFREDefaultPromoTestingOnlyParam[] = "variant_fre_only_enabled";
-const char kFREDefaultPromoTestingShortDelayParam[] =
+const char kFREDefaultBrowserPromoFirstRunOnlyParam[] =
+    "variant_fre_only_enabled";
+const char kFREDefaultBrowserPromoShortDelayParam[] =
     "variant_short_delay_enabled";
 
 // Parameters for new Mobile Identity Consistency FRE.
@@ -29,35 +35,68 @@
 const char kNewMobileIdentityConsistencyFREParamThreeSteps[] = "3steps";
 const char kNewMobileIdentityConsistencyFREParamTwoSteps[] = "2steps";
 
-// Group names for the new Mobile Identity Consistency FRE.
-const char kNewMICEFREWithUMADialogSetGroup[] =
-    "NewMobileIdentityConsistencyFREParamUMADialog";
-const char kNewMICEFREWithThreeStepsSetGroup[] =
-    "NewMobileIdentityConsistencyFREParamThreeSteps";
-const char kNewMICEFREWithTwoStepsSetGroup[] =
-    "NewMobileIdentityConsistencyFREParamTwoSteps";
-
 namespace {
 
-// Group names for the default browser promo trial.
-const char kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup[] =
-    "FREDefaultBrowserAndSmallDelayBeforeOtherPromos";
-const char kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup[] =
-    "FREDefaultBrowserAndDefaultDelayBeforeOtherPromos";
-const char kDefaultBrowserPromoAtFirstRunOnlyGroup[] =
-    "DefaultBrowserPromoAtFirstRunOnly";
+// Store local state preference with whether the client has participated in
+// IOSTrialMICeAndDefaultBrowser experiment or not.
+const char kTrialGroupMICeAndDefaultBrowserVersionPrefName[] =
+    "fre_refactoring_mice_and_default_browser.trial_version";
+// The placeholder trial version that is stored for a client who has not been
+// enrolled in the experiment.
+const int kPlaceholderTrialVersion = -1;
+// The current trial version; should be updated when the experiment is modified.
+const int kCurrentTrialVersion = 1;
+
 // Group names for the FRE redesign permissions trial.
 const char kDefaultGroup[] = "Default";
+// Group name for the FRE control group.
+const char kControlGroup[] = "Control-V1";
+// Group name for the FRE holdback group. This group holds back clients from the
+// kEnableFREUIModuleIOS behavior, which was launched in M103.
+const char kHoldbackGroup[] = "Disabled-V1";
+// Group names for the default browser promo trial.
+const char kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup[] =
+    "FREDefaultBrowserAndSmallDelayBeforeOtherPromos-V1";
+const char kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup[] =
+    "FREDefaultBrowserAndDefaultDelayBeforeOtherPromos-V1";
+const char kDefaultBrowserPromoAtFirstRunOnlyGroup[] =
+    "DefaultBrowserPromoAtFirstRunOnly-V1";
+// Group names for the new Mobile Identity Consistency FRE.
+const char kNewMICEFREWithUMADialogSetGroup[] =
+    "NewMobileIdentityConsistencyFREParamUMADialog-V1";
+const char kNewMICEFREWithThreeStepsSetGroup[] =
+    "NewMobileIdentityConsistencyFREParamThreeSteps-V1";
+const char kNewMICEFREWithTwoStepsSetGroup[] =
+    "NewMobileIdentityConsistencyFREParamTwoSteps-V1";
+
 // Experiment IDs defined for the above field trial groups.
-const variations::VariationID kDefaultTrialID = 3330131;
-const variations::VariationID kDefaultBrowserPromoAtFirstRunOnlyID = 3342136;
+const variations::VariationID kControlTrialID = 3348210;
+const variations::VariationID kHoldbackTrialID = 3348217;
+const variations::VariationID kDefaultBrowserPromoAtFirstRunOnlyID = 3348842;
 const variations::VariationID
-    kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosID = 3342137;
+    kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosID = 3348843;
 const variations::VariationID
-    kFREDefaultBrowserAndSmallDelayBeforeOtherPromosID = 3342138;
-// Group name for the FRE disabled group.
-const char kDisabledGroup[] = "Disabled";
-const variations::VariationID kDisabledTrialID = 3346917;
+    kFREDefaultBrowserAndSmallDelayBeforeOtherPromosID = 3348844;
+const variations::VariationID kNewMICEFREWithUMADialogSetID = 3348845;
+const variations::VariationID kNewMICEFREWithThreeStepsSetID = 3348846;
+const variations::VariationID kNewMICEFREWithTwoStepsSetID = 3348847;
+
+// Options for kNewDefaultBrowserPromoFREParam.
+constexpr base::FeatureParam<NewDefaultBrowserPromoFRE>::Option
+    kNewDefaultBrowserPromoFREOptions[] = {
+        {NewDefaultBrowserPromoFRE::kDefaultDelay,
+         kFREDefaultBrowserPromoDefaultDelayParam},
+        {NewDefaultBrowserPromoFRE::kFirstRunOnly,
+         kFREDefaultBrowserPromoFirstRunOnlyParam},
+        {NewDefaultBrowserPromoFRE::kShortDelay,
+         kFREDefaultBrowserPromoShortDelayParam}};
+
+// Parameter for kEnableFREDefaultBrowserScreenTesting feature.
+constexpr base::FeatureParam<NewDefaultBrowserPromoFRE>
+    kNewDefaultBrowserPromoFREParam{&kEnableFREDefaultBrowserScreenTesting,
+                                    kFREDefaultBrowserPromoParam,
+                                    NewDefaultBrowserPromoFRE::kDefaultDelay,
+                                    &kNewDefaultBrowserPromoFREOptions};
 
 // Options for kkNewMobileIdentityConsistencyFREParam.
 constexpr base::FeatureParam<NewMobileIdentityConsistencyFRE>::Option
@@ -77,10 +116,16 @@
         NewMobileIdentityConsistencyFRE::kUMADialog,
         &kNewMobileIdentityConsistencyFREOptions};
 
-// Experiment IDs defined for the second trial of the FRE UI.
-const variations::VariationID kNewMICEFREWithUMADialogSetID = 3346235;
-const variations::VariationID kNewMICEFREWithThreeStepsSetID = 3346236;
-const variations::VariationID kNewMICEFREWithTwoStepsSetID = 3346237;
+// Sets the parameter value of the new default browser parameter.
+void AssociateFieldTrialParamsForDefaultBrowserGroup(
+    const std::string& group_name,
+    const std::string& value) {
+  base::FieldTrialParams params;
+  params[kFREDefaultBrowserPromoParam] = value;
+  bool association_result = base::AssociateFieldTrialParams(
+      kIOSMICeAndDefaultBrowserTrialName, group_name, params);
+  DCHECK(association_result);
+}
 
 // Sets the parameter value of the new MICE FRE parameter.
 void AssociateFieldTrialParamsForNewMICEFREGroup(const std::string& group_name,
@@ -88,7 +133,7 @@
   base::FieldTrialParams params;
   params[kNewMobileIdentityConsistencyFREParam] = value;
   bool association_result = base::AssociateFieldTrialParams(
-      signin::kNewMobileIdentityConsistencyFRE.name, group_name, params);
+      kIOSMICeAndDefaultBrowserTrialName, group_name, params);
   DCHECK(association_result);
 }
 
@@ -96,43 +141,12 @@
 
 namespace fre_field_trial {
 
-bool IsInFirstRunDefaultBrowserAndSmallDelayBeforeOtherPromosGroup() {
-  if (base::FeatureList::IsEnabled(kEnableFREDefaultBrowserScreenTesting)) {
-    return base::GetFieldTrialParamByFeatureAsBool(
-        kEnableFREDefaultBrowserScreenTesting,
-        kFREDefaultPromoTestingShortDelayParam, false);
+NewDefaultBrowserPromoFRE GetFREDefaultBrowserScreenPromoFRE() {
+  if (base::FeatureList::IsEnabled(kEnableFREUIModuleIOS) &&
+      base::FeatureList::IsEnabled(kEnableFREDefaultBrowserScreenTesting)) {
+    return kNewDefaultBrowserPromoFREParam.Get();
   }
-  return base::FeatureList::IsEnabled(kEnableFREUIModuleIOS) &&
-         base::FieldTrialList::FindFullName(kEnableFREUIModuleIOS.name) ==
-             kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup;
-}
-
-bool IsInFirstRunDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup() {
-  if (base::FeatureList::IsEnabled(kEnableFREDefaultBrowserScreenTesting)) {
-    return base::GetFieldTrialParamByFeatureAsBool(
-        kEnableFREDefaultBrowserScreenTesting,
-        kFREDefaultPromoTestingDefaultDelayParam, false);
-  }
-  return base::FeatureList::IsEnabled(kEnableFREUIModuleIOS) &&
-         base::FieldTrialList::FindFullName(kEnableFREUIModuleIOS.name) ==
-             kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup;
-}
-
-bool IsInDefaultBrowserPromoAtFirstRunOnlyGroup() {
-  if (base::FeatureList::IsEnabled(kEnableFREDefaultBrowserScreenTesting)) {
-    return base::GetFieldTrialParamByFeatureAsBool(
-        kEnableFREDefaultBrowserScreenTesting, kFREDefaultPromoTestingOnlyParam,
-        false);
-  }
-  return base::FeatureList::IsEnabled(kEnableFREUIModuleIOS) &&
-         base::FieldTrialList::FindFullName(kEnableFREUIModuleIOS.name) ==
-             kDefaultBrowserPromoAtFirstRunOnlyGroup;
-}
-
-bool IsFREDefaultBrowserScreenEnabled() {
-  return IsInFirstRunDefaultBrowserAndSmallDelayBeforeOtherPromosGroup() ||
-         IsInFirstRunDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup() ||
-         IsInDefaultBrowserPromoAtFirstRunOnlyGroup();
+  return NewDefaultBrowserPromoFRE::kDisabled;
 }
 
 NewMobileIdentityConsistencyFRE GetNewMobileIdentityConsistencyFRE() {
@@ -142,18 +156,31 @@
   return NewMobileIdentityConsistencyFRE::kOld;
 }
 
-// Creates a trial for the first run (when there is no variations seed) if
-// necessary and enables the feature based on the randomly selected trial group.
-// Returns the group number.
-int CreateFirstRunTrial(
-    base::FieldTrial::EntropyProvider const& low_entropy_provider,
+// Creates the trial config, initializes the trial that puts clients into
+// different groups, and returns the version number of the current trial. There
+// are 9 groups:
+// - Default
+// - Control
+// - Holdback
+// - New MICE FRE with UMA dialog
+// - New MICE FRE with 3 steps
+// - New MICE FRE with 2 steps
+// - FRE default browser promo: show 14 days after first run
+// - FRE default browser promo: show 3 days after first run
+// - FRE default browser promo: only on first run
+int CreateNewMICeAndDefaultBrowserFRETrial(
+    const base::FieldTrial::EntropyProvider& low_entropy_provider,
     base::FeatureList* feature_list) {
-  // New FRE enabled/disabled.
-  int new_fre_default_percent = 0;
-
+  // Experiment groups
+  int new_fre_control_percent = 0;
+  int new_fre_holdback_percent = 0;
+  // MICe FRE experiment.
+  int new_fre_with_uma_dialog_set_percent = 0;
+  int new_fre_with_three_steps_set_percent = 0;
+  int new_fre_with_two_steps_set_percent = 0;
   // FRE's default browser screen experiment
-  int new_fre_with_default_screen_and_short_cooldown_percent = 0;
   int new_fre_with_default_screen_and_default_cooldown_percent = 0;
+  int new_fre_with_default_screen_and_short_cooldown_percent = 0;
   int new_fre_with_default_screen_only_percent = 0;
 
   switch (GetChannel()) {
@@ -161,106 +188,43 @@
     case version_info::Channel::CANARY:
     case version_info::Channel::DEV:
     case version_info::Channel::BETA:
-      new_fre_with_default_screen_and_short_cooldown_percent = 0;
-      new_fre_with_default_screen_and_default_cooldown_percent = 0;
-      new_fre_with_default_screen_only_percent = 0;
-      new_fre_default_percent = 100;
+      new_fre_control_percent = 10;
+      new_fre_holdback_percent = 10;
+      new_fre_with_uma_dialog_set_percent = 10;
+      new_fre_with_three_steps_set_percent = 10;
+      new_fre_with_two_steps_set_percent = 10;
+      new_fre_with_default_screen_and_default_cooldown_percent = 10;
+      new_fre_with_default_screen_and_short_cooldown_percent = 10;
+      new_fre_with_default_screen_only_percent = 10;
       break;
     case version_info::Channel::STABLE:
-      new_fre_with_default_screen_and_short_cooldown_percent = 0;
-      new_fre_with_default_screen_and_default_cooldown_percent = 0;
-      new_fre_with_default_screen_only_percent = 0;
-      new_fre_default_percent = 100;
-      break;
+      return kPlaceholderTrialVersion;
   }
 
   // Set up the trial and groups.
-  FirstRunFieldTrialConfig config(kEnableFREUIModuleIOS.name);
-  // Default browser promo experiment groups
-  config.AddGroup(kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup,
-                  kFREDefaultBrowserAndSmallDelayBeforeOtherPromosID,
-                  new_fre_with_default_screen_and_short_cooldown_percent);
-  config.AddGroup(kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup,
-                  kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosID,
-                  new_fre_with_default_screen_and_default_cooldown_percent);
-  config.AddGroup(kDefaultBrowserPromoAtFirstRunOnlyGroup,
-                  kDefaultBrowserPromoAtFirstRunOnlyID,
-                  new_fre_with_default_screen_only_percent);
-
-  // New FRE groups
-  config.AddGroup(kDefaultGroup, kDefaultTrialID, new_fre_default_percent);
-
-  DCHECK_EQ(100, config.GetTotalProbability());
-
-  scoped_refptr<base::FieldTrial> trial =
-      config.CreateOneTimeRandomizedTrial(kDefaultGroup, low_entropy_provider);
-
-  // Finalize the group choice and activates the trial - similar to a variation
-  // config that's marked with |starts_active| true. This is required for
-  // studies that register variation ids, so they don't reveal extra information
-  // beyond the low-entropy source.
-  int group = trial->group();
-  const std::string& group_name = trial->group_name();
-  if (group_name == kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup ||
-      group_name == kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup ||
-      group_name == kDefaultBrowserPromoAtFirstRunOnlyGroup) {
-    feature_list->RegisterFieldTrialOverride(
-        kEnableFREUIModuleIOS.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
-        trial.get());
-  }
-  return group;
-}
-
-// Creates the trial config, initialize the trial and returns the ID of the
-// new Mobile Identity Consistency FRE trial group. There are 5 groups:
-// - Control (Default)
-// - Disabled
-// - New MICE FRE with UMA dialog
-// - New MICE FRE with 3 steps
-// - New MICE FRE with 2 steps
-int CreateNewMobileIdentityConsistencyFRETrial(
-    const base::FieldTrial::EntropyProvider& low_entropy_provider,
-    base::FeatureList* feature_list) {
-  // Experiment groups
-  int new_fre_default_percent = 0;
-  int new_fre_disabled_percent = 0;
-  int new_fre_with_uma_dialog_set_percent = 0;
-  int new_fre_with_three_steps_set_percent = 0;
-  int new_fre_with_two_steps_set_percent = 0;
-
-  switch (GetChannel()) {
-    case version_info::Channel::UNKNOWN:
-    case version_info::Channel::CANARY:
-    case version_info::Channel::DEV:
-    case version_info::Channel::BETA:
-    case version_info::Channel::STABLE:
-      new_fre_disabled_percent = 0;
-      new_fre_with_uma_dialog_set_percent = 0;
-      new_fre_with_three_steps_set_percent = 0;
-      new_fre_with_two_steps_set_percent = 0;
-      new_fre_default_percent = 100;
-      break;
-  }
-
-  // Set up the trial and groups.
-  FirstRunFieldTrialConfig config(
-      signin::kNewMobileIdentityConsistencyFRE.name);
-
+  FirstRunFieldTrialConfig config(kIOSMICeAndDefaultBrowserTrialName);
+  // Disabled and control groups.
+  config.AddGroup(kControlGroup, kControlTrialID, new_fre_control_percent);
+  config.AddGroup(kHoldbackGroup, kHoldbackTrialID, new_fre_holdback_percent);
+  // MICe experiment groups. (No default browser promo.)
   config.AddGroup(kNewMICEFREWithUMADialogSetGroup,
                   kNewMICEFREWithUMADialogSetID,
                   new_fre_with_uma_dialog_set_percent);
-
   config.AddGroup(kNewMICEFREWithThreeStepsSetGroup,
                   kNewMICEFREWithThreeStepsSetID,
                   new_fre_with_three_steps_set_percent);
-
   config.AddGroup(kNewMICEFREWithTwoStepsSetGroup, kNewMICEFREWithTwoStepsSetID,
                   new_fre_with_two_steps_set_percent);
-
-  config.AddGroup(kDisabledGroup, kDisabledTrialID, new_fre_disabled_percent);
-  config.AddGroup(kDefaultGroup, kDefaultTrialID, new_fre_default_percent);
-
-  DCHECK_EQ(100, config.GetTotalProbability());
+  // Default browser promo experiment groups. (New FRE with MICe disabled.)
+  config.AddGroup(kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup,
+                  kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosID,
+                  new_fre_with_default_screen_and_default_cooldown_percent);
+  config.AddGroup(kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup,
+                  kFREDefaultBrowserAndSmallDelayBeforeOtherPromosID,
+                  new_fre_with_default_screen_and_short_cooldown_percent);
+  config.AddGroup(kDefaultBrowserPromoAtFirstRunOnlyGroup,
+                  kDefaultBrowserPromoAtFirstRunOnlyID,
+                  new_fre_with_default_screen_only_percent);
 
   // Associate field trial params to each group.
   AssociateFieldTrialParamsForNewMICEFREGroup(
@@ -272,36 +236,105 @@
   AssociateFieldTrialParamsForNewMICEFREGroup(
       kNewMICEFREWithTwoStepsSetGroup,
       kNewMobileIdentityConsistencyFREParamTwoSteps);
+  AssociateFieldTrialParamsForDefaultBrowserGroup(
+      kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup,
+      kFREDefaultBrowserPromoDefaultDelayParam);
+  AssociateFieldTrialParamsForDefaultBrowserGroup(
+      kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup,
+      kFREDefaultBrowserPromoShortDelayParam);
+  AssociateFieldTrialParamsForDefaultBrowserGroup(
+      kDefaultBrowserPromoAtFirstRunOnlyGroup,
+      kFREDefaultBrowserPromoFirstRunOnlyParam);
 
-  scoped_refptr<base::FieldTrial> trial =
-      config.CreateOneTimeRandomizedTrial(kDefaultGroup, low_entropy_provider);
+  scoped_refptr<base::FieldTrial> trial = config.CreateOneTimeRandomizedTrial(
+      /*default_group_name=*/kDefaultGroup, low_entropy_provider);
 
-  // Finalize the group choice and activates the trial - similar to a variation
+  // Finalize the group choice and activate the trial - similar to a variation
   // config that's marked with |starts_active| true. This is required for
   // studies that register variation ids, so they don't reveal extra information
   // beyond the low-entropy source.
-  int group = trial->group();
   const std::string& group_name = trial->group_name();
+  if (group_name == kDefaultGroup) {
+    // Default behavior should be expected for default group; no configuration
+    // to override any feature status is needed.
+    return kCurrentTrialVersion;
+  }
+  if (group_name == kControlGroup) {
+    // Explicitly set the features to align with the default group behavior in
+    // case the default behavior of any experiment group changes before the
+    // experiment reaches an end.
+    feature_list->RegisterFieldTrialOverride(
+        kEnableFREUIModuleIOS.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+        trial.get());
+    feature_list->RegisterFieldTrialOverride(
+        signin::kNewMobileIdentityConsistencyFRE.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+    feature_list->RegisterFieldTrialOverride(
+        kEnableFREDefaultBrowserScreenTesting.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+    return kCurrentTrialVersion;
+  }
+  if (group_name == kHoldbackGroup) {
+    feature_list->RegisterFieldTrialOverride(
+        kEnableFREUIModuleIOS.name, base::FeatureList::OVERRIDE_DISABLE_FEATURE,
+        trial.get());
+    feature_list->RegisterFieldTrialOverride(
+        signin::kNewMobileIdentityConsistencyFRE.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+    feature_list->RegisterFieldTrialOverride(
+        kEnableFREDefaultBrowserScreenTesting.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+    return kCurrentTrialVersion;
+  }
+  feature_list->RegisterFieldTrialOverride(
+      kEnableFREUIModuleIOS.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+      trial.get());
+  if (group_name == kFREDefaultBrowserAndSmallDelayBeforeOtherPromosGroup ||
+      group_name == kFREDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup ||
+      group_name == kDefaultBrowserPromoAtFirstRunOnlyGroup) {
+    feature_list->RegisterFieldTrialOverride(
+        signin::kNewMobileIdentityConsistencyFRE.name,
+        base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
+    feature_list->RegisterFieldTrialOverride(
+        kEnableFREDefaultBrowserScreenTesting.name,
+        base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
+    return kCurrentTrialVersion;
+  }
   if (group_name == kNewMICEFREWithUMADialogSetGroup ||
       group_name == kNewMICEFREWithThreeStepsSetGroup ||
       group_name == kNewMICEFREWithTwoStepsSetGroup) {
     feature_list->RegisterFieldTrialOverride(
         signin::kNewMobileIdentityConsistencyFRE.name,
         base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
-  } else if (group_name == kDisabledGroup) {
     feature_list->RegisterFieldTrialOverride(
-        signin::kNewMobileIdentityConsistencyFRE.name,
+        kEnableFREDefaultBrowserScreenTesting.name,
         base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial.get());
   }
-  return group;
+  return kCurrentTrialVersion;
 }
 
-void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {}
+void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
+  registry->RegisterIntegerPref(kTrialGroupMICeAndDefaultBrowserVersionPrefName,
+                                kPlaceholderTrialVersion);
+}
 
 void Create(const base::FieldTrial::EntropyProvider& low_entropy_provider,
             base::FeatureList* feature_list,
             PrefService* local_state) {
-  return;
+  if (FirstRun::IsChromeFirstRun()) {
+    // Create trial and group for the first time, and store the experiment
+    // version in prefs for subsequent runs.
+    int trial_version = CreateNewMICeAndDefaultBrowserFRETrial(
+        low_entropy_provider, feature_list);
+    local_state->SetInteger(kTrialGroupMICeAndDefaultBrowserVersionPrefName,
+                            trial_version);
+  } else if (local_state->GetInteger(
+                 kTrialGroupMICeAndDefaultBrowserVersionPrefName) ==
+             kCurrentTrialVersion) {
+    // The user was enrolled in this version of the experiment and was assigned
+    // to a group in a previous run, and should be kept in the same group.
+    CreateNewMICeAndDefaultBrowserFRETrial(low_entropy_provider, feature_list);
+  }
 }
 
 }  // namespace fre_field_trial
diff --git a/ios/chrome/browser/ui/first_run/fre_field_trial.h b/ios/chrome/browser/ui/first_run/fre_field_trial.h
index c3f1b95..ed9dabc 100644
--- a/ios/chrome/browser/ui/first_run/fre_field_trial.h
+++ b/ios/chrome/browser/ui/first_run/fre_field_trial.h
@@ -10,10 +10,22 @@
 class PrefRegistrySimple;
 class PrefService;
 
+// Version of the new Default Browser Promo FRE to show.
+enum class NewDefaultBrowserPromoFRE {
+  // FRE default browser promo only.
+  kFirstRunOnly = 0,
+  // Wait 3 days after FRE default browser promo.
+  kShortDelay,
+  // Wait 14 days after FRE default browser promo.
+  kDefaultDelay,
+  // FRE default browser promo not enabled.
+  kDisabled,
+};
+
 // Version of the new MICE FRE to show.
-enum class NewMobileIdentityConsistencyFRE : int {
+enum class NewMobileIdentityConsistencyFRE {
   // Old FRE with UMA dialog.
-  kUMADialog,
+  kUMADialog = 0,
   // New MICE FRE with 3 steps (welcome + sign-in + sync screens).
   kThreeSteps,
   // New MICE FRE with 2 steps (welcome with sign-in + sync screens).
@@ -26,17 +38,23 @@
 class FeatureList;
 }  // namespace base
 
+// Name of current experiment.
+extern const char kIOSMICeAndDefaultBrowserTrialName[];
+
+// Indicates which FRE default browser promo variant to use.
+extern const char kFREDefaultBrowserPromoParam[];
+
 // Indicates if the FRE default browser promo variant "Wait 14 days after FRE
 // default browser promo" is enabled.
-extern const char kFREDefaultPromoTestingDefaultDelayParam[];
+extern const char kFREDefaultBrowserPromoDefaultDelayParam[];
 
 // Indicates if the FRE default browser promo variant "FRE default browser
 // promo only" is enabled.
-extern const char kFREDefaultPromoTestingOnlyParam[];
+extern const char kFREDefaultBrowserPromoFirstRunOnlyParam[];
 
 // Indicates if the FRE default browser promo variant "Wait 3 days after FRE
 // default promo" is enabled.
-extern const char kFREDefaultPromoTestingShortDelayParam[];
+extern const char kFREDefaultBrowserPromoShortDelayParam[];
 
 // Indicates which variant of the new MICE FRE to use.
 extern const char kNewMobileIdentityConsistencyFREParam[];
@@ -44,29 +62,11 @@
 extern const char kNewMobileIdentityConsistencyFREParamThreeSteps[];
 extern const char kNewMobileIdentityConsistencyFREParamTwoSteps[];
 
-// Group names for the new Mobile Identity Consistency FRE.
-extern const char kNewMICEFREWithUMADialogSetGroup[];
-extern const char kNewMICEFREWithThreeStepsSetGroup[];
-extern const char kNewMICEFREWithTwoStepsSetGroup[];
-
 namespace fre_field_trial {
 
-// Returns true if the user is in the group that will show the default browser
-// screen in first run (FRE) with activate a short cooldown of other default
-// browser promos.
-bool IsInFirstRunDefaultBrowserAndSmallDelayBeforeOtherPromosGroup();
-
-// Returns true if the user is in the group that will show the default browser
-// screen in first run (FRE) and activate cooldown of other default browser
-// promos.
-bool IsInFirstRunDefaultBrowserAndDefaultDelayBeforeOtherPromosGroup();
-
-// Returns true if the user is in the group that will show the default browser
-// screen in first run (FRE) only.
-bool IsInDefaultBrowserPromoAtFirstRunOnlyGroup();
-
-// Returns true if the default browser screen in FRE is enabled.
-bool IsFREDefaultBrowserScreenEnabled();
+// Returns the FRE default browser promo setup according to the feature flag and
+// experiment. See NewDefaultBrowserPromoFRE.
+NewDefaultBrowserPromoFRE GetFREDefaultBrowserScreenPromoFRE();
 
 // Returns the FRE to display according to the feature flag and experiment.
 // See NewMobileIdentityConsistencyFRE.
diff --git a/ios/chrome/browser/ui/first_run/ios_first_run_field_trials.cc b/ios/chrome/browser/ui/first_run/ios_first_run_field_trials.cc
index be0516a..3d00bc8bc 100644
--- a/ios/chrome/browser/ui/first_run/ios_first_run_field_trials.cc
+++ b/ios/chrome/browser/ui/first_run/ios_first_run_field_trials.cc
@@ -24,10 +24,11 @@
 FirstRunFieldTrialConfig::CreateOneTimeRandomizedTrial(
     const std::string& default_group_name,
     const base::FieldTrial::EntropyProvider& low_entropy_provider) {
+  DCHECK_LE(GetTotalProbability(), 100);
   scoped_refptr<base::FieldTrial> trial =
       base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed(
-          trial_name_, GetTotalProbability(), default_group_name,
-          base::FieldTrial::ONE_TIME_RANDOMIZED, 0,
+          trial_name_, /*total_probability=*/100, default_group_name,
+          base::FieldTrial::ONE_TIME_RANDOMIZED, /*randomization_seed=*/0,
           /*default_group_number=*/nullptr, &low_entropy_provider);
   for (const auto& group : groups_) {
     variations::AssociateGoogleVariationID(
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index a90871b..ec756fc 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -1063,7 +1063,8 @@
          !self.sceneState.appState.postCrashLaunch &&
          !IsChromeLikelyDefaultBrowser() &&
          !HasUserOpenedSettingsFromFirstRunPromo() &&
-         !fre_field_trial::IsInDefaultBrowserPromoAtFirstRunOnlyGroup();
+         fre_field_trial::GetFREDefaultBrowserScreenPromoFRE() !=
+             NewDefaultBrowserPromoFRE::kFirstRunOnly;
 }
 
 - (void)maybeShowDefaultBrowserPromo:(Browser*)browser {
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 065491f..4ea12cd2 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -155,6 +155,7 @@
     "//ios/chrome/browser/ui/elements:elements_internal",
     "//ios/chrome/browser/ui/first_run:field_trial",
     "//ios/chrome/browser/ui/icons",
+    "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/list_model",
     "//ios/chrome/browser/ui/ntp:feature_flags",
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
index bf001cf9c..8ee36b6 100644
--- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/browser/ui/authentication/cells/table_view_signin_promo_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
+#import "ios/chrome/browser/ui/icons/chrome_symbol.h"
 #import "ios/chrome/browser/ui/settings/cells/account_sign_in_item.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_check_cell.h"
@@ -131,6 +132,13 @@
   [model setHeader:textHeaderFooterItem
       forSectionWithIdentifier:SectionIdentifierText];
 
+  TableViewDetailIconItem* symbolItem =
+      [[TableViewDetailIconItem alloc] initWithType:ItemTypeTextSettingsDetail];
+  symbolItem.text = @"Detail Icon using SF Symbols";
+  symbolItem.symbolImage = DefaultSymbolWithPointSize(kGearShapeSymbol, 18);
+  symbolItem.symbolBackgroundColor = UIColorFromRGB(0xFBBC04);
+  [model addItem:symbolItem toSectionWithIdentifier:SectionIdentifierText];
+
   TableViewTextItem* textItem =
       [[TableViewTextItem alloc] initWithType:ItemTypeText];
   textItem.text = @"Simple Text Cell";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_favicon_data_source.h b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_favicon_data_source.h
index f8dee3c..b76b2932 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_favicon_data_source.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_favicon_data_source.h
@@ -12,7 +12,7 @@
 @protocol TabFaviconDataSource
 
 // Requests the receiver to provide a favicon image corresponding to
-// |identifier|. |completion| is called with the image if it exists.
+// `identifier`. `completion` is called with the image if it exists.
 - (void)faviconForIdentifier:(NSString*)identifier
                   completion:(void (^)(UIImage*))completion;
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_cell.mm
index fcfbcbd..2897660a 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_cell.mm
@@ -107,7 +107,7 @@
 
 #pragma mark - Private
 
-// Updates this tab's style based on the value of |selected| and the current
+// Updates this tab's style based on the value of `selected` and the current
 // incognito style.
 - (UIView*)resizeableBackgroundImageForStateSelected:(BOOL)selected {
   // Style the background image first.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer.h b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer.h
index 3e94535e..183df35 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer.h
@@ -15,18 +15,18 @@
 // YES if the state is incognito.
 @property(nonatomic) BOOL isOffTheRecord;
 
-// Tells the consumer to replace its current set of items with |items| and
-// update the selected item ID to be |selectedItemID|. It's an error to pass
-// an |items| array containing items without unique IDs.
+// Tells the consumer to replace its current set of items with `items` and
+// update the selected item ID to be `selectedItemID`. It's an error to pass
+// an `items` array containing items without unique IDs.
 - (void)populateItems:(NSArray<TabSwitcherItem*>*)items
        selectedItemID:(NSString*)selectedItemID;
 
-// Tells the consumer to replace the item with ID |itemID| with |item|.
-// It's an error if |item|'s ID duplicates any other item's ID besides |itemID|.
-// The consumer should ignore this call if |itemID| has not yet been inserted.
+// Tells the consumer to replace the item with ID `itemID` with `item`.
+// It's an error if `item`'s ID duplicates any other item's ID besides `itemID`.
+// The consumer should ignore this call if `itemID` has not yet been inserted.
 - (void)replaceItemID:(NSString*)itemID withItem:(TabSwitcherItem*)item;
 
-// Tells the consumer to update the selected item ID to be |selectedItemID|.
+// Tells the consumer to update the selected item ID to be `selectedItemID`.
 - (void)selectItemWithID:(NSString*)selectedItemID;
 
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer_delegate.h b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer_delegate.h
index 9013f6ab..41f2e3cf 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer_delegate.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_consumer_delegate.h
@@ -16,7 +16,7 @@
 // Tells the receiver to show to the selected tab.
 - (void)selectTab:(int)index;
 
-// Tells the receiver to close the item with identifier |itemID|. If there is
+// Tells the receiver to close the item with identifier `itemID`. If there is
 // no item with that identifier, no item is closed.
 - (void)closeItemWithID:(NSString*)itemID;
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h
index cfbcefb3..d0410023 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h
@@ -15,7 +15,7 @@
 // Coordinator for the tab strip.
 @interface TabStripCoordinator : ChromeCoordinator
 
-// Initializes this Coordinator with its |browser| and a nil base view
+// Initializes this Coordinator with its `browser` and a nil base view
 // controller.
 - (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER;
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_mediator.mm
index b528835..0a0b7ade 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_mediator.mm
@@ -25,7 +25,7 @@
 #endif
 
 namespace {
-// Constructs a TabSwitcherItem from a |web_state|.
+// Constructs a TabSwitcherItem from a `web_state`.
 TabSwitcherItem* CreateItem(web::WebState* web_state) {
   TabSwitcherItem* item = [[TabSwitcherItem alloc]
       initWithIdentifier:web_state->GetStableIdentifier()];
@@ -37,7 +37,7 @@
   return item;
 }
 
-// Constructs an array of TabSwitcherItems from a |web_state_list|.
+// Constructs an array of TabSwitcherItems from a `web_state_list`.
 NSArray* CreateItems(WebStateList* web_state_list) {
   NSMutableArray* items = [[NSMutableArray alloc] init];
   for (int i = 0; i < web_state_list->count(); i++) {
@@ -47,7 +47,7 @@
   return [items copy];
 }
 
-// Returns the ID of the active tab in |web_state_list|.
+// Returns the ID of the active tab in `web_state_list`.
 NSString* GetActiveTabId(WebStateList* web_state_list) {
   if (!web_state_list)
     return nil;
@@ -58,7 +58,7 @@
   return web_state->GetStableIdentifier();
 }
 
-// Returns the WebState with |identifier| in |web_state_list|. Returns |nullptr|
+// Returns the WebState with `identifier` in `web_state_list`. Returns `nullptr`
 // if not found.
 web::WebState* GetWebStateWithId(WebStateList* web_state_list,
                                  NSString* identifier) {
@@ -70,7 +70,7 @@
   return nullptr;
 }
 
-// Returns the index of the tab with |identifier| in |web_state_list|. Returns
+// Returns the index of the tab with `identifier` in `web_state_list`. Returns
 // -1 if not found.
 int GetIndexOfTabWithId(WebStateList* web_state_list, NSString* identifier) {
   for (int i = 0; i < web_state_list->count(); i++) {
@@ -133,7 +133,7 @@
     _webStateList->AddObserver(_webStateListObserver.get());
 
     _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self);
-    // Observe all webStates of this |_webStateList|.
+    // Observe all webStates of this `_webStateList`.
     _allWebStateObservationForwarder =
         std::make_unique<AllWebStateObservationForwarder>(
             _webStateList, _webStateObserver.get());
@@ -238,7 +238,7 @@
 
 #pragma mark - Private
 
-// Calls |-populateItems:selectedItemID:| on the consumer.
+// Calls `-populateItems:selectedItemID:` on the consumer.
 - (void)populateConsumerItems {
   if (!self.webStateList)
     return;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm
index 3272771..1fc458a 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm
@@ -37,10 +37,10 @@
 @property(nonatomic, strong) UIButton* buttonNewTab;
 // The local model backing the collection view.
 @property(nonatomic, strong) NSMutableArray<TabSwitcherItem*>* items;
-// Identifier of the selected item. This value is disregarded if |self.items| is
+// Identifier of the selected item. This value is disregarded if `self.items` is
 // empty.
 @property(nonatomic, copy) NSString* selectedItemID;
-// Index of the selected item in |items|.
+// Index of the selected item in `items`.
 @property(nonatomic, readonly) NSUInteger selectedIndex;
 // Constraints that are used when the button needs to be kept next to the last
 // cell.
@@ -172,14 +172,14 @@
 - (void)replaceItemID:(NSString*)itemID withItem:(TabSwitcherItem*)item {
   if ([self indexOfItemWithID:itemID] == NSNotFound)
     return;
-  // Consistency check: |item|'s ID is either |itemID| or not in |items|.
+  // Consistency check: `item`'s ID is either `itemID` or not in `items`.
   DCHECK([item.identifier isEqualToString:itemID] ||
          [self indexOfItemWithID:item.identifier] == NSNotFound);
   NSUInteger index = [self indexOfItemWithID:itemID];
   self.items[index] = item;
   TabStripCell* cell = (TabStripCell*)[self.collectionView
       cellForItemAtIndexPath:CreateIndexPath(index)];
-  // |cell| may be nil if it is scrolled offscreen.
+  // `cell` may be nil if it is scrolled offscreen.
   if (cell)
     [self configureCell:cell withItem:item];
 }
@@ -209,8 +209,8 @@
 
 #pragma mark - Private
 
-// Configures |cell|'s title synchronously, and favicon asynchronously with
-// information from |item|. Updates the |cell|'s theme to this view controller's
+// Configures `cell`'s title synchronously, and favicon asynchronously with
+// information from `item`. Updates the `cell`'s theme to this view controller's
 // theme.
 - (void)configureCell:(TabStripCell*)cell withItem:(TabSwitcherItem*)item {
   if (item) {
@@ -230,8 +230,8 @@
   }
 }
 
-// Returns the index in |self.items| of the first item whose identifier is
-// |identifier|.
+// Returns the index in `self.items` of the first item whose identifier is
+// `identifier`.
 - (NSUInteger)indexOfItemWithID:(NSString*)identifier {
   auto selectedTest =
       ^BOOL(TabSwitcherItem* item, NSUInteger index, BOOL* stop) {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h
index a91db5c..dd9ad51 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h
@@ -10,7 +10,7 @@
 // Model object representing an item in the tab switchers.
 @interface TabSwitcherItem : NSObject
 
-// Create an item with |identifier|, which cannot be nil.
+// Create an item with `identifier`, which cannot be nil.
 - (instancetype)initWithIdentifier:(NSString*)identifier
     NS_DESIGNATED_INITIALIZER;
 
diff --git a/ios/chrome/browser/ui/table_view/cells/BUILD.gn b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
index 8820fc64..112102a 100644
--- a/ios/chrome/browser/ui/table_view/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
@@ -81,6 +81,7 @@
     "//ios/chrome/common/ui/table_view",
     "//ios/chrome/common/ui/table_view:cells_constants",
     "//ios/chrome/common/ui/util",
+    "//ios/chrome/common/ui/util:image_util",
     "//ios/third_party/material_components_ios",
     "//net",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
index f8c2ba0..e4c3415 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h
@@ -15,6 +15,12 @@
 // The filename for the leading icon.  If empty, no icon will be shown.
 @property(nonatomic, copy) NSString* iconImageName;
 
+// The symbol leading icon. If empty, no icon will be shown.
+@property(nonatomic, copy) UIImage* symbolImage;
+
+// The background color for the leading |symbolImage|.
+@property(nonatomic, copy) UIColor* symbolBackgroundColor;
+
 // The main text string.
 @property(nonatomic, copy) NSString* text;
 
@@ -50,6 +56,12 @@
 // the full width of the cell.
 - (void)setIconImage:(UIImage*)image;
 
+// Sets the leading symbol image with an elevated effect and its background
+// color. If set to nil, the icon will be hidden and the text labels will
+// expand to fill the full width of the cell.
+- (void)setSymbolImage:(UIImage*)image
+       backgroundColor:(UIColor*)backgroundColor;
+
 // Sets the detail text. `detailText` can be nil (or empty) to hide the detail
 // text.
 - (void)setDetailText:(NSString*)detailText;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
index db9d5a58..367869b 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/image_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -25,6 +26,18 @@
 // Minimum cell height when the cell has 2 lines.
 constexpr CGFloat kChromeTableViewTwoLinesCellHeight = 58.f;
 
+// Offset of the background image used to create the elevated effect.
+constexpr CGFloat kBackgroundImageOffset = 1;
+
+// Background image color alpha.
+constexpr CGFloat kBackgroundColorAlpha = 0.1;
+
+// Background image corner radius.
+constexpr CGFloat kBackgroundCornerRadius = 7;
+
+// Background blur radius.
+constexpr CGFloat kBackgroundBlurRadius = 3;
+
 }  // namespace
 
 @implementation TableViewDetailIconItem
@@ -45,12 +58,17 @@
   cell.textLabel.text = self.text;
   [cell setDetailText:self.detailText];
 
-  // Update the icon image, if one is present.
-  UIImage* iconImage = nil;
-  if ([self.iconImageName length]) {
-    iconImage = [UIImage imageNamed:self.iconImageName];
+  if (self.symbolImage) {
+    [cell setSymbolImage:self.symbolImage
+         backgroundColor:self.symbolBackgroundColor];
+  } else {
+    // Update the icon image, if one is present.
+    UIImage* iconImage = nil;
+    if ([self.iconImageName length]) {
+      iconImage = [UIImage imageNamed:self.iconImageName];
+      [cell setIconImage:iconImage];
+    }
   }
-  [cell setIconImage:iconImage];
   [cell setTextLayoutConstraintAxis:self.textLayoutConstraintAxis];
 }
 
@@ -160,6 +178,38 @@
   return self;
 }
 
+- (void)setSymbolImage:(UIImage*)image
+       backgroundColor:(UIColor*)backgroundColor {
+  BOOL hidden = (image == nil);
+  _iconImageView.hidden = hidden;
+  if (hidden) {
+    _iconVisibleConstraint.active = NO;
+    _iconHiddenConstraint.active = YES;
+  } else {
+    _iconImageView.backgroundColor = backgroundColor;
+    _iconImageView.layer.cornerRadius = kBackgroundCornerRadius;
+    CGFloat centerPoint = kTableViewIconImageSize / 2;
+
+    UIImage* blurredImage = BlurredImageWithImage(image, kBackgroundBlurRadius);
+    UIImageView* backgroundImageView =
+        [[UIImageView alloc] initWithImage:blurredImage];
+    backgroundImageView.center =
+        CGPointMake(centerPoint, centerPoint + kBackgroundImageOffset);
+    backgroundImageView.tintColor =
+        [UIColor.blackColor colorWithAlphaComponent:kBackgroundColorAlpha];
+    [_iconImageView addSubview:backgroundImageView];
+
+    UIImageView* foregroundImageView =
+        [[UIImageView alloc] initWithImage:image];
+    foregroundImageView.center = CGPointMake(centerPoint, centerPoint);
+    foregroundImageView.tintColor = UIColor.whiteColor;
+    [_iconImageView addSubview:foregroundImageView];
+
+    _iconHiddenConstraint.active = NO;
+    _iconVisibleConstraint.active = YES;
+  }
+}
+
 - (void)setIconImage:(UIImage*)image {
   if (image == nil && _iconImageView.image == nil) {
     return;
diff --git a/ios/chrome/browser/ui/tabs/background_tab_animation_view.h b/ios/chrome/browser/ui/tabs/background_tab_animation_view.h
index be439b7..80a172f 100644
--- a/ios/chrome/browser/ui/tabs/background_tab_animation_view.h
+++ b/ios/chrome/browser/ui/tabs/background_tab_animation_view.h
@@ -17,9 +17,9 @@
 - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
 - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
 
-// Starts an Open In New Tab animation in |parentView|, from |originPoint| with
-// a |completion| block. The named layout guide for the TabGrid button should be
-// accessible from |parentView|. |originPoint| should be in window coordinates.
+// Starts an Open In New Tab animation in `parentView`, from `originPoint` with
+// a `completion` block. The named layout guide for the TabGrid button should be
+// accessible from `parentView`. `originPoint` should be in window coordinates.
 - (void)animateFrom:(CGPoint)originPoint
     toTabGridButtonWithCompletion:(void (^)())completion;
 
diff --git a/ios/chrome/browser/ui/tabs/background_tab_animation_view.mm b/ios/chrome/browser/ui/tabs/background_tab_animation_view.mm
index 0d63025..9881b05 100644
--- a/ios/chrome/browser/ui/tabs/background_tab_animation_view.mm
+++ b/ios/chrome/browser/ui/tabs/background_tab_animation_view.mm
@@ -150,8 +150,8 @@
                              fromView:tabGridButtonLayoutGuide.owningView];
 }
 
-// Returns the animation duration, based on the |parentSize| and the |yDiff| and
-// |xDiff| between the origin and destination point. The animation is faster the
+// Returns the animation duration, based on the `parentSize` and the `yDiff` and
+// `xDiff` between the origin and destination point. The animation is faster the
 // closer the origin and destination are.
 - (CGFloat)animationDurationWithParentSize:(CGSize)parentSize
                                      xDiff:(CGFloat)xDiff
@@ -167,8 +167,8 @@
 }
 
 // Returns the BezierPath that should be followed by the animated view, based on
-// the |parentSize| and the |yDiff| and |xDiff| between the |origin| and
-// |destination| point.
+// the `parentSize` and the `yDiff` and `xDiff` between the `origin` and
+// `destination` point.
 - (UIBezierPath*)positionPathWithParentHeight:(CGFloat)parentHeight
                                         xDiff:(CGFloat)xDiff
                                         yDiff:(CGFloat)yDiff
diff --git a/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h b/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h
index aec7289..99e097e 100644
--- a/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h
+++ b/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h
@@ -15,9 +15,9 @@
 // The content view (typically the new tab's view) to animate.
 @property(nonatomic, strong) UIView* contentView;
 
-// Starts a New Tab animation in |parentView|, from |originPoint| with
-// a |completion| block. The new tab will scale up and move from the direction
-// if |originPoint| to the center of the reciever. |originPoint| must be in
+// Starts a New Tab animation in `parentView`, from `originPoint` with
+// a `completion` block. The new tab will scale up and move from the direction
+// if `originPoint` to the center of the reciever. `originPoint` must be in
 // UIWindow coordinates.
 - (void)animateFrom:(CGPoint)originPoint withCompletion:(void (^)())completion;
 
diff --git a/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.mm b/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.mm
index fae3592..66c78b707a 100644
--- a/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.mm
+++ b/ios/chrome/browser/ui/tabs/foreground_tab_animation_view.mm
@@ -34,7 +34,7 @@
 - (void)animateFrom:(CGPoint)originPoint withCompletion:(void (^)())completion {
   CGPoint origin = [self convertPoint:originPoint fromView:nil];
 
-  // Position the content view so it sits at the bottom of |self|.
+  // Position the content view so it sits at the bottom of `self`.
   CGRect frame = self.contentView.frame;
   CGFloat offset = self.frame.size.height - frame.size.height;
   frame.origin.y = offset;
@@ -43,7 +43,7 @@
   self.backgroundColor = UIColor.clearColor;
 
   // Translate the content view part of the way from the center of this view to
-  // |originPoint|.
+  // `originPoint`.
   CGFloat dx = kPositionCoefficient * (origin.x - self.contentView.center.x);
   CGFloat dy = kPositionCoefficient * (origin.y - self.contentView.center.y);
 
diff --git a/ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h b/ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h
index 58a45d0..a70e19e 100644
--- a/ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h
+++ b/ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h
@@ -15,7 +15,7 @@
 // visible or not visible.
 - (BOOL)isTabStripFullyVisible;
 
-// Asks the implementer to show the given |tabStripView|.
+// Asks the implementer to show the given `tabStripView`.
 - (void)showTabStripView:(UIView<TabStripContaining>*)tabStripView;
 
 @end
diff --git a/ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h b/ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h
index 784b17c..5632da5 100644
--- a/ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h
+++ b/ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h
@@ -20,8 +20,8 @@
 - (instancetype)init NS_UNAVAILABLE;
 - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
 
-// Starts the animation between the |currentView|, to the |newView| which has a
-// |position| relatively to the |currentView|. At the end of the animation, this
+// Starts the animation between the `currentView`, to the `newView` which has a
+// `position` relatively to the `currentView`. At the end of the animation, this
 // view is removing itself from its parent.
 - (void)animateFromCurrentView:(UIView*)currentView
                      toNewView:(UIView*)newView
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_containing.h b/ios/chrome/browser/ui/tabs/tab_strip_containing.h
index b802ad7..763259e2 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_containing.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_containing.h
@@ -11,7 +11,7 @@
 // Returns a snapshot of the Tab Strip view.
 - (UIView*)screenshotForAnimation;
 
-// Adjusts |transform| to take the current RTL mode into account.
+// Adjusts `transform` to take the current RTL mode into account.
 - (CGAffineTransform)adjustTransformForRTL:(CGAffineTransform)transform;
 
 @end
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.h b/ios/chrome/browser/ui/tabs/tab_strip_controller.h
index bacaf51..697aed7 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.h
@@ -38,11 +38,11 @@
 // Pan gesture handler for the tab strip.
 @property(nonatomic, weak) ViewRevealingVerticalPanHandler* panGestureHandler;
 
-// Animatee for this tab strip. It is not added to the |panGestureHandler| as
+// Animatee for this tab strip. It is not added to the `panGestureHandler` as
 // it needs to be run in sync with BVC.
 @property(nonatomic, readonly, strong) id<ViewRevealingAnimatee> animatee;
 
-// Designated initializer, |dispatcher| is not retained.
+// Designated initializer, `dispatcher` is not retained.
 - (instancetype)initWithBrowser:(Browser*)browser
                           style:(TabStripStyle)style NS_DESIGNATED_INITIALIZER;
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index c662cfc5..f4f0b63 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -99,9 +99,9 @@
 const CGFloat kCollapsedTabWidthThreshold = 40.0;
 
 // Autoscroll constants.  The autoscroll distance is set to
-// |kMaxAutoscrollDistance| at the edges of the scroll view.  As the tab moves
+// `kMaxAutoscrollDistance` at the edges of the scroll view.  As the tab moves
 // away from the edges of the scroll view, the autoscroll distance decreases by
-// one for each |kAutoscrollDecrementWidth| points.
+// one for each `kAutoscrollDecrementWidth` points.
 const CGFloat kMaxAutoscrollDistance = 10.0;
 const CGFloat kAutoscrollDecrementWidth = 10.0;
 
@@ -185,7 +185,7 @@
   NSMutableArray* _tabArray;
 
   // Set of TabViews that are currently closing.  These TabViews are also in
-  // |_tabArray|.  Used to translate between |_tabArray| indexes and
+  // `_tabArray`.  Used to translate between `_tabArray` indexes and
   // WebStateList indexes.
   NSMutableSet* _closingTabs;
 
@@ -210,14 +210,14 @@
   BOOL _highlightsSelectedTab;
 
   // YES when in reordering mode.
-  // TODO(rohitrao): This is redundant with |_draggedTab|.  Remove it.
+  // TODO(crbug.com/1327313): This is redundant with `_draggedTab`.  Remove it.
   BOOL _isReordering;
 
   // The tab that is currently being dragged.  nil when not in reordering mode.
   TabView* _draggedTab;
 
   // The last known location of the touch that is dragging the tab.  This
-  // location is in the coordinate system of |[_tabStripView superview]| because
+  // location is in the coordinate system of `[_tabStripView superview]` because
   // that coordinate system does not change as the scroll view scrolls.
   CGPoint _lastDragLocation;
 
@@ -263,11 +263,11 @@
 // YES if the controller has been disconnected.
 @property(nonatomic) BOOL disconnected;
 
-// If set to |YES|, tabs at either end of the tabstrip are "collapsed" into a
+// If set to `YES`, tabs at either end of the tabstrip are "collapsed" into a
 // stack, such that the visible width of the tabstrip is constant.  If set to
-// |NO|, tabs are never collapsed and the tabstrip scrolls horizontally as a
+// `NO`, tabs are never collapsed and the tabstrip scrolls horizontally as a
 // normal scroll view would.  Changing this property causes the tabstrip to
-// redraw and relayout.  Defaults to |YES|.
+// redraw and relayout.  Defaults to `YES`.
 @property(nonatomic, assign) BOOL useTabStacking;
 
 // Handler for URL drop interactions.
@@ -283,16 +283,16 @@
 // Tracks view hiding from thumb strip revealing.
 @property(nonatomic, assign) BOOL viewHiddenForThumbStrip;
 
-// Initializes the tab array based on the the entries in the |_webStateList|'s.
+// Initializes the tab array based on the the entries in the `_webStateList`'s.
 // Creates one TabView per Tab and adds it to the tabstrip.  A later call to
-// |-layoutTabs| is needed to properly place the tabs in the correct positions.
+// `-layoutTabs` is needed to properly place the tabs in the correct positions.
 - (void)initializeTabArray;
 
 // Returns an autoreleased TabView object with no content.
 - (TabView*)emptyTabView;
 
-// Returns an autoreleased TabView object based on the given |webState|.
-// |isSelected| is passed in here as an optimization, so that the TabView is
+// Returns an autoreleased TabView object based on the given `webState`.
+// `isSelected` is passed in here as an optimization, so that the TabView is
 // drawn correctly the first time, without requiring the model to send a
 // -setSelected message to the TabView.
 - (TabView*)createTabViewForWebState:(web::WebState*)webState
@@ -305,8 +305,8 @@
 // Remove the dimming view,
 - (void)removeDimmingViewWithAnimation:(BOOL)animate;
 
-// Converts between model indexes and |_tabArray| indexes.  The conversion is
-// necessary because |_tabArray| contains closing tabs whereas the WebStateList
+// Converts between model indexes and `_tabArray` indexes.  The conversion is
+// necessary because `_tabArray` contains closing tabs whereas the WebStateList
 // does not.
 - (NSUInteger)indexForWebStateListIndex:(int)modelIndex;
 - (int)webStateListIndexForIndex:(NSUInteger)index;
@@ -366,11 +366,11 @@
 // given tab view.
 - (CGRect)scrollViewFrameForTab:(TabView*)view;
 
-// Returns the portion of |frame| which is not covered by |frameOnTop|.
+// Returns the portion of `frame` which is not covered by `frameOnTop`.
 - (CGRect)calculateVisibleFrameForFrame:(CGRect)frame
                          whenUnderFrame:(CGRect)frameOnTop;
 
-// Schedules a layout of the scroll view and sets the internal |_animateLayout|
+// Schedules a layout of the scroll view and sets the internal `_animateLayout`
 // flag so that the layout will be animated.
 - (void)setNeedsLayoutWithAnimation;
 
@@ -388,14 +388,14 @@
 - (CGFloat)minTabWidth;
 
 // Automatically scroll the tab strip view to keep the given tab view visible.
-// This method must be called with a valid |tabIndex|.
+// This method must be called with a valid `tabIndex`.
 - (void)scrollTabToVisible:(int)tabIndex;
 
 // Updates the content offset of the tab strip view in order to keep the
 // selected tab view visible.
 // Content offset adjustement is only needed/performed in unstacked mode or
 // regular mode for newly opened webStates.
-// This method must be called with a valid |WebStateIndex|.
+// This method must be called with a valid `WebStateIndex`.
 - (void)updateContentOffsetForWebStateIndex:(int)WebStateIndex
                               isNewWebState:(BOOL)isNewWebState;
 
@@ -403,7 +403,7 @@
 // toggle buttons states depending on the current layout mode.
 - (void)updateScrollViewFrameForTabSwitcherButton;
 
-// Returns the existing tab view for |webState| or nil if there is no TabView
+// Returns the existing tab view for `webState` or nil if there is no TabView
 // for it.
 - (TabView*)tabViewForWebState:(web::WebState*)webState;
 
@@ -437,13 +437,13 @@
         std::make_unique<WebStateListFaviconDriverObserver>(_webStateList,
                                                             self);
     _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self);
-    // Observe all webStates of this |_webStateList|.
+    // Observe all webStates of this `_webStateList`.
     _allWebStateObservationForwarder =
         std::make_unique<AllWebStateObservationForwarder>(
             _webStateList, _webStateObserver.get());
     _style = style;
 
-    // |self.view| setup.
+    // `self.view` setup.
     _useTabStacking = [self shouldUseTabStacking];
     CGRect tabStripFrame = SceneStateBrowserAgent::FromBrowser(browser)
                                ->GetSceneState()
@@ -456,7 +456,7 @@
     if (UseRTLLayout())
       _view.transform = CGAffineTransformMakeScale(-1, 1);
 
-    // |self.tabStripView| setup.
+    // `self.tabStripView` setup.
     _tabStripView = [[TabStripView alloc] initWithFrame:_view.bounds];
     _tabStripView.autoresizingMask =
         (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
@@ -467,7 +467,7 @@
     [_view addSubview:_tabStripView];
     _view.tabStripView = _tabStripView;
 
-    // |self.buttonNewTab| setup.
+    // `self.buttonNewTab` setup.
     CGRect buttonNewTabFrame = tabStripFrame;
     buttonNewTabFrame.size.width = kNewTabButtonWidth;
     _buttonNewTab = [[UIButton alloc] initWithFrame:buttonNewTabFrame];
@@ -781,7 +781,7 @@
   return [self webStateListIndexForIndex:[_tabArray indexOfObject:view]];
 }
 
-// Updates the title and the favicon of the |view| with data from |webState|.
+// Updates the title and the favicon of the `view` with data from `webState`.
 - (void)updateTabView:(TabView*)view withWebState:(web::WebState*)webState {
   [[view titleLabel] setText:tab_util::GetTabTitle(webState)];
   [view setFavicon:nil];
@@ -795,13 +795,13 @@
   [_tabStripView setNeedsLayout];
 }
 
-// Gets PopupMenuCommands handler from |_browser|'s command dispatcher.
+// Gets PopupMenuCommands handler from `_browser`'s command dispatcher.
 - (id<PopupMenuCommands>)popupMenuCommandsHandler {
   return HandlerForProtocol(_browser->GetCommandDispatcher(),
                             PopupMenuCommands);
 }
 
-// Gets ApplicationCommands handler from |_browser|'s command dispatcher.
+// Gets ApplicationCommands handler from `_browser`'s command dispatcher.
 - (id<ApplicationCommands>)applicationCommandsHandler {
   return HandlerForProtocol(_browser->GetCommandDispatcher(),
                             ApplicationCommands);
@@ -884,7 +884,7 @@
   // TODO(crbug.com/1049882): We're seeing crashes where fromIndex is
   // kInvalidIndex, indicating that the dragged tab is no longer in the
   // WebStateList. This could happen if a tab closed itself during a drag.
-  // Investigate this further, but for now, simply test |fromIndex| before
+  // Investigate this further, but for now, simply test `fromIndex` before
   // proceeding.
   if (fromIndex == WebStateList::kInvalidIndex) {
     [self resetDragState];
@@ -1127,7 +1127,7 @@
   [_tabStripView setNeedsLayout];
 }
 
-// Observer method. |webState| moved in |webStateList|.
+// Observer method. `webState` moved in `webStateList`.
 - (void)webStateList:(WebStateList*)webStateList
      didMoveWebState:(web::WebState*)webState
            fromIndex:(int)fromIndex
@@ -1142,7 +1142,7 @@
   [self setNeedsLayoutWithAnimation];
 }
 
-// Observer method, |webState| removed from |webStateList|.
+// Observer method, `webState` removed from `webStateList`.
 - (void)webStateList:(WebStateList*)webStateList
     didDetachWebState:(web::WebState*)webState
               atIndex:(int)atIndex {
@@ -1184,7 +1184,7 @@
   [_closingTabs removeObject:view];
 }
 
-// Observer method. |webState| inserted on |webStateList|.
+// Observer method. `webState` inserted on `webStateList`.
 - (void)webStateList:(WebStateList*)webStateList
     didInsertWebState:(web::WebState*)webState
               atIndex:(int)index
@@ -1199,7 +1199,7 @@
   [self updateContentOffsetForWebStateIndex:index isNewWebState:YES];
 }
 
-// Observer method, WebState replaced in |webStateList|.
+// Observer method, WebState replaced in `webStateList`.
 - (void)webStateList:(WebStateList*)webStateList
     didReplaceWebState:(web::WebState*)oldWebState
           withWebState:(web::WebState*)newWebState
@@ -1211,7 +1211,7 @@
 #pragma mark -
 #pragma mark WebStateFaviconDriverObserver
 
-// Observer method. |webState| got a favicon update.
+// Observer method. `webState` got a favicon update.
 - (void)faviconDriver:(favicon::FaviconDriver*)driver
     didUpdateFaviconForWebState:(web::WebState*)webState {
   if (!driver)
@@ -1345,10 +1345,10 @@
   DCHECK_NE(WebStateList::kInvalidIndex, tabIndex);
 
   // The following code calculates the amount of scroll needed to make
-  // |tabIndex| visible in the "virtual" coordinate system, where root is x=0
+  // `tabIndex` visible in the "virtual" coordinate system, where root is x=0
   // and it contains all the tabs laid out as if the tabstrip was infinitely
   // long. The amount of scroll is calculated as a desired length that it is
-  // just large enough to contain all the tabs to the left of |tabIndex|, with
+  // just large enough to contain all the tabs to the left of `tabIndex`, with
   // the standard overlap.
   if (tabIndex == static_cast<int>([_tabArray count]) - 1) {
     const CGFloat tabStripAvailableSpace =
@@ -1456,8 +1456,8 @@
   // This method lays out tabs in two coordinate systems.  The first, the
   // "virtual" coordinate system, is a system rooted at x=0 that contains all
   // the tabs laid out as if the tabstrip was infinitely long.  In this system,
-  // |virtualMinX| contains the starting X coordinate of the next tab to be
-  // placed and |virtualMaxX| contains the maximum X coordinate of the last tab
+  // `virtualMinX` contains the starting X coordinate of the next tab to be
+  // placed and `virtualMaxX` contains the maximum X coordinate of the last tab
   // to be placed.
   //
   // The scroll view's content area is sized to be large enough to hold all the
@@ -1533,12 +1533,12 @@
     if (_isReordering && view == _draggedTab)
       continue;
 
-    // |realMinX| is the furthest left the tab can be, in real coordinates.
+    // `realMinX` is the furthest left the tab can be, in real coordinates.
     // This is computed by counting the number of possible collapsed tabs that
     // can be to the left of this tab, then multiplying that count by the size
     // of a collapsed tab.
     //
-    // There can be up to |[self maxNumCollapsedTabs]| to the left of the
+    // There can be up to `[self maxNumCollapsedTabs]` to the left of the
     // selected
     // tab, and the same number to the right of the selected tab.
     NSUInteger numPossibleCollapsedTabsToLeft =
@@ -1554,7 +1554,7 @@
     CGFloat realMinX =
         offset + (numPossibleCollapsedTabsToLeft * kCollapsedTabOverlap);
 
-    // |realMaxX| is the furthest right the tab can be, in real coordinates.
+    // `realMaxX` is the furthest right the tab can be, in real coordinates.
     int numPossibleCollapsedTabsToRight =
         std::min(tabCount - currentListIndex - 1, [self maxNumCollapsedTabs]);
     if (currentListIndex < selectedListIndex) {
@@ -1589,9 +1589,9 @@
         _placeholderGapWebStateListIndex--;
     }
 
-    // |tabX| stores where we are placing the tab, in real coordinates.  Start
-    // by trying to place the tab at the computed |virtualMinX|, then constrain
-    // that by |realMinX| and |realMaxX|.
+    // `tabX` stores where we are placing the tab, in real coordinates.  Start
+    // by trying to place the tab at the computed `virtualMinX`, then constrain
+    // that by `realMinX` and `realMaxX`.
     CGFloat tabX = MAX(virtualMinX, realMinX);
     if (tabX + _currentTabWidth > realMaxX)
       tabX = realMaxX - _currentTabWidth;
@@ -1817,7 +1817,7 @@
   // is non-clear to cover the WKWebView. In this case, make the tab strip
   // background clear as soon as view revealing begins so any animations that
   // should be visible behind the tab strip are visible. See the comment on
-  // |BackgroundColor()| for more details.
+  // `BackgroundColor()| for more details.
   self.view.backgroundColor = UIColor.clearColor;
   self.viewHiddenForThumbStrip = YES;
   [self updateViewHidden];
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm b/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm
index 59f5779..3279aae9 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm
@@ -37,7 +37,7 @@
 const char kInitialPageUrl[] = "/scenarioDragURLToTabStrip";
 // HTML content of an initial page with a link to the destination page.
 // Note that this string contains substrings that must exactly match the next
-// two constants (|kInitialPageLinkId| and |kInitialPageDestinationLinkText|).
+// two constants (`kInitialPageLinkId` and `kInitialPageDestinationLinkText`).
 // If these were more complex or more liable to change, a sprintf template and
 // runtime composition should be used instead.
 const char kInitialPageHtml[] =
@@ -46,7 +46,7 @@
     "style='margin-left:150px' href='/destination' id='link' aria-label='link'>"
     "link</a></body></html>";
 
-// Accessibility ID of the link on the initial page. The |aria-label| attribute
+// Accessibility ID of the link on the initial page. The `aria-label` attribute
 // makes this visible to UIKit as an accessibility ID.
 NSString* const kInitialPageLinkId = @"link";
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
index 5c35009..88e6973 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
@@ -30,7 +30,7 @@
 // synchronize animations.
 @property(nonatomic, assign) NSTimeInterval animationWaitDuration;
 
-// Animatee for this tab strip. It is not added to the |panGestureHandler| as
+// Animatee for this tab strip. It is not added to the `panGestureHandler` as
 // it needs to be run in sync with BVC.
 @property(nonatomic, readonly, strong) id<ViewRevealingAnimatee> animatee;
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_view.h b/ios/chrome/browser/ui/tabs/tab_strip_view.h
index 198b2a65..2e97c338 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_view.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_view.h
@@ -16,11 +16,11 @@
 // The TabStripViewLayoutDelegate also forward notification of change of trait
 // collection that impact layout.
 @protocol TabStripViewLayoutDelegate
-// Called from |-layoutSubviews|.  Delegates should implement this method to
+// Called from `-layoutSubviews`.  Delegates should implement this method to
 // layout subviews based on the current contentOffset of the tab strip.
 // TabStripView does not perform any other subview layout.
 - (void)layoutTabStripSubviews;
-// Called from UIView |-traitCollectionDidChange:|.
+// Called from UIView `-traitCollectionDidChange:`.
 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection;
 @end
 
diff --git a/ios/chrome/browser/ui/tabs/tab_view.h b/ios/chrome/browser/ui/tabs/tab_view.h
index cb1010a..6f4054c 100644
--- a/ios/chrome/browser/ui/tabs/tab_view.h
+++ b/ios/chrome/browser/ui/tabs/tab_view.h
@@ -22,8 +22,8 @@
 @property(nonatomic, assign) BOOL incognitoStyle;
 
 // Designated initializer.  Creates a TabView with frame equal to CGRectZero.
-// If |emptyView| is YES, it creates a TabView without buttons or spinner.
-// |selected|, the selected state of the tab, is provided to ensure the
+// If `emptyView` is YES, it creates a TabView without buttons or spinner.
+// `selected`, the selected state of the tab, is provided to ensure the
 // background is drawn correctly the first time, rather than requiring that
 // -setSelected be called in order for it to be drawn correctly.
 - (id)initWithEmptyView:(BOOL)emptyView selected:(BOOL)selected;
diff --git a/ios/chrome/browser/ui/tabs/tab_view.mm b/ios/chrome/browser/ui/tabs/tab_view.mm
index bd5d31cc..81f6440 100644
--- a/ios/chrome/browser/ui/tabs/tab_view.mm
+++ b/ios/chrome/browser/ui/tabs/tab_view.mm
@@ -55,7 +55,7 @@
 
 const CGFloat kFontSize = 14.0;
 
-// Returns a default favicon with |UIImageRenderingModeAlwaysTemplate|.
+// Returns a default favicon with `UIImageRenderingModeAlwaysTemplate`.
 UIImage* DefaultFaviconImage() {
   return [[UIImage imageNamed:@"default_world_favicon"]
       imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
@@ -82,7 +82,7 @@
   // Image view used to draw the favicon and spinner.
   UIImageView* _faviconView;
 
-  // If |YES|, this view will adjust its appearance and draw as a collapsed tab.
+  // If `YES`, this view will adjust its appearance and draw as a collapsed tab.
   BOOL _collapsed;
 
   MDCActivityIndicator* _activityIndicator;
@@ -118,7 +118,7 @@
       [self createButtonsAndLabel];
 
     // -setSelected only calls -updateStyleForSelected if the selected state
-    // changes.  |isSelected| defaults to NO, so if |selected| is also NO,
+    // changes.  `isSelected` defaults to NO, so if `selected` is also NO,
     // -updateStyleForSelected needs to be called explicitly.
     [self setSelected:selected];
     if (!selected) {
@@ -347,7 +347,7 @@
   AddSameCenterYConstraint(self, _faviconView, _titleLabel);
 }
 
-// Updates this tab's style based on the value of |selected| and the current
+// Updates this tab's style based on the value of `selected` and the current
 // incognito style.
 - (void)updateStyleForSelected:(BOOL)selected {
   // Style the background image first.
diff --git a/ios/chrome/browser/ui/tabs/target_frame_cache.h b/ios/chrome/browser/ui/tabs/target_frame_cache.h
index ec0c25f..be9a296af 100644
--- a/ios/chrome/browser/ui/tabs/target_frame_cache.h
+++ b/ios/chrome/browser/ui/tabs/target_frame_cache.h
@@ -19,10 +19,10 @@
   void AddFrame(UIView* view, CGRect rect);
   void RemoveFrame(UIView* view);
 
-  // Gets the cached target frame for |view|.
+  // Gets the cached target frame for `view`.
   CGRect GetFrame(UIView* view);
 
-  // Returns whether |view| has a cached target frame.
+  // Returns whether `view` has a cached target frame.
   bool HasFrame(UIView* view);
 
  private:
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.h b/ios/chrome/browser/ui/util/layout_guide_names.h
index 8d51b86..ba7cbd5 100644
--- a/ios/chrome/browser/ui/util/layout_guide_names.h
+++ b/ios/chrome/browser/ui/util/layout_guide_names.h
@@ -55,5 +55,7 @@
 // A guide that is constrained to match the frame of the bottom toolbar in the
 // tab grid.
 extern GuideName* const kTabGridBottomToolbarGuide;
+// A guide that is constrained to match the frame of the first Autofill result.
+extern GuideName* const kAutofillFirstSuggestionGuide;
 
 #endif  // IOS_CHROME_BROWSER_UI_UTIL_LAYOUT_GUIDE_NAMES_H_
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.mm b/ios/chrome/browser/ui/util/layout_guide_names.mm
index 3c39832..84a5ce4 100644
--- a/ios/chrome/browser/ui/util/layout_guide_names.mm
+++ b/ios/chrome/browser/ui/util/layout_guide_names.mm
@@ -25,3 +25,5 @@
 GuideName* const kPrimaryToolbarLocationViewGuide =
     @"kPrimaryToolbarLocationViewGuide";
 GuideName* const kTabGridBottomToolbarGuide = @"kTabGridBottomToolbarGuide";
+GuideName* const kAutofillFirstSuggestionGuide =
+    @"kAutofillFirstSuggestionGuide";
diff --git a/ios/chrome/common/ui/util/BUILD.gn b/ios/chrome/common/ui/util/BUILD.gn
index b461240..c20ed57 100644
--- a/ios/chrome/common/ui/util/BUILD.gn
+++ b/ios/chrome/common/ui/util/BUILD.gn
@@ -42,7 +42,10 @@
     "image_util.mm",
   ]
   deps = [ "//ui/gfx:resize_image_dimensions" ]
-  frameworks = [ "UIKit.framework" ]
+  frameworks = [
+    "UIKit.framework",
+    "CoreImage.framework",
+  ]
 }
 
 source_set("unit_tests") {
diff --git a/ios/chrome/common/ui/util/image_util.h b/ios/chrome/common/ui/util/image_util.h
index 522e274..79f8ce1 100644
--- a/ios/chrome/common/ui/util/image_util.h
+++ b/ios/chrome/common/ui/util/image_util.h
@@ -91,4 +91,7 @@
 // "//ui/gfx/image/image_util.h".
 UIImage* ResizeImageForSearchByImage(UIImage* image);
 
+// Returns a blurred image generated from the given |image| and |blurRadius|.
+UIImage* BlurredImageWithImage(UIImage* image, CGFloat blurRadius);
+
 #endif  // IOS_CHROME_COMMON_UI_UTIL_IMAGE_UTIL_H_
diff --git a/ios/chrome/common/ui/util/image_util.mm b/ios/chrome/common/ui/util/image_util.mm
index 72289377..8b612de 100644
--- a/ios/chrome/common/ui/util/image_util.mm
+++ b/ios/chrome/common/ui/util/image_util.mm
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import <CoreImage/CoreImage.h>
+
 #import "ios/chrome/common/ui/util/image_util.h"
 
 #include "ui/gfx/image/resize_image_dimensions.h"
@@ -160,3 +162,20 @@
   integralRect.size = targetSize;
   targetSize = CGRectIntegral(integralRect).size;
 }
+
+UIImage* BlurredImageWithImage(UIImage* image, CGFloat blurRadius) {
+  CIImage* inputImage = [CIImage imageWithCGImage:image.CGImage];
+
+  // Blur the UIImage with a CIFilter
+  CIFilter* filter = [CIFilter filterWithName:@"CIGaussianBlur"];
+  [filter setValue:inputImage forKey:kCIInputImageKey];
+  [filter setValue:[NSNumber numberWithFloat:blurRadius] forKey:@"inputRadius"];
+
+  CIImage* outputImage = filter.outputImage;
+  CGFloat scale = 1 / image.scale;
+  outputImage = [outputImage
+      imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)];
+  UIImage* blurredImage = [UIImage imageWithCIImage:outputImage];
+  return
+      [blurredImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+}
diff --git a/media/capabilities/BUILD.gn b/media/capabilities/BUILD.gn
index c12dc31..794dda8 100644
--- a/media/capabilities/BUILD.gn
+++ b/media/capabilities/BUILD.gn
@@ -26,6 +26,8 @@
     "in_memory_video_decode_stats_db_impl.h",
     "learning_helper.cc",
     "learning_helper.h",
+    "pending_operations.cc",
+    "pending_operations.h",
     "video_decode_stats_db.cc",
     "video_decode_stats_db.h",
     "video_decode_stats_db_impl.cc",
@@ -61,6 +63,7 @@
   testonly = true
   sources = [
     "in_memory_video_decode_stats_db_unittest.cc",
+    "pending_operations_unittest.cc",
     "video_decode_stats_db_impl_unittest.cc",
     "video_decode_stats_db_unittest.cc",
     "webrtc_video_stats_db_impl_unittest.cc",
diff --git a/media/capabilities/pending_operations.cc b/media/capabilities/pending_operations.cc
new file mode 100644
index 0000000..c2060088
--- /dev/null
+++ b/media/capabilities/pending_operations.cc
@@ -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.
+
+#include "media/capabilities/pending_operations.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/threading/thread_task_runner_handle.h"
+
+namespace media {
+namespace {
+// Timeout threshold for DB operations. See OnOperationTimeout().
+// NOTE: Used by UmaHistogramOpTime. Change the name if you change the time.
+static constexpr base::TimeDelta kPendingOpTimeout = base::Seconds(30);
+}  // namespace
+
+PendingOperations::PendingOperation::PendingOperation(
+    const std::string& uma_prefix,
+    std::string uma_str,
+    std::unique_ptr<base::CancelableOnceClosure> timeout_closure)
+    : uma_prefix_(uma_prefix),
+      uma_str_(uma_str),
+      timeout_closure_(std::move(timeout_closure)),
+      start_ticks_(base::TimeTicks::Now()) {
+  DVLOG(3) << __func__ << " Started " << uma_str_;
+}
+
+PendingOperations::PendingOperation::~PendingOperation() {
+  // Destroying a pending operation that hasn't timed out yet implies the
+  // operation has completed.
+  if (timeout_closure_ && !timeout_closure_->IsCancelled()) {
+    base::TimeDelta op_duration = base::TimeTicks::Now() - start_ticks_;
+    UmaHistogramOpTime(uma_str_, op_duration);
+    DVLOG(3) << __func__ << " Completed " << uma_str_ << " ("
+             << op_duration.InMilliseconds() << ")";
+
+    // Ensure the timeout doesn't fire. Destruction should cancel the callback
+    // implicitly, but that's not a documented contract, so just taking the safe
+    // route.
+    timeout_closure_->Cancel();
+  }
+}
+
+void PendingOperations::PendingOperation::UmaHistogramOpTime(
+    const std::string& op_name,
+    base::TimeDelta duration) {
+  base::UmaHistogramCustomMicrosecondsTimes(uma_prefix_ + op_name, duration,
+                                            base::Milliseconds(1),
+                                            kPendingOpTimeout, 50);
+}
+
+void PendingOperations::PendingOperation::OnTimeout() {
+  UmaHistogramOpTime(uma_str_, kPendingOpTimeout);
+  LOG(WARNING) << " Timeout performing " << uma_str_
+               << " operation on WebrtcVideoStatsDB";
+
+  // Cancel the closure to ensure we don't double report the task as completed
+  // in ~PendingOperation().
+  timeout_closure_->Cancel();
+}
+
+PendingOperations::PendingOperations(std::string uma_prefix)
+    : uma_prefix_(uma_prefix) {}
+
+PendingOperations::~PendingOperations() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+PendingOperations::Id PendingOperations::Start(std::string uma_str) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  Id op_id = next_op_id_++;
+
+  auto timeout_closure = std::make_unique<base::CancelableOnceClosure>(
+      base::BindOnce(&PendingOperations::OnTimeout,
+                     weak_ptr_factory_.GetWeakPtr(), op_id));
+
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, timeout_closure->callback(), kPendingOpTimeout);
+
+  pending_ops_.emplace(
+      op_id, std::make_unique<PendingOperation>(uma_prefix_, uma_str,
+                                                std::move(timeout_closure)));
+
+  return op_id;
+}
+
+void PendingOperations::Complete(Id op_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Destructing the PendingOperation will trigger UMA for completion timing.
+  int count = pending_ops_.erase(op_id);
+
+  // No big deal, but very unusual. Timeout is very generous, so tasks that
+  // timeout are generally assumed to be permanently hung.
+  if (!count)
+    DVLOG(2) << __func__ << " DB operation completed after timeout.";
+}
+
+void PendingOperations::OnTimeout(Id op_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  auto it = pending_ops_.find(op_id);
+  DCHECK(it != pending_ops_.end());
+
+  it->second->OnTimeout();
+  pending_ops_.erase(it);
+}
+
+}  // namespace media
\ No newline at end of file
diff --git a/media/capabilities/pending_operations.h b/media/capabilities/pending_operations.h
new file mode 100644
index 0000000..f775335
--- /dev/null
+++ b/media/capabilities/pending_operations.h
@@ -0,0 +1,92 @@
+// 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_CAPABILITIES_PENDING_OPERATIONS_H_
+#define MEDIA_CAPABILITIES_PENDING_OPERATIONS_H_
+
+#include "base/cancelable_callback.h"
+#include "base/containers/flat_map.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+class MEDIA_EXPORT PendingOperations {
+ public:
+  using Id = int;
+
+  // Helper to report timing information for DB operations, including when they
+  // hang indefinitely.
+  class PendingOperation {
+   public:
+    PendingOperation(
+        const std::string& uma_prefix,
+        std::string uma_str,
+        std::unique_ptr<base::CancelableOnceClosure> timeout_closure);
+    // Records task timing UMA if it hasn't already timed out.
+    virtual ~PendingOperation();
+
+    // Copies disallowed. Incompatible with move-only members and UMA logging in
+    // the destructor.
+    PendingOperation(const PendingOperation&) = delete;
+    PendingOperation& operator=(const PendingOperation&) = delete;
+
+    void UmaHistogramOpTime(const std::string& op_name,
+                            base::TimeDelta duration);
+
+    // Trigger UMA recording for timeout.
+    void OnTimeout();
+
+   private:
+    friend class VideoDecodeStatsDBImplTest;
+    friend class WebrtcVideoStatsDBImplTest;
+    const std::string& uma_prefix_;
+    const std::string uma_str_;
+    std::unique_ptr<base::CancelableOnceClosure> timeout_closure_;
+    const base::TimeTicks start_ticks_;
+  };
+
+  explicit PendingOperations(std::string uma_prefix);
+  ~PendingOperations();
+
+  // Creates a PendingOperation using `uma_str` and adds it to `pending_ops_`
+  // map. Returns Id for newly started operation. Callers must later call
+  // Complete() with this id to destroy the PendingOperation and finalize timing
+  // UMA.
+  Id Start(std::string uma_str);
+
+  // Removes PendingOperation from `pending_ops_` using `op_id_` as a key. This
+  // destroys the object and triggers timing UMA.
+  void Complete(Id op_id);
+
+  // Unified handler for timeouts of pending DB operations. PendingOperation
+  // will be notified that it timed out (to trigger timing UMA) and removed from
+  // `pending_ops_`.
+  void OnTimeout(Id id);
+
+  const base::flat_map<Id, std::unique_ptr<PendingOperation>>&
+  get_pending_ops_for_test() const {
+    return pending_ops_;
+  }
+
+ private:
+  // UMA prefix that is used for pending operations histograms.
+  const std::string uma_prefix_;
+
+  // Next Id for use in `pending_ops_` map. See Start().
+  Id next_op_id_ = 0;
+
+  // Map of operation id -> outstanding PendingOperations.
+  base::flat_map<Id, std::unique_ptr<PendingOperation>> pending_ops_;
+
+  // Ensures all access to class members come on the same sequence.
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  base::WeakPtrFactory<PendingOperations> weak_ptr_factory_{this};
+};
+
+}  // namespace media
+
+#endif  // MEDIA_CAPABILITIES_PENDING_OPERATIONS_H_
\ No newline at end of file
diff --git a/media/capabilities/pending_operations_unittest.cc b/media/capabilities/pending_operations_unittest.cc
new file mode 100644
index 0000000..5a9ce02
--- /dev/null
+++ b/media/capabilities/pending_operations_unittest.cc
@@ -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.
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "media/capabilities/pending_operations.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+namespace {
+
+class PendingOperationsTest : public ::testing::Test {
+ protected:
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  base::HistogramTester histogram_;
+};
+
+// Test that histogram is created with correct data.
+TEST_F(PendingOperationsTest, OperationTiming) {
+  const std::string kUmaPrefix = "Media.PendingOperations.";
+  const std::string kOperation = "init";
+  constexpr base::TimeDelta kInitDelay = base::Seconds(2);
+  PendingOperations pending_operations(kUmaPrefix);
+  PendingOperations::Id init_id = pending_operations.Start(kOperation);
+  EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(), 1u);
+  task_environment_.FastForwardBy(kInitDelay);
+  pending_operations.Complete(init_id);
+
+  // No pending operations.
+  EXPECT_TRUE(pending_operations.get_pending_ops_for_test().empty());
+  // UMA histogram emitted.
+  histogram_.ExpectUniqueSample(kUmaPrefix + kOperation,
+                                kInitDelay.InMicroseconds(), 1);
+}
+
+// Test that timeout histogram works.
+TEST_F(PendingOperationsTest, OperationTimeout) {
+  const std::string kUmaPrefix = "Media.PendingOperations.";
+  const std::string kOperation = "read";
+  constexpr base::TimeDelta kLongTimeout = base::Hours(1);
+  // Current setting of the pending operation timeout.
+  constexpr base::TimeDelta kPendingOperationTimeout = base::Seconds(30);
+  PendingOperations pending_operations(kUmaPrefix);
+  pending_operations.Start(kOperation);
+  EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(), 1u);
+  task_environment_.FastForwardBy(kLongTimeout);
+
+  // No pending operations.
+  EXPECT_TRUE(pending_operations.get_pending_ops_for_test().empty());
+  // UMA histogram emitted, operation reported as timeout.
+  histogram_.ExpectUniqueSample(kUmaPrefix + kOperation,
+                                kPendingOperationTimeout.InMicroseconds(), 1);
+}
+
+// Nested operations.
+struct SimulatedOperation {
+  std::string name;
+  base::TimeDelta start_time;
+  base::TimeDelta stop_time;
+  PendingOperations::Id id;
+};
+
+TEST_F(PendingOperationsTest, NestedOperation) {
+  const std::string kUmaPrefix = "Media.PendingOperations.";
+  PendingOperations pending_operations(kUmaPrefix);
+  // A list of operations named after their start and stop time.
+  SimulatedOperation operations[] = {
+      {"0_10", base::Milliseconds(0), base::Milliseconds(10), 0},
+      {"5_15", base::Milliseconds(5), base::Milliseconds(15), 0},
+      {"6_30", base::Milliseconds(6), base::Milliseconds(30), 0},
+      {"10_12", base::Milliseconds(10), base::Milliseconds(12), 0},
+      {"20_27", base::Milliseconds(20), base::Milliseconds(27), 0},
+      {"5_80", base::Milliseconds(5), base::Milliseconds(80), 0},
+      {"30_60", base::Milliseconds(30), base::Milliseconds(60), 0},
+      {"25_90", base::Milliseconds(25), base::Milliseconds(90), 0},
+  };
+
+  size_t expected_pending_operations = 0;
+  // Run a loop from 0 to 100 ms.
+  base::TimeDelta tick_length = base::Milliseconds(1);
+  for (base::TimeDelta elapsed_time; elapsed_time < base::Milliseconds(100);
+       elapsed_time += tick_length) {
+    // Start/Complete each operation if the elapsed time has reached the
+    // corresponding start/stop time.
+    for (auto& operation : operations) {
+      if (operation.start_time == elapsed_time) {
+        operation.id = pending_operations.Start(operation.name);
+        ++expected_pending_operations;
+      }
+      if (operation.stop_time == elapsed_time) {
+        pending_operations.Complete(operation.id);
+        --expected_pending_operations;
+      }
+    }
+    EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(),
+              expected_pending_operations);
+    task_environment_.FastForwardBy(tick_length);
+  }
+
+  for (const auto& operation : operations) {
+    histogram_.ExpectUniqueSample(
+        kUmaPrefix + operation.name,
+        (operation.stop_time - operation.start_time).InMicroseconds(), 1);
+  }
+}
+
+}  // namespace
+}  // namespace media
diff --git a/media/capabilities/video_decode_stats_db_impl.cc b/media/capabilities/video_decode_stats_db_impl.cc
index 7df2548..929fed2 100644
--- a/media/capabilities/video_decode_stats_db_impl.cc
+++ b/media/capabilities/video_decode_stats_db_impl.cc
@@ -18,7 +18,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/sequence_checker.h"
 #include "base/task/thread_pool.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/default_clock.h"
 #include "components/leveldb_proto/public/proto_database_provider.h"
 #include "media/base/media_switches.h"
@@ -30,22 +29,12 @@
 
 namespace {
 
-// Timeout threshold for DB operations. See OnOperationTimeout().
-// NOTE: Used by UmaHistogramOpTime. Change the name if you change the time.
-static constexpr base::TimeDelta kPendingOpTimeout = base::Seconds(30);
-
 const int kMaxFramesPerBufferDefault = 2500;
 
 const int kMaxDaysToKeepStatsDefault = 30;
 
 const bool kEnableUnweightedEntriesDefault = false;
 
-void UmaHistogramOpTime(const std::string& op_name, base::TimeDelta duration) {
-  base::UmaHistogramCustomMicrosecondsTimes(
-      "Media.VideoDecodeStatsDB.OpTiming." + op_name, duration,
-      base::Milliseconds(1), kPendingOpTimeout, 50);
-}
-
 }  // namespace
 
 const char VideoDecodeStatsDBImpl::kMaxFramesPerBufferParamName[] =
@@ -57,41 +46,6 @@
 const char VideoDecodeStatsDBImpl::kEnableUnweightedEntriesParamName[] =
     "db_enable_unweighted_entries";
 
-VideoDecodeStatsDBImpl::PendingOperation::PendingOperation(
-    std::string uma_str,
-    std::unique_ptr<base::CancelableOnceClosure> timeout_closure)
-    : uma_str_(uma_str),
-      timeout_closure_(std::move(timeout_closure)),
-      start_ticks_(base::TimeTicks::Now()) {
-  DVLOG(3) << __func__ << " Started " << uma_str_;
-}
-
-VideoDecodeStatsDBImpl::PendingOperation::~PendingOperation() {
-  // Destroying a pending operation that hasn't timed out yet implies the
-  // operation has completed.
-  if (timeout_closure_ && !timeout_closure_->IsCancelled()) {
-    base::TimeDelta op_duration = base::TimeTicks::Now() - start_ticks_;
-    UmaHistogramOpTime(uma_str_, op_duration);
-    DVLOG(3) << __func__ << " Completed " << uma_str_ << " ("
-             << op_duration.InMilliseconds() << ")";
-
-    // Ensure the timeout doesn't fire. Destruction should cancel the callback
-    // implicitly, but that's not a documented contract, so just taking the safe
-    // route.
-    timeout_closure_->Cancel();
-  }
-}
-
-void VideoDecodeStatsDBImpl::PendingOperation::OnTimeout() {
-  UmaHistogramOpTime(uma_str_, kPendingOpTimeout);
-  LOG(WARNING) << " Timeout performing " << uma_str_
-               << " operation on VideoDecodeStatsDB";
-
-  // Cancel the closure to ensure we don't double report the task as completed
-  // in ~PendingOperation().
-  timeout_closure_->Cancel();
-}
-
 // static
 int VideoDecodeStatsDBImpl::GetMaxFramesPerBuffer() {
   return base::GetFieldTrialParamByFeatureAsDouble(
@@ -143,7 +97,9 @@
 
 VideoDecodeStatsDBImpl::VideoDecodeStatsDBImpl(
     std::unique_ptr<leveldb_proto::ProtoDatabase<DecodeStatsProto>> db)
-    : db_(std::move(db)), wall_clock_(base::DefaultClock::GetInstance()) {
+    : pending_operations_(/*uma_prefix=*/"Media.VideoDecodeStatsDB.OpTiming."),
+      db_(std::move(db)),
+      wall_clock_(base::DefaultClock::GetInstance()) {
   bool time_parsed =
       base::Time::FromString(kDefaultWriteTime, &default_write_time_);
   DCHECK(time_parsed);
@@ -155,43 +111,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-VideoDecodeStatsDBImpl::PendingOpId VideoDecodeStatsDBImpl::StartPendingOp(
-    std::string uma_str) {
-  PendingOpId op_id = next_op_id_++;
-
-  auto timeout_closure = std::make_unique<base::CancelableOnceClosure>(
-      base::BindOnce(&VideoDecodeStatsDBImpl::OnPendingOpTimeout,
-                     weak_ptr_factory_.GetWeakPtr(), op_id));
-
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, timeout_closure->callback(), kPendingOpTimeout);
-
-  pending_ops_.emplace(op_id, std::make_unique<PendingOperation>(
-                                  uma_str, std::move(timeout_closure)));
-
-  return op_id;
-}
-
-void VideoDecodeStatsDBImpl::CompletePendingOp(PendingOpId op_id) {
-  // Destructing the PendingOperation will trigger UMA for completion timing.
-  int count = pending_ops_.erase(op_id);
-
-  // No big deal, but very unusual. Timeout is very generous, so tasks that
-  // timeout are generally assumed to be permanently hung.
-  if (!count)
-    DVLOG(2) << __func__ << " DB operation completed after timeout.";
-}
-
-void VideoDecodeStatsDBImpl::OnPendingOpTimeout(PendingOpId op_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  auto it = pending_ops_.find(op_id);
-  DCHECK(it != pending_ops_.end());
-
-  it->second->OnTimeout();
-  pending_ops_.erase(it);
-}
-
 void VideoDecodeStatsDBImpl::Initialize(InitializeCB init_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(init_cb);
@@ -201,19 +120,19 @@
   // case our whole DB will be less than 35K, so we aren't worried about
   // spamming the cache.
   // TODO(chcunningham): Keep an eye on the size as the table evolves.
-  db_->Init(base::BindOnce(&VideoDecodeStatsDBImpl::OnInit,
-                           weak_ptr_factory_.GetWeakPtr(),
-                           StartPendingOp("Initialize"), std::move(init_cb)));
+  db_->Init(base::BindOnce(
+      &VideoDecodeStatsDBImpl::OnInit, weak_ptr_factory_.GetWeakPtr(),
+      pending_operations_.Start("Initialize"), std::move(init_cb)));
 }
 
-void VideoDecodeStatsDBImpl::OnInit(PendingOpId op_id,
+void VideoDecodeStatsDBImpl::OnInit(PendingOperations::Id op_id,
                                     InitializeCB init_cb,
                                     leveldb_proto::Enums::InitStatus status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_NE(status, leveldb_proto::Enums::InitStatus::kInvalidOperation);
   bool success = status == leveldb_proto::Enums::InitStatus::kOK;
   DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Initialize",
                         success);
 
@@ -241,11 +160,11 @@
   DVLOG(3) << __func__ << " Reading key " << key.ToLogString()
            << " from DB with intent to update with " << entry.ToLogString();
 
-  db_->GetEntry(
-      key.Serialize(),
-      base::BindOnce(&VideoDecodeStatsDBImpl::WriteUpdatedEntry,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Read"),
-                     key, entry, std::move(append_done_cb)));
+  db_->GetEntry(key.Serialize(),
+                base::BindOnce(&VideoDecodeStatsDBImpl::WriteUpdatedEntry,
+                               weak_ptr_factory_.GetWeakPtr(),
+                               pending_operations_.Start("Read"), key, entry,
+                               std::move(append_done_cb)));
 }
 
 void VideoDecodeStatsDBImpl::GetDecodeStats(const VideoDescKey& key,
@@ -255,11 +174,11 @@
 
   DVLOG(3) << __func__ << " " << key.ToLogString();
 
-  db_->GetEntry(
-      key.Serialize(),
-      base::BindOnce(&VideoDecodeStatsDBImpl::OnGotDecodeStats,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Read"),
-                     std::move(get_stats_cb)));
+  db_->GetEntry(key.Serialize(),
+                base::BindOnce(&VideoDecodeStatsDBImpl::OnGotDecodeStats,
+                               weak_ptr_factory_.GetWeakPtr(),
+                               pending_operations_.Start("Read"),
+                               std::move(get_stats_cb)));
 }
 
 bool VideoDecodeStatsDBImpl::AreStatsUsable(
@@ -311,7 +230,7 @@
 }
 
 void VideoDecodeStatsDBImpl::WriteUpdatedEntry(
-    PendingOpId op_id,
+    PendingOperations::Id op_id,
     const VideoDescKey& key,
     const DecodeStatsEntry& new_entry,
     AppendDecodeStatsCB append_done_cb,
@@ -319,7 +238,7 @@
     std::unique_ptr<DecodeStatsProto> stats_proto) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(IsInitialized());
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
 
   // Note: outcome of "Write" operation logged in OnEntryUpdated().
   UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Read",
@@ -457,31 +376,32 @@
   std::unique_ptr<DBType::KeyEntryVector> entries =
       std::make_unique<DBType::KeyEntryVector>();
   entries->emplace_back(key.Serialize(), *stats_proto);
-  db_->UpdateEntries(
-      std::move(entries), std::make_unique<leveldb_proto::KeyVector>(),
-      base::BindOnce(&VideoDecodeStatsDBImpl::OnEntryUpdated,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Write"),
-                     std::move(append_done_cb)));
+  db_->UpdateEntries(std::move(entries),
+                     std::make_unique<leveldb_proto::KeyVector>(),
+                     base::BindOnce(&VideoDecodeStatsDBImpl::OnEntryUpdated,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    pending_operations_.Start("Write"),
+                                    std::move(append_done_cb)));
 }
 
-void VideoDecodeStatsDBImpl::OnEntryUpdated(PendingOpId op_id,
+void VideoDecodeStatsDBImpl::OnEntryUpdated(PendingOperations::Id op_id,
                                             AppendDecodeStatsCB append_done_cb,
                                             bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << __func__ << " update " << (success ? "succeeded" : "FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Write", success);
   std::move(append_done_cb).Run(success);
 }
 
 void VideoDecodeStatsDBImpl::OnGotDecodeStats(
-    PendingOpId op_id,
+    PendingOperations::Id op_id,
     GetDecodeStatsCB get_stats_cb,
     bool success,
     std::unique_ptr<DecodeStatsProto> stats_proto) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << __func__ << " get " << (success ? "succeeded" : "FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Read", success);
 
   std::unique_ptr<DecodeStatsEntry> entry;
@@ -546,17 +466,18 @@
       std::make_unique<ProtoDecodeStatsEntry::KeyEntryVector>(),
       base::BindRepeating([](const std::string& key) { return true; }),
       base::BindOnce(&VideoDecodeStatsDBImpl::OnStatsCleared,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Clear"),
+                     weak_ptr_factory_.GetWeakPtr(),
+                     pending_operations_.Start("Clear"),
                      std::move(clear_done_cb)));
 }
 
-void VideoDecodeStatsDBImpl::OnStatsCleared(PendingOpId op_id,
+void VideoDecodeStatsDBImpl::OnStatsCleared(PendingOperations::Id op_id,
                                             base::OnceClosure clear_done_cb,
                                             bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");
 
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
 
   UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Clear", success);
 
diff --git a/media/capabilities/video_decode_stats_db_impl.h b/media/capabilities/video_decode_stats_db_impl.h
index e7457ea5..328b7c7 100644
--- a/media/capabilities/video_decode_stats_db_impl.h
+++ b/media/capabilities/video_decode_stats_db_impl.h
@@ -7,8 +7,6 @@
 
 #include <memory>
 
-#include "base/cancelable_callback.h"
-#include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -17,6 +15,7 @@
 #include "components/leveldb_proto/public/proto_database.h"
 #include "media/base/media_export.h"
 #include "media/base/video_codecs.h"
+#include "media/capabilities/pending_operations.h"
 #include "media/capabilities/video_decode_stats_db.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -66,8 +65,6 @@
  private:
   friend class VideoDecodeStatsDBImplTest;
 
-  using PendingOpId = int;
-
   // Private constructor only called by tests (friends). Production code
   // should always use the static Create() method.
   VideoDecodeStatsDBImpl(
@@ -95,53 +92,9 @@
   // Returns current feature params.
   static base::FieldTrialParams GetFieldTrialParams();
 
-  // Creates a PendingOperation using |uma_str| and adds it to |pending_ops_|
-  // map. Returns PendingOpId for newly started operation. Callers must later
-  // call CompletePendingOp() with this id to destroy the PendingOperation and
-  // finalize timing UMA.
-  PendingOpId StartPendingOp(std::string uma_str);
-
-  // Removes PendingOperation from |pending_ops_| using |op_id_| as a key. This
-  // destroys the object and triggers timing UMA.
-  void CompletePendingOp(PendingOpId op_id);
-
-  // Unified handler for timeouts of pending DB operations. PendingOperation
-  // will be notified that it timed out (to trigger timing UMA) and removed from
-  // |penidng_ops_|.
-  void OnPendingOpTimeout(PendingOpId id);
-
-  // Helper to report timing information for DB operations, including when they
-  // hang indefinitely.
-  class PendingOperation {
-   public:
-    PendingOperation(
-        std::string uma_str,
-        std::unique_ptr<base::CancelableOnceClosure> timeout_closure);
-    // Records task timing UMA if it hasn't already timed out.
-    virtual ~PendingOperation();
-
-    // Copies disallowed. Incompatible with move-only members and UMA logging in
-    // the destructor.
-    PendingOperation(const PendingOperation&) = delete;
-    PendingOperation& operator=(const PendingOperation&) = delete;
-
-    // Trigger UMA recording for timeout.
-    void OnTimeout();
-
-   private:
-    friend class VideoDecodeStatsDBImplTest;
-
-    std::string uma_str_;
-    std::unique_ptr<base::CancelableOnceClosure> timeout_closure_;
-    base::TimeTicks start_ticks_;
-  };
-
-  // Map of operation id -> outstanding PendingOperations.
-  base::flat_map<PendingOpId, std::unique_ptr<PendingOperation>> pending_ops_;
-
   // Called when the database has been initialized. Will immediately call
   // |init_cb| to forward |success|.
-  void OnInit(PendingOpId id,
+  void OnInit(PendingOperations::Id id,
               InitializeCB init_cb,
               leveldb_proto::Enums::InitStatus status);
 
@@ -150,7 +103,7 @@
 
   // Passed as the callback for |OnGotDecodeStats| by |AppendDecodeStats| to
   // update the database once we've read the existing stats entry.
-  void WriteUpdatedEntry(PendingOpId op_id,
+  void WriteUpdatedEntry(PendingOperations::Id op_id,
                          const VideoDescKey& key,
                          const DecodeStatsEntry& entry,
                          AppendDecodeStatsCB append_done_cb,
@@ -159,21 +112,21 @@
 
   // Called when the database has been modified after a call to
   // |WriteUpdatedEntry|. Will run |append_done_cb| when done.
-  void OnEntryUpdated(PendingOpId op_id,
+  void OnEntryUpdated(PendingOperations::Id op_id,
                       AppendDecodeStatsCB append_done_cb,
                       bool success);
 
   // Called when GetDecodeStats() operation was performed. |get_stats_cb|
   // will be run with |success| and a |DecodeStatsEntry| created from
   // |stats_proto| or nullptr if no entry was found for the requested key.
-  void OnGotDecodeStats(PendingOpId op_id,
+  void OnGotDecodeStats(PendingOperations::Id op_id,
                         GetDecodeStatsCB get_stats_cb,
                         bool success,
                         std::unique_ptr<DecodeStatsProto> stats_proto);
 
   // Internal callback for OnLoadAllKeysForClearing(), initially triggered by
   // ClearStats(). Method simply logs |success| and runs |clear_done_cb|.
-  void OnStatsCleared(PendingOpId op_id,
+  void OnStatsCleared(PendingOperations::Id op_id,
                       base::OnceClosure clear_done_cb,
                       bool success);
 
@@ -189,8 +142,7 @@
     wall_clock_ = tick_clock;
   }
 
-  // Next PendingOpId for use in |pending_ops_| map. See StartPendingOp().
-  PendingOpId next_op_id_ = 0;
+  PendingOperations pending_operations_;
 
   // Indicates whether initialization is completed. Does not indicate whether it
   // was successful. Will be reset upon calling DestroyStats(). Failed
diff --git a/media/capabilities/video_decode_stats_db_impl_unittest.cc b/media/capabilities/video_decode_stats_db_impl_unittest.cc
index 565b743..ab075f6 100644
--- a/media/capabilities/video_decode_stats_db_impl_unittest.cc
+++ b/media/capabilities/video_decode_stats_db_impl_unittest.cc
@@ -77,13 +77,19 @@
   }
 
   void VerifyOnePendingOp(std::string op_name) {
-    EXPECT_EQ(stats_db_->pending_ops_.size(), 1u);
-    VideoDecodeStatsDBImpl::PendingOperation* pending_op =
-        stats_db_->pending_ops_.begin()->second.get();
+    EXPECT_EQ(stats_db_->pending_operations_.get_pending_ops_for_test().size(),
+              1u);
+    PendingOperations::PendingOperation* pending_op =
+        stats_db_->pending_operations_.get_pending_ops_for_test()
+            .begin()
+            ->second.get();
     EXPECT_EQ(pending_op->uma_str_, op_name);
   }
 
-  void VerifyNoPendingOps() { EXPECT_TRUE(stats_db_->pending_ops_.empty()); }
+  void VerifyNoPendingOps() {
+    EXPECT_TRUE(
+        stats_db_->pending_operations_.get_pending_ops_for_test().empty());
+  }
 
   int GetMaxFramesPerBuffer() {
     return VideoDecodeStatsDBImpl::GetMaxFramesPerBuffer();
diff --git a/media/capabilities/webrtc_video_stats_db_impl.cc b/media/capabilities/webrtc_video_stats_db_impl.cc
index dd524f5..6dbf930 100644
--- a/media/capabilities/webrtc_video_stats_db_impl.cc
+++ b/media/capabilities/webrtc_video_stats_db_impl.cc
@@ -19,7 +19,6 @@
 #include "base/sequence_checker.h"
 #include "base/strings/string_util.h"
 #include "base/task/thread_pool.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/default_clock.h"
 #include "components/leveldb_proto/public/proto_database_provider.h"
 #include "media/base/media_switches.h"
@@ -30,55 +29,6 @@
 using ProtoVideoStatsEntry =
     leveldb_proto::ProtoDatabase<WebrtcVideoStatsEntryProto>;
 
-namespace {
-
-// Timeout threshold for DB operations. See OnOperationTimeout().
-// NOTE: Used by UmaHistogramOpTime. Change the name if you change the time.
-static constexpr base::TimeDelta kPendingOpTimeout = base::Seconds(30);
-
-void UmaHistogramOpTime(const std::string& op_name, base::TimeDelta duration) {
-  base::UmaHistogramCustomMicrosecondsTimes(
-      "Media.WebrtcVideoStatsDB.OpTiming." + op_name, duration,
-      base::Milliseconds(1), kPendingOpTimeout, 50);
-}
-
-}  // namespace
-
-WebrtcVideoStatsDBImpl::PendingOperation::PendingOperation(
-    std::string uma_str,
-    std::unique_ptr<base::CancelableOnceClosure> timeout_closure)
-    : uma_str_(uma_str),
-      timeout_closure_(std::move(timeout_closure)),
-      start_ticks_(base::TimeTicks::Now()) {
-  DVLOG(3) << __func__ << " Started " << uma_str_;
-}
-
-WebrtcVideoStatsDBImpl::PendingOperation::~PendingOperation() {
-  // Destroying a pending operation that hasn't timed out yet implies the
-  // operation has completed.
-  if (timeout_closure_ && !timeout_closure_->IsCancelled()) {
-    base::TimeDelta op_duration = base::TimeTicks::Now() - start_ticks_;
-    UmaHistogramOpTime(uma_str_, op_duration);
-    DVLOG(3) << __func__ << " Completed " << uma_str_ << " ("
-             << op_duration.InMilliseconds() << ")";
-
-    // Ensure the timeout doesn't fire. Destruction should cancel the callback
-    // implicitly, but that's not a documented contract, so just taking the safe
-    // route.
-    timeout_closure_->Cancel();
-  }
-}
-
-void WebrtcVideoStatsDBImpl::PendingOperation::OnTimeout() {
-  UmaHistogramOpTime(uma_str_, kPendingOpTimeout);
-  LOG(WARNING) << " Timeout performing " << uma_str_
-               << " operation on WebrtcVideoStatsDB";
-
-  // Cancel the closure to ensure we don't double report the task as completed
-  // in ~PendingOperation().
-  timeout_closure_->Cancel();
-}
-
 // static
 std::unique_ptr<WebrtcVideoStatsDBImpl> WebrtcVideoStatsDBImpl::Create(
     base::FilePath db_dir,
@@ -97,7 +47,9 @@
 WebrtcVideoStatsDBImpl::WebrtcVideoStatsDBImpl(
     std::unique_ptr<leveldb_proto::ProtoDatabase<WebrtcVideoStatsEntryProto>>
         db)
-    : db_(std::move(db)), wall_clock_(base::DefaultClock::GetInstance()) {
+    : pending_operations_(/*uma_prefix=*/"Media.WebrtcVideoStatsDB.OpTiming."),
+      db_(std::move(db)),
+      wall_clock_(base::DefaultClock::GetInstance()) {
   DCHECK(db_);
 }
 
@@ -105,61 +57,24 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-WebrtcVideoStatsDBImpl::PendingOpId WebrtcVideoStatsDBImpl::StartPendingOp(
-    std::string uma_str) {
-  PendingOpId op_id = next_op_id_++;
-
-  auto timeout_closure = std::make_unique<base::CancelableOnceClosure>(
-      base::BindOnce(&WebrtcVideoStatsDBImpl::OnPendingOpTimeout,
-                     weak_ptr_factory_.GetWeakPtr(), op_id));
-
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, timeout_closure->callback(), kPendingOpTimeout);
-
-  pending_ops_.emplace(op_id, std::make_unique<PendingOperation>(
-                                  uma_str, std::move(timeout_closure)));
-
-  return op_id;
-}
-
-void WebrtcVideoStatsDBImpl::CompletePendingOp(PendingOpId op_id) {
-  // Destructing the PendingOperation will trigger UMA for completion timing.
-  int count = pending_ops_.erase(op_id);
-
-  // No big deal, but very unusual. Timeout is very generous, so tasks that
-  // timeout are generally assumed to be permanently hung.
-  if (!count)
-    DVLOG(2) << __func__ << " DB operation completed after timeout.";
-}
-
-void WebrtcVideoStatsDBImpl::OnPendingOpTimeout(PendingOpId op_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  auto it = pending_ops_.find(op_id);
-  DCHECK(it != pending_ops_.end());
-
-  it->second->OnTimeout();
-  pending_ops_.erase(it);
-}
-
 void WebrtcVideoStatsDBImpl::Initialize(InitializeCB init_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(init_cb);
   DCHECK(!IsInitialized());
 
-  db_->Init(base::BindOnce(&WebrtcVideoStatsDBImpl::OnInit,
-                           weak_ptr_factory_.GetWeakPtr(),
-                           StartPendingOp("Initialize"), std::move(init_cb)));
+  db_->Init(base::BindOnce(
+      &WebrtcVideoStatsDBImpl::OnInit, weak_ptr_factory_.GetWeakPtr(),
+      pending_operations_.Start("Initialize"), std::move(init_cb)));
 }
 
-void WebrtcVideoStatsDBImpl::OnInit(PendingOpId op_id,
+void WebrtcVideoStatsDBImpl::OnInit(PendingOperations::Id op_id,
                                     InitializeCB init_cb,
                                     leveldb_proto::Enums::InitStatus status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_NE(status, leveldb_proto::Enums::InitStatus::kInvalidOperation);
   bool success = status == leveldb_proto::Enums::InitStatus::kOK;
   DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Initialize",
                         success);
 
@@ -188,11 +103,11 @@
            << " from DB with intent to update with "
            << video_stats.ToLogString();
 
-  db_->GetEntry(
-      key.Serialize(),
-      base::BindOnce(&WebrtcVideoStatsDBImpl::WriteUpdatedEntry,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Read"),
-                     key, video_stats, std::move(append_done_cb)));
+  db_->GetEntry(key.Serialize(),
+                base::BindOnce(&WebrtcVideoStatsDBImpl::WriteUpdatedEntry,
+                               weak_ptr_factory_.GetWeakPtr(),
+                               pending_operations_.Start("Read"), key,
+                               video_stats, std::move(append_done_cb)));
 }
 
 void WebrtcVideoStatsDBImpl::GetVideoStats(const VideoDescKey& key,
@@ -202,11 +117,11 @@
 
   DVLOG(3) << __func__ << " " << key.ToLogStringForDebug();
 
-  db_->GetEntry(
-      key.Serialize(),
-      base::BindOnce(&WebrtcVideoStatsDBImpl::OnGotVideoStats,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Read"),
-                     std::move(get_stats_cb)));
+  db_->GetEntry(key.Serialize(),
+                base::BindOnce(&WebrtcVideoStatsDBImpl::OnGotVideoStats,
+                               weak_ptr_factory_.GetWeakPtr(),
+                               pending_operations_.Start("Read"),
+                               std::move(get_stats_cb)));
 }
 
 void WebrtcVideoStatsDBImpl::GetVideoStatsCollection(
@@ -237,7 +152,8 @@
   db_->LoadKeysAndEntriesWhile(
       key_without_pixels, key_iterator_controller,
       base::BindOnce(&WebrtcVideoStatsDBImpl::OnGotVideoStatsCollection,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Read"),
+                     weak_ptr_factory_.GetWeakPtr(),
+                     pending_operations_.Start("Read"),
                      std::move(get_stats_cb)));
 }
 
@@ -269,7 +185,7 @@
 }
 
 void WebrtcVideoStatsDBImpl::WriteUpdatedEntry(
-    PendingOpId op_id,
+    PendingOperations::Id op_id,
     const VideoDescKey& key,
     const VideoStats& new_video_stats,
     AppendVideoStatsCB append_done_cb,
@@ -278,7 +194,7 @@
   DVLOG(3) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(IsInitialized());
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
 
   // Note: outcome of "Write" operation logged in OnEntryUpdated().
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Read",
@@ -345,31 +261,32 @@
   std::unique_ptr<DBType::KeyEntryVector> entries =
       std::make_unique<DBType::KeyEntryVector>();
   entries->emplace_back(key.Serialize(), new_entry_proto);
-  db_->UpdateEntries(
-      std::move(entries), std::make_unique<leveldb_proto::KeyVector>(),
-      base::BindOnce(&WebrtcVideoStatsDBImpl::OnEntryUpdated,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Write"),
-                     std::move(append_done_cb)));
+  db_->UpdateEntries(std::move(entries),
+                     std::make_unique<leveldb_proto::KeyVector>(),
+                     base::BindOnce(&WebrtcVideoStatsDBImpl::OnEntryUpdated,
+                                    weak_ptr_factory_.GetWeakPtr(),
+                                    pending_operations_.Start("Write"),
+                                    std::move(append_done_cb)));
 }
 
-void WebrtcVideoStatsDBImpl::OnEntryUpdated(PendingOpId op_id,
+void WebrtcVideoStatsDBImpl::OnEntryUpdated(PendingOperations::Id op_id,
                                             AppendVideoStatsCB append_done_cb,
                                             bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << __func__ << " update " << (success ? "succeeded" : "FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Write", success);
   std::move(append_done_cb).Run(success);
 }
 
 void WebrtcVideoStatsDBImpl::OnGotVideoStats(
-    PendingOpId op_id,
+    PendingOperations::Id op_id,
     GetVideoStatsCB get_stats_cb,
     bool success,
     std::unique_ptr<WebrtcVideoStatsEntryProto> stats_proto) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << __func__ << " get " << (success ? "succeeded" : "FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Read", success);
 
   // Convert from WebrtcVideoStatsEntryProto to VideoStatsEntry.
@@ -397,14 +314,14 @@
 }
 
 void WebrtcVideoStatsDBImpl::OnGotVideoStatsCollection(
-    PendingOpId op_id,
+    PendingOperations::Id op_id,
     GetVideoStatsCollectionCB get_stats_cb,
     bool success,
     std::unique_ptr<std::map<std::string, WebrtcVideoStatsEntryProto>>
         stats_proto_collection) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << __func__ << " get " << (success ? "succeeded" : "FAILED!");
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Read", success);
   // Convert from map of WebrtcVideoStatsEntryProto to VideoStatsCollection.
   absl::optional<VideoStatsCollection> collection;
@@ -450,17 +367,18 @@
       std::make_unique<ProtoVideoStatsEntry::KeyEntryVector>(),
       base::BindRepeating([](const std::string& key) { return true; }),
       base::BindOnce(&WebrtcVideoStatsDBImpl::OnStatsCleared,
-                     weak_ptr_factory_.GetWeakPtr(), StartPendingOp("Clear"),
+                     weak_ptr_factory_.GetWeakPtr(),
+                     pending_operations_.Start("Clear"),
                      std::move(clear_done_cb)));
 }
 
-void WebrtcVideoStatsDBImpl::OnStatsCleared(PendingOpId op_id,
+void WebrtcVideoStatsDBImpl::OnStatsCleared(PendingOperations::Id op_id,
                                             base::OnceClosure clear_done_cb,
                                             bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");
 
-  CompletePendingOp(op_id);
+  pending_operations_.Complete(op_id);
 
   UMA_HISTOGRAM_BOOLEAN("Media.WebrtcVideoStatsDB.OpSuccess.Clear", success);
 
diff --git a/media/capabilities/webrtc_video_stats_db_impl.h b/media/capabilities/webrtc_video_stats_db_impl.h
index 3506905..3c48cc4 100644
--- a/media/capabilities/webrtc_video_stats_db_impl.h
+++ b/media/capabilities/webrtc_video_stats_db_impl.h
@@ -7,8 +7,6 @@
 
 #include <memory>
 
-#include "base/cancelable_callback.h"
-#include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/field_trial_params.h"
@@ -16,6 +14,7 @@
 #include "components/leveldb_proto/public/proto_database.h"
 #include "media/base/media_export.h"
 #include "media/base/video_codecs.h"
+#include "media/capabilities/pending_operations.h"
 #include "media/capabilities/webrtc_video_stats_db.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -64,61 +63,15 @@
   friend class WebrtcVideoStatsDBImplTest;
   friend class WebrtcVideoPerfLPMFuzzerHelper;
 
-  using PendingOpId = int;
-
   // Private constructor only called by tests (friends). Production code
   // should always use the static Create() method.
   explicit WebrtcVideoStatsDBImpl(
       std::unique_ptr<leveldb_proto::ProtoDatabase<WebrtcVideoStatsEntryProto>>
           db);
 
-  // Creates a PendingOperation using `uma_str` and adds it to `pending_ops_`
-  // map. Returns PendingOpId for newly started operation. Callers must later
-  // call CompletePendingOp() with this id to destroy the PendingOperation and
-  // finalize timing UMA.
-  PendingOpId StartPendingOp(std::string uma_str);
-
-  // Removes PendingOperation from `pending_ops_` using `op_id_` as a key. This
-  // destroys the object and triggers timing UMA.
-  void CompletePendingOp(PendingOpId op_id);
-
-  // Unified handler for timeouts of pending DB operations. PendingOperation
-  // will be notified that it timed out (to trigger timing UMA) and removed from
-  // `pending_ops_`.
-  void OnPendingOpTimeout(PendingOpId id);
-
-  // Helper to report timing information for DB operations, including when they
-  // hang indefinitely.
-  class PendingOperation {
-   public:
-    PendingOperation(
-        std::string uma_str,
-        std::unique_ptr<base::CancelableOnceClosure> timeout_closure);
-    // Records task timing UMA if it hasn't already timed out.
-    virtual ~PendingOperation();
-
-    // Copies disallowed. Incompatible with move-only members and UMA logging in
-    // the destructor.
-    PendingOperation(const PendingOperation&) = delete;
-    PendingOperation& operator=(const PendingOperation&) = delete;
-
-    // Trigger UMA recording for timeout.
-    void OnTimeout();
-
-   private:
-    friend class WebrtcVideoStatsDBImplTest;
-
-    std::string uma_str_;
-    std::unique_ptr<base::CancelableOnceClosure> timeout_closure_;
-    base::TimeTicks start_ticks_;
-  };
-
-  // Map of operation id -> outstanding PendingOperations.
-  base::flat_map<PendingOpId, std::unique_ptr<PendingOperation>> pending_ops_;
-
   // Called when the database has been initialized. Will immediately call
   // `init_cb` to forward `success`.
-  void OnInit(PendingOpId id,
+  void OnInit(PendingOperations::Id id,
               InitializeCB init_cb,
               leveldb_proto::Enums::InitStatus status);
 
@@ -128,7 +81,7 @@
   // Passed as the callback for `OnGotVideoStats` by `AppendVideoStats` to
   // update the database once we've read the existing stats entry.
   void WriteUpdatedEntry(
-      PendingOpId op_id,
+      PendingOperations::Id op_id,
       const VideoDescKey& key,
       const VideoStats& new_video_stats,
       AppendVideoStatsCB append_done_cb,
@@ -137,14 +90,14 @@
 
   // Called when the database has been modified after a call to
   // `WriteUpdatedEntry`. Will run `append_done_cb` when done.
-  void OnEntryUpdated(PendingOpId op_id,
+  void OnEntryUpdated(PendingOperations::Id op_id,
                       AppendVideoStatsCB append_done_cb,
                       bool success);
 
   // Called when GetVideoStats() operation was performed. `get_stats_cb`
   // will be run with `success` and a `VideoStatsEntry` created from
   // `stats_proto` or nullptr if no entry was found for the requested key.
-  void OnGotVideoStats(PendingOpId op_id,
+  void OnGotVideoStats(PendingOperations::Id op_id,
                        GetVideoStatsCB get_stats_cb,
                        bool success,
                        std::unique_ptr<WebrtcVideoStatsEntryProto> stats_proto);
@@ -154,7 +107,7 @@
   // created from the `stats_proto` map or nullptr if no entries were found for
   // the filtered key.
   void OnGotVideoStatsCollection(
-      PendingOpId op_id,
+      PendingOperations::Id op_id,
       GetVideoStatsCollectionCB get_stats_cb,
       bool success,
       std::unique_ptr<std::map<std::string, WebrtcVideoStatsEntryProto>>
@@ -162,7 +115,7 @@
 
   // Internal callback for OnLoadAllKeysForClearing(), initially triggered by
   // ClearStats(). Method simply logs `success` and runs `clear_done_cb`.
-  void OnStatsCleared(PendingOpId op_id,
+  void OnStatsCleared(PendingOperations::Id op_id,
                       base::OnceClosure clear_done_cb,
                       bool success);
 
@@ -174,8 +127,7 @@
     wall_clock_ = tick_clock;
   }
 
-  // Next PendingOpId for use in `pending_ops_` map. See StartPendingOp().
-  PendingOpId next_op_id_ = 0;
+  PendingOperations pending_operations_;
 
   // Indicates whether initialization is completed. Does not indicate whether it
   // was successful. Will be reset upon calling DestroyStats(). Failed
diff --git a/media/capabilities/webrtc_video_stats_db_impl_unittest.cc b/media/capabilities/webrtc_video_stats_db_impl_unittest.cc
index aadc150..e1ba546 100644
--- a/media/capabilities/webrtc_video_stats_db_impl_unittest.cc
+++ b/media/capabilities/webrtc_video_stats_db_impl_unittest.cc
@@ -94,13 +94,19 @@
   }
 
   void VerifyOnePendingOp(std::string op_name) {
-    EXPECT_EQ(stats_db_->pending_ops_.size(), 1u);
-    WebrtcVideoStatsDBImpl::PendingOperation* pending_op =
-        stats_db_->pending_ops_.begin()->second.get();
+    EXPECT_EQ(stats_db_->pending_operations_.get_pending_ops_for_test().size(),
+              1u);
+    PendingOperations::PendingOperation* pending_op =
+        stats_db_->pending_operations_.get_pending_ops_for_test()
+            .begin()
+            ->second.get();
     EXPECT_EQ(pending_op->uma_str_, op_name);
   }
 
-  void VerifyNoPendingOps() { EXPECT_TRUE(stats_db_->pending_ops_.empty()); }
+  void VerifyNoPendingOps() {
+    EXPECT_TRUE(
+        stats_db_->pending_operations_.get_pending_ops_for_test().empty());
+  }
 
   base::TimeDelta GetMaxTimeToKeepStats() {
     return WebrtcVideoStatsDBImpl::GetMaxTimeToKeepStats();
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index 47ed0b97..9eb02a6b 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -362,6 +362,15 @@
       if (!IsConfiguredForTesting()) {
         encoder_ = std::make_unique<H264VaapiVideoEncoderDelegate>(
             vaapi_wrapper_, error_cb);
+        // HW encoders on Intel GPUs will not put average QP in slice/tile
+        // header when it is not working at CQP mode. Currently only H264 is
+        // working at non CQP mode.
+        if (VaapiWrapper::GetImplementationType() ==
+                VAImplementation::kIntelI965 ||
+            VaapiWrapper::GetImplementationType() ==
+                VAImplementation::kIntelIHD) {
+          encoder_info_.reports_average_qp = false;
+        }
       }
       break;
     case VideoCodec::kVP8:
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
index 775efb0..84babee 100644
--- a/net/base/port_util.cc
+++ b/net/base/port_util.cc
@@ -116,18 +116,7 @@
 // should only remain in this list for about a year to give time for users to
 // migrate off while stopping them from becoming permanent parts of the web
 // platform.
-constexpr int kAllowablePorts[] = {
-    // TODO(https://crbug.com/1199642) Remove port 554 around 2021/10/15.
-    554,
-    // TODO(https://crbug.com/1220079) Remove ports 989 and 990 around
-    // 2022/02/01.
-    989,
-    990,
-    // TODO(https://crbig.com/1210779) Remove port 6566 around 2021/08/12.
-    6566,
-    // TODO(https://crbug.com/1196846) Remove port 10080 around 2022/04/01.
-    10080,
-};
+constexpr int kAllowablePorts[] = {};
 
 int g_scoped_allowable_port = 0;
 
diff --git a/net/quic/platform/impl/DEPS b/net/quic/platform/impl/DEPS
deleted file mode 100644
index 2c12fec5..0000000
--- a/net/quic/platform/impl/DEPS
+++ /dev/null
@@ -1,4 +0,0 @@
-include_rules = [
-  # Allow string_view.h since absl::string_view is widely used in QUICHE API.
-  "+third_party/abseil-cpp/absl/strings",
-]
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 0fb3cb5..975480f 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -567,16 +567,6 @@
   return false;
 }
 
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class CacheTransparencyCacheNotUsedReason {
-  kTryingSingleKeyedCache = 0,
-  kIncompatibleRequestType = 1,
-  kIncompatibleRequestLoadFlags = 2,
-  kIncompatibleRequestHeaders = 3,
-  kMaxValue = kIncompatibleRequestHeaders,
-};
-
 }  // namespace
 
 URLLoader::MaybeSyncURLLoaderClient::MaybeSyncURLLoaderClient(
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index adfcec31..a64d99a 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -79,6 +79,19 @@
 struct OriginPolicy;
 class URLLoaderFactory;
 
+// When a request matches a pervasive payload url and checksum a value from this
+// enum will be logged to the "Network.CacheTransparency.CacheNotUsed"
+// histogram. These values are persisted to logs. Entries should not be
+// renumbered and numeric values should never be reused. This is exposed in the
+// header file for use in tests.
+enum class CacheTransparencyCacheNotUsedReason {
+  kTryingSingleKeyedCache = 0,
+  kIncompatibleRequestType = 1,
+  kIncompatibleRequestLoadFlags = 2,
+  kIncompatibleRequestHeaders = 3,
+  kMaxValue = kIncompatibleRequestHeaders,
+};
+
 class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
     : public mojom::URLLoader,
       public net::URLRequest::Delegate,
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 3eb5119d..8a77c0d 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -7384,6 +7384,17 @@
     SendRequest(path);
   }
 
+  // Causes an expectation failure if the specified reason was not logged.
+  void ExpectNotUsedReason(CacheTransparencyCacheNotUsedReason reason) const {
+    // The count is 2 because each test sends two requests.
+    histogram_tester_.ExpectUniqueSample(kNotUsedHistogram, reason, 2);
+  }
+
+  // Causes an expectation failure if any reason was logged.
+  void ExpectNoSamples() const {
+    histogram_tester_.ExpectTotalCount(kNotUsedHistogram, 0);
+  }
+
   int network_request_count() { return network_request_count_; }
 
   void set_third_party_cookies_enabled(bool value) {
@@ -7400,6 +7411,8 @@
 
  private:
   static constexpr char kPervasivePayload[] = "/pervasive.js";
+  static constexpr char kNotUsedHistogram[] =
+      "Network.CacheTransparency.CacheNotUsed";
 
   base::test::ScopedFeatureList pervasive_payloads_feature_;
   base::test::ScopedFeatureList cache_transparency_feature_;
@@ -7410,42 +7423,51 @@
   std::string method_ = "GET";
   int load_flags_ = net::LOAD_NORMAL;
   std::string headers_;
+  base::HistogramTester histogram_tester_;
 };
 
-// This test is critical. If it doesn't pass, then the results of the other
-// URLLoaderCacheTransparencyTests are meaningless.
 TEST_F(URLLoaderCacheTransparencyTest, SuccessfulPervasivePayload) {
   SendTwoRequestsWithDifferentOrigins();
   EXPECT_EQ(1, network_request_count());
+  ExpectNotUsedReason(
+      CacheTransparencyCacheNotUsedReason::kTryingSingleKeyedCache);
 }
 
 TEST_F(URLLoaderCacheTransparencyTest, ThirdPartyCookiesDisabled) {
   set_third_party_cookies_enabled(false);
   SendTwoRequestsWithDifferentOrigins();
   EXPECT_EQ(2, network_request_count());
+  ExpectNoSamples();
 }
 
 TEST_F(URLLoaderCacheTransparencyTest, NotAPervasivePayload) {
   SendTwoRequestsWithDifferentOrigins("/cacheable.js");
   EXPECT_EQ(2, network_request_count());
+  ExpectNoSamples();
 }
 
 TEST_F(URLLoaderCacheTransparencyTest, NotAGETRequest) {
   set_method("POST");
   SendTwoRequestsWithDifferentOrigins();
   EXPECT_EQ(2, network_request_count());
+  ExpectNotUsedReason(
+      CacheTransparencyCacheNotUsedReason::kIncompatibleRequestType);
 }
 
 TEST_F(URLLoaderCacheTransparencyTest, IncompatibleLoadFlags) {
   set_load_flags(net::LOAD_SKIP_VARY_CHECK);
   SendTwoRequestsWithDifferentOrigins();
   EXPECT_EQ(2, network_request_count());
+  ExpectNotUsedReason(
+      CacheTransparencyCacheNotUsedReason::kIncompatibleRequestLoadFlags);
 }
 
 TEST_F(URLLoaderCacheTransparencyTest, IncompatibleHeaders) {
   set_headers("Range: bytes=0-5\r\n");
   SendTwoRequestsWithDifferentOrigins();
   EXPECT_EQ(2, network_request_count());
+  ExpectNotUsedReason(
+      CacheTransparencyCacheNotUsedReason::kIncompatibleRequestHeaders);
 }
 
 }  // namespace network
diff --git a/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc b/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
index 6af5491..f8fe4665 100644
--- a/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
+++ b/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
@@ -32,6 +32,7 @@
   video_capture_buffer_info->pixel_format = buffer_info->pixel_format;
   video_capture_buffer_info->coded_size = buffer_info->coded_size;
   video_capture_buffer_info->visible_rect = buffer_info->visible_rect;
+  video_capture_buffer_info->color_space.emplace();
 
   media::VideoFrameMetadata media_frame_metadata;
   switch (buffer_info->rotation) {
@@ -72,9 +73,11 @@
   if (buffer_handle->platform_handle) {
     auto& platform_handle = buffer_handle->platform_handle;
     if (platform_handle->is_shared_memory_handle()) {
+      gfx_buffer_handle.type = gfx::GpuMemoryBufferType::SHARED_MEMORY_BUFFER;
       gfx_buffer_handle.region =
           std::move(platform_handle->get_shared_memory_handle());
     } else if (platform_handle->is_native_pixmap_handle()) {
+      gfx_buffer_handle.type = gfx::GpuMemoryBufferType::NATIVE_PIXMAP;
       auto& native_pixmap_handle = platform_handle->get_native_pixmap_handle();
       gfx::NativePixmapHandle gfx_native_pixmap_handle;
       gfx_native_pixmap_handle.planes = std::move(native_pixmap_handle->planes);
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 940cbb994..5afd28d 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -7036,7 +7036,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8240,15 +8240,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8274,7 +8274,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8325,15 +8325,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8359,7 +8359,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8750,15 +8750,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8784,7 +8784,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8835,15 +8835,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8869,7 +8869,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -9371,7 +9371,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -9445,7 +9445,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 21ea223..bd9090e 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -83,7 +83,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -142,7 +142,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -411,7 +411,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -471,7 +471,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -851,7 +851,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -911,7 +911,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -1289,7 +1289,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -1348,7 +1348,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -14755,7 +14755,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -19565,7 +19565,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -40947,7 +40947,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -45642,7 +45642,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46214,15 +46214,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46248,7 +46248,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46299,15 +46299,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46333,7 +46333,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46724,15 +46724,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46758,7 +46758,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46809,15 +46809,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46843,7 +46843,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47238,15 +47238,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47272,7 +47272,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47323,15 +47323,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47357,7 +47357,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47748,15 +47748,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47782,7 +47782,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47833,15 +47833,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47867,7 +47867,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48330,15 +48330,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48364,7 +48364,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48415,15 +48415,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48449,7 +48449,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48840,15 +48840,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48874,7 +48874,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48925,15 +48925,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48959,7 +48959,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49422,15 +49422,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--client-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49456,7 +49456,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49507,15 +49507,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49541,7 +49541,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49932,15 +49932,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M102/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M102/out/Release",
           "--impl-version=102",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49966,7 +49966,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M102",
-              "revision": "version:102.0.5005.71"
+              "revision": "version:102.0.5005.72"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50017,15 +50017,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -50051,7 +50051,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.20"
+              "revision": "version:103.0.5060.22"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50298,7 +50298,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index ecf679f..72efabc 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5865,21 +5865,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -5892,7 +5892,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "isolate_profile_data": true,
@@ -6030,21 +6030,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -6056,7 +6056,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "args": [
@@ -6176,21 +6176,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -6202,7 +6202,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.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 879f69e..9803cb05a 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -16066,7 +16066,7 @@
             {
               "cipd_package": "chromium/android_webview/tools/cts_archive",
               "location": "android_webview/tools/cts_archive",
-              "revision": "5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC"
+              "revision": "T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -87946,21 +87946,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -87968,7 +87968,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "isolate_profile_data": true,
@@ -88081,28 +88081,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.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 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "args": [
@@ -88202,28 +88202,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.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 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "isolate_profile_data": true,
@@ -89561,20 +89561,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5080.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -89588,7 +89588,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "merge": {
@@ -89726,20 +89726,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5080.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -89752,7 +89752,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "args": [
@@ -89872,20 +89872,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -89898,7 +89898,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.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "merge": {
@@ -91394,20 +91394,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5080.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -91421,7 +91421,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "merge": {
@@ -91559,20 +91559,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5080.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -91585,7 +91585,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "args": [
@@ -91705,20 +91705,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.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.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 104.0.5080.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -91731,7 +91731,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.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       },
       {
         "merge": {
@@ -92466,20 +92466,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5080.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5081.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_v104.0.5080.0",
-              "revision": "version:104.0.5080.0"
+              "location": "lacros_version_skew_tests_v104.0.5081.0",
+              "revision": "version:104.0.5081.0"
             }
           ],
           "dimension_sets": [
@@ -92492,7 +92492,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5080.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5081.0"
       }
     ]
   },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 0062ed1..9d85112 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -5390,7 +5390,7 @@
             {
               "cipd_package": 'chromium/android_webview/tools/cts_archive',
               'location': 'android_webview/tools/cts_archive',
-              'revision': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'revision': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
             }
           ]
         },
@@ -5427,7 +5427,7 @@
             {
               "cipd_package": 'chromium/android_webview/tools/cts_archive',
               'location': 'android_webview/tools/cts_archive',
-              'revision': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'revision': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
             }
           ]
         },
@@ -5445,7 +5445,7 @@
             {
               "cipd_package": 'chromium/android_webview/tools/cts_archive',
               'location': 'android_webview/tools/cts_archive',
-              'revision': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'revision': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
             }
           ]
         },
@@ -5461,7 +5461,7 @@
             {
               "cipd_package": 'chromium/android_webview/tools/cts_archive',
               'location': 'android_webview/tools/cts_archive',
-              'revision': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'revision': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
             }
           ]
         },
@@ -5476,7 +5476,7 @@
             {
               "cipd_package": 'chromium/android_webview/tools/cts_archive',
               'location': 'android_webview/tools/cts_archive',
-              'revision': '5LE8LGJkJ-CNdRQNzEbaoZaCgxdhZZBvjWidr9l6NggC',
+              'revision': 'T4HLqIHU4KwoyPjGSDGrJe-FlDBIEGRLG0Uh-CghvpwC',
             }
           ]
         },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 773d767..2dce507 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5080.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5081.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 104.0.5080.0',
+    'identifier': 'Lacros version skew testing ash 104.0.5081.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v104.0.5080.0',
-          'revision': 'version:104.0.5080.0',
+          'location': 'lacros_version_skew_tests_v104.0.5081.0',
+          'revision': 'version:104.0.5081.0',
         },
       ],
     },
@@ -462,16 +462,16 @@
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=103',
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--impl-version=103'
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -479,23 +479,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.20',
+          'revision': 'version:103.0.5060.22'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M102/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=102',
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M102/out/Release',
+      '--impl-version=102'
     ],
     'identifier': 'with_impl_from_102',
     'swarming': {
@@ -503,10 +503,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.71',
+          'revision': 'version:102.0.5005.72'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -606,16 +606,16 @@
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=103',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--impl-version=103'
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -623,23 +623,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.20',
+          'revision': 'version:103.0.5060.22'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M102/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=102',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M102/out/Release',
+      '--impl-version=102'
     ],
     'identifier': 'with_impl_from_102',
     'swarming': {
@@ -647,10 +647,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.71',
+          'revision': 'version:102.0.5005.72'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -750,16 +750,16 @@
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--client-version=103',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--client-version=103'
     ],
     'identifier': 'with_client_from_103',
     'swarming': {
@@ -767,23 +767,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.20',
+          'revision': 'version:103.0.5060.22'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M102/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--client-version=102',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M102/out/Release',
+      '--client-version=102'
     ],
     'identifier': 'with_client_from_102',
     'swarming': {
@@ -791,10 +791,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M102',
-          'revision': 'version:102.0.5005.71',
+          'revision': 'version:102.0.5005.72'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f009a76d..d2f50fb 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1231,6 +1231,27 @@
             ]
         }
     ],
+    "AutofillRemoveInaccessibleProfileValues": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "ios",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "AutofillRemoveInaccessibleProfileValues"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutofillRemoveInvalidPhoneNumberOnImport": [
         {
             "platforms": [
@@ -1896,7 +1917,7 @@
                 {
                     "name": "CacheTransparencyEnabled",
                     "params": {
-                        "pervasive-payloads": "http://127.0.0.1:4353/pervasive.js,87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"
+                        "pervasive-payloads": "1,http://127.0.0.1:4353/pervasive.js,87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"
                     },
                     "enable_features": [
                         "CacheTransparency",
@@ -1906,7 +1927,7 @@
                 {
                     "name": "InputPervasivePayloadsList",
                     "params": {
-                        "pervasive-payloads": "http://127.0.0.1:4353/pervasive.js,87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"
+                        "pervasive-payloads": "1,http://127.0.0.1:4353/pervasive.js,87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"
                     },
                     "enable_features": [
                         "PervasivePayloadsList"
@@ -6470,25 +6491,6 @@
             ]
         }
     ],
-    "PrivacyGuide": [
-        {
-            "platforms": [
-                "linux",
-                "windows",
-                "chromeos",
-                "chromeos_lacros",
-                "mac"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PrivacyGuide"
-                    ]
-                }
-            ]
-        }
-    ],
     "PrivacyPreservingPrefetchProxy": [
         {
             "platforms": [
diff --git a/third_party/blink/common/privacy_budget/BUILD.gn b/third_party/blink/common/privacy_budget/BUILD.gn
index 0e8611ce..35d2a792 100644
--- a/third_party/blink/common/privacy_budget/BUILD.gn
+++ b/third_party/blink/common/privacy_budget/BUILD.gn
@@ -20,6 +20,7 @@
     "identifiability_metrics.cc",
     "identifiability_sample_collector.cc",
     "identifiability_sample_collector_test_utils.h",
+    "identifiability_study_document_created.cc",
     "identifiability_study_settings.cc",
     "identifiable_token_builder.cc",
   ]
diff --git a/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc b/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc
new file mode 100644
index 0000000..3881883
--- /dev/null
+++ b/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc
@@ -0,0 +1,80 @@
+// 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/public/common/privacy_budget/identifiability_study_document_created.h"
+
+#include "services/metrics/public/cpp/metrics_export.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
+
+namespace blink {
+
+IdentifiabilityStudyDocumentCreated::IdentifiabilityStudyDocumentCreated(
+    ukm::SourceIdObj source_id)
+    : source_id_(source_id.ToInt64()) {}
+
+IdentifiabilityStudyDocumentCreated::IdentifiabilityStudyDocumentCreated(
+    ukm::SourceId source_id)
+    : source_id_(source_id) {}
+
+IdentifiabilityStudyDocumentCreated::~IdentifiabilityStudyDocumentCreated() =
+    default;
+
+IdentifiabilityStudyDocumentCreated&
+IdentifiabilityStudyDocumentCreated::SetNavigationSourceId(
+    ukm::SourceId navigation_source_id) {
+  navigation_source_id_ = navigation_source_id;
+  return *this;
+}
+
+IdentifiabilityStudyDocumentCreated&
+IdentifiabilityStudyDocumentCreated::SetIsMainFrame(bool is_main_frame) {
+  is_main_frame_ = is_main_frame;
+  return *this;
+}
+
+IdentifiabilityStudyDocumentCreated&
+IdentifiabilityStudyDocumentCreated::SetIsCrossSiteFrame(
+    bool is_cross_site_frame) {
+  is_cross_site_frame_ = is_cross_site_frame;
+  return *this;
+}
+
+IdentifiabilityStudyDocumentCreated&
+IdentifiabilityStudyDocumentCreated::SetIsCrossOriginFrame(
+    bool is_cross_origin_frame) {
+  is_cross_origin_frame_ = is_cross_origin_frame;
+  return *this;
+}
+
+void IdentifiabilityStudyDocumentCreated::Record(ukm::UkmRecorder* recorder) {
+  using Metrics = blink::IdentifiableSurface::ReservedSurfaceMetrics;
+  base::flat_map<uint64_t, int64_t> metrics = {
+      {IdentifiableSurface::FromTypeAndToken(
+           blink::IdentifiableSurface::Type::kReservedInternal,
+           Metrics::kDocumentCreated_IsCrossOriginFrame)
+           .ToUkmMetricHash(),
+       is_cross_origin_frame_},
+      {IdentifiableSurface::FromTypeAndToken(
+           blink::IdentifiableSurface::Type::kReservedInternal,
+           Metrics::kDocumentCreated_IsCrossSiteFrame)
+           .ToUkmMetricHash(),
+       is_cross_site_frame_},
+      {IdentifiableSurface::FromTypeAndToken(
+           blink::IdentifiableSurface::Type::kReservedInternal,
+           Metrics::kDocumentCreated_IsMainFrame)
+           .ToUkmMetricHash(),
+       is_main_frame_},
+      {IdentifiableSurface::FromTypeAndToken(
+           blink::IdentifiableSurface::Type::kReservedInternal,
+           Metrics::kDocumentCreated_NavigationSourceId)
+           .ToUkmMetricHash(),
+       navigation_source_id_}};
+
+  recorder->AddEntry(ukm::mojom::UkmEntry::New(
+      source_id_, ukm::builders::Identifiability::kEntryNameHash, metrics));
+}
+
+}  // namespace blink
diff --git a/third_party/blink/public/common/privacy_budget/BUILD.gn b/third_party/blink/public/common/privacy_budget/BUILD.gn
index 49a07de..1e0d6ea 100644
--- a/third_party/blink/public/common/privacy_budget/BUILD.gn
+++ b/third_party/blink/public/common/privacy_budget/BUILD.gn
@@ -18,6 +18,7 @@
     "identifiability_metric_builder.h",
     "identifiability_metrics.h",
     "identifiability_sample_collector.h",
+    "identifiability_study_document_created.h",
     "identifiability_study_settings.h",
     "identifiability_study_settings_provider.h",
     "identifiable_sample.h",
@@ -30,6 +31,7 @@
     ":internal",
     "//base",
     "//services/metrics/public/cpp:metrics_cpp",
+    "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/cpp:cpp",
     "//third_party/blink/public/common:common_export",
     "//third_party/blink/public/mojom:web_feature_mojo_bindings",
diff --git a/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h b/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h
new file mode 100644
index 0000000..30dd9980
--- /dev/null
+++ b/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h
@@ -0,0 +1,49 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_
+
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/common/common_export.h"
+
+namespace blink {
+
+class BLINK_COMMON_EXPORT IdentifiabilityStudyDocumentCreated {
+ public:
+  // Construct an IdentifiabilityStudyDocumentCreated for the given |source_id|.
+  // The source must be known to UKM.
+  explicit IdentifiabilityStudyDocumentCreated(ukm::SourceIdObj source_id);
+
+  // Same as previous constructor, but uses SourceId instead of SourceIdObj.
+  explicit IdentifiabilityStudyDocumentCreated(ukm::SourceId source_id);
+
+  ~IdentifiabilityStudyDocumentCreated();
+
+  // Record collected metrics to `recorder`.
+  void Record(ukm::UkmRecorder* recorder);
+
+  IdentifiabilityStudyDocumentCreated& SetNavigationSourceId(
+      ukm::SourceId navigation_source_id);
+
+  IdentifiabilityStudyDocumentCreated& SetIsMainFrame(bool is_main_frame);
+
+  IdentifiabilityStudyDocumentCreated& SetIsCrossOriginFrame(
+      bool is_cross_origin_frame);
+
+  IdentifiabilityStudyDocumentCreated& SetIsCrossSiteFrame(
+      bool is_cross_site_frame);
+
+ private:
+  const ukm::SourceId source_id_;
+  ukm::SourceId navigation_source_id_;
+  bool is_main_frame_;
+  bool is_cross_origin_frame_;
+  bool is_cross_site_frame_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
index a1eacf9..f4e099a03 100644
--- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h
+++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -11,6 +11,7 @@
 #include <functional>
 #include <tuple>
 
+#include "services/metrics/public/cpp/ukm_builders.h"
 #include "third_party/blink/public/common/privacy_budget/identifiable_token.h"
 
 namespace blink {
@@ -251,13 +252,31 @@
     kMax = (1 << kTypeBits) - 1
   };
 
+  // These are metrics names of type 0 and are always reported when the study is
+  // enabled.
+  enum class ReservedSurfaceMetrics : uint64_t {
+    kDocumentCreated_IsCrossOriginFrame = 0,
+    kDocumentCreated_IsCrossSiteFrame = 1,
+    kDocumentCreated_IsMainFrame = 2,
+    kDocumentCreated_NavigationSourceId = 3,
+    kMax = kDocumentCreated_NavigationSourceId
+  };
+  static_assert(
+      static_cast<uint64_t>(ReservedSurfaceMetrics::kMax) <
+          std::min(
+              ukm::builders::Identifiability::kGeneratorVersion_926NameHash,
+              ukm::builders::Identifiability::kStudyGeneration_626NameHash),
+      "All the ReservedSurfaceMetrics enum values should be strictly smaller "
+      "than kGeneratorVersion_926NameHash and kStudyGeneration_626NameHash to "
+      "avoid collisions.");
+
   // HTML canvas readback -- bits [0-3] of the 64-bit input are the context type
   // (Type::kCanvasReadback), bits [4-6] are skipped ops, sensitive ops, and
   // partial image ops bits, respectively. The remaining bits are for the canvas
   // operations digest. If the digest wasn't calculated (there's no digest for
   // WebGL, for instance), the digest field is 0.
   enum CanvasTaintBit : uint64_t {
-    // At least one drawing operation didn't update the digest -- this is ether
+    // At least one drawing operation didn't update the digest -- this is either
     // due to performance or resource consumption reasons.
     kSkipped = UINT64_C(0x10),
 
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 42bc9726..e889a0e 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -785,7 +785,6 @@
       RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics
       RTCPeerConnectionSdpSemanticsPlanB
       RtcpMuxPolicyNegotiate
-      RTPDataChannel
       SharedArrayBufferConstructedWithoutIsolation
       TextToSpeech_DisallowedByAutoplay
       V8SharedArrayBufferConstructedInExtensionWithoutIsolation
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 dc15c49..d73c77c 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
@@ -2650,8 +2650,8 @@
   kV8Window_ShowOpenFilePicker_Method = 3340,
   kV8Window_ShowSaveFilePicker_Method = 3341,
   kV8Window_ShowDirectoryPicker_Method = 3342,
-  kRTCConstraintEnableRtpDataChannelsTrue = 3344,
-  kRTCConstraintEnableRtpDataChannelsFalse = 3345,
+  kOBSOLETE_RTCConstraintEnableRtpDataChannelsTrue = 3344,
+  kOBSOLETE_RTCConstraintEnableRtpDataChannelsFalse = 3345,
   kFileSystemAccessDragAndDrop = 3346,
   kRTCAdaptivePtime = 3347,
   kHTMLMetaElementReferrerPolicyMultipleTokensAffectingRequest = 3348,
@@ -3516,9 +3516,9 @@
   kNavigatorUAData_Platform = 4195,
   kNavigatorUAData_Brands = 4196,
   kOldConstraintsParsed = 4197,
-  kOldConstraintNotReported = 4198,
-  kOldConstraintRejected = 4199,
-  kOldConstraintIgnored = 4200,
+  kOBSOLETE_OldConstraintNotReported = 4198,
+  kOBSOLETE_OldConstraintRejected = 4199,
+  kOBSOLETE_OldConstraintIgnored = 4200,
   kExplicitOverflowVisibleOnReplacedElement = 4201,
   kExplicitOverflowVisibleOnReplacedElementWithObjectProp = 4202,
   kPrivateNetworkAccessNullIpAddress = 4203,
diff --git a/third_party/blink/public/platform/media/video_frame_compositor.h b/third_party/blink/public/platform/media/video_frame_compositor.h
index 391ea0a..13f8b5e 100644
--- a/third_party/blink/public/platform/media/video_frame_compositor.h
+++ b/third_party/blink/public/platform/media/video_frame_compositor.h
@@ -109,6 +109,7 @@
   scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
   void PutCurrentFrame() override;
   base::TimeDelta GetPreferredRenderInterval() override;
+  void OnContextLost() override;
 
   // Returns |current_frame_|, without offering a guarantee as to how recently
   // it was updated. In certain applications, one might need to periodically
diff --git a/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h b/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h
index bb77a84..702d214 100644
--- a/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h
+++ b/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h
@@ -11,7 +11,7 @@
 
 namespace blink {
 namespace scheduler {
-class MainThreadSchedulerImpl;
+class ThreadSchedulerImpl;
 }  // namespace scheduler
 
 // VirtualTime is a headless feature which is intended to make renders (more)
@@ -35,7 +35,7 @@
   // non-existent resource and it has an error handler which always fetches
   // another non-existent resource, then there is a risk that virtual time will
   // be blocked forever unless we use VirtualTaskDuration::kNonInstant).
-  WebScopedVirtualTimePauser(scheduler::MainThreadSchedulerImpl*,
+  WebScopedVirtualTimePauser(scheduler::ThreadSchedulerImpl*,
                              VirtualTaskDuration,
                              const WebString& debug_name);
 
@@ -62,7 +62,7 @@
   bool paused_ = false;
   bool virtual_time_enabled_when_paused_ = false;
   VirtualTaskDuration duration_ = VirtualTaskDuration::kInstant;
-  scheduler::MainThreadSchedulerImpl* scheduler_;  // NOT OWNED
+  scheduler::ThreadSchedulerImpl* scheduler_;  // NOT OWNED
   WebString debug_name_;
   intptr_t trace_id_;
 };
diff --git a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
index ffa8b4a..a40fff1 100644
--- a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
+++ b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
@@ -9,6 +9,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_chrome_os.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_management.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_management.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_accelerator_event.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_accelerator_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_hid.h",
diff --git a/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni b/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni
index 2f05415..5bfe790c 100644
--- a/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni
+++ b/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni
@@ -11,6 +11,7 @@
         [
           "//third_party/blink/renderer/extensions/chromeos/chromeos.idl",
           "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_management.idl",
+          "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.idl",
           "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window.idl",
           "//third_party/blink/renderer/extensions/chromeos/system_extensions/hid/cros_hid.idl",
         ],
diff --git a/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py b/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
index 1d5482b..8068b5d0 100755
--- a/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
+++ b/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
@@ -67,6 +67,11 @@
         '--suffix',
         help=
         'specify a suffix to the namespace, i.e., "Modules". Default is None.')
+    parser.add_option(
+        '--export-macro',
+        help='specify an export to use for the symbols, i.e.,'
+        '"MODULES_EXPORT". Default is suffix_EXPORT if --suffix is present or '
+        'CORE_EXPORT if not.')
 
     options, args = parser.parse_args()
     if options.event_idl_files_list is None:
@@ -81,7 +86,8 @@
     return options
 
 
-def write_event_interfaces_file(event_idl_files, destination_filename, suffix):
+def write_event_interfaces_file(event_idl_files, destination_filename, suffix,
+                                export_macro):
     def interface_line(full_path):
         relative_dir_local = os.path.dirname(
             os.path.relpath(full_path, REPO_ROOT_DIR))
@@ -98,8 +104,13 @@
         return (relative_dir_posix, interface_name, extended_attributes_list)
 
     lines = ['{', 'metadata: {', '  namespace: "event_interface_names",']
+
     if suffix:
         lines.append('  suffix: "' + suffix + '",')
+
+    if export_macro:
+        lines.append('  export: "%s",' % export_macro)
+    elif suffix:
         lines.append('  export: "%s_EXPORT",' % suffix.upper())
     else:
         lines.append('  export: "CORE_EXPORT",')
@@ -130,7 +141,7 @@
     options = parse_options()
     event_idl_files = read_file_to_list(options.event_idl_files_list)
     write_event_interfaces_file(event_idl_files, options.event_interfaces_file,
-                                options.suffix)
+                                options.suffix, options.export_macro)
 
 
 if __name__ == '__main__':
diff --git a/third_party/blink/renderer/bindings/scripts/scripts.gni b/third_party/blink/renderer/bindings/scripts/scripts.gni
index e636739..86bcff8 100644
--- a/third_party/blink/renderer/bindings/scripts/scripts.gni
+++ b/third_party/blink/renderer/bindings/scripts/scripts.gni
@@ -14,6 +14,7 @@
 #   sources = A list of IDL files to process.
 #   output_file = The .in file to write, relative to the blink_gen_dir.
 #   suffix = (Optional) String to be passed to script via --suffix
+#   export_macro = (Optional) String to be passed to script via --export-macro
 template("generate_event_interfaces") {
   action(target_name) {
     # Write the file list to a unique temp file to avoid blowing out the
@@ -44,5 +45,12 @@
         invoker.suffix,
       ]
     }
+
+    if (defined(invoker.export_macro)) {
+      args += [
+        "--export-macro",
+        invoker.export_macro,
+      ]
+    }
   }
 }
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
index 000be003..8743467 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
@@ -43,6 +43,8 @@
   (property.is_animation_property and 'kAnimation' or ''),
   (property.supports_incremental_style and 'kSupportsIncrementalStyle' or ''),
   (property.idempotent and 'kIdempotent' or ''),
+  ((property.overlapping or property.legacy_overlapping) and 'kOverlapping' or ''),
+  (property.legacy_overlapping and 'kLegacyOverlapping' or ''),
   (property.valid_for_first_letter and 'kValidForFirstLetter' or ''),
   (property.valid_for_first_line and 'kValidForFirstLine' or ''),
   (property.valid_for_cue and 'kValidForCue' or ''),
diff --git a/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl b/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
index f6dd475..71d6d2f1 100644
--- a/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
@@ -12,6 +12,8 @@
 #include "third_party/blink/renderer/core/core_export.h"
 {% elif export == 'MODULES_EXPORT' %}
 #include "third_party/blink/renderer/modules/modules_export.h"
+{% elif export == 'EXTENSIONS_CHROMEOS_EXPORT' %}
+#include "third_party/blink/renderer/extensions/chromeos/chromeos_extensions.h"
 {% else %}
 #include "third_party/blink/renderer/platform/platform_export.h"
 {% endif %}
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 25e64d19..1c6b396 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -590,6 +590,26 @@
       valid_type: "bool",
     },
 
+    // If true, then the ComputedStyle field for this property overlaps with
+    // another property.
+    //
+    // Overlapping properties are *partially* overlapping, or do otherwise not
+    // have compatible or interchangeable values with each other.
+    overlapping: {
+      default: false,
+      valid_type: "bool",
+    },
+
+    // Like 'overlapping', but set on -webkit-prefixed properties that should
+    // ultimately be removed.
+    //
+    // Note that properties that are legacy_overlapping are also overlapping
+    // (i.e. legacy_overlapping:true implies overlapping:true).
+    legacy_overlapping: {
+      default: false,
+      valid_type: "bool",
+    },
+
     // - valid_for_canvas_formatted_text: true
     //
     // Whether the property can be used to style the top-level container
@@ -1701,6 +1721,8 @@
         name: "border-width",
         resolver: "bottom",
       },
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-collapse",
@@ -1723,6 +1745,8 @@
       },
       valid_for_first_letter: true,
       is_border: true,
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-image-repeat",
@@ -1735,6 +1759,8 @@
       },
       valid_for_first_letter: true,
       is_border: true,
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-image-slice",
@@ -1747,6 +1773,8 @@
       },
       valid_for_first_letter: true,
       is_border: true,
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-image-source",
@@ -1757,6 +1785,8 @@
       style_builder_custom_functions: ["value"],
       valid_for_first_letter: true,
       is_border: true,
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-image-width",
@@ -1770,6 +1800,8 @@
       },
       valid_for_first_letter: true,
       is_border: true,
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-left-color",
@@ -1831,6 +1863,8 @@
         name: "border-width",
         resolver: "left",
       },
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-right-color",
@@ -1892,6 +1926,8 @@
         name: "border-width",
         resolver: "right",
       },
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "border-top-color",
@@ -1992,6 +2028,8 @@
         name: "border-width",
         resolver: "top",
       },
+      // Overlaps with -webkit-border-image.
+      overlapping: true,
     },
     {
       name: "bottom",
@@ -3654,6 +3692,8 @@
       type_name: "LengthPoint",
       converter: "ConvertPosition",
       typedom_types: ["Position"],
+      // Overlaps with -webkit-perspective-origin-[x,y].
+      overlapping: true,
     },
     {
       name: "pointer-events",
@@ -4697,6 +4737,8 @@
       type_name: "TransformOrigin",
       converter: "ConvertTransformOrigin",
       supports_incremental_style: true,
+      // Overlaps with -webkit-transform-origin-[x,y,z].
+      overlapping: true,
     },
     {
       name: "transform-style",
@@ -4873,6 +4915,8 @@
       style_builder_custom_functions: ["value"],
       valid_for_first_letter: true,
       affected_by_all: false,
+      // Overlaps with border-image.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-border-vertical-spacing",
@@ -5245,6 +5289,8 @@
       converter: "ConvertLength",
       computable: false,
       affected_by_all: false,
+      // Overlaps with perspective-origin.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-perspective-origin-y",
@@ -5253,6 +5299,8 @@
       converter: "ConvertLength",
       computable: false,
       affected_by_all: false,
+      // Overlaps with perspective-origin.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-print-color-adjust",
@@ -5406,6 +5454,8 @@
       converter: "ConvertLength",
       computable: false,
       affected_by_all: false,
+      // Overlaps with transform-origin.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-transform-origin-y",
@@ -5414,6 +5464,8 @@
       converter: "ConvertLength",
       computable: false,
       affected_by_all: false,
+      // Overlaps with transform-origin.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-transform-origin-z",
@@ -5422,6 +5474,8 @@
       converter: "ConvertComputedLength<float>",
       computable: false,
       affected_by_all: false,
+      // Overlaps with transform-origin.
+      legacy_overlapping: true,
     },
     {
       name: "-webkit-user-drag",
diff --git a/third_party/blink/renderer/core/css/properties/css_property.h b/third_party/blink/renderer/core/css/properties/css_property.h
index 57dba2b..051d97a 100644
--- a/third_party/blink/renderer/core/css/properties/css_property.h
+++ b/third_party/blink/renderer/core/css/properties/css_property.h
@@ -184,6 +184,10 @@
     // https://github.com/WICG/canvas-formatted-text
     kValidForCanvasFormattedText = 1 << 26,
     kValidForCanvasFormattedTextRun = 1 << 27,
+    // See overlapping in css_properties.json5.
+    kOverlapping = 1 << 28,
+    // See legacy_overlapping in css_properties.json5.
+    kLegacyOverlapping = 1 << 29,
   };
 
   constexpr CSSProperty(CSSPropertyID property_id,
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc b/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc
index 2ef0ada..a95f8b52 100644
--- a/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc
@@ -118,4 +118,42 @@
   EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, true));
 }
 
+TEST(CascadeFilterTest, FilterLegacyOverlapping) {
+  auto filter = CascadeFilter().Add(CSSProperty::kLegacyOverlapping, true);
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginX()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginY()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginZ()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitPerspectiveOriginX()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitPerspectiveOriginY()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitBorderImage()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyTransformOrigin()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyPerspectiveOrigin()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyBorderImageSource()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyBorderImageSlice()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyBorderImageRepeat()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyBorderImageWidth()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyBorderImageOutset()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyColor()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyFloat()));
+}
+
+TEST(CascadeFilterTest, FilterOverlapping) {
+  auto filter = CascadeFilter().Add(CSSProperty::kOverlapping, true);
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginX()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginY()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitTransformOriginZ()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitPerspectiveOriginX()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitPerspectiveOriginY()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyWebkitBorderImage()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyTransformOrigin()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyPerspectiveOrigin()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyBorderImageSource()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyBorderImageSlice()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyBorderImageRepeat()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyBorderImageWidth()));
+  EXPECT_TRUE(filter.Rejects(GetCSSPropertyBorderImageOutset()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyColor()));
+  EXPECT_FALSE(filter.Rejects(GetCSSPropertyFloat()));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
index 494494e..2067cf23 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -660,6 +660,7 @@
         layout_object->SetIntrinsicLogicalWidthsDirty();
         layout_object->SetChildNeedsLayout();
         // Make sure we don't use cached NGFragmentItem objects.
+        To<LayoutBox>(layout_object)->DisassociatePhysicalFragments();
         To<LayoutBox>(layout_object)->ClearLayoutResults();
       }
     }
diff --git a/third_party/blink/renderer/core/editing/editor_test.cc b/third_party/blink/renderer/core/editing/editor_test.cc
index e415117..b4f327e 100644
--- a/third_party/blink/renderer/core/editing/editor_test.cc
+++ b/third_party/blink/renderer/core/editing/editor_test.cc
@@ -63,7 +63,7 @@
 
   const String kPasswordValue = "secret";
   element.Focus();
-  element.setValue(kPasswordValue);
+  element.SetValue(kPasswordValue);
   element.SetSelectionRange(0, kPasswordValue.length());
 
   Editor& editor = GetDocument().GetFrame()->GetEditor();
@@ -121,7 +121,7 @@
   Editor& editor = GetDocument().GetFrame()->GetEditor();
   editor.ReplaceSelection("NEW");
 
-  EXPECT_EQ("HENEWLLO", text_control.value());
+  EXPECT_EQ("HENEWLLO", text_control.Value());
 }
 
 // http://crbug.com/263819
@@ -151,7 +151,7 @@
   auto& input = *To<HTMLInputElement>(GetElementById("target"));
   input.Focus();
   GetDocument().execCommand("insertText", false, "xyz", ASSERT_NO_EXCEPTION);
-  ASSERT_EQ("xyz", input.value());
+  ASSERT_EQ("xyz", input.Value());
   ASSERT_EQ(0, SizeOfRedoStack());
   ASSERT_EQ(1, SizeOfUndoStack());
 
@@ -188,7 +188,7 @@
   auto& input = *To<HTMLInputElement>(GetElementById("target"));
   input.Focus();
   GetDocument().execCommand("insertText", false, "xyz", ASSERT_NO_EXCEPTION);
-  ASSERT_EQ("xyz", input.value());
+  ASSERT_EQ("xyz", input.Value());
   ASSERT_EQ(0, SizeOfRedoStack());
   ASSERT_EQ(1, SizeOfUndoStack());
 
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
index fecaef0..36c100f 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -130,50 +130,50 @@
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("fooX");
+  input->SetValue("fooX");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("fooX", input->value());
+  EXPECT_EQ("fooX", input->Value());
   Controller().ExtendSelectionAndDelete(0, 0);
-  EXPECT_EQ("fooX", input->value());
+  EXPECT_EQ("fooX", input->Value());
 
-  input->setValue("fooX");
+  input->SetValue("fooX");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("fooX", input->value());
+  EXPECT_EQ("fooX", input->Value());
   Controller().ExtendSelectionAndDelete(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
-  input->setValue(
+  input->SetValue(
       String::FromUTF8("foo\xE2\x98\x85"));  // U+2605 == "black star"
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo\xE2\x98\x85", input->value().Utf8());
+  EXPECT_EQ("foo\xE2\x98\x85", input->Value().Utf8());
   Controller().ExtendSelectionAndDelete(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
-  input->setValue(
+  input->SetValue(
       String::FromUTF8("foo\xF0\x9F\x8F\x86"));  // U+1F3C6 == "trophy"
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().ExtendSelectionAndDelete(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
   // composed U+0E01 "ka kai" + U+0E49 "mai tho"
-  input->setValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
+  input->SetValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
+  EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->Value().Utf8());
   Controller().ExtendSelectionAndDelete(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
-  input->setValue("fooX");
+  input->SetValue("fooX");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("fooX", input->value());
+  EXPECT_EQ("fooX", input->Value());
   Controller().ExtendSelectionAndDelete(0, 1);
-  EXPECT_EQ("fooX", input->value());
+  EXPECT_EQ("fooX", input->Value());
 }
 
 TEST_F(InputMethodControllerTest, SetCompositionFromExistingText) {
@@ -546,19 +546,19 @@
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("foo ");
+  input->SetValue("foo ");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo ", input->value());
+  EXPECT_EQ("foo ", input->Value());
   Controller().ExtendSelectionAndDelete(0, 0);
-  EXPECT_EQ("foo ", input->value());
+  EXPECT_EQ("foo ", input->Value());
 
-  input->setValue("foo ");
+  input->SetValue("foo ");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo ", input->value());
+  EXPECT_EQ("foo ", input->Value());
   Controller().ExtendSelectionAndDelete(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
   Vector<ImeTextSpan> ime_text_spans;
   ime_text_spans.push_back(ImeTextSpan(
@@ -568,7 +568,7 @@
 
   Controller().SetComposition(String(""), ime_text_spans, 0, 3);
 
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -617,144 +617,144 @@
   Controller().SetComposition("foo", ime_text_spans, 0, 3);
   Controller().FinishComposingText(InputMethodController::kKeepSelection);
 
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 }
 
 TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithEmptyText) {
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("");
+  input->SetValue("");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
   Controller().DeleteSurroundingText(0, 0);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 
-  input->setValue("");
+  input->SetValue("");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 
-  input->setValue("");
+  input->SetValue("");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 
-  input->setValue("");
+  input->SetValue("");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
   Controller().DeleteSurroundingText(1, 1);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 }
 
 TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithRangeSelection) {
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
   Controller().DeleteSurroundingText(0, 0);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
   Controller().DeleteSurroundingText(1, 1);
-  EXPECT_EQ("ell", input->value());
+  EXPECT_EQ("ell", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
   Controller().DeleteSurroundingText(100, 0);
-  EXPECT_EQ("ello", input->value());
+  EXPECT_EQ("ello", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
   Controller().DeleteSurroundingText(0, 100);
-  EXPECT_EQ("hell", input->value());
+  EXPECT_EQ("hell", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
   Controller().DeleteSurroundingText(100, 100);
-  EXPECT_EQ("ell", input->value());
+  EXPECT_EQ("ell", input->Value());
 }
 
 TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithCursorSelection) {
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("hllo", input->value());
+  EXPECT_EQ("hllo", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ("helo", input->value());
+  EXPECT_EQ("helo", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(0, 0);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(1, 1);
-  EXPECT_EQ("hlo", input->value());
+  EXPECT_EQ("hlo", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(100, 0);
-  EXPECT_EQ("llo", input->value());
+  EXPECT_EQ("llo", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(0, 100);
-  EXPECT_EQ("he", input->value());
+  EXPECT_EQ("he", input->Value());
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
   Controller().DeleteSurroundingText(100, 100);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 
-  input->setValue("h");
+  input->SetValue("h");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("h", input->value());
+  EXPECT_EQ("h", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(1, 1));
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 
-  input->setValue("h");
+  input->SetValue("h");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
-  EXPECT_EQ("h", input->value());
+  EXPECT_EQ("h", input->Value());
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ("", input->value());
+  EXPECT_EQ("", input->Value());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -763,60 +763,60 @@
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
   // U+2605 == "black star". It takes up 1 space.
-  input->setValue(String::FromUTF8("foo\xE2\x98\x85"));
+  input->SetValue(String::FromUTF8("foo\xE2\x98\x85"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("foo\xE2\x98\x85", input->value().Utf8());
+  EXPECT_EQ("foo\xE2\x98\x85", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
   // U+1F3C6 == "trophy". It takes up 2 space.
-  input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("foo\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(5, 5));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("foo\xED\xA0\xBC", input->value().Utf8());
+  EXPECT_EQ("foo\xED\xA0\xBC", input->Value().Utf8());
 
   // composed U+0E01 "ka kai" + U+0E49 "mai tho". It takes up 2 space.
-  input->setValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
+  input->SetValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(5, 5));
-  EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
+  EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("foo\xE0\xB8\x81", input->value().Utf8());
+  EXPECT_EQ("foo\xE0\xB8\x81", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(2, 0);
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(3, 0);
-  EXPECT_EQ("foo\xED\xA0\xBC", input->value().Utf8());
+  EXPECT_EQ("foo\xED\xA0\xBC", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(4, 0);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
-  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(5, 0);
-  EXPECT_EQ("fo", input->value());
+  EXPECT_EQ("fo", input->Value());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -825,60 +825,60 @@
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
   // U+2605 == "black star". It takes up 1 space.
-  input->setValue(String::FromUTF8("\xE2\x98\x85 foo"));
+  input->SetValue(String::FromUTF8("\xE2\x98\x85 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xE2\x98\x85 foo", input->value().Utf8());
+  EXPECT_EQ("\xE2\x98\x85 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ(" foo", input->value());
+  EXPECT_EQ(" foo", input->Value());
 
   // U+1F3C6 == "trophy". It takes up 2 space.
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86 foo"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ("\xED\xBF\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xED\xBF\x86 foo", input->Value().Utf8());
 
   // composed U+0E01 "ka kai" + U+0E49 "mai tho". It takes up 2 space.
-  input->setValue(String::FromUTF8("\xE0\xB8\x81\xE0\xB9\x89 foo"));
+  input->SetValue(String::FromUTF8("\xE0\xB8\x81\xE0\xB9\x89 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89 foo", input->value().Utf8());
+  EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 1);
-  EXPECT_EQ("\xE0\xB9\x89 foo", input->value().Utf8());
+  EXPECT_EQ("\xE0\xB9\x89 foo", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 2);
-  EXPECT_EQ("\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 3);
-  EXPECT_EQ("\xED\xBF\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xED\xBF\x86 foo", input->Value().Utf8());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 4);
-  EXPECT_EQ(" foo", input->value());
+  EXPECT_EQ(" foo", input->Value());
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
-  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->Value().Utf8());
   Controller().DeleteSurroundingText(0, 5);
-  EXPECT_EQ("foo", input->value());
+  EXPECT_EQ("foo", input->Value());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -887,14 +887,14 @@
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
   // "trophy" + "trophy".
-  input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
+  input->SetValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
-  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 1);
   // Deleted second half of the first trophy and the first half of the second
   // trophy, so we ended up with a complete trophy.
-  EXPECT_EQ("\xF0\x9F\x8F\x86", input->value().Utf8());
+  EXPECT_EQ("\xF0\x9F\x8F\x86", input->Value().Utf8());
 }
 
 // This test comes from http://crbug.com/1024738. It is basically the same to
@@ -903,14 +903,14 @@
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
   // p̂p̂ (U+0070 U+0302 U+0070 U+0302)
-  input->setValue(String::FromUTF8("\x70\xCC\x82\x70\xCC\x82"));
+  input->SetValue(String::FromUTF8("\x70\xCC\x82\x70\xCC\x82"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
-  EXPECT_EQ("\x70\xCC\x82\x70\xCC\x82", input->value().Utf8());
+  EXPECT_EQ("\x70\xCC\x82\x70\xCC\x82", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("\x70\xCC\x82\x70", input->value().Utf8());
+  EXPECT_EQ("\x70\xCC\x82\x70", input->Value().Utf8());
   Controller().DeleteSurroundingText(1, 0);
-  EXPECT_EQ("\x70\xCC\x82", input->value().Utf8());
+  EXPECT_EQ("\x70\xCC\x82", input->Value().Utf8());
 }
 
 TEST_F(InputMethodControllerTest, DeleteSurroundingTextForMultipleNodes) {
@@ -954,19 +954,19 @@
   // A "black star" is 1 grapheme cluster. It has 1 code point, and its length
   // is 1 (abbreviated as [1,1,1]). A "trophy": [1,1,2]. The composed text:
   // [1,2,2].
-  input->setValue(String::FromUTF8(
+  input->SetValue(String::FromUTF8(
       "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   // The cursor is at the end of the text.
   Controller().SetEditableSelectionOffsets(PlainTextRange(8, 8));
 
   Controller().DeleteSurroundingTextInCodePoints(2, 0);
-  EXPECT_EQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 ", input->value().Utf8());
+  EXPECT_EQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 ", input->Value().Utf8());
   Controller().DeleteSurroundingTextInCodePoints(4, 0);
-  EXPECT_EQ("a", input->value());
+  EXPECT_EQ("a", input->Value());
 
   // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
-  input->setValue(String::FromUTF8(
+  input->SetValue(String::FromUTF8(
       "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   // The cursor is at the end of the text.
@@ -975,7 +975,7 @@
   // We should only delete 1 code point.
   Controller().DeleteSurroundingTextInCodePoints(1, 0);
   EXPECT_EQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81",
-            input->value().Utf8());
+            input->Value().Utf8());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -984,17 +984,17 @@
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
   // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
-  input->setValue(String::FromUTF8(
+  input->SetValue(String::FromUTF8(
       "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
 
   Controller().DeleteSurroundingTextInCodePoints(0, 5);
-  EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
+  EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89", input->Value().Utf8());
 
   Controller().DeleteSurroundingTextInCodePoints(0, 1);
   // We should only delete 1 code point.
-  EXPECT_EQ("\xE0\xB9\x89", input->value().Utf8());
+  EXPECT_EQ("\xE0\xB9\x89", input->Value().Utf8());
 }
 
 TEST_F(InputMethodControllerTest,
@@ -1003,12 +1003,12 @@
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
   // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
-  input->setValue(String::FromUTF8(
+  input->SetValue(String::FromUTF8(
       "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(3, 3));
   Controller().DeleteSurroundingTextInCodePoints(2, 2);
-  EXPECT_EQ("a\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
+  EXPECT_EQ("a\xE0\xB8\x81\xE0\xB9\x89", input->Value().Utf8());
 }
 
 TEST_F(InputMethodControllerTest, DeleteSurroundingTextInCodePointsWithImage) {
@@ -1034,37 +1034,37 @@
   const UChar kUText[] = {'a', 0xD83C, 0x2605, 0xDFC6, ' ', '\0'};
   const String& text = String(kUText);
 
-  input->setValue(text);
+  input->SetValue(text);
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   // The invalid high surrogate is encoded as '\xED\xA0\xBC', and invalid low
   // surrogate is encoded as '\xED\xBF\x86'.
-  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86 ", input->value().Utf8());
+  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86 ", input->Value().Utf8());
 
   Controller().SetEditableSelectionOffsets(PlainTextRange(5, 5));
   // Delete a SPACE.
   Controller().DeleteSurroundingTextInCodePoints(1, 0);
-  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->value().Utf8());
+  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->Value().Utf8());
   // Do nothing since there is an invalid surrogate in the requested range.
   Controller().DeleteSurroundingTextInCodePoints(2, 0);
-  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->value().Utf8());
+  EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->Value().Utf8());
 
   Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
   // Delete 'a'.
   Controller().DeleteSurroundingTextInCodePoints(0, 1);
-  EXPECT_EQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->value().Utf8());
+  EXPECT_EQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->Value().Utf8());
   // Do nothing since there is an invalid surrogate in the requested range.
   Controller().DeleteSurroundingTextInCodePoints(0, 2);
-  EXPECT_EQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->value().Utf8());
+  EXPECT_EQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->Value().Utf8());
 }
 
 TEST_F(InputMethodControllerTest, SetCompositionForInputWithNewCaretPositions) {
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("hello");
+  input->SetValue("hello");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
-  EXPECT_EQ("hello", input->value());
+  EXPECT_EQ("hello", input->Value());
   EXPECT_EQ(2u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(2u, Controller().GetSelectionOffsets().End());
 
@@ -1076,42 +1076,42 @@
   // The caret exceeds left boundary.
   // "*heABllo", where * stands for caret.
   Controller().SetComposition("AB", ime_text_spans, -100, -100);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(0u, Controller().GetSelectionOffsets().End());
 
   // The caret is on left boundary.
   // "*heABllo".
   Controller().SetComposition("AB", ime_text_spans, -2, -2);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(0u, Controller().GetSelectionOffsets().End());
 
   // The caret is before the composing text.
   // "he*ABllo".
   Controller().SetComposition("AB", ime_text_spans, 0, 0);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(2u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(2u, Controller().GetSelectionOffsets().End());
 
   // The caret is after the composing text.
   // "heAB*llo".
   Controller().SetComposition("AB", ime_text_spans, 2, 2);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(4u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(4u, Controller().GetSelectionOffsets().End());
 
   // The caret is on right boundary.
   // "heABllo*".
   Controller().SetComposition("AB", ime_text_spans, 5, 5);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(7u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(7u, Controller().GetSelectionOffsets().End());
 
   // The caret exceeds right boundary.
   // "heABllo*".
   Controller().SetComposition("AB", ime_text_spans, 100, 100);
-  EXPECT_EQ("heABllo", input->value());
+  EXPECT_EQ("heABllo", input->Value());
   EXPECT_EQ(7u, Controller().GetSelectionOffsets().Start());
   EXPECT_EQ(7u, Controller().GetSelectionOffsets().End());
 }
@@ -1674,7 +1674,7 @@
   auto* textarea =
       To<HTMLTextAreaElement>(InsertHTMLElement("<textarea id='txt'>", "txt"));
 
-  textarea->setValue("abc\n");
+  textarea->SetValue("abc\n");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
 
@@ -1686,7 +1686,7 @@
   Controller().SetComposition(String(""), ime_text_spans, 0, 3);
   Controller().CommitText(String("def"), ime_text_spans, 0);
 
-  EXPECT_EQ("abc\ndef", textarea->value());
+  EXPECT_EQ("abc\ndef", textarea->Value());
 }
 
 TEST_F(InputMethodControllerTest, WhitespaceFixup) {
@@ -1714,16 +1714,16 @@
   auto* input =
       To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
 
-  input->setValue("Abc Def Ghi");
+  input->SetValue("Abc Def Ghi");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
   Vector<ImeTextSpan> empty_ime_text_spans;
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 8));
   Controller().CommitText(String(""), empty_ime_text_spans, 0);
-  EXPECT_EQ("Abc Ghi", input->value());
+  EXPECT_EQ("Abc Ghi", input->Value());
 
   Controller().SetEditableSelectionOffsets(PlainTextRange(4, 7));
   Controller().CommitText(String("1"), empty_ime_text_spans, 0);
-  EXPECT_EQ("Abc 1", input->value());
+  EXPECT_EQ("Abc 1", input->Value());
 }
 
 static String GetMarkedText(
@@ -2590,10 +2590,10 @@
   EXPECT_EQ(kWebTextInputTypeText, Controller().TextInputType());
 
   Controller().SetComposition("abcde", Vector<ImeTextSpan>(), 4, 4);
-  EXPECT_EQ("abcde", input->value());
+  EXPECT_EQ("abcde", input->Value());
 
   Controller().FinishComposingText(InputMethodController::kKeepSelection);
-  EXPECT_EQ("abcd", input->value());
+  EXPECT_EQ("abcd", input->Value());
 }
 
 TEST_F(InputMethodControllerTest, InputModeOfFocusedElement) {
@@ -3178,7 +3178,7 @@
 
   // Close out the composition, triggering the input event handler.
   Controller().FinishComposingText(InputMethodController::kKeepSelection);
-  EXPECT_EQ("he", input->value());
+  EXPECT_EQ("he", input->Value());
 
   // Verify that the input handler was able to properly move the selection.
   EXPECT_EQ(1u, input->selectionStart());
@@ -3208,7 +3208,7 @@
 
   // Close out the composition, triggering the input event handler.
   Controller().FinishComposingText(InputMethodController::kDoNotKeepSelection);
-  EXPECT_EQ("he", input->value());
+  EXPECT_EQ("he", input->Value());
 
   // Verify that the input handler was able to properly move the selection.
   EXPECT_EQ(1u, input->selectionStart());
@@ -3238,7 +3238,7 @@
 
   // Close out the composition, triggering the compositionend event handler.
   Controller().FinishComposingText(InputMethodController::kKeepSelection);
-  EXPECT_EQ("he", input->value());
+  EXPECT_EQ("he", input->Value());
 
   // Verify that the compositionend handler was able to properly move the
   // selection.
@@ -3270,7 +3270,7 @@
 
   // Close out the composition, triggering the compositionend event handler.
   Controller().FinishComposingText(InputMethodController::kDoNotKeepSelection);
-  EXPECT_EQ("he", input->value());
+  EXPECT_EQ("he", input->Value());
 
   // Verify that the compositionend handler was able to properly move the
   // selection.
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
index 50a6b70..740097f 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
@@ -82,7 +82,7 @@
   SetBodyContent("<input>");
   auto* input = To<HTMLInputElement>(GetDocument().QuerySelector("input"));
   input->Focus();
-  input->setValue("Hello, input field");
+  input->SetValue("Hello, input field");
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
 
   Position new_position(input->InnerEditorElement()->firstChild(), 3);
diff --git a/third_party/blink/renderer/core/exported/web_form_control_element.cc b/third_party/blink/renderer/core/exported/web_form_control_element.cc
index 190a645..4695583 100644
--- a/third_party/blink/renderer/core/exported/web_form_control_element.cc
+++ b/third_party/blink/renderer/core/exported/web_form_control_element.cc
@@ -153,18 +153,18 @@
 
 void WebFormControlElement::SetValue(const WebString& value, bool send_events) {
   if (auto* input = ::blink::DynamicTo<HTMLInputElement>(*private_)) {
-    input->setValue(value,
+    input->SetValue(value,
                     send_events
                         ? TextFieldEventBehavior::kDispatchInputAndChangeEvent
                         : TextFieldEventBehavior::kDispatchNoEvent);
   } else if (auto* textarea =
                  ::blink::DynamicTo<HTMLTextAreaElement>(*private_)) {
-    textarea->setValue(
+    textarea->SetValue(
         value, send_events
                    ? TextFieldEventBehavior::kDispatchInputAndChangeEvent
                    : TextFieldEventBehavior::kDispatchNoEvent);
   } else if (auto* select = ::blink::DynamicTo<HTMLSelectElement>(*private_)) {
-    select->setValue(value, send_events);
+    select->SetValue(value, send_events);
   }
 }
 
@@ -193,7 +193,7 @@
   } else if (auto* select = ::blink::DynamicTo<HTMLSelectElement>(*private_)) {
     if (!Focused())
       DispatchFocusEvent();
-    select->setValue(value, true);
+    select->SetValue(value, true);
     if (!Focused())
       DispatchBlurEvent();
   }
@@ -201,11 +201,11 @@
 
 WebString WebFormControlElement::Value() const {
   if (auto* input = ::blink::DynamicTo<HTMLInputElement>(*private_))
-    return input->value();
+    return input->Value();
   if (auto* textarea = ::blink::DynamicTo<HTMLTextAreaElement>(*private_))
-    return textarea->value();
+    return textarea->Value();
   if (auto* select = ::blink::DynamicTo<HTMLSelectElement>(*private_))
-    return select->value();
+    return select->Value();
   return WebString();
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index 80880220..aafe46c7 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -3257,7 +3257,7 @@
   auto* text_area_element = To<HTMLTextAreaElement>(static_cast<Node*>(
       web_view->MainFrameImpl()->GetDocument().GetElementById(
           blanklinestextbox)));
-  text_area_element->setValue("hello");
+  text_area_element->SetValue("hello");
 
   // Long-press past last word of textbox.
   EXPECT_TRUE(SimulateGestureAtElementById(
@@ -3994,53 +3994,53 @@
   auto* input_element = To<HTMLInputElement>(document->getElementById("date"));
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)->ResponseHandler(true, 0);
-  EXPECT_EQ("1970-01-01", input_element->value());
+  EXPECT_EQ("1970-01-01", input_element->Value());
 
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)
       ->ResponseHandler(true, std::numeric_limits<double>::quiet_NaN());
-  EXPECT_EQ("", input_element->value());
+  EXPECT_EQ("", input_element->Value());
 
   input_element =
       To<HTMLInputElement>(document->getElementById("datetimelocal"));
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)->ResponseHandler(true, 0);
-  EXPECT_EQ("1970-01-01T00:00", input_element->value());
+  EXPECT_EQ("1970-01-01T00:00", input_element->Value());
 
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)
       ->ResponseHandler(true, std::numeric_limits<double>::quiet_NaN());
-  EXPECT_EQ("", input_element->value());
+  EXPECT_EQ("", input_element->Value());
 
   input_element = To<HTMLInputElement>(document->getElementById("month"));
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)->ResponseHandler(true, 0);
-  EXPECT_EQ("1970-01", input_element->value());
+  EXPECT_EQ("1970-01", input_element->Value());
 
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)
       ->ResponseHandler(true, std::numeric_limits<double>::quiet_NaN());
-  EXPECT_EQ("", input_element->value());
+  EXPECT_EQ("", input_element->Value());
 
   input_element = To<HTMLInputElement>(document->getElementById("time"));
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)->ResponseHandler(true, 0);
-  EXPECT_EQ("00:00", input_element->value());
+  EXPECT_EQ("00:00", input_element->Value());
 
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)
       ->ResponseHandler(true, std::numeric_limits<double>::quiet_NaN());
-  EXPECT_EQ("", input_element->value());
+  EXPECT_EQ("", input_element->Value());
 
   input_element = To<HTMLInputElement>(document->getElementById("week"));
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)->ResponseHandler(true, 0);
-  EXPECT_EQ("1970-W01", input_element->value());
+  EXPECT_EQ("1970-W01", input_element->Value());
 
   OpenDateTimeChooser(web_view_impl, input_element);
   GetExternalDateTimeChooser(web_view_impl)
       ->ResponseHandler(true, std::numeric_limits<double>::quiet_NaN());
-  EXPECT_EQ("", input_element->value());
+  EXPECT_EQ("", input_element->Value());
 
   // Clear the WebViewClient from the webViewHelper to avoid use-after-free in
   // the WebViewHelper destructor.
diff --git a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc
index 42f7ad68..5eba69f 100644
--- a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc
@@ -212,10 +212,6 @@
     case WebFeature::kRtcpMuxPolicyNegotiate:
       return DeprecationInfo::WithTranslation(
           feature, DeprecationIssueType::kRtcpMuxPolicyNegotiate);
-    case WebFeature::kRTCConstraintEnableRtpDataChannelsFalse:
-    case WebFeature::kRTCConstraintEnableRtpDataChannelsTrue:
-      return DeprecationInfo::WithTranslation(
-          feature, DeprecationIssueType::kRTPDataChannel);
     case WebFeature::kV8SharedArrayBufferConstructedWithoutIsolation:
       return DeprecationInfo::WithTranslation(
           feature,
diff --git a/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc b/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
index b363ab0..77694b5 100644
--- a/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
@@ -63,7 +63,7 @@
 
 void BaseCheckableInputType::AppendToFormData(FormData& form_data) const {
   if (GetElement().checked())
-    form_data.AppendFromElement(GetElement().GetName(), GetElement().value());
+    form_data.AppendFromElement(GetElement().GetName(), GetElement().Value());
 }
 
 void BaseCheckableInputType::HandleKeydownEvent(KeyboardEvent& event) {
diff --git a/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc b/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
index 5d3a8fd..da90b26 100644
--- a/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
@@ -69,11 +69,11 @@
 void BaseTemporalInputType::SetValueAsDate(
     const absl::optional<base::Time>& value,
     ExceptionState&) const {
-  GetElement().setValue(SerializeWithDate(value));
+  GetElement().SetValue(SerializeWithDate(value));
 }
 
 double BaseTemporalInputType::ValueAsDouble() const {
-  const Decimal value = ParseToNumber(GetElement().value(), Decimal::Nan());
+  const Decimal value = ParseToNumber(GetElement().Value(), Decimal::Nan());
   return value.IsFinite() ? value.ToDouble()
                           : DateComponents::InvalidMilliseconds();
 }
@@ -91,7 +91,7 @@
 }
 
 bool BaseTemporalInputType::TypeMismatch() const {
-  return TypeMismatchFor(GetElement().value());
+  return TypeMismatchFor(GetElement().Value());
 }
 
 String BaseTemporalInputType::ValueNotEqualText(const Decimal& value) const {
@@ -188,7 +188,7 @@
 }
 
 String BaseTemporalInputType::VisibleValue() const {
-  return LocalizeValue(GetElement().value());
+  return LocalizeValue(GetElement().Value());
 }
 
 String BaseTemporalInputType::SanitizeValue(
diff --git a/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
index 727330f7b..f94c811 100644
--- a/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
+++ b/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
@@ -136,7 +136,7 @@
 void ChooserOnlyTemporalInputTypeView::DidChooseValue(const String& value) {
   if (will_be_destroyed_)
     return;
-  GetElement().setValue(value,
+  GetElement().SetValue(value,
                         TextFieldEventBehavior::kDispatchInputAndChangeEvent);
 }
 
@@ -145,7 +145,7 @@
     return;
   DCHECK(std::isfinite(value) || std::isnan(value));
   if (std::isnan(value)) {
-    GetElement().setValue(g_empty_string,
+    GetElement().SetValue(g_empty_string,
                           TextFieldEventBehavior::kDispatchInputAndChangeEvent);
   } else {
     GetElement().setValueAsNumber(
diff --git a/third_party/blink/renderer/core/html/forms/color_input_type.cc b/third_party/blink/renderer/core/html/forms/color_input_type.cc
index 262612c5..23f28b0e 100644
--- a/third_party/blink/renderer/core/html/forms/color_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/color_input_type.cc
@@ -116,7 +116,7 @@
 
 Color ColorInputType::ValueAsColor() const {
   Color color;
-  bool success = color.SetFromString(GetElement().value());
+  bool success = color.SetFromString(GetElement().Value());
   DCHECK(success);
   return color;
 }
@@ -236,7 +236,7 @@
     return;
 
   color_swatch->SetInlineStyleProperty(CSSPropertyID::kBackgroundColor,
-                                       GetElement().value());
+                                       GetElement().Value());
 }
 
 HTMLElement* ColorInputType::ShadowColorSwatch() const {
diff --git a/third_party/blink/renderer/core/html/forms/email_input_type.cc b/third_party/blink/renderer/core/html/forms/email_input_type.cc
index 4e574da..e63c38ad 100644
--- a/third_party/blink/renderer/core/html/forms/email_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/email_input_type.cc
@@ -204,11 +204,11 @@
 }
 
 bool EmailInputType::TypeMismatch() const {
-  return TypeMismatchFor(GetElement().value());
+  return TypeMismatchFor(GetElement().Value());
 }
 
 String EmailInputType::TypeMismatchText() const {
-  String invalid_address = FindInvalidAddress(GetElement().value());
+  String invalid_address = FindInvalidAddress(GetElement().Value());
   DCHECK(!invalid_address.IsNull());
   if (invalid_address.IsEmpty()) {
     return GetLocale().QueryString(
@@ -301,7 +301,7 @@
 }
 
 String EmailInputType::VisibleValue() const {
-  String value = GetElement().value();
+  String value = GetElement().Value();
   if (!GetElement().Multiple())
     return ConvertEmailAddressToUnicode(value);
 
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc
index 4e999a3..7c171ba 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -586,7 +586,7 @@
       control->AppendToFormData(form_data);
     if (auto* input = DynamicTo<HTMLInputElement>(element)) {
       if (input->type() == input_type_names::kPassword &&
-          !input->value().IsEmpty())
+          !input->Value().IsEmpty())
         form_data.SetContainsPasswordData(true);
     }
   }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index bb76480b..b789880 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -204,11 +204,11 @@
 }
 
 bool HTMLInputElement::TooLong() const {
-  return TooLong(value(), kCheckDirtyFlag);
+  return TooLong(Value(), kCheckDirtyFlag);
 }
 
 bool HTMLInputElement::TooShort() const {
-  return TooShort(value(), kCheckDirtyFlag);
+  return TooShort(Value(), kCheckDirtyFlag);
 }
 
 bool HTMLInputElement::TypeMismatch() const {
@@ -216,7 +216,7 @@
 }
 
 bool HTMLInputElement::ValueMissing() const {
-  return input_type_->ValueMissing(value());
+  return input_type_->ValueMissing(Value());
 }
 
 bool HTMLInputElement::HasBadInput() const {
@@ -224,7 +224,7 @@
 }
 
 bool HTMLInputElement::PatternMismatch() const {
-  return input_type_->PatternMismatch(value());
+  return input_type_->PatternMismatch(Value());
 }
 
 bool HTMLInputElement::TooLong(const String& value,
@@ -238,11 +238,11 @@
 }
 
 bool HTMLInputElement::RangeUnderflow() const {
-  return input_type_->RangeUnderflow(value());
+  return input_type_->RangeUnderflow(Value());
 }
 
 bool HTMLInputElement::RangeOverflow() const {
-  return input_type_->RangeOverflow(value());
+  return input_type_->RangeOverflow(Value());
 }
 
 String HTMLInputElement::validationMessage() const {
@@ -269,7 +269,7 @@
 }
 
 bool HTMLInputElement::StepMismatch() const {
-  return input_type_->StepMismatch(value());
+  return input_type_->StepMismatch(Value());
 }
 
 bool HTMLInputElement::GetAllowedValueStep(Decimal* step) const {
@@ -547,7 +547,7 @@
       String new_value = SanitizeValue(non_attribute_value_);
       if (!EqualIgnoringNullity(new_value, non_attribute_value_)) {
         if (HasDirtyValue())
-          setValue(new_value);
+          SetValue(new_value);
         else
           SetNonDirtyValue(new_value);
       }
@@ -1121,7 +1121,7 @@
   input_type_view_->UpdateView();
 }
 
-String HTMLInputElement::value() const {
+String HTMLInputElement::Value() const {
   switch (input_type_->GetValueMode()) {
     case ValueMode::kFilename:
       return input_type_->ValueInFilenameValueMode();
@@ -1139,7 +1139,7 @@
 }
 
 String HTMLInputElement::ValueOrDefaultLabel() const {
-  String value = this->value();
+  String value = this->Value();
   if (!value.IsNull())
     return value;
   return input_type_->DefaultLabel();
@@ -1147,7 +1147,7 @@
 
 void HTMLInputElement::SetValueForUser(const String& value) {
   // Call setValue and make it send a change event.
-  setValue(value, TextFieldEventBehavior::kDispatchChangeEvent);
+  SetValue(value, TextFieldEventBehavior::kDispatchChangeEvent);
 }
 
 void HTMLInputElement::SetSuggestedValue(const String& value) {
@@ -1193,10 +1193,10 @@
   }
 
   if (GetAutofillState() != WebAutofillState::kAutofilled) {
-    setValue(value);
+    SetValue(value);
   } else {
-    String old_value = this->value();
-    setValue(value);
+    String old_value = this->Value();
+    SetValue(value);
     if (Page* page = GetDocument().GetPage()) {
       page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
                                                                old_value);
@@ -1204,7 +1204,7 @@
   }
 }
 
-void HTMLInputElement::setValue(const String& value,
+void HTMLInputElement::SetValue(const String& value,
                                 TextFieldEventBehavior event_behavior,
                                 TextControlSetValueSelection selection) {
   input_type_->WarnIfValueIsInvalidAndElementIsVisible(value);
@@ -1221,7 +1221,7 @@
 
   EventQueueScope scope;
   String sanitized_value = SanitizeValue(value);
-  bool value_changed = sanitized_value != this->value();
+  bool value_changed = sanitized_value != this->Value();
 
   SetLastChangeWasNotUserEdit();
   needs_to_update_view_value_ = true;
@@ -1256,7 +1256,7 @@
 }
 
 void HTMLInputElement::SetNonDirtyValue(const String& new_value) {
-  setValue(new_value);
+  SetValue(new_value);
   has_dirty_value_ = false;
 }
 
@@ -1312,7 +1312,7 @@
   DCHECK_EQ(type(), input_type_names::kRange);
   const StepRange step_range(CreateStepRange(kRejectAny));
   const Decimal old_value =
-      ParseToDecimalForNumberType(value(), step_range.DefaultValue());
+      ParseToDecimalForNumberType(Value(), step_range.DefaultValue());
   return step_range.ProportionFromValue(step_range.ClampValue(old_value));
 }
 
@@ -1627,11 +1627,11 @@
 }
 
 bool HTMLInputElement::IsInRange() const {
-  return willValidate() && input_type_->IsInRange(value());
+  return willValidate() && input_type_->IsInRange(Value());
 }
 
 bool HTMLInputElement::IsOutOfRange() const {
-  return willValidate() && input_type_->IsOutOfRange(value());
+  return willValidate() && input_type_->IsOutOfRange(Value());
 }
 
 bool HTMLInputElement::IsRequiredFormControl() const {
@@ -2189,7 +2189,7 @@
 
 void HTMLInputElement::MaybeReportPiiMetrics() {
   // Don't report metrics if the field is empty.
-  if (value().IsEmpty())
+  if (Value().IsEmpty())
     return;
 
   // Report the PII types derived from autofill field semantic type prediction.
@@ -2211,9 +2211,9 @@
   // For Email, we add a length limitation (based on
   // https://www.rfc-editor.org/errata_search.php?rfc=3696) in addition to
   // matching with the pattern given by the HTML standard.
-  if (value().length() <= kMaxEmailFieldLength &&
+  if (Value().length() <= kMaxEmailFieldLength &&
       EmailInputType::IsValidEmailAddress(GetDocument().EnsureEmailRegexp(),
-                                          value())) {
+                                          Value())) {
     UseCounter::Count(GetDocument(),
                       WebFeature::kEmailFieldFilled_PatternMatch);
   }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 3f41dadd..e707fe64 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -138,13 +138,13 @@
 
   void setType(const AtomicString&);
 
-  String value() const override;
-  void setValue(
+  String Value() const override;
+  void SetValue(
       const String&,
       TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent,
       TextControlSetValueSelection =
           TextControlSetValueSelection::kSetSelectionToEnd) override;
-  String valueForBinding() const { return value(); }
+  String valueForBinding() const { return Value(); }
   void setValueForBinding(const String&, ExceptionState&);
   void SetValueForUser(const String&);
   // Update the value, and clear hasDirtyValue() flag.
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
index 5deb619..0cbd611 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
@@ -276,7 +276,7 @@
   ASSERT_TRUE(input->GetLayoutObject());
   EXPECT_FALSE(input->GetLayoutObject()->ShouldCheckForPaintInvalidation());
 
-  input->setValue("");
+  input->SetValue("");
   GetDocument().UpdateStyleAndLayoutTree();
 
   ASSERT_TRUE(input->GetLayoutObject());
@@ -328,15 +328,15 @@
   TestElement().setType(GetParam().new_type);
   GetDocument().UpdateStyleAndLayoutTree();
 
-  TestElement().setValue(GetParam().temporary_value);
+  TestElement().SetValue(GetParam().temporary_value);
   GetDocument().UpdateStyleAndLayoutTree();
 
   EXPECT_CALL(chrome_client(),
               PasswordFieldReset(Truly([this](const HTMLInputElement& e) {
-                return e.isSameNode(&TestElement()) && e.value().IsEmpty();
+                return e.isSameNode(&TestElement()) && e.Value().IsEmpty();
               })))
       .Times(GetParam().expected_call ? 1 : 0);
-  TestElement().setValue("");
+  TestElement().SetValue("");
   GetDocument().UpdateStyleAndLayoutTree();
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index 5f87c64..73ae0e9 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -277,7 +277,7 @@
     option->remove(IGNORE_EXCEPTION_FOR_TESTING);
 }
 
-String HTMLSelectElement::value() const {
+String HTMLSelectElement::Value() const {
   if (HTMLOptionElement* option = SelectedOption())
     return option->value();
   return "";
@@ -285,10 +285,10 @@
 
 void HTMLSelectElement::setValueForBinding(const String& value) {
   if (GetAutofillState() != WebAutofillState::kAutofilled) {
-    setValue(value);
+    SetValue(value);
   } else {
-    String old_value = this->value();
-    setValue(value);
+    String old_value = this->Value();
+    SetValue(value);
     if (Page* page = GetDocument().GetPage()) {
       page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
                                                                old_value);
@@ -296,7 +296,7 @@
   }
 }
 
-void HTMLSelectElement::setValue(const String& value, bool send_events) {
+void HTMLSelectElement::SetValue(const String& value, bool send_events) {
   HTMLOptionElement* option = nullptr;
   // Find the option with value() matching the given parameter and make it the
   // current selection.
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h
index a480111..bd45a00 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -92,9 +92,9 @@
   using Node::remove;
   void remove(int index);
 
-  String value() const;
-  void setValue(const String&, bool send_events = false);
-  String valueForBinding() const { return value(); }
+  String Value() const;
+  void SetValue(const String&, bool send_events = false);
+  String valueForBinding() const { return Value(); }
   void setValueForBinding(const String&);
   String SuggestedValue() const;
   void SetSuggestedValue(const String&);
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
index e03f4843..6e6b535 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -115,12 +115,12 @@
 }
 
 FormControlState HTMLTextAreaElement::SaveFormControlState() const {
-  return is_dirty_ ? FormControlState(value()) : FormControlState();
+  return is_dirty_ ? FormControlState(Value()) : FormControlState();
 }
 
 void HTMLTextAreaElement::RestoreFormControlState(
     const FormControlState& state) {
-  setValue(state[0]);
+  SetValue(state[0]);
 }
 
 int HTMLTextAreaElement::scrollWidth() {
@@ -163,7 +163,7 @@
   HTMLElement::ChildrenChanged(change);
   SetLastChangeWasNotUserEdit();
   if (is_dirty_)
-    SetInnerEditorValue(value());
+    SetInnerEditorValue(Value());
   else
     SetNonDirtyValue(defaultValue(), TextControlSetValueSelection::kClamp);
 }
@@ -280,7 +280,7 @@
   GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kForm);
 
   const String& text =
-      (wrap_ == kHardWrap) ? ValueWithHardLineBreaks() : value();
+      (wrap_ == kHardWrap) ? ValueWithHardLineBreaks() : Value();
   form_data.AppendFromElement(GetName(), text);
 
   const AtomicString& dirname_attr_value =
@@ -355,7 +355,7 @@
   AddPlaceholderBreakElementIfNecessary();
   SetValueBeforeFirstUserEditIfNotSet();
   UpdateValue();
-  CheckIfValueWasReverted(value());
+  CheckIfValueWasReverted(Value());
   SetNeedsValidityCheck();
   SetAutofillState(WebAutofillState::kNotFilled);
   UpdatePlaceholderVisibility();
@@ -435,16 +435,16 @@
   UpdatePlaceholderVisibility();
 }
 
-String HTMLTextAreaElement::value() const {
+String HTMLTextAreaElement::Value() const {
   return value_;
 }
 
 void HTMLTextAreaElement::setValueForBinding(const String& value) {
   if (GetAutofillState() != WebAutofillState::kAutofilled) {
-    setValue(value);
+    SetValue(value);
   } else {
-    String old_value = this->value();
-    setValue(value);
+    String old_value = this->Value();
+    SetValue(value);
     if (Page* page = GetDocument().GetPage()) {
       page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
                                                                old_value);
@@ -452,7 +452,7 @@
   }
 }
 
-void HTMLTextAreaElement::setValue(const String& value,
+void HTMLTextAreaElement::SetValue(const String& value,
                                    TextFieldEventBehavior event_behavior,
                                    TextControlSetValueSelection selection) {
   SetValueCommon(value, event_behavior, selection);
@@ -481,7 +481,7 @@
 
   // Return early because we don't want to trigger other side effects when the
   // value isn't changing. This is interoperable.
-  if (normalized_value == value())
+  if (normalized_value == Value())
     return;
 
   // selectionStart and selectionEnd values can be changed by
@@ -568,12 +568,12 @@
     return GetLocale().QueryString(IDS_FORM_VALIDATION_VALUE_MISSING);
 
   if (TooLong()) {
-    return GetLocale().ValidationMessageTooLongText(value().length(),
+    return GetLocale().ValidationMessageTooLongText(Value().length(),
                                                     maxLength());
   }
 
   if (TooShort()) {
-    return GetLocale().ValidationMessageTooShortText(value().length(),
+    return GetLocale().ValidationMessageTooShortText(Value().length(),
                                                      minLength());
   }
 
@@ -589,7 +589,7 @@
   // For textarea elements, the value is missing only if it is mutable.
   // https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-required
   return IsRequiredFormControl() && !IsDisabledOrReadOnly() &&
-         (value ? *value : this->value()).IsEmpty();
+         (value ? *value : this->Value()).IsEmpty();
 }
 
 bool HTMLTextAreaElement::TooLong() const {
@@ -613,7 +613,7 @@
   if (max < 0)
     return false;
   unsigned len =
-      value ? ComputeLengthForAPIValue(*value) : this->value().length();
+      value ? ComputeLengthForAPIValue(*value) : this->Value().length();
   return len > static_cast<unsigned>(max);
 }
 
@@ -629,7 +629,7 @@
     return false;
   // An empty string is excluded from minlength check.
   unsigned len =
-      value ? ComputeLengthForAPIValue(*value) : this->value().length();
+      value ? ComputeLengthForAPIValue(*value) : this->Value().length();
   return len > 0 && len < static_cast<unsigned>(min);
 }
 
@@ -710,7 +710,7 @@
     const Element& source,
     CloneChildrenFlag flag) {
   const auto& source_element = To<HTMLTextAreaElement>(source);
-  SetValueCommon(source_element.value(),
+  SetValueCommon(source_element.Value(),
                  TextFieldEventBehavior::kDispatchNoEvent,
                  TextControlSetValueSelection::kSetSelectionToEnd);
   is_dirty_ = source_element.is_dirty_;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
index 7767b9e..ba20a2c 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -44,17 +44,17 @@
 
   bool ShouldWrapText() const { return wrap_ != kNoWrap; }
 
-  String value() const override;
-  void setValue(
+  String Value() const override;
+  void SetValue(
       const String&,
       TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent,
       TextControlSetValueSelection =
           TextControlSetValueSelection::kSetSelectionToEnd) override;
-  String valueForBinding() const { return value(); }
+  String valueForBinding() const { return Value(); }
   void setValueForBinding(const String&);
   String defaultValue() const;
   void setDefaultValue(const String&);
-  int textLength() const { return value().length(); }
+  int textLength() const { return Value().length(); }
 
   void SetSuggestedValue(const String& value) override;
 
@@ -89,7 +89,7 @@
   bool SupportsPlaceholder() const override { return true; }
   String GetPlaceholderValue() const final;
   void UpdatePlaceholderText() override;
-  bool IsEmptyValue() const override { return value().IsEmpty(); }
+  bool IsEmptyValue() const override { return Value().IsEmpty(); }
 
   bool IsOptionalFormControl() const override {
     return !IsRequiredFormControl();
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc
index bf77eea6..57b324e 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc
@@ -63,11 +63,11 @@
   RunDocumentLifecycle();
   EXPECT_TRUE(textarea.ValueWithHardLineBreaks().IsEmpty());
 
-  textarea.setValue("12345678");
+  textarea.SetValue("12345678");
   RunDocumentLifecycle();
   EXPECT_EQ("1234\n5678", textarea.ValueWithHardLineBreaks());
 
-  textarea.setValue("1234567890\n");
+  textarea.SetValue("1234567890\n");
   RunDocumentLifecycle();
   EXPECT_EQ("1234\n5678\n90\n", textarea.ValueWithHardLineBreaks());
 
@@ -98,7 +98,7 @@
 
 #define LTO "\xE2\x80\xAD"
 #define RTO "\xE2\x80\xAE"
-  textarea.setValue(
+  textarea.SetValue(
       String::FromUTF8(RTO "Hebrew" LTO " English " RTO "Arabic" LTO));
   // This textarea is rendered as:
   //    -----------------
diff --git a/third_party/blink/renderer/core/html/forms/input_type.cc b/third_party/blink/renderer/core/html/forms/input_type.cc
index fa914660..96677fe 100644
--- a/third_party/blink/renderer/core/html/forms/input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/input_type.cc
@@ -154,7 +154,7 @@
 }
 
 void InputType::AppendToFormData(FormData& form_data) const {
-  form_data.AppendFromElement(GetElement().GetName(), GetElement().value());
+  form_data.AppendFromElement(GetElement().GetName(), GetElement().Value());
 }
 
 String InputType::ResultForDialogSubmit() const {
@@ -187,7 +187,7 @@
 void InputType::SetValueAsDecimal(const Decimal& new_value,
                                   TextFieldEventBehavior event_behavior,
                                   ExceptionState&) const {
-  GetElement().setValue(Serialize(new_value), event_behavior);
+  GetElement().SetValue(Serialize(new_value), event_behavior);
 }
 
 void InputType::ReadingChecked() const {}
@@ -372,7 +372,7 @@
 
 std::pair<String, String> InputType::ValidationMessage(
     const InputTypeView& input_type_view) const {
-  const String value = GetElement().value();
+  const String value = GetElement().Value();
 
   // The order of the following checks is meaningful. e.g. We'd like to show the
   // badInput message even if the control has other validation errors.
@@ -603,7 +603,7 @@
 }
 
 String InputType::VisibleValue() const {
-  return GetElement().value();
+  return GetElement().Value();
 }
 
 String InputType::SanitizeValue(const String& proposed_value) const {
@@ -836,7 +836,7 @@
                                       "This form element is not steppable.");
     return;
   }
-  const Decimal current = ParseToNumber(GetElement().value(), 0);
+  const Decimal current = ParseToNumber(GetElement().Value(), 0);
   ApplyStep(current, n, kRejectAny, TextFieldEventBehavior::kDispatchNoEvent,
             exception_state);
 }
@@ -900,7 +900,7 @@
   else
     sign = 0;
 
-  Decimal current = ParseToNumberOrNaN(GetElement().value());
+  Decimal current = ParseToNumberOrNaN(GetElement().Value());
   if (!current.IsFinite()) {
     current = DefaultValueForStepUp();
     const Decimal next_diff = step * n;
diff --git a/third_party/blink/renderer/core/html/forms/input_type_view.cc b/third_party/blink/renderer/core/html/forms/input_type_view.cc
index 0f2354f..376bf86acb 100644
--- a/third_party/blink/renderer/core/html/forms/input_type_view.cc
+++ b/third_party/blink/renderer/core/html/forms/input_type_view.cc
@@ -192,14 +192,14 @@
 }
 
 FormControlState InputTypeView::SaveFormControlState() const {
-  String current_value = GetElement().value();
+  String current_value = GetElement().Value();
   if (current_value == GetElement().DefaultValue())
     return FormControlState();
   return FormControlState(current_value);
 }
 
 void InputTypeView::RestoreFormControlState(const FormControlState& state) {
-  GetElement().setValue(state[0]);
+  GetElement().SetValue(state[0]);
 }
 
 bool InputTypeView::IsDraggedSlider() const {
diff --git a/third_party/blink/renderer/core/html/forms/month_input_type.cc b/third_party/blink/renderer/core/html/forms/month_input_type.cc
index 49c6515..7531502 100644
--- a/third_party/blink/renderer/core/html/forms/month_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/month_input_type.cc
@@ -58,7 +58,7 @@
 
 double MonthInputType::ValueAsDate() const {
   DateComponents date;
-  if (!ParseToDateComponents(GetElement().value(), &date))
+  if (!ParseToDateComponents(GetElement().Value(), &date))
     return DateComponents::InvalidMilliseconds();
   double msec = date.MillisecondsSinceEpoch();
   DCHECK(std::isfinite(msec));
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
index ca279dc..d4e2e864 100644
--- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
+++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -205,7 +205,7 @@
 }
 
 void MultipleFieldsTemporalInputTypeView::EditControlValueChanged() {
-  String old_value = GetElement().value();
+  String old_value = GetElement().Value();
   String new_value =
       input_type_->SanitizeValue(GetDateTimeEditElement()->Value());
   // Even if oldValue is null and newValue is "", we should assume they are
@@ -285,7 +285,7 @@
   if (will_be_destroyed_)
     return;
   if (GetElement().IsValidValue(value)) {
-    GetElement().setValue(value, TextFieldEventBehavior::kDispatchInputEvent);
+    GetElement().SetValue(value, TextFieldEventBehavior::kDispatchInputEvent);
     return;
   }
 
@@ -314,7 +314,7 @@
     return;
   DCHECK(std::isfinite(value) || std::isnan(value));
   if (std::isnan(value)) {
-    GetElement().setValue(g_empty_string,
+    GetElement().SetValue(g_empty_string,
                           TextFieldEventBehavior::kDispatchInputEvent);
   } else {
     GetElement().setValueAsNumber(value, ASSERT_NO_EXCEPTION,
@@ -494,7 +494,7 @@
 
 bool MultipleFieldsTemporalInputTypeView::HasBadInput() const {
   DateTimeEditElement* edit = GetDateTimeEditElement();
-  return GetElement().value().IsEmpty() && edit &&
+  return GetElement().Value().IsEmpty() && edit &&
          edit->AnyEditableFieldsHaveValues();
 }
 
@@ -568,7 +568,7 @@
     has_value = input_type_->ParseToDateComponents(
         GetElement().SuggestedValue(), &date);
   else
-    has_value = input_type_->ParseToDateComponents(GetElement().value(), &date);
+    has_value = input_type_->ParseToDateComponents(GetElement().Value(), &date);
   if (!has_value)
     input_type_->SetMillisecondToDateComponents(
         layout_parameters.step_range.Minimum().ToDouble(), &date);
@@ -660,7 +660,7 @@
 }
 
 void MultipleFieldsTemporalInputTypeView::ClearValue() {
-  GetElement().setValue("",
+  GetElement().SetValue("",
                         TextFieldEventBehavior::kDispatchInputAndChangeEvent);
   GetElement().UpdateClearButtonVisibility();
 }
diff --git a/third_party/blink/renderer/core/html/forms/number_input_type.cc b/third_party/blink/renderer/core/html/forms/number_input_type.cc
index ec0f229c..1fb387f 100644
--- a/third_party/blink/renderer/core/html/forms/number_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/number_input_type.cc
@@ -112,19 +112,19 @@
 }
 
 double NumberInputType::ValueAsDouble() const {
-  return ParseToDoubleForNumberType(GetElement().value());
+  return ParseToDoubleForNumberType(GetElement().Value());
 }
 
 void NumberInputType::SetValueAsDouble(double new_value,
                                        TextFieldEventBehavior event_behavior,
                                        ExceptionState& exception_state) const {
-  GetElement().setValue(SerializeForNumberType(new_value), event_behavior);
+  GetElement().SetValue(SerializeForNumberType(new_value), event_behavior);
 }
 
 void NumberInputType::SetValueAsDecimal(const Decimal& new_value,
                                         TextFieldEventBehavior event_behavior,
                                         ExceptionState& exception_state) const {
-  GetElement().setValue(SerializeForNumberType(new_value), event_behavior);
+  GetElement().SetValue(SerializeForNumberType(new_value), event_behavior);
 }
 
 bool NumberInputType::TypeMismatchFor(const String& value) const {
@@ -132,7 +132,7 @@
 }
 
 bool NumberInputType::TypeMismatch() const {
-  DCHECK(!TypeMismatchFor(GetElement().value()));
+  DCHECK(!TypeMismatchFor(GetElement().Value()));
   return false;
 }
 
@@ -295,7 +295,7 @@
 }
 
 String NumberInputType::VisibleValue() const {
-  return LocalizeValue(GetElement().value());
+  return LocalizeValue(GetElement().Value());
 }
 
 String NumberInputType::ConvertFromVisibleValue(
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type.cc b/third_party/blink/renderer/core/html/forms/password_input_type.cc
index 864fb317..c1b3523 100644
--- a/third_party/blink/renderer/core/html/forms/password_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/password_input_type.cc
@@ -101,7 +101,7 @@
 void PasswordInputType::DidSetValueByUserEdit() {
   if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
     // If the last character is deleted, we hide the reveal button.
-    if (GetElement().value().IsEmpty()) {
+    if (GetElement().Value().IsEmpty()) {
       should_show_reveal_button_ = false;
     }
     UpdatePasswordRevealButton();
@@ -212,7 +212,7 @@
   if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
     // This is the only scenario we go from no reveal button to showing the
     // reveal button: the password is empty and we have some user input.
-    if (GetElement().value().IsEmpty())
+    if (GetElement().Value().IsEmpty())
       should_show_reveal_button_ = true;
   }
 
diff --git a/third_party/blink/renderer/core/html/forms/radio_node_list.cc b/third_party/blink/renderer/core/html/forms/radio_node_list.cc
index b8d28ff..3617535 100644
--- a/third_party/blink/renderer/core/html/forms/radio_node_list.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_node_list.cc
@@ -57,7 +57,7 @@
   if (!input_element)
     return nullptr;
   if (input_element->type() != input_type_names::kRadio ||
-      input_element->value().IsEmpty())
+      input_element->Value().IsEmpty())
     return nullptr;
   return input_element;
 }
@@ -70,7 +70,7 @@
     const HTMLInputElement* input_element = ToRadioButtonInputElement(*item(i));
     if (!input_element || !input_element->checked())
       continue;
-    return input_element->value();
+    return input_element->Value();
   }
   return String();
 }
@@ -81,7 +81,7 @@
   unsigned length = this->length();
   for (unsigned i = 0; i < length; ++i) {
     HTMLInputElement* input_element = ToRadioButtonInputElement(*item(i));
-    if (!input_element || input_element->value() != value)
+    if (!input_element || input_element->Value() != value)
       continue;
     input_element->setChecked(true);
     return;
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc
index 58f8fb09..89997202 100644
--- a/third_party/blink/renderer/core/html/forms/range_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -107,7 +107,7 @@
 }
 
 double RangeInputType::ValueAsDouble() const {
-  return ParseToDoubleForNumberType(GetElement().value());
+  return ParseToDoubleForNumberType(GetElement().Value());
 }
 
 void RangeInputType::SetValueAsDouble(double new_value,
@@ -180,7 +180,7 @@
 
   const String& key = event.key();
 
-  const Decimal current = ParseToNumberOrNaN(GetElement().value());
+  const Decimal current = ParseToNumberOrNaN(GetElement().Value());
   DCHECK(current.IsFinite());
 
   StepRange step_range(CreateStepRange(kRejectAny));
@@ -279,17 +279,17 @@
 
 void RangeInputType::SanitizeValueInResponseToMinOrMaxAttributeChange() {
   if (GetElement().HasDirtyValue())
-    GetElement().setValue(GetElement().value());
+    GetElement().SetValue(GetElement().Value());
   else
-    GetElement().SetNonDirtyValue(GetElement().value());
+    GetElement().SetNonDirtyValue(GetElement().Value());
   GetElement().UpdateView();
 }
 
 void RangeInputType::StepAttributeChanged() {
   if (GetElement().HasDirtyValue())
-    GetElement().setValue(GetElement().value());
+    GetElement().SetValue(GetElement().Value());
   else
-    GetElement().SetNonDirtyValue(GetElement().value());
+    GetElement().SetNonDirtyValue(GetElement().Value());
   GetElement().UpdateView();
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/search_input_type.cc b/third_party/blink/renderer/core/html/forms/search_input_type.cc
index e01f86fd..a6fbe93 100644
--- a/third_party/blink/renderer/core/html/forms/search_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/search_input_type.cc
@@ -147,7 +147,7 @@
       shadow_element_names::kIdSearchClearButton);
   if (!button)
     return;
-  if (GetElement().value().IsEmpty()) {
+  if (GetElement().Value().IsEmpty()) {
     button->SetInlineStyleProperty(CSSPropertyID::kOpacity, 0.0,
                                    CSSPrimitiveValue::UnitType::kNumber);
     button->SetInlineStyleProperty(CSSPropertyID::kPointerEvents,
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
index d4d6887..1760571 100644
--- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
+++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -151,7 +151,7 @@
   }
 
   String value_string = SerializeForNumberType(value);
-  if (value_string == input->value())
+  if (value_string == input->Value())
     return;
 
   // FIXME: This is no longer being set from renderer. Consider updating the
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 8e00b55..2709e004 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -254,7 +254,7 @@
 void TextControlElement::SetValueBeforeFirstUserEditIfNotSet() {
   if (!value_before_first_user_edit_.IsNull())
     return;
-  String value = this->value();
+  String value = this->Value();
   value_before_first_user_edit_ = value.IsNull() ? g_empty_string : value;
 }
 
@@ -283,7 +283,7 @@
 
 void TextControlElement::DispatchFormControlChangeEvent() {
   if (!value_before_first_user_edit_.IsNull() &&
-      !EqualIgnoringNullity(value_before_first_user_edit_, value())) {
+      !EqualIgnoringNullity(value_before_first_user_edit_, Value())) {
     ClearValueBeforeFirstUserEdit();
     DispatchChangeEvent();
   } else {
@@ -293,7 +293,7 @@
 
 void TextControlElement::EnqueueChangeEvent() {
   if (!value_before_first_user_edit_.IsNull() &&
-      !EqualIgnoringNullity(value_before_first_user_edit_, value())) {
+      !EqualIgnoringNullity(value_before_first_user_edit_, Value())) {
     Event* event = Event::CreateBubble(event_type_names::kChange);
     event->SetTarget(this);
     GetDocument().EnqueueAnimationFrameEvent(event);
@@ -337,7 +337,7 @@
   text.Append(replacement);
   text.Append(StringView(original_text, end));
 
-  setValue(text.ToString(), TextFieldEventBehavior::kDispatchNoEvent,
+  SetValue(text.ToString(), TextFieldEventBehavior::kDispatchNoEvent,
            TextControlSetValueSelection::kDoNotSet);
 
   if (selection_mode == "select") {
@@ -926,19 +926,19 @@
   // problem, it would be best to fix it some day.
   HTMLElement* inner_text = InnerEditorElement();
   if (!inner_text || !IsTextControl())
-    return value();
+    return Value();
 
   auto* layout_object = To<LayoutBlockFlow>(inner_text->GetLayoutObject());
   if (!layout_object)
-    return value();
+    return Value();
 
   if (layout_object->IsLayoutNGObject()) {
     NGInlineCursor cursor(*layout_object);
     if (!cursor)
-      return value();
+      return Value();
     const auto* mapping = NGInlineNode::GetOffsetMapping(layout_object);
     if (!mapping)
-      return value();
+      return Value();
     Position break_position = GetNextSoftBreak(*mapping, cursor);
     StringBuilder result;
     for (Node& node : NodeTraversal::DescendantsOf(*inner_text)) {
@@ -971,7 +971,7 @@
   unsigned break_offset;
   RootInlineBox* line = layout_object->FirstRootBox();
   if (!line)
-    return value();
+    return Value();
 
   GetNextSoftBreak(line, break_node, break_offset);
 
@@ -1051,7 +1051,7 @@
 void TextControlElement::SetAutofillValue(const String& value) {
   // Set the value trimmed to the max length of the field and dispatch the input
   // and change events.
-  setValue(value.Substring(0, maxLength()),
+  SetValue(value.Substring(0, maxLength()),
            TextFieldEventBehavior::kDispatchInputAndChangeEvent);
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.h b/third_party/blink/renderer/core/html/forms/text_control_element.h
index dfb25f6..af6e3d3 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.h
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -121,8 +121,8 @@
   void CheckIfValueWasReverted(const String&);
   void ClearValueBeforeFirstUserEdit();
 
-  virtual String value() const = 0;
-  virtual void setValue(
+  virtual String Value() const = 0;
+  virtual void SetValue(
       const String&,
       TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent,
       TextControlSetValueSelection =
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
index b4a561c6..eca1305 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
@@ -68,7 +68,7 @@
 
 TEST_F(TextControlElementTest, SetSelectionRangeDoesNotCauseLayout) {
   Input().Focus();
-  Input().setValue("Hello, input form.");
+  Input().SetValue("Hello, input form.");
   Input().SetSelectionRange(1, 1);
 
   // Force layout if document().updateStyleAndLayoutIgnorePendingStylesheets()
@@ -81,7 +81,7 @@
 }
 
 TEST_F(TextControlElementTest, IndexForPosition) {
-  Input().setValue("Hello");
+  Input().SetValue("Hello");
   HTMLElement* inner_editor = Input().InnerEditorElement();
   EXPECT_EQ(5u, TextControlElement::IndexForPosition(
                     inner_editor,
diff --git a/third_party/blink/renderer/core/html/forms/url_input_type.cc b/third_party/blink/renderer/core/html/forms/url_input_type.cc
index a442514..21343232 100644
--- a/third_party/blink/renderer/core/html/forms/url_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/url_input_type.cc
@@ -52,7 +52,7 @@
 }
 
 bool URLInputType::TypeMismatch() const {
-  return TypeMismatchFor(GetElement().value());
+  return TypeMismatchFor(GetElement().Value());
 }
 
 String URLInputType::TypeMismatchText() const {
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 16fff22..bb9fa523 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1312,7 +1312,7 @@
   is_deferred = false;
   if (auto* input_element = DynamicTo<HTMLInputElement>(*this)) {
     bool has_strong_directionality;
-    return DetermineDirectionality(input_element->value(),
+    return DetermineDirectionality(input_element->Value(),
                                    &has_strong_directionality);
   }
 
diff --git a/third_party/blink/renderer/core/input/touch_event_manager_test.cc b/third_party/blink/renderer/core/input/touch_event_manager_test.cc
index c2a410b..5266a0a 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager_test.cc
+++ b/third_party/blink/renderer/core/input/touch_event_manager_test.cc
@@ -102,7 +102,7 @@
       To<HTMLInputElement>(GetDocument().getElementById("slideElement"));
   // Allow off by 1 error because it may result in different value in some
   // platform.
-  EXPECT_NEAR(23, ParseToDoubleForNumberType(input->value()), 1);
+  EXPECT_NEAR(23, ParseToDoubleForNumberType(input->Value()), 1);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
index 0b40a08..9b17250 100644
--- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
@@ -590,9 +590,6 @@
     case DeprecationIssueType::kRtcpMuxPolicyNegotiate:
       type = protocol::Audits::DeprecationIssueTypeEnum::RtcpMuxPolicyNegotiate;
       break;
-    case DeprecationIssueType::kRTPDataChannel:
-      type = protocol::Audits::DeprecationIssueTypeEnum::RTPDataChannel;
-      break;
     case DeprecationIssueType::kSharedArrayBufferConstructedWithoutIsolation:
       type = protocol::Audits::DeprecationIssueTypeEnum::
           SharedArrayBufferConstructedWithoutIsolation;
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
index 221f57c..6d740b1 100644
--- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
+++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
@@ -83,7 +83,6 @@
   kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics,
   kRTCPeerConnectionSdpSemanticsPlanB,
   kRtcpMuxPolicyNegotiate,
-  kRTPDataChannel,
   kSharedArrayBufferConstructedWithoutIsolation,
   kTextToSpeech_DisallowedByAutoplay,
   kV8SharedArrayBufferConstructedInExtensionWithoutIsolation,
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
index 78df0c94..146e7b9b 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -540,11 +540,11 @@
     }
 
     if (auto* textarea_element = DynamicTo<HTMLTextAreaElement>(*element)) {
-      SetRare(nodes->getTextValue(nullptr), index, textarea_element->value());
+      SetRare(nodes->getTextValue(nullptr), index, textarea_element->Value());
     }
 
     if (auto* input_element = DynamicTo<HTMLInputElement>(*element)) {
-      SetRare(nodes->getInputValue(nullptr), index, input_element->value());
+      SetRare(nodes->getInputValue(nullptr), index, input_element->Value());
       if ((input_element->type() == input_type_names::kRadio) ||
           (input_element->type() == input_type_names::kCheckbox)) {
         if (input_element->checked()) {
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
index 882f890..91d73314 100644
--- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -250,10 +250,10 @@
     }
 
     if (auto* textarea_element = DynamicTo<HTMLTextAreaElement>(*element))
-      value->setTextValue(textarea_element->value());
+      value->setTextValue(textarea_element->Value());
 
     if (auto* input_element = DynamicTo<HTMLInputElement>(*element)) {
-      value->setInputValue(input_element->value());
+      value->setInputValue(input_element->Value());
       if ((input_element->type() == input_type_names::kRadio) ||
           (input_element->type() == input_type_names::kCheckbox)) {
         value->setInputChecked(input_element->checked());
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 22a6d46..2e7a63c3 100644
--- a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
+++ b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
@@ -244,6 +244,24 @@
                                      .width);
 }
 
+// crbug.com/1327891
+TEST_F(DeferredShapingTest, FragmentAssociationAfterUnlock) {
+  SetBodyInnerHTML(R"HTML(
+<div style="height:1800px"></div>
+<div id="target">IFC</div>)HTML");
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_TRUE(IsDefer("target"));
+  EXPECT_TRUE(IsLocked("target"));
+  auto* box = GetLayoutBoxByElementId("target");
+  auto* fragment = box->GetPhysicalFragment(0);
+  EXPECT_EQ(box, fragment->GetLayoutObject());
+
+  ScrollAndWaitForIntersectionCheck(1800);
+  EXPECT_FALSE(IsDefer("target"));
+  EXPECT_FALSE(IsLocked("target"));
+  EXPECT_EQ(nullptr, fragment->GetLayoutObject());
+}
+
 TEST_F(DeferredShapingTest, UpdateTextInDeferred) {
   SetBodyInnerHTML(R"HTML(
 <div style="height:1800px"></div>
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index bbd4439..c47759e 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -502,14 +502,7 @@
   ShapeOutsideInfo::RemoveInfo(*this);
 
   if (!DocumentBeingDestroyed()) {
-    if (FirstInlineFragmentItemIndex()) {
-      NGFragmentItems::LayoutObjectWillBeDestroyed(*this);
-      ClearFirstInlineFragmentItemIndex();
-    }
-    if (measure_result_)
-      measure_result_->PhysicalFragment().LayoutObjectWillBeDestroyed();
-    for (auto result : layout_results_)
-      result->PhysicalFragment().LayoutObjectWillBeDestroyed();
+    DisassociatePhysicalFragments();
     GetDocument()
         .GetFrame()
         ->GetInputMethodController()
@@ -520,6 +513,17 @@
   LayoutBoxModelObject::WillBeDestroyed();
 }
 
+void LayoutBox::DisassociatePhysicalFragments() {
+  if (FirstInlineFragmentItemIndex()) {
+    NGFragmentItems::LayoutObjectWillBeDestroyed(*this);
+    ClearFirstInlineFragmentItemIndex();
+  }
+  if (measure_result_)
+    measure_result_->PhysicalFragment().LayoutObjectWillBeDestroyed();
+  for (auto result : layout_results_)
+    result->PhysicalFragment().LayoutObjectWillBeDestroyed();
+}
+
 void LayoutBox::InsertedIntoTree() {
   NOT_DESTROYED();
   LayoutBoxModelObject::InsertedIntoTree();
@@ -3412,7 +3416,7 @@
   // Column fragments are not really associated with a layout object.
   if (IsLayoutFlowThread())
     DCHECK(box_fragment.IsColumnBox());
-  else
+  else if (!IsShapingDeferred())
     DCHECK_EQ(this, box_fragment.GetLayoutObject());
 #endif
   ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 46c2d48a..1e7fbc2e 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1196,6 +1196,8 @@
   void RestoreLegacyLayoutResults(const NGLayoutResult* measure_result,
                                   const NGLayoutResult* layout_result);
   void ClearLayoutResults();
+  // Clear LayoutObject fields of physical fragments.
+  void DisassociatePhysicalFragments();
 
   // Call when NG fragment count or size changed. Only call if the fragment
   // count is or was larger than 1.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index 326c5637..4ec2a0d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -37,6 +37,8 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h"
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+#include "third_party/blink/renderer/core/mathml_names.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
 
 namespace blink {
@@ -2682,6 +2684,12 @@
   if (ConstraintSpace().IsTableCell()) {
     builder.SetIsTableCellChild(true);
 
+    // Always shrink-to-fit children within a <mtd> element.
+    if (Node().GetDOMNode() &&
+        Node().GetDOMNode()->HasTagName(mathml_names::kMtdTag)) {
+      builder.SetInlineAutoBehavior(NGAutoBehavior::kFitContent);
+    }
+
     // Some scrollable percentage-sized children of table-cells use their
     // min-size (instead of sizing normally).
     //
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 2730acb..64c61250 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -1790,7 +1790,7 @@
   }
 
   if (auto* select = DynamicTo<HTMLSelectElement>(*element)) {
-    select->setValue(value.IsEmpty()
+    select->SetValue(value.IsEmpty()
                          ? String()  // Null string resets the autofill state.
                          : value,
                      true /* send_events */);
diff --git a/third_party/blink/renderer/extensions/chromeos/BUILD.gn b/third_party/blink/renderer/extensions/chromeos/BUILD.gn
index c2bc0dbc..6e1e1d3f 100644
--- a/third_party/blink/renderer/extensions/chromeos/BUILD.gn
+++ b/third_party/blink/renderer/extensions/chromeos/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//third_party/blink/renderer/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
 import("//third_party/blink/renderer/build/scripts/scripts.gni")
 import("//third_party/blink/renderer/config.gni")
 import("//third_party/blink/renderer/extensions/extensions.gni")
@@ -57,19 +58,46 @@
 }
 
 group("make_chromeos_generated") {
-  public_deps = [ ":make_chromeos_generated_event_target_names" ]
+  public_deps = [
+    ":make_chromeos_generated_event_names",
+    ":make_chromeos_generated_event_target_names",
+    ":make_chromeos_generated_event_type_names",
+  ]
 }
 
 blink_chromeos_extensions_output_dir = "$blink_extensions_output_dir/chromeos"
 
+# generate_event_interfaces ----------------------------------------------------
+generate_event_interfaces("chromeos_event_interfaces") {
+  sources = [ "system_extensions/window_management/cros_accelerator_event.idl" ]
+
+  output_file = "extensions/chromeos/event_interface_chromeos_names.json5"
+  suffix = "ChromeOS"
+  export_macro = "EXTENSIONS_CHROMEOS_EXPORT"
+}
+
 # make_names -------------------------------------------------------------------
 make_names("make_chromeos_generated_event_target_names") {
   in_files = [ "event_target_chromeos_names.json5" ]
   output_dir = blink_chromeos_extensions_output_dir
 }
 
+make_names("make_chromeos_generated_event_names") {
+  in_files = [ "$blink_chromeos_extensions_output_dir/event_interface_chromeos_names.json5" ]
+  output_dir = blink_chromeos_extensions_output_dir
+  deps = make_core_generated_deps + [ ":chromeos_event_interfaces" ]
+}
+
+make_names("make_chromeos_generated_event_type_names") {
+  in_files = [ "event_type_chromeos_names.json5" ]
+  output_dir = blink_chromeos_extensions_output_dir
+}
+
 blink_extensions_chromeos_sources("chromeos_events") {
-  sources = [ "event_target_chromeos.h" ]
+  sources = [
+    "event_chromeos.h",
+    "event_target_chromeos.h",
+  ]
   public_deps = [ ":chromeos_generated" ]
 }
 
@@ -77,7 +105,11 @@
   # Targets from above that generate outputs that need to be compiled.
   # All sources declared as outputs from these targets will be compiled
   # into one target.
-  targets_generating_sources = [ ":make_chromeos_generated_event_target_names" ]
+  targets_generating_sources = [
+    ":make_chromeos_generated_event_names",
+    ":make_chromeos_generated_event_target_names",
+    ":make_chromeos_generated_event_type_names",
+  ]
 
   sources = []
   foreach(current, targets_generating_sources) {
diff --git a/third_party/blink/renderer/extensions/chromeos/chromeos.idl b/third_party/blink/renderer/extensions/chromeos/chromeos.idl
index 367a2f0..30cf43a7 100644
--- a/third_party/blink/renderer/extensions/chromeos/chromeos.idl
+++ b/third_party/blink/renderer/extensions/chromeos/chromeos.idl
@@ -2,7 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-interface ChromeOS {
+[
+    // Use `Global` to be able to expose other interfaces to ChromeOS. This is
+    // not the intended use of Global.
+    // TODO(yukishiino): Replace with a more appropriate extended attribute.
+    Global=ChromeOSExtensions
+] interface ChromeOS {
   [RuntimeEnabled=BlinkExtensionChromeOSWindowManagement,CallWith=ExecutionContext]
   readonly attribute CrosWindowManagement windowManagement;
   [RuntimeEnabled=BlinkExtensionChromeOSHID,CallWith=ExecutionContext]
diff --git a/third_party/blink/renderer/extensions/chromeos/chromeos_extensions.cc b/third_party/blink/renderer/extensions/chromeos/chromeos_extensions.cc
index 8957af2..b907c269 100644
--- a/third_party/blink/renderer/extensions/chromeos/chromeos_extensions.cc
+++ b/third_party/blink/renderer/extensions/chromeos/chromeos_extensions.cc
@@ -8,7 +8,9 @@
 #include "third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_chrome_os.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/extensions/chromeos/chromeos.h"
+#include "third_party/blink/renderer/extensions/chromeos/event_interface_chromeos_names.h"
 #include "third_party/blink/renderer/extensions/chromeos/event_target_chromeos_names.h"
+#include "third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.h"
 #include "third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_management.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/extensions_registry.h"
@@ -53,11 +55,15 @@
   // Static strings need to be initialized here, before
   // CoreInitializer::Initialize().
   const unsigned kChromeOSStaticStringsCount =
-      event_target_names::kChromeOSNamesCount;
+      event_target_names::kChromeOSNamesCount +
+      event_type_names::kChromeOSNamesCount +
+      event_interface_names::kChromeOSNamesCount;
   StringImpl::ReserveStaticStringsCapacityForSize(
       kChromeOSStaticStringsCount + StringImpl::AllStaticStrings().size());
 
   event_target_names::InitChromeOS();
+  event_type_names::InitChromeOS();
+  event_interface_names::InitChromeOS();
 }
 
 void ChromeOSExtensions::InitServiceWorkerGlobalScope(
diff --git a/third_party/blink/renderer/extensions/chromeos/event_chromeos.h b/third_party/blink/renderer/extensions/chromeos/event_chromeos.h
new file mode 100644
index 0000000..c6cf5d4
--- /dev/null
+++ b/third_party/blink/renderer/extensions/chromeos/event_chromeos.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_EVENT_CHROMEOS_H_
+#define THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_EVENT_CHROMEOS_H_
+
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/extensions/chromeos/event_interface_chromeos_names.h"
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_EVENT_CHROMEOS_H_
diff --git a/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5 b/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5
new file mode 100644
index 0000000..c9a65f95
--- /dev/null
+++ b/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5
@@ -0,0 +1,10 @@
+{
+  metadata: {
+    namespace: "event_type_names",
+    suffix: "ChromeOS",
+  },
+
+  data: [
+    "acceleratordown",
+  ]
+}
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn
index 35acf1c..8fd4493 100644
--- a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn
+++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn
@@ -6,6 +6,8 @@
 
 blink_extensions_chromeos_sources("window_management") {
   sources = [
+    "cros_accelerator_event.cc",
+    "cros_accelerator_event.h",
     "cros_window.cc",
     "cros_window.h",
     "cros_window_management.cc",
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.cc b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.cc
new file mode 100644
index 0000000..0b4443f
--- /dev/null
+++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.cc
@@ -0,0 +1,32 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.h"
+
+#include "third_party/blink/renderer/extensions/chromeos/event_chromeos.h"
+#include "third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.h"
+
+namespace blink {
+
+CrosAcceleratorEvent* CrosAcceleratorEvent::Create() {
+  return MakeGarbageCollected<CrosAcceleratorEvent>();
+}
+
+// TODO(b/221123297): Support both `acceleratordown` and `acceleratorup`.
+CrosAcceleratorEvent::CrosAcceleratorEvent()
+    : Event(event_type_names::kAcceleratordown,
+            Bubbles::kYes,
+            Cancelable::kNo) {}
+
+CrosAcceleratorEvent::~CrosAcceleratorEvent() = default;
+
+void CrosAcceleratorEvent::Trace(Visitor* visitor) const {
+  Event::Trace(visitor);
+}
+
+const AtomicString& CrosAcceleratorEvent::InterfaceName() const {
+  return event_interface_names::kCrosAcceleratorEvent;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.h b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.h
new file mode 100644
index 0000000..6c7254c
--- /dev/null
+++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.h
@@ -0,0 +1,28 @@
+// 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_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_ACCELERATOR_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_ACCELERATOR_EVENT_H_
+
+#include "third_party/blink/renderer/core/dom/events/event.h"
+
+namespace blink {
+
+class CrosAcceleratorEvent final : public Event {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static CrosAcceleratorEvent* Create();
+
+  CrosAcceleratorEvent();
+  ~CrosAcceleratorEvent() override;
+
+  void Trace(Visitor*) const override;
+
+  const AtomicString& InterfaceName() const override;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_ACCELERATOR_EVENT_H_
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.idl b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.idl
new file mode 100644
index 0000000..912d1b1
--- /dev/null
+++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// Fired when an accelerator is pressed and released.
+// TODO(b/221123297): Add remaining attributes and change the constructor
+// to take a Init dictionary.
+[
+    RuntimeEnabled=BlinkExtensionChromeOSWindowManagement,
+    Exposed=ChromeOSExtensions
+] interface CrosAcceleratorEvent : Event {
+   constructor();
+};
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index b9a4256..33ea700 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2500,9 +2500,9 @@
   if (!EqualIgnoringASCIICase(type, "color"))
     return AXObject::ColorValue();
 
-  // HTMLInputElement::value always returns a string parseable by Color.
+  // HTMLInputElement::Value always returns a string parseable by Color.
   Color color;
-  bool success = color.SetFromString(input->value());
+  bool success = color.SetFromString(input->Value());
   DCHECK(success);
   return color.Rgb();
 }
@@ -2979,7 +2979,7 @@
         input->type() != input_type_names::kRadio &&
         input->type() != input_type_names::kReset &&
         input->type() != input_type_names::kSubmit) {
-      return input->value();
+      return input->Value();
     }
   }
 
@@ -3180,14 +3180,14 @@
 
   auto* html_input_element = DynamicTo<HTMLInputElement>(*GetNode());
   if (html_input_element && layout_object->IsTextFieldIncludingNG()) {
-    html_input_element->setValue(
+    html_input_element->SetValue(
         string, TextFieldEventBehavior::kDispatchInputAndChangeEvent);
     return true;
   }
 
   if (auto* text_area_element = DynamicTo<HTMLTextAreaElement>(*GetNode())) {
     DCHECK(layout_object->IsTextAreaIncludingNG());
-    text_area_element->setValue(
+    text_area_element->SetValue(
         string, TextFieldEventBehavior::kDispatchInputAndChangeEvent);
     return true;
   }
@@ -4907,7 +4907,7 @@
       name_sources->push_back(NameSource(*found_text_alternative, kValueAttr));
       name_sources->back().type = name_from;
     }
-    String value = input_element->value();
+    String value = input_element->Value();
     if (!value.IsNull()) {
       text_alternative = value;
       if (name_sources) {
@@ -4973,7 +4973,7 @@
       name_sources->back().type = name_from;
     }
     name_from = ax::mojom::blink::NameFrom::kAttribute;
-    String value = input_element->value();
+    String value = input_element->Value();
     if (!value.IsNull()) {
       text_alternative = value;
       if (name_sources) {
@@ -5053,7 +5053,7 @@
     name_from = ax::mojom::blink::NameFrom::kValue;
 
     String displayed_file_path = GetValueForControl();
-    String upload_button_text = input_element->UploadButton()->value();
+    String upload_button_text = input_element->UploadButton()->Value();
     if (!displayed_file_path.IsEmpty()) {
       text_alternative = displayed_file_path + ", " + upload_button_text;
     } else {
@@ -5474,7 +5474,7 @@
           DescriptionSource(found_description, kValueAttr));
       description_sources->back().type = description_from;
     }
-    String value = input_element->value();
+    String value = input_element->Value();
     if (!value.IsNull()) {
       description = value;
       if (description_sources) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
index 12a90d8..5884765b 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
@@ -1258,7 +1258,7 @@
   ASSERT_TRUE(IsTextControl(input));
   TextControlElement& text_control = ToTextControl(*input);
   // The "value" attribute should not contain the extra spaces.
-  ASSERT_EQ(valid_email.length(), text_control.value().length());
+  ASSERT_EQ(valid_email.length(), text_control.Value().length());
 
   const AXObject* ax_input = GetAXObjectByElementId("input");
   ASSERT_NE(nullptr, ax_input);
@@ -1507,13 +1507,13 @@
   ASSERT_NE(nullptr, textarea);
   ASSERT_TRUE(IsTextControl(textarea));
   TextControlElement& text_control = ToTextControl(*textarea);
-  ASSERT_LE(1u, text_control.value().length());
+  ASSERT_LE(1u, text_control.Value().length());
 
   const AXObject* ax_textarea = GetAXObjectByElementId("textarea");
   ASSERT_NE(nullptr, ax_textarea);
   ASSERT_EQ(ax::mojom::Role::kTextField, ax_textarea->RoleValue());
 
-  for (unsigned int i = 0; i < text_control.value().length() - 1; ++i) {
+  for (unsigned int i = 0; i < text_control.Value().length() - 1; ++i) {
     AXSelection::Builder builder;
     AXSelection ax_selection =
         builder.SetBase(AXPosition::CreatePositionInTextObject(*ax_textarea, i))
@@ -1523,7 +1523,7 @@
 
     testing::Message message;
     message << "While selecting forward character "
-            << static_cast<char>(text_control.value()[i]) << " at position "
+            << static_cast<char>(text_control.Value()[i]) << " at position "
             << i << " in textarea.";
     SCOPED_TRACE(message);
     EXPECT_TRUE(ax_selection.Select());
@@ -1533,7 +1533,7 @@
     EXPECT_EQ("forward", text_control.selectionDirection());
   }
 
-  for (unsigned int i = text_control.value().length(); i > 0; --i) {
+  for (unsigned int i = text_control.Value().length(); i > 0; --i) {
     AXSelection::Builder builder;
     AXSelection ax_selection =
         builder.SetBase(AXPosition::CreatePositionInTextObject(*ax_textarea, i))
@@ -1543,7 +1543,7 @@
 
     testing::Message message;
     message << "While selecting backward character "
-            << static_cast<char>(text_control.value()[i]) << " at position "
+            << static_cast<char>(text_control.Value()[i]) << " at position "
             << i << " in textarea.";
     SCOPED_TRACE(message);
     EXPECT_TRUE(ax_selection.Select());
diff --git a/third_party/blink/renderer/modules/accessibility/ax_slider.cc b/third_party/blink/renderer/modules/accessibility/ax_slider.cc
index a70e8d3..a4f9e4a 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_slider.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_slider.cc
@@ -73,10 +73,10 @@
 bool AXSlider::OnNativeSetValueAction(const String& value) {
   HTMLInputElement* input = GetInputElement();
 
-  if (input->value() == value)
+  if (input->Value() == value)
     return false;
 
-  input->setValue(value, TextFieldEventBehavior::kDispatchInputAndChangeEvent);
+  input->SetValue(value, TextFieldEventBehavior::kDispatchInputAndChangeEvent);
 
   // Fire change event manually, as SliderThumbElement::StopDragging does.
   input->DispatchFormControlChangeEvent();
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
index e1a558f9..84836e44 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
@@ -94,7 +94,7 @@
   }
 
   MaybeUpdateTimelineInterval();
-  setValue(String::Number(current_time));
+  SetValue(String::Number(current_time));
 
   if (!suppress_aria)
     UpdateAria();
@@ -157,7 +157,7 @@
     return;
   }
 
-  double time = value().ToDouble();
+  double time = Value().ToDouble();
   double duration = MediaElement().duration();
   // Workaround for floating point error - it's possible for this element's max
   // attribute to be rounded to a value slightly higher than the duration. If
@@ -244,7 +244,7 @@
   // value since timeline's minimum value is not necessarily zero.
   if (is_live_) {
     current_time =
-        value().ToDouble() - GetFloatingPointAttribute(html_names::kMinAttr);
+        Value().ToDouble() - GetFloatingPointAttribute(html_names::kMinAttr);
     duration = GetFloatingPointAttribute(html_names::kMaxAttr) -
                GetFloatingPointAttribute(html_names::kMinAttr);
   }
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
index 443d6e95..7fb96da 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
@@ -95,10 +95,10 @@
 }
 
 void MediaControlVolumeSliderElement::SetVolume(double volume) {
-  if (value().ToDouble() == volume)
+  if (Value().ToDouble() == volume)
     return;
 
-  setValue(String::Number(volume));
+  SetValue(String::Number(volume));
   SetVolumeInternal(volume);
 }
 
@@ -157,7 +157,7 @@
   }
 
   if (event.type() == event_type_names::kInput)
-    UnmuteAndSetVolume(value().ToDouble());
+    UnmuteAndSetVolume(Value().ToDouble());
 
   if (event.type() == event_type_names::kFocus)
     GetMediaControls().OpenVolumeSliderIfNecessary();
@@ -181,7 +181,7 @@
 }
 
 void MediaControlVolumeSliderElement::OnWheelEvent(WheelEvent* wheel_event) {
-  double current_volume = value().ToDouble();
+  double current_volume = Value().ToDouble();
   double new_volume = (wheel_event->wheelDelta() > 0)
                           ? current_volume + kScrollVolumeDelta
                           : current_volume - kScrollVolumeDelta;
diff --git a/third_party/blink/renderer/modules/mediastream/DEPS b/third_party/blink/renderer/modules/mediastream/DEPS
index 2476259a..35cbf47 100644
--- a/third_party/blink/renderer/modules/mediastream/DEPS
+++ b/third_party/blink/renderer/modules/mediastream/DEPS
@@ -59,6 +59,7 @@
         "+base/containers/circular_deque.h",
         "+base/run_loop.h",
         "+cc/layers/layer.h",
+        "+media/video/fake_gpu_memory_buffer.h",
         "+media/video/mock_gpu_memory_buffer_video_frame_pool.h",
         "+media/video/mock_gpu_video_accelerator_factories.h",
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc b/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
index 0ebd41d..442d9d0 100644
--- a/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
@@ -96,7 +96,6 @@
 const char kMediaStreamRenderToAssociatedSink[] =
     "chromeRenderToAssociatedSink";
 // RenderToAssociatedSink will be going away some time.
-const char kMediaStreamAudioHotword[] = "googHotword";
 const char kEchoCancellation[] = "echoCancellation";
 const char kDisableLocalEcho[] = "disableLocalEcho";
 const char kGoogEchoCancellation[] = "googEchoCancellation";
@@ -105,10 +104,7 @@
 const char kGoogExperimentalAutoGainControl[] = "googAutoGainControl2";
 const char kGoogNoiseSuppression[] = "googNoiseSuppression";
 const char kGoogExperimentalNoiseSuppression[] = "googNoiseSuppression2";
-const char kGoogBeamforming[] = "googBeamforming";
-const char kGoogArrayGeometry[] = "googArrayGeometry";
 const char kGoogHighpassFilter[] = "googHighpassFilter";
-const char kGoogTypingNoiseDetection[] = "googTypingNoiseDetection";
 const char kGoogAudioMirroring[] = "googAudioMirroring";
 // Audio constraints.
 const char kDAEchoCancellation[] = "googDAEchoCancellation";
@@ -117,37 +113,13 @@
 
 // Legacy RTCPeerConnection constructor constraints.
 
-// DtlsSrtpKeyAgreement and RtpDataChannels are already ignored, except when
-// building Fuchsia.
+// DtlsSrtpKeyAgreement is already ignored, except when building Fuchsia.
 // TODO(crbug.com/804275): Ignore on all platforms when Fuchsia dependency is
 // gone to unblock mediaConstraints removal.
 const char kEnableDtlsSrtp[] = "DtlsSrtpKeyAgreement";
-const char kEnableRtpDataChannels[] = "RtpDataChannels";
 // TODO(https://crbug.com/1315576): Deprecate and ignore.
 const char kEnableIPv6[] = "googIPv6";
-// Legacy goog-constraints that are already ignored.
-const char kNumUnsignalledRecvStreams[] = "googNumUnsignalledRecvStreams";
-const char kCombinedAudioVideoBwe[] = "googCombinedAudioVideoBwe";
-const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold";
-const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold";
-const char kCpuUnderuseEncodeRsdThreshold[] =
-    "googCpuUnderuseEncodeRsdThreshold";
-const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold";
-const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage";
-const char kHighStartBitrate[] = "googHighStartBitrate";
-const char kPayloadPadding[] = "googPayloadPadding";
-const char kAudioLatency[] = "latencyMs";
-const char kUseRtpMux[] = "googUseRtpMUX";
-const char kEnableDscp[] = "googDscp";
-const char kScreencastMinBitrate[] = "googScreencastMinBitrate";
-const char kEnableVideoSuspendBelowMinBitrate[] = "googSuspendBelowMinBitrate";
-const char kCpuOveruseDetection[] = "googCpuOveruseDetection";
 
-// Names that have been used in the past, but should now be ignored.
-// Kept around for backwards compatibility.
-// https://crbug.com/579729
-const char kGoogLeakyBucket[] = "googLeakyBucket";
-const char kPowerLineFrequency[] = "googPowerLineFrequency";
 // Names used for testing.
 const char kTestConstraint1[] = "valid_and_supported_1";
 const char kTestConstraint2[] = "valid_and_supported_2";
@@ -276,7 +248,6 @@
 static void ParseOldStyleNames(
     ExecutionContext* context,
     const Vector<NameValueStringConstraint>& old_names,
-    bool report_unknown_names,
     MediaTrackConstraintSetPlatform& result,
     MediaErrorState& error_state) {
   if (old_names.size() > 0) {
@@ -354,21 +325,7 @@
       // Special dispensation for Fuchsia to run SDES in 2022
       // TODO(crbug.com/804275): Delete when Fuchsia no longer depends on it.
       result.enable_dtls_srtp.SetExact(ToBoolean(constraint.value_));
-#else
-      UseCounter::Count(context, WebFeature::kOldConstraintIgnored);
 #endif
-    } else if (constraint.name_.Equals(kEnableRtpDataChannels)) {
-      // This constraint does not turn on RTP data channels, but we do not
-      // want it to cause an error, so we parse it and ignore it.
-      bool value = ToBoolean(constraint.value_);
-      if (value) {
-        Deprecation::CountDeprecation(
-            context, WebFeature::kRTCConstraintEnableRtpDataChannelsTrue);
-      } else {
-        Deprecation::CountDeprecation(
-            context, WebFeature::kRTCConstraintEnableRtpDataChannelsFalse);
-      }
-      UseCounter::Count(context, WebFeature::kOldConstraintIgnored);
     } else if (constraint.name_.Equals(kEnableIPv6)) {
       result.enable_i_pv6.SetExact(ToBoolean(constraint.value_));
       // Count deprecated usage of googIPv6, when it is set to false. Setting it
@@ -378,35 +335,6 @@
         Deprecation::CountDeprecation(context,
                                       WebFeature::kLegacyConstraintGoogIPv6);
       }
-    } else if (constraint.name_.Equals(kCpuUnderuseThreshold) ||
-               constraint.name_.Equals(kCpuOveruseThreshold) ||
-               constraint.name_.Equals(kCpuUnderuseEncodeRsdThreshold) ||
-               constraint.name_.Equals(kCpuOveruseEncodeRsdThreshold) ||
-               constraint.name_.Equals(kCpuOveruseEncodeUsage) ||
-               constraint.name_.Equals(kGoogLeakyBucket) ||
-               constraint.name_.Equals(kGoogBeamforming) ||
-               constraint.name_.Equals(kGoogArrayGeometry) ||
-               constraint.name_.Equals(kPowerLineFrequency) ||
-               constraint.name_.Equals(kMediaStreamAudioHotword) ||
-               constraint.name_.Equals(kGoogTypingNoiseDetection) ||
-               constraint.name_.Equals(kNumUnsignalledRecvStreams) ||
-               constraint.name_.Equals(kCombinedAudioVideoBwe) ||
-               constraint.name_.Equals(kHighStartBitrate) ||
-               constraint.name_.Equals(kAudioLatency) ||
-               constraint.name_.Equals(kUseRtpMux) ||
-               constraint.name_.Equals(kPayloadPadding) ||
-               constraint.name_.Equals(kEnableDscp) ||
-               constraint.name_.Equals(kScreencastMinBitrate) ||
-               constraint.name_.Equals(kEnableVideoSuspendBelowMinBitrate) ||
-               constraint.name_.Equals(kCpuOveruseDetection)) {
-      // TODO(crbug.com/856176): Remove the kGoogBeamforming and
-      // kGoogArrayGeometry special cases.
-      context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-          mojom::ConsoleMessageSource::kDeprecation,
-          mojom::ConsoleMessageLevel::kWarning,
-          "Obsolete constraint named " + String(constraint.name_) +
-              " is ignored. Please stop using it."));
-      UseCounter::Count(context, WebFeature::kOldConstraintIgnored);
     } else if (constraint.name_.Equals(kTestConstraint1) ||
                constraint.name_.Equals(kTestConstraint2)) {
       // These constraints are only for testing parsing.
@@ -415,20 +343,8 @@
         error_state.ThrowConstraintError("Illegal value for constraint",
                                          constraint.name_);
       }
-    } else {
-      if (report_unknown_names) {
-        UseCounter::Count(context, WebFeature::kOldConstraintRejected);
-        context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-            mojom::ConsoleMessageSource::kDeprecation,
-            mojom::ConsoleMessageLevel::kWarning,
-            "Unknown constraint named " + String(constraint.name_) +
-                " rejected"));
-        error_state.ThrowConstraintError("Unknown name of constraint detected",
-                                         constraint.name_);
-      } else {
-        UseCounter::Count(context, WebFeature::kOldConstraintNotReported);
-      }
     }
+    // else: Nothing. Unrecognized constraints are simply ignored.
   }
 }
 
@@ -440,7 +356,7 @@
   MediaTrackConstraintSetPlatform basic;
   MediaTrackConstraintSetPlatform advanced;
   MediaConstraints constraints;
-  ParseOldStyleNames(context, mandatory, true, basic, error_state);
+  ParseOldStyleNames(context, mandatory, basic, error_state);
   if (error_state.HadException())
     return constraints;
   // We ignore unknow names and syntax errors in optional constraints.
@@ -449,7 +365,7 @@
   for (const auto& optional_constraint : optional) {
     MediaTrackConstraintSetPlatform advanced_element;
     Vector<NameValueStringConstraint> element_as_list(1, optional_constraint);
-    ParseOldStyleNames(context, element_as_list, false, advanced_element,
+    ParseOldStyleNames(context, element_as_list, advanced_element,
                        ignored_error_state);
     if (!advanced_element.IsUnconstrained())
       advanced_vector.push_back(advanced_element);
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index ab6e4e35..efe69f0 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -583,6 +583,21 @@
   return rendering_frame_buffer_->average_frame_duration();
 }
 
+void WebMediaPlayerMSCompositor::OnContextLost() {
+  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+  // current_frame_'s resource in the context has been lost, so current_frame_
+  // is not valid any more. current_frame_ should be reset. Now the compositor
+  // has no concept of resetting current_frame_, so a black frame is set.
+  base::AutoLock auto_lock(current_frame_lock_);
+  if (!current_frame_ || (!current_frame_->HasTextures() &&
+                          !current_frame_->HasGpuMemoryBuffer())) {
+    return;
+  }
+  scoped_refptr<media::VideoFrame> black_frame =
+      media::VideoFrame::CreateBlackFrame(current_frame_->natural_size());
+  SetCurrentFrame(std::move(black_frame), false, absl::nullopt);
+}
+
 void WebMediaPlayerMSCompositor::StartRendering() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   {
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index d4facc1..603f9c5 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -113,6 +113,7 @@
   scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
   void PutCurrentFrame() override;
   base::TimeDelta GetPreferredRenderInterval() override;
+  void OnContextLost() override;
 
   void StartRendering();
   void StopRendering();
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
index bc9eecc..0b7231d5 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
@@ -20,6 +20,7 @@
 #include "media/base/media_util.h"
 #include "media/base/test_helpers.h"
 #include "media/base/video_frame.h"
+#include "media/video/fake_gpu_memory_buffer.h"
 #include "media/video/mock_gpu_memory_buffer_video_frame_pool.h"
 #include "media/video/mock_gpu_video_accelerator_factories.h"
 #include "third_party/blink/public/common/media/display_type.h"
@@ -1446,6 +1447,34 @@
   EXPECT_GE(compositor_->GetPreferredRenderInterval(), base::TimeDelta());
 }
 
+TEST_P(WebMediaPlayerMSTest, OnContextLost) {
+  InitializeWebMediaPlayerMS();
+  LoadAndGetFrameProvider(true);
+
+  gfx::Size frame_size(320, 240);
+  auto non_gpu_frame = media::VideoFrame::CreateZeroInitializedFrame(
+      media::PIXEL_FORMAT_I420, frame_size, gfx::Rect(frame_size), frame_size,
+      base::Seconds(10));
+  compositor_->EnqueueFrame(non_gpu_frame, true);
+  base::RunLoop().RunUntilIdle();
+  // frame without gpu resource should be remained even though context is lost
+  compositor_->OnContextLost();
+  EXPECT_EQ(non_gpu_frame, compositor_->GetCurrentFrame());
+
+  std::unique_ptr<gfx::GpuMemoryBuffer> gmb =
+      std::make_unique<media::FakeGpuMemoryBuffer>(
+          frame_size, gfx::BufferFormat::YUV_420_BIPLANAR);
+  gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes];
+  auto gpu_frame = media::VideoFrame::WrapExternalGpuMemoryBuffer(
+      gfx::Rect(frame_size), frame_size, std::move(gmb), mailbox_holders,
+      base::DoNothing(), base::TimeDelta());
+  compositor_->EnqueueFrame(gpu_frame, true);
+  base::RunLoop().RunUntilIdle();
+  // frame with gpu resource should be reset if context is lost
+  compositor_->OnContextLost();
+  EXPECT_NE(gpu_frame, compositor_->GetCurrentFrame());
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          WebMediaPlayerMSTest,
                          ::testing::Combine(::testing::Bool(),
diff --git a/third_party/blink/renderer/modules/webaudio/audio_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_handler.cc
index adab44e..a48430a1 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_handler.cc
@@ -22,16 +22,9 @@
 AudioHandler::AudioHandler(NodeType node_type,
                            AudioNode& node,
                            float sample_rate)
-    : last_processing_time_(-1),
-      last_non_silent_time_(0),
-      is_initialized_(false),
-      node_type_(kNodeTypeUnknown),
-      node_(&node),
+    : node_(&node),
       context_(node.context()),
-      deferred_task_handler_(&context_->GetDeferredTaskHandler()),
-      connection_ref_count_(0),
-      is_disabled_(false),
-      channel_count_(2) {
+      deferred_task_handler_(&context_->GetDeferredTaskHandler()) {
   SetNodeType(node_type);
   SetInternalChannelCountMode(kMax);
   SetInternalChannelInterpretation(AudioBus::kSpeakers);
diff --git a/third_party/blink/renderer/modules/webaudio/audio_handler.h b/third_party/blink/renderer/modules/webaudio/audio_handler.h
index 8700ae9a..bd8fb71 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_handler.h
@@ -219,18 +219,18 @@
   // The last time (context time) that his handler ran its Process() method.
   // For each render quantum, we only want to process just once to handle fanout
   // of this handler.
-  double last_processing_time_;
+  double last_processing_time_ = -1;
 
   // The last time (context time) when this node did not have silent inputs.
-  double last_non_silent_time_;
+  double last_non_silent_time_ = 0;
 
  private:
   void SetNodeType(NodeType);
 
   void SendLogMessage(const String& message);
 
-  bool is_initialized_;
-  NodeType node_type_;
+  bool is_initialized_ = false;
+  NodeType node_type_ = kNodeTypeUnknown;
 
   // The owner AudioNode. Accessed only on the main thread.
   const WeakPersistent<AudioNode> node_;
@@ -248,9 +248,9 @@
   Vector<std::unique_ptr<AudioNodeInput>> inputs_;
   Vector<std::unique_ptr<AudioNodeOutput>> outputs_;
 
-  int connection_ref_count_;
+  int connection_ref_count_ = 0;
 
-  bool is_disabled_;
+  bool is_disabled_ = false;
 
   // Used to trigger one single textlog indicating that processing started as
   // intended. Set to true once in the first call to the ProcessIfNecessary
@@ -272,7 +272,7 @@
   void SetInternalChannelCountMode(ChannelCountMode);
   void SetInternalChannelInterpretation(AudioBus::ChannelInterpretation);
 
-  unsigned channel_count_;
+  unsigned channel_count_ = 2;
   // The new channel count mode that will be used to set the actual mode in the
   // pre or post rendering phase.
   ChannelCountMode new_channel_count_mode_;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
index 921ebf3..7aefa197 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_listener.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
@@ -101,8 +101,6 @@
                              0.0,
                              AudioParamHandler::AutomationRate::kAudio,
                              AudioParamHandler::AutomationRateMode::kVariable)),
-      last_update_time_(-1),
-      is_listener_dirty_(false),
       position_x_values_(
           context.GetDeferredTaskHandler().RenderQuantumFrames()),
       position_y_values_(
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.h b/third_party/blink/renderer/modules/webaudio/audio_listener.h
index 1cbdf89..d89010b 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_listener.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_listener.h
@@ -167,12 +167,12 @@
   gfx::Vector3dF last_up_;
 
   // Last time that the automations were updated.
-  double last_update_time_;
+  double last_update_time_ = -1;
 
   // Set every rendering quantum if the listener has moved in any way
   // (position, forward, or up).  This should only be read or written to from
   // the audio thread.
-  bool is_listener_dirty_;
+  bool is_listener_dirty_ = false;
 
   void UpdateValuesIfNeeded(uint32_t frames_to_process);
 
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_output.cc b/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
index 7a17b070..b44a648 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
@@ -39,12 +39,7 @@
                                  unsigned number_of_channels)
     : handler_(*handler),
       number_of_channels_(number_of_channels),
-      desired_number_of_channels_(number_of_channels),
-      is_in_place_(false),
-      is_enabled_(true),
-      did_call_dispose_(false),
-      rendering_fan_out_count_(0),
-      rendering_param_fan_out_count_(0) {
+      desired_number_of_channels_(number_of_channels) {
   DCHECK_LE(number_of_channels, BaseAudioContext::MaxNumberOfChannels());
 
   internal_bus_ = AudioBus::Create(
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_output.h b/third_party/blink/renderer/modules/webaudio/audio_node_output.h
index c8387759..5256097 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_node_output.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_node_output.h
@@ -143,22 +143,22 @@
   scoped_refptr<AudioBus> in_place_bus_;
   // If m_isInPlace is true, use m_inPlaceBus as the valid AudioBus; If false,
   // use the default m_internalBus.
-  bool is_in_place_;
+  bool is_in_place_ = false;
 
   // This HashSet holds connection references. We must call
   // AudioNode::makeConnection when we add an AudioNodeInput to this, and must
   // call AudioNode::breakConnection() when we remove an AudioNodeInput from
   // this.
   HashSet<AudioNodeInput*> inputs_;
-  bool is_enabled_;
+  bool is_enabled_ = true;
 
-  bool did_call_dispose_;
+  bool did_call_dispose_ = false;
 
   // For the purposes of rendering, keeps track of the number of inputs and
   // AudioParams we're connected to.  These value should only be changed at the
   // very start or end of the rendering quantum.
-  unsigned rendering_fan_out_count_;
-  unsigned rendering_param_fan_out_count_;
+  unsigned rendering_fan_out_count_ = 0;
+  unsigned rendering_param_fan_out_count_ = 0;
 
   // This collection of raw pointers is safe because they are retained by
   // AudioParam objects retained by m_connectedParams of the owner AudioNode.
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc
index 1337e19..d2846df 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc
@@ -26,7 +26,6 @@
                                                          AudioNode& node,
                                                          float sample_rate)
     : AudioHandler(node_type, node, sample_rate),
-      start_time_(0),
       end_time_(kUnknownTime),
       playback_state_(UNSCHEDULED_STATE) {
   if (Context()->GetExecutionContext()) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h
index d96a345..0056456b 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h
@@ -122,7 +122,7 @@
 
   // m_startTime is the time to start playing based on the context's timeline (0
   // or a time less than the context's current time means "now").
-  double start_time_;  // in seconds
+  double start_time_ = 0;  // in seconds
 
   // m_endTime is the time to stop playing based on the context's timeline (0 or
   // a time less than the context's current time means "now").  If it hasn't
diff --git a/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc b/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
index 83a58f42..01accbb 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
@@ -30,7 +30,7 @@
 namespace blink {
 
 AudioSummingJunction::AudioSummingJunction(DeferredTaskHandler& handler)
-    : deferred_task_handler_(&handler), rendering_state_need_updating_(false) {}
+    : deferred_task_handler_(&handler) {}
 
 AudioSummingJunction::~AudioSummingJunction() {
   GetDeferredTaskHandler().AssertGraphOwner();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_summing_junction.h b/third_party/blink/renderer/modules/webaudio/audio_summing_junction.h
index 37353c1..5fd7beb 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_summing_junction.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_summing_junction.h
@@ -88,7 +88,7 @@
   Vector<AudioNodeOutput*> rendering_outputs_;
 
   // m_renderingStateNeedUpdating keeps track if m_outputs is modified.
-  bool rendering_state_need_updating_;
+  bool rendering_state_need_updating_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index 443c29ab..df9f219d 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -92,13 +92,9 @@
       InspectorHelperMixin(*AudioGraphTracer::FromDocument(*document),
                            String()),
       destination_node_(nullptr),
-      is_resolving_resume_promises_(false),
       task_runner_(document->GetTaskRunner(TaskType::kInternalMedia)),
-      is_cleared_(false),
-      has_posted_cleanup_task_(false),
       deferred_task_handler_(DeferredTaskHandler::Create(
           document->GetTaskRunner(TaskType::kInternalMedia))),
-      context_state_(kSuspended),
       periodic_wave_sine_(nullptr),
       periodic_wave_square_(nullptr),
       periodic_wave_sawtooth_(nullptr),
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
index 158a79c8..6b418c39 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -383,12 +383,12 @@
   // True if we're in the process of resolving promises for resume().  Resolving
   // can take some time and the audio context process loop is very fast, so we
   // don't want to call resolve an excessive number of times.
-  bool is_resolving_resume_promises_;
+  bool is_resolving_resume_promises_ = false;
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
  private:
-  bool is_cleared_;
+  bool is_cleared_ = false;
   void Clear();
 
   // When the context goes away, there might still be some sources which
@@ -401,13 +401,13 @@
   // Set to |true| by the audio thread when it posts a main-thread task to
   // perform delayed state sync'ing updates that needs to be done on the main
   // thread. Cleared by the main thread task once it has run.
-  bool has_posted_cleanup_task_;
+  bool has_posted_cleanup_task_ = false;
 
   // Graph locking.
   scoped_refptr<DeferredTaskHandler> deferred_task_handler_;
 
   // The state of the BaseAudioContext.
-  AudioContextState context_state_;
+  AudioContextState context_state_ = kSuspended;
 
   AsyncAudioDecoder audio_decoder_;
 
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_processor.cc b/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
index 134562f..85f6c976 100644
--- a/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
+++ b/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
@@ -42,13 +42,10 @@
     : AudioDSPKernelProcessor(sample_rate,
                               number_of_channels,
                               render_quantum_frames),
-      type_(FilterType::kLowPass),
       parameter1_(&frequency),
       parameter2_(&q),
       parameter3_(&gain),
-      parameter4_(&detune),
-      filter_coefficients_dirty_(true),
-      has_sample_accurate_values_(false) {}
+      parameter4_(&detune) {}
 
 BiquadProcessor::~BiquadProcessor() {
   if (IsInitialized()) {
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_processor.h b/third_party/blink/renderer/modules/webaudio/biquad_processor.h
index f3efd89..8dec01f 100644
--- a/third_party/blink/renderer/modules/webaudio/biquad_processor.h
+++ b/third_party/blink/renderer/modules/webaudio/biquad_processor.h
@@ -94,7 +94,7 @@
   void SetType(FilterType);
 
  private:
-  FilterType type_;
+  FilterType type_ = FilterType::kLowPass;
 
   scoped_refptr<AudioParamHandler> parameter1_;
   scoped_refptr<AudioParamHandler> parameter2_;
@@ -102,10 +102,10 @@
   scoped_refptr<AudioParamHandler> parameter4_;
 
   // so DSP kernels know when to re-compute coefficients
-  bool filter_coefficients_dirty_;
+  bool filter_coefficients_dirty_ = true;
 
   // Set to true if any of the filter parameters are sample-accurate.
-  bool has_sample_accurate_values_;
+  bool has_sample_accurate_values_ = false;
 
   // Set to true if any of the filter parameters are a-rate.
   bool is_audio_rate_;
diff --git a/third_party/blink/renderer/modules/webaudio/convolver_handler.cc b/third_party/blink/renderer/modules/webaudio/convolver_handler.cc
index c0fb407..8ea1bdc 100644
--- a/third_party/blink/renderer/modules/webaudio/convolver_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/convolver_handler.cc
@@ -28,7 +28,7 @@
 namespace blink {
 
 ConvolverHandler::ConvolverHandler(AudioNode& node, float sample_rate)
-    : AudioHandler(kNodeTypeConvolver, node, sample_rate), normalize_(true) {
+    : AudioHandler(kNodeTypeConvolver, node, sample_rate) {
   AddInput();
   AddOutput(1);
 
diff --git a/third_party/blink/renderer/modules/webaudio/convolver_handler.h b/third_party/blink/renderer/modules/webaudio/convolver_handler.h
index 49974779f..b17f4fb 100644
--- a/third_party/blink/renderer/modules/webaudio/convolver_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/convolver_handler.h
@@ -61,7 +61,7 @@
   mutable Mutex process_lock_;
 
   // Normalize the impulse response or not. Must default to true.
-  bool normalize_;
+  bool normalize_ = true;
 
   FRIEND_TEST_ALL_PREFIXES(ConvolverNodeTest, ReverbLifetime);
 };
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
index 1981e1c..0926026 100644
--- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -295,9 +295,7 @@
 
 DeferredTaskHandler::DeferredTaskHandler(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : automatic_pull_handlers_need_updating_(false),
-      task_runner_(std::move(task_runner)),
-      audio_thread_(0) {}
+    : task_runner_(std::move(task_runner)), audio_thread_(0) {}
 
 scoped_refptr<DeferredTaskHandler> DeferredTaskHandler::Create(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
index 34dd488..81d0f7c 100644
--- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
@@ -228,7 +228,7 @@
   Vector<scoped_refptr<AudioHandler>> rendering_automatic_pull_handlers_;
 
   // Keeps track if the |automatic_pull_handlers| storage is touched.
-  bool automatic_pull_handlers_need_updating_;
+  bool automatic_pull_handlers_need_updating_ = false;
 
   // Number of frames to use when rendering the graph.  This is the frames to
   // process for each node.
diff --git a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc
index c98d12e..66367fd 100644
--- a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc
@@ -49,10 +49,7 @@
     : AudioHandler(kNodeTypeMediaElementAudioSource,
                    node,
                    node.context()->sampleRate()),
-      media_element_(media_element),
-      source_number_of_channels_(0),
-      source_sample_rate_(0),
-      is_origin_tainted_(false) {
+      media_element_(media_element) {
   DCHECK(IsMainThread());
   // Default to stereo. This could change depending on what the media element
   // .src is set to.
diff --git a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.h b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.h
index a693cc40..c83db2e8 100644
--- a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.h
@@ -81,8 +81,8 @@
   CrossThreadWeakPersistent<HTMLMediaElement> media_element_;
   Mutex process_lock_;
 
-  unsigned source_number_of_channels_;
-  double source_sample_rate_;
+  unsigned source_number_of_channels_ = 0;
+  double source_sample_rate_ = 0;
 
   std::unique_ptr<MediaMultiChannelResampler> multi_channel_resampler_;
 
@@ -92,7 +92,7 @@
   // this node outputs silence.  This can happen if the media element source is
   // a cross-origin source which we're not allowed to access due to CORS
   // restrictions.
-  bool is_origin_tainted_;
+  bool is_origin_tainted_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
index 5fae458..03e1426b 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -131,7 +131,6 @@
                                          float sample_rate,
                                          ExceptionState& exception_state)
     : BaseAudioContext(document, kOfflineContext),
-      is_rendering_started_(false),
       total_render_frames_(number_of_frames) {
   destination_node_ = OfflineAudioDestinationNode::Create(
       this, number_of_channels, number_of_frames, sample_rate);
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
index b2b138e1..ad8f5f07 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -137,7 +137,7 @@
   // running. Note that initial state of context is 'Suspended', which is the
   // same state when the context is suspended, so we cannot utilize it for this
   // purpose.
-  bool is_rendering_started_;
+  bool is_rendering_started_ = false;
 
   // Total render sample length.
   uint32_t total_render_frames_;
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.cc
index a35fb23..24446af 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.cc
@@ -29,9 +29,7 @@
     uint32_t frames_to_process,
     float sample_rate)
     : AudioDestinationHandler(node),
-      frames_processed_(0),
       frames_to_process_(frames_to_process),
-      is_rendering_started_(false),
       number_of_channels_(number_of_channels),
       sample_rate_(sample_rate),
       main_thread_task_runner_(Context()->GetExecutionContext()->GetTaskRunner(
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.h b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.h
index 1175ce3..21f6884 100644
--- a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_handler.h
@@ -119,13 +119,13 @@
 
   // These variables are for counting the number of frames for the current
   // progress and the remaining frames to be processed.
-  size_t frames_processed_;
+  size_t frames_processed_ = 0;
   uint32_t frames_to_process_;
 
   // This flag is necessary to distinguish the state of the context between
   // 'created' and 'suspended'. If this flag is false and the current state
   // is 'suspended', it means the context is created and have not started yet.
-  bool is_rendering_started_;
+  bool is_rendering_started_ = false;
 
   unsigned number_of_channels_;
   float sample_rate_;
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc b/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc
index 711713dc..58455c6 100644
--- a/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc
@@ -36,8 +36,6 @@
     : AudioScheduledSourceHandler(kNodeTypeOscillator, node, sample_rate),
       frequency_(&frequency),
       detune_(&detune),
-      first_render_(true),
-      virtual_read_index_(0),
       phase_increments_(GetDeferredTaskHandler().RenderQuantumFrames()),
       detune_values_(GetDeferredTaskHandler().RenderQuantumFrames()) {
   if (wave_table) {
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_handler.h b/third_party/blink/renderer/modules/webaudio/oscillator_handler.h
index fce06c67..d82cd1a 100644
--- a/third_party/blink/renderer/modules/webaudio/oscillator_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/oscillator_handler.h
@@ -162,12 +162,12 @@
   // Detune value (deviating from the frequency) in Cents.
   scoped_refptr<AudioParamHandler> detune_;
 
-  bool first_render_;
+  bool first_render_ = true;
 
   // m_virtualReadIndex is a sample-frame index into our buffer representing the
   // current playback position.  Since it's floating-point, it has sub-sample
   // accuracy.
-  double virtual_read_index_;
+  double virtual_read_index_ = 0;
 
   // Stores sample-accurate values calculated according to frequency and detune.
   AudioFloatArray phase_increments_;
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
index 407e0f6..2f7f86f6b 100644
--- a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
+++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
@@ -161,9 +161,7 @@
 }
 
 PeriodicWaveImpl::PeriodicWaveImpl(float sample_rate)
-    : v8_external_memory_(0),
-      sample_rate_(sample_rate),
-      cents_per_range_(kCentsPerRange) {
+    : sample_rate_(sample_rate), cents_per_range_(kCentsPerRange) {
   float nyquist = 0.5 * sample_rate_;
   lowest_fundamental_frequency_ = nyquist / MaxNumberOfPartials();
   rate_scale_ = PeriodicWaveSize() / sample_rate_;
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.h b/third_party/blink/renderer/modules/webaudio/periodic_wave.h
index 19c59b7..5a5bbd9b 100644
--- a/third_party/blink/renderer/modules/webaudio/periodic_wave.h
+++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.h
@@ -123,7 +123,7 @@
  private:
   void GenerateBasicWaveform(int);
 
-  size_t v8_external_memory_;
+  size_t v8_external_memory_ = 0;
 
   float sample_rate_;
   unsigned number_of_ranges_;
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
index 26b8680..0ae569b 100644
--- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
+++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
@@ -53,8 +53,7 @@
       magnitude_buffer_(kDefaultFFTSize / 2),
       smoothing_time_constant_(kDefaultSmoothingTimeConstant),
       min_decibels_(kDefaultMinDecibels),
-      max_decibels_(kDefaultMaxDecibels),
-      last_analysis_time_(-1) {
+      max_decibels_(kDefaultMaxDecibels) {
   analysis_frame_ = std::make_unique<FFTFrame>(kDefaultFFTSize);
 }
 
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.h b/third_party/blink/renderer/modules/webaudio/realtime_analyser.h
index 0784f55..dc78c60 100644
--- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.h
+++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.h
@@ -116,7 +116,7 @@
   double max_decibels_;
 
   // Time at which the FFT was last computed.
-  double last_analysis_time_;
+  double last_analysis_time_ = -1;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
index 876d7f47..041cb1f 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
@@ -37,9 +37,7 @@
     const HeapVector<Member<AudioBuffer>>& input_buffers,
     const HeapVector<Member<AudioBuffer>>& output_buffers)
     : AudioHandler(kNodeTypeScriptProcessor, node, sample_rate),
-      double_buffer_index_(0),
       buffer_size_(buffer_size),
-      buffer_read_write_index_(0),
       number_of_input_channels_(number_of_input_channels),
       number_of_output_channels_(number_of_output_channels),
       internal_input_bus_(AudioBus::Create(
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
index b6b3b59..08fd4f8 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
@@ -75,7 +75,7 @@
   // Double buffering
   uint32_t DoubleBufferIndex() const { return double_buffer_index_; }
   void SwapBuffers() { double_buffer_index_ = 1 - double_buffer_index_; }
-  uint32_t double_buffer_index_;
+  uint32_t double_buffer_index_ = 0;
 
   // Protects |shared_input_buffers| and |shared_output_buffers_|.
   mutable Mutex buffer_lock_;
@@ -83,7 +83,7 @@
   WTF::Vector<std::unique_ptr<SharedAudioBuffer>> shared_output_buffers_;
 
   uint32_t buffer_size_;
-  uint32_t buffer_read_write_index_;
+  uint32_t buffer_read_write_index_ = 0;
   uint32_t number_of_input_channels_;
   uint32_t number_of_output_channels_;
 
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
index fe6feb5..5e84404 100644
--- a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
+++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
@@ -44,7 +44,6 @@
 
 WaveShaperDSPKernel::WaveShaperDSPKernel(WaveShaperProcessor* processor)
     : AudioDSPKernel(processor),
-      tail_time_(0),
       // 4 times render size to handle 4x oversampling.
       virtual_index_(4 * RenderQuantumFrames()),
       index_(4 * RenderQuantumFrames()),
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
index 1fc42c0..35addcbd 100644
--- a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
+++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
@@ -103,7 +103,7 @@
   // such that a zero input produces a non-zero output.  In this case, the node
   // has an infinite tail so that silent input continues to produce non-silent
   // output.
-  double tail_time_;
+  double tail_time_ = 0;
 
   // Work arrays needed by WaveShaperCurveValues().  Mutable so this
   // const function can modify these arrays.  There's no state or
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc
index 047c28a..8f65095c 100644
--- a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc
+++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc
@@ -36,8 +36,7 @@
                                          unsigned render_quantum_frames)
     : AudioDSPKernelProcessor(sample_rate,
                               number_of_channels,
-                              render_quantum_frames),
-      oversample_(kOverSampleNone) {}
+                              render_quantum_frames) {}
 
 WaveShaperProcessor::~WaveShaperProcessor() {
   if (IsInitialized()) {
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.h b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.h
index 6a8b77d..939d780f 100644
--- a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.h
+++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.h
@@ -65,7 +65,7 @@
   // m_curve represents the non-linear shaping curve.
   std::unique_ptr<Vector<float>> curve_;
 
-  OverSampleType oversample_;
+  OverSampleType oversample_ = kOverSampleNone;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
index 8affac65..767ad59d 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
+++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -636,6 +636,8 @@
       return WGPUFeatureName_Depth24UnormStencil8;
     case V8GPUFeatureName::Enum::kDepth32FloatStencil8:
       return WGPUFeatureName_Depth32FloatStencil8;
+    case V8GPUFeatureName::Enum::kIndirectFirstInstance:
+      return WGPUFeatureName_IndirectFirstInstance;
   }
 }
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
index df15792..73b5883c 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
@@ -13,7 +13,8 @@
     "shader-float16",
     "depth-clamping",
     "depth24unorm-stencil8",
-    "depth32float-stencil8"
+    "depth32float-stencil8",
+    "indirect-first-instance"
 };
 
 [
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index e7001a1..c6ea218 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -290,6 +290,9 @@
   waiting_for_compositor_ack_ = false;
   last_frame_id_.reset();
 
+  if (video_frame_provider_)
+    video_frame_provider_->OnContextLost();
+
   resource_provider_->OnContextLost();
 
   // NOTE: These objects should be reset last; and if `bundle_proxy`_ is set, it
@@ -526,7 +529,6 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!compositor_frame_sink_)
     return;
-
   const auto is_driving_frame_updates = IsDrivingFrameUpdates();
   compositor_frame_sink_->SetNeedsBeginFrame(is_driving_frame_updates);
   power_mode_voter_->VoteFor(power_scheduler::PowerMode::kVideoPlayback);
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
index 437691d..b6f42bc 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
@@ -59,6 +59,7 @@
   MOCK_METHOD0(HasCurrentFrame, bool());
   MOCK_METHOD0(GetCurrentFrame, scoped_refptr<media::VideoFrame>());
   MOCK_METHOD0(PutCurrentFrame, void());
+  MOCK_METHOD0(OnContextLost, void());
 
   base::TimeDelta GetPreferredRenderInterval() override {
     return preferred_interval;
@@ -698,6 +699,7 @@
       .Times(0);
   EXPECT_CALL(mock_embedded_frame_sink_provider, CreateCompositorFrameSink_(_))
       .Times(1);
+  EXPECT_CALL(*video_frame_provider_, OnContextLost()).Times(1);
   submitter_->OnContextLost();
   OnReceivedContextProvider(true, context_provider_);
   task_environment_.RunUntilIdle();
@@ -719,6 +721,7 @@
       .Times(0);
   EXPECT_CALL(mock_embedded_frame_sink_provider, CreateCompositorFrameSink_(_))
       .Times(1);
+  EXPECT_CALL(*video_frame_provider_, OnContextLost()).Times(1);
   submitter_->OnContextLost();
   OnReceivedContextProvider(false, nullptr);
   task_environment_.RunUntilIdle();
diff --git a/third_party/blink/renderer/platform/media/DEPS b/third_party/blink/renderer/platform/media/DEPS
index cee97c54..4401bda 100644
--- a/third_party/blink/renderer/platform/media/DEPS
+++ b/third_party/blink/renderer/platform/media/DEPS
@@ -46,6 +46,7 @@
     "+components/viz/test",
     "+media/mojo/services",
     "+media/renderers",
+    "+media/video/fake_gpu_memory_buffer.h",
     "+gin/v8_initializer.h",
     "+mojo/core/embedder/embedder.h",
 
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor.cc b/third_party/blink/renderer/platform/media/video_frame_compositor.cc
index 2e30bda..4cfa47f 100644
--- a/third_party/blink/renderer/platform/media/video_frame_compositor.cc
+++ b/third_party/blink/renderer/platform/media/video_frame_compositor.cc
@@ -462,4 +462,19 @@
   return new_frame || had_new_background_frame;
 }
 
+void VideoFrameCompositor::OnContextLost() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  // current_frame_'s resource in the context has been lost, so current_frame_
+  // is not valid any more. current_frame_ should be reset. Now the compositor
+  // has no concept of resetting current_frame_, so a black frame is set.
+  base::AutoLock lock(current_frame_lock_);
+  if (!current_frame_ || (!current_frame_->HasTextures() &&
+                          !current_frame_->HasGpuMemoryBuffer())) {
+    return;
+  }
+  scoped_refptr<media::VideoFrame> black_frame =
+      media::VideoFrame::CreateBlackFrame(current_frame_->natural_size());
+  SetCurrentFrame_Locked(std::move(black_frame), tick_clock_->NowTicks());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc
index 81f02b3b..5893c7cd 100644
--- a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc
+++ b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc
@@ -16,6 +16,7 @@
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "media/base/video_frame.h"
+#include "media/video/fake_gpu_memory_buffer.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/web_video_frame_submitter.h"
@@ -492,4 +493,46 @@
             viz::BeginFrameArgs::MinInterval());
 }
 
+TEST_F(VideoFrameCompositorTest, OnContextLost) {
+  scoped_refptr<media::VideoFrame> non_gpu_frame = CreateOpaqueFrame();
+
+  gfx::Size encode_size(320, 240);
+  std::unique_ptr<gfx::GpuMemoryBuffer> gmb =
+      std::make_unique<media::FakeGpuMemoryBuffer>(
+          encode_size, gfx::BufferFormat::YUV_420_BIPLANAR);
+  gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes];
+  scoped_refptr<media::VideoFrame> gpu_frame =
+      media::VideoFrame::WrapExternalGpuMemoryBuffer(
+          gfx::Rect(encode_size), encode_size, std::move(gmb), mailbox_holders,
+          base::DoNothing(), base::TimeDelta());
+
+  compositor_->set_background_rendering_for_testing(true);
+
+  EXPECT_CALL(*submitter_, IsDrivingFrameUpdates)
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(true));
+
+  // Move the clock forward. Otherwise, the current time will be 0, will appear
+  // null, and will cause DCHECKs.
+  tick_clock_.Advance(base::Seconds(1));
+
+  EXPECT_CALL(*this, Render(_, _, RenderingMode::kStartup))
+      .WillOnce(Return(non_gpu_frame));
+  StartVideoRendererSink();
+  compositor()->OnContextLost();
+  // frame which dose not have gpu resource should be maintained even though
+  // context is lost.
+  EXPECT_EQ(non_gpu_frame, compositor()->GetCurrentFrame());
+
+  tick_clock_.Advance(base::Seconds(1));
+  EXPECT_CALL(*this, Render(_, _, _)).WillOnce(Return(gpu_frame));
+  compositor()->UpdateCurrentFrameIfStale(
+      VideoFrameCompositor::UpdateType::kBypassClient);
+  compositor()->OnContextLost();
+  // frame which has gpu resource should be reset if context is lost
+  EXPECT_NE(gpu_frame, compositor()->GetCurrentFrame());
+
+  StopVideoRendererSink(true);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
index 2fb454a..58b22b6 100644
--- a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
@@ -4,6 +4,9 @@
 
 #include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
 
+#include "base/trace_event/trace_event.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
+
 namespace blink {
 namespace scheduler {
 
@@ -12,6 +15,116 @@
   GetOnTaskCompletionCallbacks().push_back(std::move(on_completion_task));
 }
 
+void ThreadSchedulerImpl::Shutdown() {
+  GetHelper().ResetTimeDomain();
+  virtual_time_domain_.reset();
+}
+
+base::TimeTicks ThreadSchedulerImpl::MonotonicallyIncreasingVirtualTime() {
+  return GetTickClock()->NowTicks();
+}
+
+base::TimeTicks ThreadSchedulerImpl::EnableVirtualTime(
+    base::Time initial_time) {
+  if (virtual_time_domain_)
+    return virtual_time_domain_->InitialTicks();
+  if (initial_time.is_null())
+    initial_time = base::Time::Now();
+  base::TimeTicks initial_ticks = GetTickClock()->NowTicks();
+  virtual_time_domain_ = std::make_unique<AutoAdvancingVirtualTimeDomain>(
+      initial_time, initial_ticks, &GetHelper());
+  GetHelper().SetTimeDomain(virtual_time_domain_.get());
+
+  OnVirtualTimeEnabled();
+
+  DCHECK(!virtual_time_stopped_);
+  virtual_time_domain_->SetCanAdvanceVirtualTime(true);
+
+  return initial_ticks;
+}
+
+void ThreadSchedulerImpl::DisableVirtualTimeForTesting() {
+  if (!IsVirtualTimeEnabled())
+    return;
+  // Reset virtual time and all tasks queues back to their initial state.
+  SetVirtualTimeStopped(false);
+
+  // This can only happen during test tear down, in which case there is no need
+  // to notify the pages that virtual time was disabled.
+  GetHelper().ResetTimeDomain();
+
+  virtual_time_domain_.reset();
+
+  OnVirtualTimeDisabled();
+}
+
+bool ThreadSchedulerImpl::VirtualTimeAllowedToAdvance() const {
+  DCHECK(!virtual_time_stopped_ || virtual_time_domain_);
+  return !virtual_time_stopped_;
+}
+
+void ThreadSchedulerImpl::GrantVirtualTimeBudget(
+    base::TimeDelta budget,
+    base::OnceClosure budget_exhausted_callback) {
+  GetVirtualTimeTaskRunner()->PostDelayedTask(
+      FROM_HERE, std::move(budget_exhausted_callback), budget);
+  // This can shift time forwards if there's a pending MaybeAdvanceVirtualTime,
+  // so it's important this is called second.
+  virtual_time_domain_->SetVirtualTimeFence(GetTickClock()->NowTicks() +
+                                            budget);
+}
+
+void ThreadSchedulerImpl::SetVirtualTimePolicy(VirtualTimePolicy policy) {
+  DCHECK(IsVirtualTimeEnabled());
+  virtual_time_policy_ = policy;
+  ApplyVirtualTimePolicy();
+}
+
+void ThreadSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount(
+    int max_task_starvation_count) {
+  DCHECK(IsVirtualTimeEnabled());
+  max_virtual_time_task_starvation_count_ = max_task_starvation_count;
+  ApplyVirtualTimePolicy();
+}
+
+WebScopedVirtualTimePauser
+ThreadSchedulerImpl::CreateWebScopedVirtualTimePauser(
+    const WTF::String& name,
+    WebScopedVirtualTimePauser::VirtualTaskDuration duration) {
+  return WebScopedVirtualTimePauser(this, duration, name);
+}
+
+bool ThreadSchedulerImpl::IsVirtualTimeEnabled() const {
+  return !!virtual_time_domain_;
+}
+
+base::TimeTicks ThreadSchedulerImpl::IncrementVirtualTimePauseCount() {
+  virtual_time_pause_count_++;
+  if (IsVirtualTimeEnabled())
+    ApplyVirtualTimePolicy();
+  return GetTickClock()->NowTicks();
+}
+
+void ThreadSchedulerImpl::DecrementVirtualTimePauseCount() {
+  virtual_time_pause_count_--;
+  DCHECK_GE(virtual_time_pause_count_, 0);
+  if (IsVirtualTimeEnabled())
+    ApplyVirtualTimePolicy();
+}
+
+void ThreadSchedulerImpl::MaybeAdvanceVirtualTime(
+    base::TimeTicks new_virtual_time) {
+  if (virtual_time_domain_)
+    virtual_time_domain_->MaybeAdvanceVirtualTime(new_virtual_time);
+}
+
+AutoAdvancingVirtualTimeDomain* ThreadSchedulerImpl::GetVirtualTimeDomain() {
+  return virtual_time_domain_.get();
+}
+
+ThreadSchedulerImpl::ThreadSchedulerImpl() = default;
+ThreadSchedulerImpl::~ThreadSchedulerImpl() = default;
+
 void ThreadSchedulerImpl::DispatchOnTaskCompletionCallbacks() {
   for (auto& closure : GetOnTaskCompletionCallbacks()) {
     std::move(closure).Run();
@@ -19,5 +132,83 @@
   GetOnTaskCompletionCallbacks().clear();
 }
 
+namespace {
+const char* VirtualTimePolicyToString(
+    VirtualTimeController::VirtualTimePolicy virtual_time_policy) {
+  switch (virtual_time_policy) {
+    case VirtualTimeController::VirtualTimePolicy::kAdvance:
+      return "ADVANCE";
+    case VirtualTimeController::VirtualTimePolicy::kPause:
+      return "PAUSE";
+    case VirtualTimeController::VirtualTimePolicy::kDeterministicLoading:
+      return "DETERMINISTIC_LOADING";
+  }
+}
+}  // namespace
+
+void ThreadSchedulerImpl::WriteVirtualTimeInfoIntoTrace(
+    perfetto::TracedDictionary& dict) const {
+  dict.Add("virtual_time_stopped", virtual_time_stopped_);
+  dict.Add("virtual_time_pause_count", virtual_time_pause_count_);
+  dict.Add("virtual_time_policy",
+           VirtualTimePolicyToString(virtual_time_policy_));
+  dict.Add("virtual_time", !!virtual_time_domain_);
+}
+
+void ThreadSchedulerImpl::SetVirtualTimeStopped(bool virtual_time_stopped) {
+  DCHECK(virtual_time_domain_);
+  if (virtual_time_stopped_ == virtual_time_stopped)
+    return;
+  virtual_time_stopped_ = virtual_time_stopped;
+  virtual_time_domain_->SetCanAdvanceVirtualTime(!virtual_time_stopped);
+
+  if (virtual_time_stopped)
+    OnVirtualTimePaused();
+  else
+    OnVirtualTimeResumed();
+}
+
+void ThreadSchedulerImpl::ApplyVirtualTimePolicy() {
+  DCHECK(virtual_time_domain_);
+  switch (virtual_time_policy_) {
+    case VirtualTimePolicy::kAdvance:
+      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
+          GetHelper().IsInNestedRunloop()
+              ? 0
+              : max_virtual_time_task_starvation_count_);
+      virtual_time_domain_->SetVirtualTimeFence(base::TimeTicks());
+      SetVirtualTimeStopped(false);
+      break;
+    case VirtualTimePolicy::kPause:
+      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(0);
+      virtual_time_domain_->SetVirtualTimeFence(GetTickClock()->NowTicks());
+      SetVirtualTimeStopped(true);
+      break;
+    case VirtualTimePolicy::kDeterministicLoading:
+      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
+          GetHelper().IsInNestedRunloop()
+              ? 0
+              : max_virtual_time_task_starvation_count_);
+
+      // We pause virtual time while the run loop is nested because that implies
+      // something modal is happening such as the DevTools debugger pausing the
+      // system. We also pause while the renderer is waiting for various
+      // asynchronous things e.g. resource load or navigation.
+      SetVirtualTimeStopped(virtual_time_pause_count_ != 0 ||
+                            GetHelper().IsInNestedRunloop());
+      break;
+  }
+}
+
+void ThreadSchedulerImpl::OnBeginNestedRunLoop() {
+  if (IsVirtualTimeEnabled())
+    ApplyVirtualTimePolicy();
+}
+
+void ThreadSchedulerImpl::OnExitNestedRunLoop() {
+  if (IsVirtualTimeEnabled())
+    ApplyVirtualTimePolicy();
+}
+
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
index 9a81ce7..286a8ac 100644
--- a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
@@ -9,8 +9,11 @@
 
 #include "base/task/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
 #include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/virtual_time_controller.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 namespace base {
 class TickClock;
@@ -22,14 +25,15 @@
 
 namespace blink {
 namespace scheduler {
-
-class SchedulerHelper;
+class AutoAdvancingVirtualTimeDomain;
 
 // Scheduler-internal interface for the common methods between
 // MainThreadSchedulerImpl and NonMainThreadSchedulerImpl which should
 // not be exposed outside the scheduler.
 class PLATFORM_EXPORT ThreadSchedulerImpl : public ThreadScheduler,
-                                            public WebThreadScheduler {
+                                            public WebThreadScheduler,
+                                            public VirtualTimeController,
+                                            public SchedulerHelper::Observer {
  public:
   // This type is defined in both ThreadScheduler and WebThreadScheduler,
   // so the use of this type causes ambiguous lookup. Redefine this again
@@ -53,9 +57,36 @@
   void SetV8Isolate(v8::Isolate* isolate) override { isolate_ = isolate; }
   v8::Isolate* isolate() const { return isolate_; }
 
+  // ThreadScheduler implementation.
+  void Shutdown() override;
+  base::TimeTicks MonotonicallyIncreasingVirtualTime() override;
+
+  // VirtualTimeController implementation.
+  base::TimeTicks EnableVirtualTime(base::Time initial_time) override;
+  void DisableVirtualTimeForTesting() override;
+  bool VirtualTimeAllowedToAdvance() const override;
+  void GrantVirtualTimeBudget(
+      base::TimeDelta budget,
+      base::OnceClosure budget_exhausted_callback) override;
+  void SetVirtualTimePolicy(VirtualTimePolicy virtual_time_policy) override;
+  void SetMaxVirtualTimeTaskStarvationCount(
+      int max_task_starvation_count) override;
+  WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+      const WTF::String& name,
+      WebScopedVirtualTimePauser::VirtualTaskDuration) override;
+
+  bool IsVirtualTimeEnabled() const;
+  base::TimeTicks IncrementVirtualTimePauseCount();
+  void DecrementVirtualTimePauseCount();
+  void MaybeAdvanceVirtualTime(base::TimeTicks new_virtual_time);
+  AutoAdvancingVirtualTimeDomain* GetVirtualTimeDomain();
+  VirtualTimePolicy GetVirtualTimePolicyForTest() const {
+    return virtual_time_policy_;
+  }
+
  protected:
-  ThreadSchedulerImpl() {}
-  ~ThreadSchedulerImpl() override = default;
+  ThreadSchedulerImpl();
+  ~ThreadSchedulerImpl() override;
 
   // Returns the list of callbacks to execute after the current task.
   virtual WTF::Vector<base::OnceClosure>& GetOnTaskCompletionCallbacks() = 0;
@@ -67,8 +98,50 @@
   // task.
   void DispatchOnTaskCompletionCallbacks();
 
+  void WriteVirtualTimeInfoIntoTrace(perfetto::TracedDictionary& dict) const;
+
+  // A derived implementation should provide a task runner associated for
+  // virtual time control tasks (when VT budget is exhausted, callback will be
+  // posted there).
+  virtual base::SequencedTaskRunner* GetVirtualTimeTaskRunner() {
+    NOTREACHED();
+    return nullptr;
+  }
+  virtual void OnVirtualTimeEnabled() {}
+  virtual void OnVirtualTimeDisabled() {}
+
+  // Tells the derived implementation that VT is now paused and it has to
+  // insert fences into its task queues as required.
+  virtual void OnVirtualTimePaused() {}
+  // Tells the derived implementation that VT is now resumed and it has to
+  // remove fences added when time was paused from the queues it manages.
+  virtual void OnVirtualTimeResumed() {}
+
  private:
+  void NotifyVirtualTimePaused();
+  void SetVirtualTimeStopped(bool virtual_time_stopped);
+  void ApplyVirtualTimePolicy();
+
+  // SchedulerHelper::Observer implementation:
+  void OnBeginNestedRunLoop() override;
+  void OnExitNestedRunLoop() override;
+
   v8::Isolate* isolate_ = nullptr;
+
+  // Note |virtual_time_domain_| is only present iff virtual time is enabled.
+  std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_;
+  VirtualTimePolicy virtual_time_policy_ = VirtualTimePolicy::kAdvance;
+
+  // In VirtualTimePolicy::kDeterministicLoading virtual time is only allowed
+  // to advance if this is zero.
+  int virtual_time_pause_count_ = 0;
+
+  // The maximum number amount of delayed task starvation we will allow in
+  // VirtualTimePolicy::kAdvance or VirtualTimePolicy::kDeterministicLoading
+  // unless the run_loop is nested (in which case infinite starvation is
+  // allowed). NB a value of 0 allows infinite starvation.
+  int max_virtual_time_task_starvation_count_ = 0;
+  bool virtual_time_stopped_ = false;
 };
 
 }  // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 713fafd..63a709bf 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -46,7 +46,6 @@
 #include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
@@ -439,10 +438,6 @@
           "Scheduler.TaskPriority",
           &main_thread_scheduler_impl->tracing_controller_,
           OptionalTaskPriorityToString),
-      virtual_time_policy(VirtualTimePolicy::kAdvance),
-      virtual_time_pause_count(0),
-      max_virtual_time_task_starvation_count(0),
-      virtual_time_stopped(false),
       prioritize_compositing_after_input(
           false,
           "Scheduler.PrioritizeCompositingAfterInput",
@@ -600,7 +595,6 @@
     scoped_refptr<MainThreadTaskQueue> queue = task_runners_.begin()->first;
     queue->ShutdownTaskQueue();
   }
-
   if (virtual_time_control_task_queue_)
     virtual_time_control_task_queue_->ShutdownTaskQueue();
 }
@@ -624,9 +618,11 @@
 void MainThreadSchedulerImpl::Shutdown() {
   if (was_shutdown_)
     return;
-
   base::TimeTicks now = NowTicks();
   main_thread_only().metrics_helper.OnRendererShutdown(now);
+  // This needs to be after metrics helper, to prevent it being confused by
+  // potential virtual time domain shutdown!
+  ThreadSchedulerImpl::Shutdown();
 
   ShutdownAllQueues();
 
@@ -714,7 +710,7 @@
   // If this is a timer queue, and virtual time is enabled and paused, it should
   // be suspended by adding a fence to prevent immediate tasks from running when
   // they're not supposed to.
-  if (main_thread_only().virtual_time_stopped &&
+  if (!VirtualTimeAllowedToAdvance() &&
       !task_queue->CanRunWhenVirtualTimePaused()) {
     task_queue->GetTaskQueue()->InsertFence(
         TaskQueue::InsertFencePosition::kNow);
@@ -1749,18 +1745,12 @@
   return &main_thread_only().idle_time_estimator;
 }
 
-base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime(
-    base::Time initial_time) {
-  if (virtual_time_domain_)
-    return virtual_time_domain_->InitialTicks();
-  if (initial_time.is_null())
-    initial_time = base::Time::Now();
-  base::TimeTicks initial_ticks = NowTicks();
-  DCHECK(!virtual_time_domain_);
-  virtual_time_domain_ = std::make_unique<AutoAdvancingVirtualTimeDomain>(
-      initial_time, initial_ticks, &helper_);
-  helper_.SetTimeDomain(virtual_time_domain_.get());
+base::SequencedTaskRunner* MainThreadSchedulerImpl::GetVirtualTimeTaskRunner() {
+  return virtual_time_control_task_queue_->GetTaskRunnerWithDefaultTaskType()
+      .get();
+}
 
+void MainThreadSchedulerImpl::OnVirtualTimeEnabled() {
   DCHECK(!virtual_time_control_task_queue_);
   virtual_time_control_task_queue_ =
       helper_.NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
@@ -1769,33 +1759,17 @@
       TaskQueue::kControlPriority);
 
   ForceUpdatePolicy();
+
   for (auto* page_scheduler : main_thread_only().page_schedulers) {
     page_scheduler->OnVirtualTimeEnabled();
   }
-
-  DCHECK(!main_thread_only().virtual_time_stopped);
-  virtual_time_domain_->SetCanAdvanceVirtualTime(true);
-
-  return initial_ticks;
 }
 
-bool MainThreadSchedulerImpl::IsVirtualTimeEnabled() const {
-  return !!virtual_time_domain_;
-}
-
-void MainThreadSchedulerImpl::DisableVirtualTimeForTesting() {
-  if (!IsVirtualTimeEnabled())
-    return;
-  // Reset virtual time and all tasks queues back to their initial state.
-  SetVirtualTimeStopped(false);
-
-  // This can only happen during test tear down, in which case there is no need
-  // to notify the pages that virtual time was disabled.
-
-  helper_.ResetTimeDomain();
+void MainThreadSchedulerImpl::OnVirtualTimeDisabled() {
   virtual_time_control_task_queue_->ShutdownTaskQueue();
   virtual_time_control_task_queue_ = nullptr;
-  virtual_time_domain_.reset();
+
+  ForceUpdatePolicy();
 
   ForceUpdatePolicy();
 
@@ -1804,22 +1778,7 @@
   main_thread_only().metrics_helper.ResetForTest(now);
 }
 
-void MainThreadSchedulerImpl::SetVirtualTimeStopped(bool virtual_time_stopped) {
-  DCHECK(IsVirtualTimeEnabled());
-  if (main_thread_only().virtual_time_stopped == virtual_time_stopped)
-    return;
-  main_thread_only().virtual_time_stopped = virtual_time_stopped;
-
-  virtual_time_domain_->SetCanAdvanceVirtualTime(!virtual_time_stopped);
-
-  if (virtual_time_stopped) {
-    VirtualTimePaused();
-  } else {
-    VirtualTimeResumed();
-  }
-}
-
-void MainThreadSchedulerImpl::VirtualTimePaused() {
+void MainThreadSchedulerImpl::OnVirtualTimePaused() {
   for (const auto& pair : task_runners_) {
     if (pair.first->CanRunWhenVirtualTimePaused())
       continue;
@@ -1829,7 +1788,7 @@
   }
 }
 
-void MainThreadSchedulerImpl::VirtualTimeResumed() {
+void MainThreadSchedulerImpl::OnVirtualTimeResumed() {
   for (const auto& pair : task_runners_) {
     if (pair.first->CanRunWhenVirtualTimePaused())
       continue;
@@ -1839,94 +1798,6 @@
   }
 }
 
-bool MainThreadSchedulerImpl::VirtualTimeAllowedToAdvance() const {
-  return !main_thread_only().virtual_time_stopped;
-}
-
-void MainThreadSchedulerImpl::GrantVirtualTimeBudget(
-    base::TimeDelta budget,
-    base::OnceClosure budget_exhausted_callback) {
-  virtual_time_control_task_queue_->GetTaskRunnerWithDefaultTaskType()
-      ->PostDelayedTask(FROM_HERE, std::move(budget_exhausted_callback),
-                        budget);
-  // This can shift time forwards if there's a pending MaybeAdvanceVirtualTime,
-  // so it's important this is called second.
-  virtual_time_domain_->SetVirtualTimeFence(NowTicks() + budget);
-}
-
-base::TimeTicks MainThreadSchedulerImpl::IncrementVirtualTimePauseCount() {
-  main_thread_only().virtual_time_pause_count++;
-  if (IsVirtualTimeEnabled())
-    ApplyVirtualTimePolicy();
-  return NowTicks();
-}
-
-void MainThreadSchedulerImpl::DecrementVirtualTimePauseCount() {
-  main_thread_only().virtual_time_pause_count--;
-  DCHECK_GE(main_thread_only().virtual_time_pause_count, 0);
-  if (IsVirtualTimeEnabled())
-    ApplyVirtualTimePolicy();
-}
-
-void MainThreadSchedulerImpl::MaybeAdvanceVirtualTime(
-    base::TimeTicks new_virtual_time) {
-  if (IsVirtualTimeEnabled())
-    virtual_time_domain_->MaybeAdvanceVirtualTime(new_virtual_time);
-}
-
-void MainThreadSchedulerImpl::SetVirtualTimePolicy(VirtualTimePolicy policy) {
-  DCHECK(IsVirtualTimeEnabled());
-  main_thread_only().virtual_time_policy = policy;
-  ApplyVirtualTimePolicy();
-}
-
-void MainThreadSchedulerImpl::ApplyVirtualTimePolicy() {
-  DCHECK(IsVirtualTimeEnabled());
-  switch (main_thread_only().virtual_time_policy) {
-    case VirtualTimePolicy::kAdvance:
-      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
-          helper_.IsInNestedRunloop()
-              ? 0
-              : main_thread_only().max_virtual_time_task_starvation_count);
-      virtual_time_domain_->SetVirtualTimeFence(base::TimeTicks());
-      SetVirtualTimeStopped(false);
-      break;
-    case VirtualTimePolicy::kPause:
-      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(0);
-      virtual_time_domain_->SetVirtualTimeFence(NowTicks());
-      SetVirtualTimeStopped(true);
-      break;
-    case VirtualTimePolicy::kDeterministicLoading:
-      virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
-          helper_.IsInNestedRunloop()
-              ? 0
-              : main_thread_only().max_virtual_time_task_starvation_count);
-
-      // We pause virtual time while the run loop is nested because that implies
-      // something modal is happening such as the DevTools debugger pausing the
-      // system. We also pause while the renderer is waiting for various
-      // asynchronous things e.g. resource load or navigation.
-      SetVirtualTimeStopped(main_thread_only().virtual_time_pause_count != 0 ||
-                            helper_.IsInNestedRunloop());
-      break;
-  }
-}
-
-void MainThreadSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount(
-    int max_task_starvation_count) {
-  DCHECK(IsVirtualTimeEnabled());
-  main_thread_only().max_virtual_time_task_starvation_count =
-      max_task_starvation_count;
-  ApplyVirtualTimePolicy();
-}
-
-WebScopedVirtualTimePauser
-MainThreadSchedulerImpl::CreateWebScopedVirtualTimePauser(
-    const WTF::String& name,
-    WebScopedVirtualTimePauser::VirtualTaskDuration duration) {
-  return WebScopedVirtualTimePauser(this, duration, name);
-}
-
 void MainThreadSchedulerImpl::CreateTraceEventObjectSnapshot() const {
   TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
       TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"),
@@ -1995,13 +1866,6 @@
            any_thread().last_gesture_was_compositor_driven);
   dict.Add("default_gesture_prevented", any_thread().default_gesture_prevented);
   dict.Add("is_audio_playing", main_thread_only().is_audio_playing);
-  dict.Add("virtual_time_stopped", main_thread_only().virtual_time_stopped);
-  dict.Add("virtual_time_pause_count",
-           main_thread_only().virtual_time_pause_count);
-  dict.Add("virtual_time_policy",
-           VirtualTimePolicyToString(main_thread_only().virtual_time_policy));
-  dict.Add("virtual_time", !!virtual_time_domain_);
-
   dict.Add("page_schedulers", [&](perfetto::TracedValue context) {
     auto array = std::move(context).WriteArray();
     for (const auto* page_scheduler : main_thread_only().page_schedulers) {
@@ -2024,6 +1888,7 @@
 
   dict.Add("user_model", any_thread().user_model);
   dict.Add("render_widget_scheduler_signals", render_widget_scheduler_signals_);
+  WriteVirtualTimeInfoIntoTrace(dict);
 }
 
 bool MainThreadSchedulerImpl::Policy::IsQueueEnabled(
@@ -2378,26 +2243,10 @@
   return PauseRenderer();
 }
 
-base::TimeTicks MainThreadSchedulerImpl::MonotonicallyIncreasingVirtualTime() {
-  return NowTicks();
-}
-
 WebThreadScheduler* MainThreadSchedulerImpl::GetWebMainThreadScheduler() {
   return this;
 }
 
-void MainThreadSchedulerImpl::OnBeginNestedRunLoop() {
-  DCHECK(!main_thread_only().running_queues.empty());
-  if (IsVirtualTimeEnabled())
-    ApplyVirtualTimePolicy();
-}
-
-void MainThreadSchedulerImpl::OnExitNestedRunLoop() {
-  DCHECK(!main_thread_only().running_queues.empty());
-  if (IsVirtualTimeEnabled())
-    ApplyVirtualTimePolicy();
-}
-
 const base::TickClock* MainThreadSchedulerImpl::GetTickClock() const {
   return helper_.GetClock();
 }
@@ -2679,11 +2528,6 @@
                                              NowTicks());
 }
 
-AutoAdvancingVirtualTimeDomain*
-MainThreadSchedulerImpl::GetVirtualTimeDomain() {
-  return virtual_time_domain_.get();
-}
-
 void MainThreadSchedulerImpl::OnTraceLogEnabled() {
   CreateTraceEventObjectSnapshot();
   tracing_controller_.OnTraceLogEnabled();
@@ -2903,22 +2747,6 @@
   }
 }
 
-// static
-const char* MainThreadSchedulerImpl::VirtualTimePolicyToString(
-    VirtualTimePolicy virtual_time_policy) {
-  switch (virtual_time_policy) {
-    case VirtualTimePolicy::kAdvance:
-      return "ADVANCE";
-    case VirtualTimePolicy::kPause:
-      return "PAUSE";
-    case VirtualTimePolicy::kDeterministicLoading:
-      return "DETERMINISTIC_LOADING";
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
-}
-
 WTF::Vector<base::OnceClosure>&
 MainThreadSchedulerImpl::GetOnTaskCompletionCallbacks() {
   return main_thread_only().on_task_completion_callbacks;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index 9db6948..b44686149 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -32,7 +32,6 @@
 #include "third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h"
 #include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
 #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h"
@@ -74,15 +73,12 @@
 class AgentGroupSchedulerImpl;
 class FrameSchedulerImpl;
 class PageSchedulerImpl;
-class TaskQueueThrottler;
 class WebRenderWidgetSchedulingState;
 class CPUTimeBudgetPool;
 
 class PLATFORM_EXPORT MainThreadSchedulerImpl
     : public ThreadSchedulerImpl,
-      public VirtualTimeController,
       public IdleHelper::Delegate,
-      public SchedulerHelper::Observer,
       public RenderWidgetSignals::Observer,
       public base::trace_event::TraceLog::AsyncEnabledStateObserver {
  public:
@@ -158,7 +154,6 @@
 
   static const char* UseCaseToString(UseCase use_case);
   static const char* RAILModeToString(RAILMode rail_mode);
-  static const char* VirtualTimePolicyToString(VirtualTimePolicy);
 
   explicit MainThreadSchedulerImpl(
       std::unique_ptr<base::sequence_manager::SequenceManager>
@@ -230,7 +225,6 @@
   WebAgentGroupScheduler* GetCurrentAgentGroupScheduler() override;
   std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseScheduler()
       override;
-  base::TimeTicks MonotonicallyIncreasingVirtualTime() override;
   NonMainThreadSchedulerImpl* AsNonMainThreadScheduler() override {
     return nullptr;
   }
@@ -294,25 +288,6 @@
 
   scoped_refptr<base::sequence_manager::TaskQueue> NewTaskQueueForTest();
 
-  // VirtualTimeController implementation.
-  base::TimeTicks EnableVirtualTime(base::Time initial_time) override;
-  void DisableVirtualTimeForTesting() override;
-  bool VirtualTimeAllowedToAdvance() const override;
-  void GrantVirtualTimeBudget(
-      base::TimeDelta budget,
-      base::OnceClosure budget_exhausted_callback) override;
-  void SetVirtualTimePolicy(VirtualTimePolicy virtual_time_policy) override;
-  void SetMaxVirtualTimeTaskStarvationCount(
-      int max_task_starvation_count) override;
-  WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
-      const WTF::String& name,
-      WebScopedVirtualTimePauser::VirtualTaskDuration) override;
-
-  bool IsVirtualTimeEnabled() const;
-  base::TimeTicks IncrementVirtualTimePauseCount();
-  void DecrementVirtualTimePauseCount();
-  void MaybeAdvanceVirtualTime(base::TimeTicks new_virtual_time);
-
   void RemoveAgentGroupScheduler(AgentGroupSchedulerImpl*);
   void AddPageScheduler(PageSchedulerImpl*);
   void RemovePageScheduler(PageSchedulerImpl*);
@@ -355,8 +330,6 @@
                                base::TimeTicks time_remaining);
   bool PolicyNeedsUpdateForTesting();
 
-  AutoAdvancingVirtualTimeDomain* GetVirtualTimeDomain();
-
   std::unique_ptr<CPUTimeBudgetPool> CreateCPUTimeBudgetPoolForTesting(
       const char* name);
 
@@ -462,9 +435,12 @@
   // WebThreadScheduler private implementation:
   WebThreadScheduler* GetWebMainThreadScheduler() override;
 
-  // SchedulerHelper::Observer implementation:
-  void OnBeginNestedRunLoop() override;
-  void OnExitNestedRunLoop() override;
+  // ThreadSchedulerImpl overrides
+  base::SequencedTaskRunner* GetVirtualTimeTaskRunner() override;
+  void OnVirtualTimeEnabled() override;
+  void OnVirtualTimeDisabled() override;
+  void OnVirtualTimePaused() override;
+  void OnVirtualTimeResumed() override;
 
   static const char* TimeDomainTypeToString(TimeDomainType domain_type);
 
@@ -688,20 +664,6 @@
   void PauseRendererImpl();
   void ResumeRendererImpl();
 
-  void NotifyVirtualTimePaused();
-  void SetVirtualTimeStopped(bool virtual_time_stopped);
-  void ApplyVirtualTimePolicy();
-
-  // Pauses the timer queues by inserting a fence that blocks any tasks posted
-  // after this point from running. Orthogonal to PauseTimerQueue. Care must
-  // be taken when using this API to avoid fighting with the TaskQueueThrottler.
-  void VirtualTimePaused();
-
-  // Removes the fence added by VirtualTimePaused allowing timers to execute
-  // normally. Care must be taken when using this API to avoid fighting with the
-  // TaskQueueThrottler.
-  void VirtualTimeResumed();
-
   // Returns true if there is a change in the main thread's policy that should
   // trigger a priority update.
   bool ShouldUpdateTaskQueuePriorities(Policy new_policy) const;
@@ -802,9 +764,6 @@
 
   MemoryPurgeManager memory_purge_manager_;
 
-  // Note |virtual_time_domain_| is lazily created.
-  std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_;
-
   base::RepeatingClosure update_policy_closure_;
   DeadlineTaskRunner delayed_update_policy_runner_;
   CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
@@ -818,8 +777,6 @@
         base::TimeTicks now);
     ~MainThreadOnly();
 
-    bool IsInNestedRunloop();
-
     IdleTimeEstimator idle_time_estimator;
     TraceableState<UseCase, TracingCategory::kDefault> current_use_case;
     Policy current_policy;
@@ -869,19 +826,6 @@
         TracingCategory::kInfo>
         task_priority_for_tracing;  // Only used for tracing.
 
-    VirtualTimePolicy virtual_time_policy;
-
-    // In VirtualTimePolicy::kDeterministicLoading virtual time is only allowed
-    // to advance if this is zero.
-    int virtual_time_pause_count;
-
-    // The maximum number amount of delayed task starvation we will allow in
-    // VirtualTimePolicy::kAdvance or VirtualTimePolicy::kDeterministicLoading
-    // unless the run_loop is nested (in which case infinite starvation is
-    // allowed). NB a value of 0 allows infinite starvation.
-    int max_virtual_time_task_starvation_count;
-    bool virtual_time_stopped;
-
     // Holds task queues that are currently running.
     // The queue for the inmost task is at the top of stack when there are
     // nested RunLoops.
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index 318dbf8..49fcb83f 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -374,10 +374,6 @@
     return any_thread().begin_main_frame_on_critical_path;
   }
 
-  VirtualTimePolicy virtual_time_policy() const {
-    return main_thread_only().virtual_time_policy;
-  }
-
   void PerformMicrotaskCheckpoint() override {
     if (on_microtask_checkpoint_)
       std::move(on_microtask_checkpoint_).Run();
@@ -3458,7 +3454,7 @@
 TEST_F(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) {
   EXPECT_TRUE(scheduler_->IsVirtualTimeEnabled());
   EXPECT_EQ(VirtualTimeController::VirtualTimePolicy::kPause,
-            scheduler_->virtual_time_policy());
+            scheduler_->GetVirtualTimePolicyForTest());
   EXPECT_EQ(base::Time::Now(), base::Time::FromJsTime(1000000.0));
 }
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc b/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc
index d3c27ee..779728ef 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc
@@ -6,7 +6,7 @@
 
 #include "base/trace_event/trace_event.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
 
 namespace blink {
 
@@ -14,7 +14,7 @@
     : scheduler_(nullptr) {}
 
 WebScopedVirtualTimePauser::WebScopedVirtualTimePauser(
-    scheduler::MainThreadSchedulerImpl* scheduler,
+    scheduler::ThreadSchedulerImpl* scheduler,
     VirtualTaskDuration duration,
     const WebString& name)
     : duration_(duration),
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
index 1eba3f0..6f7c0a24 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -180,6 +180,7 @@
 
 void WorkerThreadScheduler::Shutdown() {
   DCHECK(initialized_);
+  ThreadSchedulerImpl::Shutdown();
   idle_helper_.Shutdown();
   GetHelper().Shutdown();
 }
diff --git a/third_party/blink/renderer/platform/wtf/cross_thread_copier.cc b/third_party/blink/renderer/platform/wtf/cross_thread_copier.cc
index 8f2dfdb..fa9004e3 100644
--- a/third_party/blink/renderer/platform/wtf/cross_thread_copier.cc
+++ b/third_party/blink/renderer/platform/wtf/cross_thread_copier.cc
@@ -38,11 +38,6 @@
 
 namespace WTF {
 
-CrossThreadCopier<String>::Type CrossThreadCopier<String>::Copy(
-    const String& str) {
-  return str.IsolatedCopy();
-}
-
 // Test CrossThreadCopier using static_assert.
 
 // Verify that ThreadSafeRefCounted objects get handled correctly.
diff --git a/third_party/blink/renderer/platform/wtf/cross_thread_copier.h b/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
index 0628c6ad..39630b4 100644
--- a/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
+++ b/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
@@ -116,10 +116,8 @@
 };
 
 template <>
-struct CrossThreadCopier<String> {
+struct CrossThreadCopier<String> : public CrossThreadCopierPassThrough<String> {
   STATIC_ONLY(CrossThreadCopier);
-  typedef String Type;
-  WTF_EXPORT static Type Copy(const String&);
 };
 
 }  // namespace WTF
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0f32fe3..e43d331 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1635,10 +1635,6 @@
 
 # ====== MathMLCore-only tests from here ======
 
-# This test fail because we don't properly center elements in MathML tables.
-crbug.com/1125111 external/wpt/mathml/presentation-markup/tables/table-003.html [ Failure ]
-crbug.com/1125111 external/wpt/mathml/presentation-markup/direction/direction-006.html [ Failure ]
-
 # These tests fail because some CSS properties affect MathML layout.
 crbug.com/1227601 external/wpt/mathml/relations/css-styling/ignored-properties-001.html [ Failure Timeout ]
 crbug.com/1227598 external/wpt/mathml/relations/css-styling/width-height-001.html [ Failure ]
@@ -1866,9 +1862,10 @@
 crbug.com/1158554 external/wpt/css/css-conditional/at-supports-046.html [ Failure ]
 
 
-# @container
+# @container / contain:inline-size
 crbug.com/1294155 external/wpt/css/css-contain/container-queries/canvas-as-container-004.html [ Failure ]
 crbug.com/1307656 external/wpt/css/css-contain/container-queries/crashtests/columns-in-table-002-crash.html [ Crash ]
+crbug.com/1328066 external/wpt/css/css-contain/contain-inline-size-intrinsic.html [ Failure ]
 
 # CSS Scrollbars
 crbug.com/891944 external/wpt/css/css-scrollbars/textarea-scrollbar-width-none.html [ Failure ]
@@ -3193,6 +3190,7 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/private-network-access/fetch.window.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/content-security-policy/wasm-unsafe-eval/postMessage-wasm-module.html [ Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/content-security-policy/wasm-unsafe-eval/postMessage-wasm-module.html [ Timeout ]
 crbug.com/626703 [ Mac11 ] external/wpt/content-security-policy/wasm-unsafe-eval/postMessage-wasm-module.html [ Timeout ]
@@ -6592,15 +6590,6 @@
 crbug.com/1285275 virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
 crbug.com/1285275 virtual/fenced-frame-shadow-dom/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
 crbug.com/1285275 virtual/partitioned-cookies/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
-# Crash inside NavigationRequest::CoopCoepSanityCheck:
-crbug.com/1314369 external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?7-8 [ Crash Failure ]
-crbug.com/1314369 external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?9-10 [ Crash Failure ]
-crbug.com/1314369 virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?7-8 [ Crash Failure ]
-crbug.com/1314369 virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?9-10 [ Crash Failure ]
-crbug.com/1314369 virtual/fenced-frame-shadow-dom/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?7-8 [ Crash Failure ]
-crbug.com/1314369 virtual/fenced-frame-shadow-dom/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?9-10 [ Crash Failure ]
-crbug.com/1314369 virtual/partitioned-cookies/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?7-8 [ Crash Failure ]
-crbug.com/1314369 virtual/partitioned-cookies/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?9-10 [ Crash Failure ]
 
 # Sheriff 2022-03-10
 crbug.com/1304956 storage/indexeddb/dont-wedge.html [ Failure Pass ]
@@ -6811,6 +6800,9 @@
 
 # Disabled to allow a DevTools roll
 crbug.com/1325751 http/tests/devtools/extensions/extensions-api.js [ Failure Pass ]
+crbug.com/1328014 http/tests/devtools/sources/debugger-ui/debugger-expand-scope.js [ Failure Pass ]
+crbug.com/1328014 http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes.js [ Failure Pass ]
+crbug.com/1328014 http/tests/devtools/sources/debugger/debugger-scope-minified-variables.js [ Failure Pass ]
 
 # Throttling a hidden-cross origin frame may stall animations.
 crbug.com/1323246 external/wpt/web-animations/timing-model/timelines/sibling-iframe-timeline.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index 6ae9ece..18b7d03 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -2231,7 +2231,6 @@
 crbug.com/1050754 external/wpt/fetch/api/request/request-consume-empty.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/api/request/request-consume.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/api/request/request-disturbed.any.sharedworker.html [ Failure ]
-crbug.com/1050754 external/wpt/fetch/api/request/request-error.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/api/request/request-headers.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/api/request/request-init-002.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/api/request/request-init-stream.any.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 469c7da..aa8a0fe 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 7594a0c97b68125066065797ecf793752562c520
+Version: b628ce32cee7ac7a52ea724d3d0335673fabb5f4
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 969fdb2..e4610ff 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
@@ -11647,7 +11647,7 @@
    },
    "file-system-access": {
     "local_FileSystemBaseHandle-IndexedDB-manual.https.html": [
-     "6f2e0d7ef1092abd79eb2e7c512f0398139ab5a5",
+     "f9a58d457fc1b122fa8cdd02e9053a359ffa52e7",
      [
       null,
       {}
@@ -144034,7 +144034,7 @@
       ]
      ],
      "overflow-clip-margin-002.html": [
-      "79dcaad63bae2ae7d8240f2af5dfd184de4f1f2f",
+      "5f6d740e0bcff6f1dc56dbc011da0dc107ca2201",
       [
        null,
        [
@@ -144073,7 +144073,7 @@
       ]
      ],
      "overflow-clip-margin-005.html": [
-      "2d03a969719cd1334e6e6912b553ba05c263d713",
+      "1b4b4aa943f1fbfecbd434be1722d7bf0e61c2dd",
       [
        null,
        [
@@ -144530,6 +144530,19 @@
        {}
       ]
      ],
+     "text-overflow-ellipsis-003.html": [
+      "a2570c558bfce63c60b73cf0fc530357e86642c9",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/text-overflow-ellipsis-003-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "text-overflow-ellipsis-editing-input.html": [
       "b235ca503a80c42d2083ba78195d9b28e1307c22",
       [
@@ -147802,6 +147815,19 @@
        {}
       ]
      ],
+     "position-relative-table-caption.html": [
+      "20ff62888008d0b344a6dfab01a0dee1aa173347",
+      [
+       null,
+       [
+        [
+         "/css/css-position/position-relative-table-top-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "position-relative-table-tbody-left-absolute-child.html": [
       "98e759a8c0a83817b3d691503e807ed5ed549936",
       [
@@ -169732,6 +169758,19 @@
         ],
         {}
        ]
+      ],
+      "shaping_lig-001.html": [
+       "059b8df72472bdcd51f3f7f55390e98b46b838e8",
+       [
+        null,
+        [
+         [
+          "/css/css-text/shaping/reference/shaping_lig-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
       ]
      },
      "tab-size": {
@@ -170690,6 +170729,19 @@
         {}
        ]
       ],
+      "text-indent-each-line-hanging.html": [
+       "2c3ac08df4a8a7962ec3ce1e1d1318ee39bdd7fb",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-indent/reference/text-indent-each-line-hanging-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "text-indent-percentage-001.xht": [
        "6da26308b266e6d1574d78238f9d12cf5a404b25",
        [
@@ -170754,6 +170806,19 @@
         ],
         {}
        ]
+      ],
+      "text-indent-with-absolute-pos-child.html": [
+       "16a6deb4769d444c88f95e1018efc5144a327f1d",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-indent/reference/text-indent-with-absolute-pos-child-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
       ]
      },
      "text-justify": {
@@ -192867,19 +192932,6 @@
      ]
     },
     "css-transitions": {
-     "inherit-background-color-transition.html": [
-      "f4dec80fad45af302675efed4b225b46d02492f1",
-      [
-       null,
-       [
-        [
-         "/css/css-transitions/inherit-background-color-transition-ref.html",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
      "no-transition-from-ua-to-blocking-stylesheet.html": [
       "4967eabda86bf42be467b826f8782e91a115748e",
       [
@@ -246749,33 +246801,15 @@
      "545f0bec6d9822e7862fc4010fb8d52d3dc4b768",
      []
     ],
-    "file_to_save.txt": [
-     "3f5238e841d7f3af9a87fb8e8fe4e784dc662a67",
-     []
-    ],
-    "idbworker.js": [
-     "359f6fb69119b5c6605047f0e0c38ef6fe847009",
-     []
-    ],
-    "interleaved-cursors-common.js": [
-     "a76ec528c99c72767a7889df1d7d7df582485ce2",
-     []
-    ],
-    "key-generators": {
-     "reading-autoincrement-common.js": [
-      "45c8ffef923870909cb9b0e2af128081e5bce41a",
-      []
-     ]
-    },
-    "nested-cloning-common.js": [
-     "db5f710ceb5652ed8b9746f883948fac41262d6b",
-     []
-    ],
     "resources": {
      "cross-origin-helper-frame.html": [
       "997c5a2b72bafcad3421ccb48e48e323de6ef6f0",
       []
      ],
+     "file_to_save.txt": [
+      "3f5238e841d7f3af9a87fb8e8fe4e784dc662a67",
+      []
+     ],
      "idb-partitioned-basic-iframe.tentative.html": [
       "ed6bbf272f0af4609e77afa7679ec5f0d677e100",
       []
@@ -246787,19 +246821,35 @@
      "idbfactory-origin-isolation-iframe.html": [
       "d405ea48e15e298241a2c400a6d04adbd054e1e5",
       []
+     ],
+     "idbworker.js": [
+      "359f6fb69119b5c6605047f0e0c38ef6fe847009",
+      []
+     ],
+     "interleaved-cursors-common.js": [
+      "a76ec528c99c72767a7889df1d7d7df582485ce2",
+      []
+     ],
+     "nested-cloning-common.js": [
+      "db5f710ceb5652ed8b9746f883948fac41262d6b",
+      []
+     ],
+     "reading-autoincrement-common.js": [
+      "45c8ffef923870909cb9b0e2af128081e5bce41a",
+      []
+     ],
+     "support-promises.js": [
+      "9128bfe151ab9cda59ff6e3d4487024b0b7cd0cb",
+      []
+     ],
+     "support.js": [
+      "8dbfa6f1e37d7631bf5f69b9da9b906876c5d2cf",
+      []
      ]
     },
     "serialize-sharedarraybuffer-throws.https.html.headers": [
      "5f8621ef83660c66f0d037ea28fafefb558140f1",
      []
-    ],
-    "support-promises.js": [
-     "9128bfe151ab9cda59ff6e3d4487024b0b7cd0cb",
-     []
-    ],
-    "support.js": [
-     "8dbfa6f1e37d7631bf5f69b9da9b906876c5d2cf",
-     []
     ]
    },
    "LICENSE.md": [
@@ -278495,7 +278545,7 @@
       []
      ],
      "overflow-clip-margin-002-ref.html": [
-      "84110e57792086613515a824483fa0b9a8d75ff0",
+      "412602adae9175ac2f898822afdf5606723af531",
       []
      ],
      "overflow-clip-margin-003-ref.html": [
@@ -278507,7 +278557,7 @@
       []
      ],
      "overflow-clip-margin-005-ref.html": [
-      "84110e57792086613515a824483fa0b9a8d75ff0",
+      "412602adae9175ac2f898822afdf5606723af531",
       []
      ],
      "overflow-clip-margin-006-ref.html": [
@@ -278808,6 +278858,10 @@
       "7dbadf995ed89bc3032c4ca1b53e1cebecd6237e",
       []
      ],
+     "text-overflow-ellipsis-003-ref.html": [
+      "42349bbead88538a3a6c49a75d5dc2069367d1f5",
+      []
+     ],
      "text-overflow-ellipsis-editing-input-ref.html": [
       "3902072bc58b7bf62290edafbce1b735288af716",
       []
@@ -284283,6 +284337,10 @@
        "shaping_lig-000-ref.html": [
         "7b92b83625b3800d3791efbe1248d8cc5ca2beb0",
         []
+       ],
+       "shaping_lig-001-ref.html": [
+        "df71a1d01925a908b97326e74a90c09b9b87ca4c",
+        []
        ]
       }
      },
@@ -284706,6 +284764,10 @@
         "517f9e65fde0f2951fb8175b77a13eaf3514a62d",
         []
        ],
+       "text-indent-each-line-hanging-ref.html": [
+        "3357d7d8f5fb766b613b092839f331f3654053b0",
+        []
+       ],
        "text-indent-percentage-001-ref.xht": [
         "5b065d1db7ac1e399668e8588727be09922bf62b",
         []
@@ -284717,6 +284779,10 @@
        "text-indent-tab-positions-001-ref.html": [
         "4d85456dd172b108486b51eedddb687209a30b2a",
         []
+       ],
+       "text-indent-with-absolute-pos-child-ref.html": [
+        "e5feb2c7f98dcf426a7874ca2b57e0d15f18ffe3",
+        []
        ]
       }
      },
@@ -288064,10 +288130,6 @@
       "f72f11dccae5e8b63de6148573723f86fbb4c708",
       []
      ],
-     "inherit-background-color-transition-ref.html": [
-      "b7a5824836e157f21649fabe12a701b860e04c9f",
-      []
-     ],
      "no-transition-from-ua-to-blocking-stylesheet-ref.html": [
       "93b4ae982e80d31df4cb0eac448ceb3341c57a81",
       []
@@ -304550,6 +304612,14 @@
       "43c44cffd64e01f12a8d0dc22bbddfdd05a79a90",
       []
      ],
+     "reflection-credentialless.tentative.https.any.js.headers": [
+      "32523a697886f7fb26ab4456e5b14cb19d8c1aae",
+      []
+     ],
+     "reflection-require-corp.tentative.https.any.js.headers": [
+      "6604450991a122e3e241e40b1b9e0516c525389d",
+      []
+     ],
      "report-only-require-corp.https.html.headers": [
       "289659a41fdf41178781c764643f8946f4ec09b7",
       []
@@ -337454,42 +337524,42 @@
    },
    "IndexedDB": {
     "abort-in-initial-upgradeneeded.html": [
-     "20040158e9c99482cca547764bbb4a22ae358623",
+     "e37056974fac6364b64f36f1b6fc357ee21508f1",
      [
       null,
       {}
      ]
     ],
     "bigint_value.htm": [
-     "9ce980a2d6eddfc514950543524dab9aa8f91325",
+     "d3934fc7c45b9f2a53074f7b76d2847820d91b76",
      [
       null,
       {}
      ]
     ],
     "bindings-inject-keys-bypass-setters.html": [
-     "91d586bde35dcfc89da49068b1a3b63295552bb1",
+     "866b9397ce74847ef62ec2a3c71724e3e7543501",
      [
       null,
       {}
      ]
     ],
     "bindings-inject-values-bypass-chain.html": [
-     "02fdb8a64ca1774ee8b3a2db40650141149dc684",
+     "b03e425618c37b7bdf36cd2b92ab533f8f32f978",
      [
       null,
       {}
      ]
     ],
     "bindings-inject-values-bypass-setters.html": [
-     "c16c0a4e010f9805796cd93f9cbd1f141e6c91e5",
+     "d10ff636db64ed87a392859497b6f97bdd4680f0",
      [
       null,
       {}
      ]
     ],
     "blob-contenttype.any.js": [
-     "0b2debae7b1a6498523459ee97882257a7ac974c",
+     "ee5105d128940caa3c3ed28ccf8570e4dcdfccc3",
      [
       "IndexedDB/blob-contenttype.any.html",
       {
@@ -337500,7 +337570,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ],
         [
          "timeout",
@@ -337520,7 +337590,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ],
         [
          "timeout",
@@ -337532,7 +337602,7 @@
      ]
     ],
     "blob-delete-objectstore-db.any.js": [
-     "61d7bad914e96a9063c97e3a14844aa8c30079e4",
+     "773099c12c5681cca54216755977900c5d0ef0b0",
      [
       "IndexedDB/blob-delete-objectstore-db.any.html",
       {
@@ -337543,7 +337613,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -337558,14 +337628,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "blob-valid-after-deletion.any.js": [
-     "d353bc3a990a0cd66f2927552c584668d8ce97fd",
+     "7a080fde683c8bb351df353978d33948c95d7694",
      [
       "IndexedDB/blob-valid-after-deletion.any.html",
       {
@@ -337576,7 +337646,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -337591,14 +337661,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "blob-valid-before-commit.any.js": [
-     "0ec2e2903fba7cbc274c5c4055b1cee1ac3544ea",
+     "a4989ab194186a362bf53cc3f69a0aad29382e99",
      [
       "IndexedDB/blob-valid-before-commit.any.html",
       {
@@ -337609,7 +337679,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -337624,35 +337694,35 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "clone-before-keypath-eval.html": [
-     "c885620e292219ec4cf23514a49a9044a866322a",
+     "bba11d040be1fee42275db03fe9ae91fe6d0c20e",
      [
       null,
       {}
      ]
     ],
     "close-in-upgradeneeded.html": [
-     "fb278f91dba35fa496c5221027f9fd0337e09d1a",
+     "09229813ff35bcf1d73c533c2433b333ba6a8fba",
      [
       null,
       {}
      ]
     ],
     "cursor-overloads.htm": [
-     "343e5a4cc1f22bb472e595f5eff1798e3227b784",
+     "6dc957de55dde1cc73c0049d1e1c165772c6c88e",
      [
       null,
       {}
      ]
     ],
     "database-names-by-origin.html": [
-     "2224d5b5c371f791a64849f36ace5b830f6e1a65",
+     "374b05c8fd292185403711a34515aa5566f34c54",
      [
       null,
       {
@@ -337661,7 +337731,7 @@
      ]
     ],
     "delete-range.any.js": [
-     "c11c68a609e444cffc9dd9aa1387cfc01be9a9de",
+     "db45c3ea6ca786ff3ee532d07e65c92adacb4d9a",
      [
       "IndexedDB/delete-range.any.html",
       {
@@ -337672,7 +337742,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -337687,35 +337757,35 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "delete-request-queue.html": [
-     "3459dfc04d8f913aa59e90dc63e5e6fe6d8b943b",
+     "d8dfbf9a6061dd89244841e9edc42426b5f3e9bb",
      [
       null,
       {}
      ]
     ],
     "error-attributes.html": [
-     "33f546496b312dcbf3291fa9ebe61e71e2de59c8",
+     "f410660b1df25c4bb0e533acf20f97354ff5823d",
      [
       null,
       {}
      ]
     ],
     "event-dispatch-active-flag.html": [
-     "4b97c98dd83972322f04ea0221aff3111f3f22d2",
+     "c430c3b2c50dc3440610d1a33f43fbd9ed433b5e",
      [
       null,
       {}
      ]
     ],
     "file_support.sub.html": [
-     "157ba6cd0910daaab0ba4752f173848a5dc39746",
+     "fe4bdf13ed18098c9e35643f20249b5477a073dd",
      [
       null,
       {
@@ -337724,35 +337794,35 @@
      ]
     ],
     "fire-error-event-exception.html": [
-     "0a3f12265894f03adfb2b6577e5d35dbf0c89c5d",
+     "26803eb826366d2f6fd8499a22226c5bf74ab8dc",
      [
       null,
       {}
      ]
     ],
     "fire-success-event-exception.html": [
-     "ab0ac44eb7c33ba5f62caa6dca49935c8296cf26",
+     "0961a12141092fb29af633a1e586703015190fca",
      [
       null,
       {}
      ]
     ],
     "fire-upgradeneeded-event-exception.html": [
-     "1a8163a58b15606e2f00bc6439238c03267ce83b",
+     "7160dbdfc7d6b52239fc8c4b07a0543fdea83d6f",
      [
       null,
       {}
      ]
     ],
     "get-databases.any.js": [
-     "2e533dceb0187902045c9e77fb685ba298a10f27",
+     "ac1ab15f27f7624238ab695957f50cc5bde1b453",
      [
       "IndexedDB/get-databases.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -337763,7 +337833,7 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -337784,14 +337854,14 @@
      ]
     ],
     "idb-binary-key-detached.htm": [
-     "5c368d08fee0cb30315d63484510332a728cbf5e",
+     "06a2cc3554352dbcfb1eb8f48fef787c97fa0199",
      [
       null,
       {}
      ]
     ],
     "idb-binary-key-roundtrip.htm": [
-     "36b7863fe05d72a1a3e1ba9bb3fc803838409065",
+     "79edd28d059f65a7f3ea5b41b88c6f6e4181c6f7",
      [
       null,
       {
@@ -337800,14 +337870,14 @@
      ]
     ],
     "idb-explicit-commit-throw.any.js": [
-     "751096a3307d88ca910e8844579b1c0c59a41cec",
+     "8a9dd94056e6326f6743acebde9fdb17ec2af693",
      [
       "IndexedDB/idb-explicit-commit-throw.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -337818,21 +337888,21 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
      ]
     ],
     "idb-explicit-commit.any.js": [
-     "922f2907c9536becbd083e5229f263682c01123f",
+     "898d461d7b590a3dd2b0c2f06cb19f25ee48ffac",
      [
       "IndexedDB/idb-explicit-commit.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -337843,7 +337913,7 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -337871,56 +337941,56 @@
      ]
     ],
     "idb_webworkers.htm": [
-     "9c29d00b30e13b0ed719ebc15e09c0d1e6201199",
+     "5a061c26502413c20c333c574a6afe3e61002efc",
      [
       null,
       {}
      ]
     ],
     "idbcursor-advance-continue-async.htm": [
-     "ccadb7fa95a606e2818691de46512a3b5a32309e",
+     "38532f24a6e1c9304b32fd45e473400bad7cb148",
      [
       null,
       {}
      ]
     ],
     "idbcursor-advance-exception-order.html": [
-     "a0294e9b7a1e7342270ba7837dd44f0ae26dcfb6",
+     "00464cb33aaea7c30b981d08ea42c8e6e0c4f09f",
      [
       null,
       {}
      ]
     ],
     "idbcursor-advance-invalid.htm": [
-     "67e03187c0fc5cd1ff76404440439aa52cd0f26b",
+     "5459f0bd4eeba509f82d4fa9457413dd8691bbe7",
      [
       null,
       {}
      ]
     ],
     "idbcursor-advance.htm": [
-     "f08a2594f3dd00c3ed611f55da85dde1c4296433",
+     "208d66f76e55edc2dfe7b19c5be59763dbfb87b1",
      [
       null,
       {}
      ]
     ],
     "idbcursor-continue-exception-order.htm": [
-     "4e697bc43024524c478ebc5ae19577968ffae407",
+     "6561ec396c23e13df200ed43c7515305ccb7d2ad",
      [
       null,
       {}
      ]
     ],
     "idbcursor-continue.htm": [
-     "372d452f78134fd2028cb9c845cbe899411a0934",
+     "37209c2832277787c3bc8ecb7dcb9f1a4808f988",
      [
       null,
       {}
      ]
     ],
     "idbcursor-continuePrimaryKey-exception-order.htm": [
-     "0df6e3a3a92426c71a7fec00f56d6f70f5dd64c4",
+     "477dabc60e800ac4744b604488170c9fd522f96c",
      [
       null,
       {
@@ -337936,91 +338006,91 @@
      ]
     ],
     "idbcursor-continuePrimaryKey.htm": [
-     "df292ce3e230de45edfbce959d42639882465dae",
+     "8cc5ac0a06961efac8791724821cd3cd60333075",
      [
       null,
       {}
      ]
     ],
     "idbcursor-delete-exception-order.htm": [
-     "96c7297b93ff11de22bcf3acd9bc43589d8e4681",
+     "72d565749718a624344480d4d336cf23776f71e3",
      [
       null,
       {}
      ]
     ],
     "idbcursor-direction-index-keyrange.htm": [
-     "2de3854dc9bfc0e6e9cd986883c4a5cbcd86579b",
+     "ff2d2fa4d215e58f9ba9ab88bd74e7006340ea7f",
      [
       null,
       {}
      ]
     ],
     "idbcursor-direction-index.htm": [
-     "0eb926d9ec0ff0bbdb87ebb9ae55cfce6831bba7",
+     "c8539ebe3040d03df51fb80c433bd2dc51c8242e",
      [
       null,
       {}
      ]
     ],
     "idbcursor-direction-objectstore-keyrange.htm": [
-     "96f92a0445a46a2a93183a2da24350e7c2c35318",
+     "a9ac619359e9aaa01c2f549c1da07a3248ae4420",
      [
       null,
       {}
      ]
     ],
     "idbcursor-direction-objectstore.htm": [
-     "85088ee724442c251a9462145ba1a172f815938f",
+     "3dd1337f53f5188dea5a91699bcfe0438f97c78d",
      [
       null,
       {}
      ]
     ],
     "idbcursor-direction.htm": [
-     "246cd79aac8b3660d9c8179f13e7e0809a862787",
+     "d0af677ffc319a0e0f8280bb87a0a48c30f9e3d8",
      [
       null,
       {}
      ]
     ],
     "idbcursor-iterating-update.htm": [
-     "d2a7b9f01e61afed41f11956482cfc631cd5421a",
+     "00fdb5a0c008bcc1d2f5ebcef8c2bbc0ba517f4b",
      [
       null,
       {}
      ]
     ],
     "idbcursor-key.htm": [
-     "8014c4221eb51d6d3322d259541803f66c3c245a",
+     "89dff5d664fb8a19d8c5c2fd1685ad0ee9a0a516",
      [
       null,
       {}
      ]
     ],
     "idbcursor-primarykey.htm": [
-     "2fe24ece8b8ee8a4e3097b0693b60fbbd56f85b6",
+     "a517bb41c6589b058874459c1def0060b8564640",
      [
       null,
       {}
      ]
     ],
     "idbcursor-request-source.html": [
-     "9216a0c4416b47ab5ab51e0b407429512a0125d2",
+     "9e2f72b4d45beb6941783a08e69a59dafbde5366",
      [
       null,
       {}
      ]
     ],
     "idbcursor-request.any.js": [
-     "60e68548d20ce0fb55c1051b4410e7e49e06f644",
+     "79d4bca2c4b59120bb17243097f809992fe0e499",
      [
       "IndexedDB/idbcursor-request.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -338031,406 +338101,406 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbcursor-reused.htm": [
-     "603041e7cdf98bcbbf9a513970902db72b038e97",
+     "e3f8de378c62205882417350b846f62a06f4e70d",
      [
       null,
       {}
      ]
     ],
     "idbcursor-source.htm": [
-     "b23551c8d49c60ca9225b4d6ce0a8fa5eeeb9013",
+     "608e1a0326cf6a4b55d653cd6cb072d2ee479ac1",
      [
       null,
       {}
      ]
     ],
     "idbcursor-update-exception-order.htm": [
-     "22c2940ac4ad6b5df73d5cd2973a35e8037acca9",
+     "9324752d5eb7f4d3ccd8c63fd660627a9890f46b",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index.htm": [
-     "0e5c5147496546067a03fdc6c8c95b6bc5bf3e24",
+     "47ffcc12456f5299eb46e577d6150aada245f78a",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index2.htm": [
-     "93660566f84d7c47d021aff7ad0504aacad51ea2",
+     "fd267a66622f58185e0ee71da2cfc307f532f1b8",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index3.htm": [
-     "27e040d4fece4be28f78b0b7ea9dd8bee33bd9b7",
+     "a531d68682effec5a74fc7c0ef738a4267c6977b",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index5.htm": [
-     "88b4ed88919ef8635f1bebde1bfff39e577c4f0e",
+     "04e3d08436601522bdfe94b389b1bc590a4d7713",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index6.htm": [
-     "ed4c8f3dadacdcacf70f688a98e736bada2d3182",
+     "3a1168f57a5af9f9c209b755b97bb0ca1ce6cedd",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index7.htm": [
-     "52f8ea2ba6929acb3116c8caca2e20676ae0e031",
+     "f5ecc6144c234f056786a6f165c72979ecaf8ea2",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index8.htm": [
-     "a3420b162bee67f65e53a0b4c5226c1f5b30138c",
+     "1f9ff9c453ae393ad77b2c111c8208cc2e3d7926",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_index9.htm": [
-     "9aba54b1fa1c8df49f66b3e32d5019b46d7627bc",
+     "1756419c6d254f072e198b4cd96c46260314a751",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_objectstore.htm": [
-     "5ae9a813c70c2c62ac77874de1360c3eef4d915d",
+     "4ac0ed78fb0e7aeb3930478b7c5e6228fcb89308",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_objectstore2.htm": [
-     "9af1925cdefec5e7ae4fad065ebd8245f2d17088",
+     "d9e3fa2e1045f8a7d9bf3989c390509ba739cd34",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_objectstore3.htm": [
-     "d2f2f84719e933e112bfa482d91a9267e47e04a8",
+     "84e8dd80513c7a7ac478277f27e590400601d426",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_objectstore4.htm": [
-     "57e4f589c41aab907a90afc0f63d2b4503d9d8df",
+     "134dcf72790a276e3912d8cca4cc2b6a7fb2b0ee",
      [
       null,
       {}
      ]
     ],
     "idbcursor_advance_objectstore5.htm": [
-     "454329d260cacd40ca18649056d50c0253a1950c",
+     "2c6fa640aed149039e559de04c4a1ae14dc4448a",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_delete_objectstore.htm": [
-     "7cae5fd0e3275fd10450f169ff96dc263cc72be0",
+     "722612210d4969d5cb2f4d43d2b0592f677fb008",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index.htm": [
-     "8b0d079a939c14456f95e2e256c49da2fbf1a9aa",
+     "5649f97d468e588ad184b4fc6f977aa5393df8f8",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index2.htm": [
-     "84a01092444f68715f668d5edb1b83e96c1ba5d2",
+     "a3b082f8a7765ba9ea93789430850a12982d5718",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index3.htm": [
-     "f2bd4fc62e827e909038d9c63804629755b09f93",
+     "c5b6c1841d3b6dbb5ceb5744801a47263cb4a3b9",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index4.htm": [
-     "6196bb0137560a5248fe6e9adefdce95bee3187e",
+     "f186499c50ca17fad38e3c024b97defb8f8d0ae2",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index5.htm": [
-     "101d5db81746250901a6052fea488042a0c8e2b1",
+     "298acd97ea572078558cd5f4e9bc3c906c82455a",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index6.htm": [
-     "0040ca72137e6adbff9b90c73f857ff73b277b83",
+     "c31e63133aaa9a9b66ea1a2fd1c87c58f5e07fec",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index7.htm": [
-     "7db922d6b840ca39013a7048c1df927616373557",
+     "61bfe85b2749e8d21629a973e4015b18aace6201",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_index8.htm": [
-     "b4c69aa08fe74dbeba82a4ec2caace8cc7466052",
+     "e4cbe7261f3957b3d3dd733a3fcd41e5a54d2d92",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_invalid.htm": [
-     "f9df05aa533b4c127010b88f14e5d7111e403740",
+     "877255c10fbce87c5c7d5ebe7814856e306694bd",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore.htm": [
-     "e86edc464cbeb6632c46f978019402d2db1f703b",
+     "08e2d703a8a3354b371c14a745a8742cd0e833c5",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore2.htm": [
-     "8cff47088fcfcaf2777396c0816ad18f0c59f760",
+     "92114ba17dd474b4b38489d15faaaed2d5845739",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore3.htm": [
-     "385dceaaef736db1584fec082bdae57df05fecdb",
+     "e0d1780f432ea246f3470df5c0d0fcfdd65d6bb9",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore4.htm": [
-     "480bd2f1f066d32a1bfcce225812d725ce2537b6",
+     "2ed3a4297d6d0ce9668b79d029d9e12b27fcb190",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore5.htm": [
-     "5dff6d8f763d6c95c5b044a303651cf4f3d2dfb9",
+     "1796003f4841fbc9ae66c7b0c7350825f3a01390",
      [
       null,
       {}
      ]
     ],
     "idbcursor_continue_objectstore6.htm": [
-     "7f56f838ea51bfaa6558ef514307829d3df9f174",
+     "7a2b50752ce1e8862c72b8d6246616a0f6e3c20f",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_index.htm": [
-     "8cddcea994f35ef21af500df7b90287e46fb3ae6",
+     "f0ff049fbfbd76676c7ed1f56a1315744687dde5",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_index2.htm": [
-     "7b9970d3ee0035eadf0bc9f55cb01b5ba7e7cf69",
+     "15003bbd548c470574dac660fd8dd560bf179ced",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_index3.htm": [
-     "3b4241d50f99e89de1d251eef715fe3b297e5f6e",
+     "afe945e646277bc39f96b8a99be171bb5a6a361b",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_index4.htm": [
-     "cccce2be271c5ef7580522b9afa4d3628376e5b1",
+     "8eb6915b885879be61c935b5cdda64ab9d55ea15",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_index5.htm": [
-     "af08367c4cccf1a97aae5e0348bee894b7056286",
+     "76ce6d0e50e10dfe86bcabbb45c05cb9158ebfa5",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_objectstore.htm": [
-     "044a4e57183c65769137def838dc56fb47214946",
+     "ca3ae48dc5dd94add822d9546b909438e0b2efc6",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_objectstore2.htm": [
-     "b4eac9b675f2e4ea96e1d7ba912fda7765528b20",
+     "ddf574aef17fe12526628287b768d31abce1e4f0",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_objectstore3.htm": [
-     "05fa9edb723f1211a3344f8d437d94d52c2f3c94",
+     "4a4ea736c41077d5fc4ed1ab86c4e80be67d5fec",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_objectstore4.htm": [
-     "b0d993ab961a41e4c736cadf0ca90d483c899f58",
+     "5ecdb4bf1790b8e7ec19548012b8f1e652948c4a",
      [
       null,
       {}
      ]
     ],
     "idbcursor_delete_objectstore5.htm": [
-     "94a0926a50c2f4f7e1f17e91de4610fe1a174bdc",
+     "cad6e4d25da7d06af57ab4cb7ecf949ce021f779",
      [
       null,
       {}
      ]
     ],
     "idbcursor_iterating.htm": [
-     "b555d7447e17b1996a559928d3466c38199a5c70",
+     "beb109b99bcc750ac0c5c9218239e0b2f11104a4",
      [
       null,
       {}
      ]
     ],
     "idbcursor_iterating_index.htm": [
-     "950fa77c9463ae944fca00ac98598711e5de1b06",
+     "bde6cd8bd72be05e153832313958a98872ed7785",
      [
       null,
       {}
      ]
     ],
     "idbcursor_iterating_index2.htm": [
-     "9110a2e85b5e8e5915b97937e1b3f1823471e540",
+     "c71a7cb7133eb698bfafbeca56ef36f94708918e",
      [
       null,
       {}
      ]
     ],
     "idbcursor_iterating_objectstore.htm": [
-     "4d54de8eac80ab371a8ff751d933e5673e2b0212",
+     "10b394287ac28c1d15c72613ddace8ddb5b6a176",
      [
       null,
       {}
      ]
     ],
     "idbcursor_iterating_objectstore2.htm": [
-     "299d4c1cd3f75a495fb31c0415d93e4d1afea6d8",
+     "119243f5cc8d1e7403bbc6d9ef268dc11f64fcad",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index.htm": [
-     "5fa1f940a99e8395d2cda81d11eb177c6d86e2e5",
+     "ecc08d7cfcfd90f080adc1c1b23ade88421f5fb0",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index2.htm": [
-     "9ec247b01bd4a23f92bbbf25f3592b5bb3ff77d7",
+     "25a59aedea6b30cba953398c751c71d9aabcd7dc",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index3.htm": [
-     "9386583a06affb768db99f8437d7f976c3c9b52e",
+     "a7d87eed821fc78a13c4ebd2d06141e88f5cea95",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index4.htm": [
-     "463b2f9025622af7b2f21308f3f6d717e9b97674",
+     "c7b05270da2e3fc7e04d6f79b8deb834c13bc239",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index5.htm": [
-     "564d904f9fe86511161fe82c2eb2d6ac70846371",
+     "52af19d7d679afb00666942698ce3901650a49d9",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index6.htm": [
-     "9639fb9f7337e347cdfb813a10d34f708bdcaa96",
+     "ca34e07d7db4b33cc956df3e2f8a72129f649f8e",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index7.htm": [
-     "25f59a1e32c6dd0487e0b5ea58d6453fc51b58cf",
+     "44a37bc6e268865a04fe1b039a76c83c0a66d0d7",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index8.htm": [
-     "cf33e1d75040fd1156b63cd56f17dec1384f46a0",
+     "1e7cbdc5cd69afa75dd3bf5a65ff40a5e55e2570",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_index9.any.js": [
-     "d666b598be04cb16f7a6c57ccac19fdc62e81810",
+     "1f0d2e7976839d1cd89181741954b48728019dbd",
      [
       "IndexedDB/idbcursor_update_index9.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -338441,126 +338511,126 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
      ]
     ],
     "idbcursor_update_objectstore.htm": [
-     "8aa6a13721d6598a6b2d687fdc08396d9d0eb8c7",
+     "13ed4ad4789e818aa963af4266aed39e27532bec",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore2.htm": [
-     "6c7a13370a996d87b925b9086018971888c60a3c",
+     "d07eb613f76c880825d7881655dc40069b6cb0e5",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore3.htm": [
-     "e19f5853bc41becf9c50631631858171b193c3ef",
+     "3582f0967ca3fc346c0bb253f1f97524f761701e",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore4.htm": [
-     "07209e55bb2b095d020494b9cc4e5ce5249bc075",
+     "6e63bc42f5c879ef3a4acc32a7558b37c3f416b1",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore5.htm": [
-     "2b73a51d42e79fb32e1f1a241f362fd75e3e2de8",
+     "e358caa3929afedafc55142f4d54ca3f0810b482",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore6.htm": [
-     "a2f8140829a78a5039dc6b3fa8dab4330146ee05",
+     "c961debfb2773fc659e1387b8ebce58751fcd576",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore7.htm": [
-     "4751289e6dfe197d2e52a41e8761ade655c0ff03",
+     "c71cb66a2fd25a97360ba3e8c15648be8548fff9",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore8.htm": [
-     "3dcb94e9fbb23208dd85ef126f0007409d8be4b2",
+     "113ad5f4fd9d5c927d393db537c56e5647ac16dc",
      [
       null,
       {}
      ]
     ],
     "idbcursor_update_objectstore9.htm": [
-     "c112b073fc7b09fdf94dd7e51a83029760da82fa",
+     "55b624f540a24fb112df31e4bd87fd20e0e872e6",
      [
       null,
       {}
      ]
     ],
     "idbdatabase-createObjectStore-exception-order.htm": [
-     "1d6cbe8ea45dce9def0a2d60ee482379b83a8b65",
+     "1ca2ce1d7ccb9915c616645e626e5d0c417cdc2b",
      [
       null,
       {}
      ]
     ],
     "idbdatabase-deleteObjectStore-exception-order.htm": [
-     "dc1bdf34015f0f14b8c9a70bd2a2bc3b00764c6e",
+     "4d98a31f120af4503a92d1e695199485e552d887",
      [
       null,
       {}
      ]
     ],
     "idbdatabase-transaction-exception-order.html": [
-     "4dfb821c67b58f10b4978fcd42df5c342bee2bc3",
+     "d06efe1d2f91e7bc77a8c0ade62c9bc62d6d1702",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_close.htm": [
-     "781f8cba9d18c33b5ce58a58919c02dd96772721",
+     "8ebebaf1b8816d0beaec02899114d7c60a442b89",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_close2.htm": [
-     "68bafb9463828d75be8a6c513dfa8f5f6bb167cf",
+     "26bc4ce6383ec8d7abdec06c7cfbd112f9b5afc0",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore-createIndex-emptyname.htm": [
-     "97f860a7a8f23c0fc3f26c66b263e14860ec82d9",
+     "161902c2ab0eb655c9642d58d2b1bc4328dabc21",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore.htm": [
-     "36fe93250010b476e7c583a422cf0a11db480544",
+     "783bc0a183458db5c486494eb33d57fb123cab68",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore10-1000ends.htm": [
-     "dad6fd3a933f544252c88eb7b58c3cf75cddce7d",
+     "6997562d3ae68751d35950849fd839d198b1845c",
      [
       null,
       {
@@ -338569,63 +338639,63 @@
      ]
     ],
     "idbdatabase_createObjectStore10-emptyname.htm": [
-     "cee4754a8eb4fa375248e3e1478456157496add9",
+     "0ed28e9e7ee0c2cb80229bcf0ade9dcfb085629b",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore11.htm": [
-     "ca04f21d6d0f57ffc6f738a602cd6225a0e64827",
+     "f1a9310c070d00f87df9be6741fccffa92ca7dea",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore2.htm": [
-     "78f06ff9b909ce4ddf7be72f7f035029f1bb5af6",
+     "e819678acb168e073f1550223f38c2f7b55dd0d4",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore3.htm": [
-     "0eeefd613c2209fda26847f1232424f37f44e946",
+     "d0006bfe1fa6a7a8297d3c5bd45d4b5686f4d4a1",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore4.htm": [
-     "9c7279929ebea4a925713a05f46297513d0ea1e9",
+     "bd5989335a4fff99f129eaa6cf165de87f91e5d9",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore5.htm": [
-     "7e205096e4cee9b76cc9b7e75399b179caf214c8",
+     "a30b73c594669956967a8e371ab5667023bf82b1",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore6.htm": [
-     "6c7a542db0d688bfb7f985f31fcadc60787fa527",
+     "54a2df81e9d3999776f7581ddca5f10293b3eda9",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore7.htm": [
-     "37b4e8ede005685367c712b11052243d7196d7eb",
+     "b2a7a03b1c8713d467b9d5eec6ae2135ed01e8ce",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_createObjectStore8-parameters.htm": [
-     "7cc69765b0f8cf341c149852f2aab0d8f45bf688",
+     "99a473d418779b9283734a9f3117b8bac52305a1",
      [
       null,
       {
@@ -338634,70 +338704,70 @@
      ]
     ],
     "idbdatabase_createObjectStore9-invalidparameters.htm": [
-     "1fdad86308563bddf89f0c06de80fcaa102bd82c",
+     "65b7535abbadbda282a8849a44da7222825aa4c3",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_deleteObjectStore.htm": [
-     "b69570cc0630c0fea5da48315fd6fec457ab3cc6",
+     "e3f6a775c56d9de04da6261d7b6e189cb1b2139d",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_deleteObjectStore2.htm": [
-     "531b3d37aaae4a230ab6e21972b220cde4fb3a06",
+     "91f118ef62a3bd009dc2e9961f0dc87f554ccafc",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_deleteObjectStore3.htm": [
-     "a8db5b49cbbe984788b7000e9679f24cf3228e40",
+     "3ddbe8ec62b42f24f54445ae3b3cec25793ee3a4",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_deleteObjectStore4-not_reused.htm": [
-     "729fce6db5a8df7177dde6027020daa6fad9cd19",
+     "0a5e1b83cf1676149a1c547332264f682edf2572",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_transaction.htm": [
-     "c883167a62a4d8a4291057d7079f18fa50a8354e",
+     "8e8264f8eab9ab2f890e38cfe9c18b7a3f1b7428",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_transaction2.htm": [
-     "310014bc5105695e8fe690362c0f23c3f0c676a0",
+     "e3b4d41f4ed4dbe45bb2bfad5d4018465d6c9c45",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_transaction3.htm": [
-     "4d2542a5eeff7b4a3642570b355fe94bcf9df8f3",
+     "f664e9ab20da35f43c03a6827a0a2e48db41ccad",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_transaction4.htm": [
-     "1df37ab373934525f0fb878521d7100f44180d10",
+     "3a164c25f59ced647599d3cc33bdcd063b9edff9",
      [
       null,
       {}
      ]
     ],
     "idbdatabase_transaction5.htm": [
-     "4d2bdcbe4bb22508c9cccfabb04418580695be32",
+     "451939731faa24afe7a7a1d703b5d5eadbd54062",
      [
       null,
       {}
@@ -338718,14 +338788,14 @@
      ]
     ],
     "idbfactory-deleteDatabase-request-success.html": [
-     "a44c5c244dc81ff4c9a7691a6c5d0da37471bc0d",
+     "130c427a407e40aaca1adacdb4f78d1f50188ead",
      [
       null,
       {}
      ]
     ],
     "idbfactory-open-error-properties.html": [
-     "92e772e0fa87abd3155061d9527018ffb60f619f",
+     "c4bc3ffaa5b13a6d642766fb9e4452fd2d9673e1",
      [
       null,
       {}
@@ -338739,35 +338809,35 @@
      ]
     ],
     "idbfactory-open-request-error.html": [
-     "5d69f57153f0ab880b5a0c3dc0432e3d53ba9fe4",
+     "cfd6862afa60406056a2e84fa905b21f4345e127",
      [
       null,
       {}
      ]
     ],
     "idbfactory-open-request-success.html": [
-     "0c2ab948531a194fdc76423b54a327e500cc0dad",
+     "fb6ff9034de85c017e5b586e14f445da18b1b099",
      [
       null,
       {}
      ]
     ],
     "idbfactory-origin-isolation.html": [
-     "3f200877ba7c75a2bcb1bf670d0f0f6b25b2c69e",
+     "90d1abf7c5fa1d0912c3289f5bc710b25f9f29f0",
      [
       null,
       {}
      ]
     ],
     "idbfactory_cmp.htm": [
-     "7b301ece46d6b7f1753b8a61ae96674882fe81cb",
+     "e896743ff6ef4cf8987ded93f9ae48aa5ced0812",
      [
       null,
       {}
      ]
     ],
     "idbfactory_cmp2.htm": [
-     "1932bbab49e09acc90358b9a44d800c30fb61ca3",
+     "68f87333db07f0d1799d0fa2161a025e3f143c84",
      [
       null,
       {}
@@ -338788,105 +338858,105 @@
      ]
     ],
     "idbfactory_deleteDatabase.htm": [
-     "fd7a908d3d87fd3777d36893445edb548844d5c8",
+     "28c18cccbb0793386210aea0843e429ef77ca7da",
      [
       null,
       {}
      ]
     ],
     "idbfactory_deleteDatabase2.htm": [
-     "0c7c73a28fc83ddbedfdcc420a5f1d11e60573f7",
+     "e503c3437fbf942ee78d3c147bf4a597228f82fd",
      [
       null,
       {}
      ]
     ],
     "idbfactory_deleteDatabase3.htm": [
-     "ebc55dd6f2849e5b35bfa7440341a5bc0a45332d",
+     "2895013f27184bcdfca2738c880b53206ea4ad8b",
      [
       null,
       {}
      ]
     ],
     "idbfactory_deleteDatabase4.htm": [
-     "2f680853b90d63b60696d47e0abdcdf02b3abae8",
+     "5a0d90bf50558f7b9ae14627106634538070ab24",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open.htm": [
-     "bca2cfdc80158b6a86236329e8bac6191a546841",
+     "8e0b2412c9199c9d5542e2184774af04317b431b",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open10.htm": [
-     "9767f268eab6e7d48154b393df9d11e2b4b93d3e",
+     "e0dda3681e2aada5875501955d73c13295d02fd6",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open11.htm": [
-     "ae7f0e243ae3a3a62560e14ed7b4cab14f0f44ab",
+     "47acb2c7272117929ca81203c9f351b4175fac7c",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open12.htm": [
-     "f6a13104341bf80025a0f2d6d0d4a72ce4174cc4",
+     "ee713ef352073b6dc19346a931593c3e5e547233",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open2.htm": [
-     "ba72b78eea0c894c22d4a10b4e6a1dfc863ba3ce",
+     "00ebbd3d0f0d2614a1281d3de03586a122ef327d",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open3.htm": [
-     "ac8ca5e1b655fc9f6c17ef479adfd4eb1956aa6d",
+     "19cd5c5254dd1b40d023c5f45f4a02c184f5dc3d",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open4.htm": [
-     "9571d825be9d05b747acd2d76ce1e5346ce70df1",
+     "6983ca0737f029f34dd19c0e0afbcdbf5ef5c0b8",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open5.htm": [
-     "eef37efcfcbb6a372c9b92f39b32822c565eba56",
+     "f6ddb17001a4bdeb99faf01bbbf6afcbdc6ab5e0",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open6.htm": [
-     "c2e2c080d0c3ad3665c884184f04d5b798bfd3a7",
+     "2b2cb334e46875e9d7b2b56eeeab12fab0678011",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open7.htm": [
-     "d22d28d01899832834829717b2d9327be73bdfba",
+     "ccb3d0674893ce4b4066405c6761c160a47ade28",
      [
       null,
       {}
      ]
     ],
     "idbfactory_open8.htm": [
-     "7e2ac93ec06f15b33a310926ccde092d929d0c28",
+     "04c57df2ed43aa70d9cf54b6522630ed8cea3a36",
      [
       null,
       {}
@@ -338900,35 +338970,35 @@
      ]
     ],
     "idbindex-cross-realm-methods.html": [
-     "978fc21e0fcedea8993b3dcd6a029283366e97ec",
+     "70b587db3ec5fe4d9e9936e85d9154302930af56",
      [
       null,
       {}
      ]
     ],
     "idbindex-getAll-enforcerange.html": [
-     "ab0c18b04ff53fdf78932fe86189bd7cc3322c14",
+     "55104227c8017152f9dadccdde5f3fabde4f1498",
      [
       null,
       {}
      ]
     ],
     "idbindex-getAllKeys-enforcerange.html": [
-     "fc65311a5644827c2ffe341ac61833699715fcc7",
+     "e7a98f06fe47a0b19f6465c9cf1357f5ff01217c",
      [
       null,
       {}
      ]
     ],
     "idbindex-multientry-arraykeypath.htm": [
-     "c23f96d8456b31b3c0e59e7651c7c4379ddc1dfc",
+     "303eef7e92a0094dfcac7bf2cd359a1cbbfb4a3b",
      [
       null,
       {}
      ]
     ],
     "idbindex-multientry-big.htm": [
-     "bcaea97c98803a28a8d9ee14b2f89c6168596340",
+     "14e2055cf9a09e1544080927b74d78ca97b522e3",
      [
       null,
       {
@@ -338937,42 +339007,42 @@
      ]
     ],
     "idbindex-multientry.htm": [
-     "ff880550a49e29cf3758364a3fdd2b4f862291f9",
+     "4ca2bea0aa4277b15ad56b88731cc1d67c7782c6",
      [
       null,
       {}
      ]
     ],
     "idbindex-objectStore-SameObject.html": [
-     "9aceb5ca4564c1898a2c82b1f839c5fc5a34a832",
+     "e2dcd0d8e5bba13ddb11d252c75b1868e6f847eb",
      [
       null,
       {}
      ]
     ],
     "idbindex-query-exception-order.html": [
-     "2c3e9b23c5b3637960ebf0feda0e0caf1f1f8751",
+     "2f25eb55980b4ab1a636a4224ce6fee45a3358da",
      [
       null,
       {}
      ]
     ],
     "idbindex-rename-abort.html": [
-     "b61988e9b5c764b5b72b4937b8d76fd3aed15e67",
+     "00e6e36de870b1ea08262bf89f1bf2acce9e69ef",
      [
       null,
       {}
      ]
     ],
     "idbindex-rename-errors.html": [
-     "b314b5495799fe57d3ecfba408d84073460081a7",
+     "7b6b0f17edfad6842ae136866c9774b0428d9d59",
      [
       null,
       {}
      ]
     ],
     "idbindex-rename.html": [
-     "da1d6c9ce9cb32f44d53c5c25c162869e66102fb",
+     "b6d97e6ae92c71133c0dc7a953051e517f867cca",
      [
       null,
       {
@@ -338981,14 +339051,14 @@
      ]
     ],
     "idbindex-request-source.html": [
-     "3788eff0546651777e2684a93333dcc5f8f9cb0d",
+     "ac4e2847ec9d2528227eaa5d1dc295466555c80f",
      [
       null,
       {}
      ]
     ],
     "idbindex_batchGetAll.tentative.any.js": [
-     "d730723c9f770961074cc7e1938f0e7387bab561",
+     "fe21445e83f8c414c3091b2699f451aef7310e2e",
      [
       "IndexedDB/idbindex_batchGetAll.tentative.any.html",
       {
@@ -338999,7 +339069,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339014,175 +339084,175 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbindex_count.htm": [
-     "1b84ef9b79e6cb3924993cb862635f30a44916db",
+     "b1fdf4bc7ac4c6d2b7fd99bd2d9b11871d26b19a",
      [
       null,
       {}
      ]
     ],
     "idbindex_count2.htm": [
-     "1494fe116fd5ba56f4611e8c76679503e9f474ae",
+     "c3f6f32449b47a23bc2f5ca6092e763d7271dba7",
      [
       null,
       {}
      ]
     ],
     "idbindex_count3.htm": [
-     "7fb34347cdb0ac1bef50fd96da9d5adecd0c937d",
+     "a94e8985546101a374fbd79102294a418a626408",
      [
       null,
       {}
      ]
     ],
     "idbindex_count4.htm": [
-     "ce25412a25f529e138cb2077f4dd87d085909d67",
+     "0b3c7fe582b9a9fba49baf2e619018e3d0af00b9",
      [
       null,
       {}
      ]
     ],
     "idbindex_get.htm": [
-     "5afd8b5e8f685bc675e48b3a3a67f2710ce6fae5",
+     "0b65cace6ef5e179ae6fca0ce2f963870db72419",
      [
       null,
       {}
      ]
     ],
     "idbindex_get2.htm": [
-     "52b1d371ebff58c58a3fbf8de75d105569f73e9e",
+     "93569b519933e86fe7df7473ce3e35b4df8485fd",
      [
       null,
       {}
      ]
     ],
     "idbindex_get3.htm": [
-     "d0f900789057d0ceeef4d79ec1171e48b9c6ea61",
+     "62a0a4f3baf34dee7d1f94beb5709c1fa2cf0d72",
      [
       null,
       {}
      ]
     ],
     "idbindex_get4.htm": [
-     "e81bc94d8e0c314f4892099797fdb86d118e4aa3",
+     "980a5d2aa9b1d6930cd2fc157831ebee68e38de0",
      [
       null,
       {}
      ]
     ],
     "idbindex_get5.htm": [
-     "f1f3386cd22935d6b0912aeac490e2c14d68ce66",
+     "9b0bfe4b35f55b341e9d260e83e403db4e9bb64f",
      [
       null,
       {}
      ]
     ],
     "idbindex_get6.htm": [
-     "5304b18b1a0646595c5c9f3655d7ca767b99288d",
+     "ca51b8492fcac9617f3289ab5c5d1f24720cd02b",
      [
       null,
       {}
      ]
     ],
     "idbindex_get7.htm": [
-     "9008c50184b995b60445e85ffc4a528b0edb4eb5",
+     "ce41ce5b8a18ef85567e530e53259b6a53d11653",
      [
       null,
       {}
      ]
     ],
     "idbindex_get8.htm": [
-     "9bfc48422fe0fd821362c15bec118fa0c9558643",
+     "a2565419b98bca59003cccacb830896fcc4108c7",
      [
       null,
       {}
      ]
     ],
     "idbindex_getAll.html": [
-     "2b07b4b2e583e10c00a7a09f6ec4c46d3f7b415a",
+     "bd2a021386be57f857fb28de0c27afb966e5ed22",
      [
       null,
       {}
      ]
     ],
     "idbindex_getAllKeys.html": [
-     "a882312db48f12ec6bc6ecc9be428db063ac1a92",
+     "5640bfdee7eed532a582f753a358c0879c37bff1",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey.htm": [
-     "536f2fd39f64ca0e78fbc352c3ba69c9db219fab",
+     "b9ca84984ce4afcffefb39e6311b2dc37c52762d",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey2.htm": [
-     "9e86732426827432c910531368953fadedcde422",
+     "6582e06064e96dc9d74cd27f583a17f3f48e1b7e",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey3.htm": [
-     "238107ccc6a40dc8b3bc4cdc1ffb11bbebb313fe",
+     "40ed76d17412e91c3a1aabd2911f6607285c856a",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey4.htm": [
-     "d0d1f5734c38fdfc811a1a36612a592db2a024c6",
+     "a5eb700c0de08b423b179ec2861e731b71ed0ffd",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey5.htm": [
-     "5fa33087cd6c045d0d3ed8f717d29d0786410c24",
+     "315513139713d94004b65235f331ba4a04763b76",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey6.htm": [
-     "18cdeb9e939227388cafc9140c1bbcac5f7ae4ea",
+     "b71967d4fbde70eccf4a2b51591ed10866cdb163",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey7.htm": [
-     "4b005739caca87e4d6b17cd20f0372ccd9e5305b",
+     "90a9cfc22483d1b64d1002e6e3753e2d3796540f",
      [
       null,
       {}
      ]
     ],
     "idbindex_getKey8.htm": [
-     "316da6a7d19d51d6c6cf9407aa70e9d8c5c819a8",
+     "cf0affb2105b31dd238252e1e6b112334d98e6b8",
      [
       null,
       {}
      ]
     ],
     "idbindex_indexNames.htm": [
-     "f80c4c1379032c5fe08dc4795c18d6ae4768622c",
+     "1b05de51e702cd2e615a39d243127f29abc2a193",
      [
       null,
       {}
      ]
     ],
     "idbindex_keyPath.any.js": [
-     "19cf231f44b801240876c5d27f72dd6f2b9d2d68",
+     "711ce9a9fd2c1ed4ef8196e9197bdeaacdf3f186",
      [
       "IndexedDB/idbindex_keyPath.any.html",
       {
@@ -339193,7 +339263,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339208,63 +339278,63 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbindex_openCursor.htm": [
-     "17d9e6841571e4dbc380e1768a4c667a365de5f9",
+     "7baf2cf9ed730182b11dead6e5e8975f1498b45f",
      [
       null,
       {}
      ]
     ],
     "idbindex_openCursor2.htm": [
-     "13e55fff1d6fdb5a22adcfbe17f3b9aa1422734b",
+     "66608271ceec980dde8568a9e71d9df7831b2fab",
      [
       null,
       {}
      ]
     ],
     "idbindex_openCursor3.htm": [
-     "02beb0042ab180bae1ad91d68a3c4f34e7b8b181",
+     "91a98464e08d2c793912f363095aeb2d329c0129",
      [
       null,
       {}
      ]
     ],
     "idbindex_openKeyCursor.htm": [
-     "c88a13db07685cf14ecb983a129026d08e27be64",
+     "9436684c3d1050ed06a23837eed5397b3134ebbb",
      [
       null,
       {}
      ]
     ],
     "idbindex_openKeyCursor2.htm": [
-     "9153b11b8df6e445c8918aab50c09418bf14cf91",
+     "ec97345a873109b1a4273214127765238877d1ec",
      [
       null,
       {}
      ]
     ],
     "idbindex_openKeyCursor3.htm": [
-     "1c7f86f8d98df3f042a1958e0046c712d4758dc5",
+     "cb5cce0cda05c30f68dbd555737d29f82b1c61f7",
      [
       null,
       {}
      ]
     ],
     "idbindex_openKeyCursor4.htm": [
-     "32bc088f257e212703b8478e6eee53cbd11374d0",
+     "bcc1511c90c8a8611bb2023b1e995f774edc1f64",
      [
       null,
       {}
      ]
     ],
     "idbindex_reverse_cursor.any.js": [
-     "0b3c767fee17cb2739bd49a05237beaea5129e20",
+     "88c367466df7dfd94be4ca022686007839c253af",
      [
       "IndexedDB/idbindex_reverse_cursor.any.html",
       {
@@ -339275,7 +339345,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -339290,14 +339360,14 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
      ]
     ],
     "idbindex_tombstones.any.js": [
-     "05617a384f6d31b2c000a737f47e966650fbd214",
+     "7a2dcc9cb11649d0dea1d445db8e8b5639549741",
      [
       "IndexedDB/idbindex_tombstones.any.html",
       {
@@ -339308,7 +339378,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -339323,7 +339393,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -339337,98 +339407,98 @@
      ]
     ],
     "idbkeyrange.htm": [
-     "7a2db3e9c2b0a2f49ea6753c4d2d02aa1f16f0b4",
+     "a387dc74e6e5422df6b631b8fcf498fe1f479f8b",
      [
       null,
       {}
      ]
     ],
     "idbkeyrange_incorrect.htm": [
-     "931ed518b9e3c38827f6536ea501d4f0f0d8a87e",
+     "ec72a7e7aeb85673a1c9d3f522f914c4d97adbd2",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-add-put-exception-order.html": [
-     "71ea2a07f4efc1cbc4ed766f23882b331053962f",
+     "e5a73d4b9fa038cd35bacedece8ab610582dc468",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-clear-exception-order.html": [
-     "b5678d98afdc5b0c7596c8d9c96573424fbad77d",
+     "993704d1d3a588bc122adecc7323a708d5e65393",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-cross-realm-methods.html": [
-     "bbdefa37282892acfa0fee99e13474ba676df01c",
+     "ae58d7ea9255a1ea518f0a3752f6fda0ad80761b",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-delete-exception-order.html": [
-     "671dfa4b35eaec7d6d1a12a0fe3692fed7ff0bae",
+     "c33667f4b387355e4b9a4d5ff1ab2fc52b78360c",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-deleteIndex-exception-order.html": [
-     "389e7a32393b126fb9c89f99a092df3cb03b3afb",
+     "b3aaebe8375b38bc2e54f9e155f4e971ab348ad5",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-getAll-enforcerange.html": [
-     "0c4eb89905dc001a6e6293f43da1c646e5ea0ed0",
+     "c37da818b965018c6b15ccbb857c2384e6f75384",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-getAllKeys-enforcerange.html": [
-     "23fe5966912e8ff955a82a1612a219301ad31ca2",
+     "e05fa942b34d34ce265878033bc9bfa913a83401",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-index-finished.html": [
-     "67b0945cc982711153f6d062db05cd5710f40571",
+     "7d9b6dbfc6fde9149d858a03f882fc25345ac37e",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-query-exception-order.html": [
-     "24d10555b75d9332c52908928625f7c3d4b5c72a",
+     "26fce5fd2f75f743bdbb2d49c9a5d057b32b84a2",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-rename-abort.html": [
-     "75893cd84c012d4bc662ba11fd79ef1eacaf49cc",
+     "0a7c54ee58f51927add8ed11aa5817d2b3fdbadd",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-rename-errors.html": [
-     "3a90955ae762d38903585b80e4db2710abbc636f",
+     "ad2ff9a6577d05029016ec8fbef7fe3acdb74e15",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-rename-store.html": [
-     "7556ec192e81ba09aeff7521ffff3e12a90a7274",
+     "97fa2e0c1fee475b006ff36df7d1099c87ac3190",
      [
       null,
       {
@@ -339437,133 +339507,133 @@
      ]
     ],
     "idbobjectstore-request-source.html": [
-     "32bf370ab60ca791d8d401c2c04e51a4d19a40b3",
+     "a710bf5270028d6272b7a36559cd77f6ecdf41cf",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore-transaction-SameObject.html": [
-     "4ddf700fd0cb052d79a333fa784ea299786ad3be",
+     "a498f2670054c3d839c99c002b48004810a9ff3b",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add.htm": [
-     "f091d1faf12ff99ebdf92565d7b21215219cd5f4",
+     "5cad69436e330c50f8e68cf87adc179b0eea8e4f",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add10.htm": [
-     "59594f828876a02d61f32b9f7b26305bfa6687ff",
+     "d84004250de4d5ef674aa74cbf141a67fd9c7b45",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add11.htm": [
-     "ba2450fb2508302bffa75e8344c263c143f584aa",
+     "b1d9f71fd0650fe01d4860ee8f0742feea0b5769",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add12.htm": [
-     "6ffa9db79a0695d5aa22b51781fcd23034018a15",
+     "fc5a7bcebbea4bf9886baeb725b3470bd1deeac8",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add13.htm": [
-     "fb4fc2dbab6a35c9c18deed6403a016eccc24d68",
+     "ec82989b01aacb72be4fc1f8b97a4e9f0514049b",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add14.htm": [
-     "5bac57cb7652a561b266c123b6346e7c9624a5e7",
+     "10bf8a18ce417da86d30a89da15f1b050d82b271",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add15.htm": [
-     "ff7483892444e3bd20fb69249158baa92d5064b4",
+     "909accc1b1ce81bf05f5d971607da063122997d3",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add16.htm": [
-     "f20d7962705ecc7fa0162dd743f7d513e647fddf",
+     "453082340fb8590c11dc9e78110c5c50201f8e54",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add2.htm": [
-     "70c0554458848c61a7b7bdb4ce998afa416e8c3b",
+     "95c45dda2827a8b0dcf90559970f386b0b49e3e6",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add3.htm": [
-     "ac397372d486317beb18f2d8bdc7193413f3467c",
+     "9209e7505da2c7d897ccf881416646617dd96a80",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add4.htm": [
-     "c4b875cd41f098bac6a8981ac218feddd18dd12d",
+     "35d88fe3a2282c102040524b436ea4c8407feb7d",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add5.htm": [
-     "1c1cd1fb2843793b7cedfb1566b2b40685fd586d",
+     "cfe8e23879609079262b35a5998a9052f255d3d8",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add6.htm": [
-     "c6f1910a3eed63363f807fd3cbdad1f0b519c07c",
+     "12c4eedeaee0e45122291ee80bc4726315362efd",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add7.htm": [
-     "1b2a6dac3fa4aaeda24da6725cce9f93b268a2dd",
+     "fe32f457ebe3d7c63b34b1f37ee2614094713da4",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add8.htm": [
-     "b3266fdc0f6cbe9207ab257529eb891e6e28753c",
+     "3ca14776d9472bd4bb9b3e9b19dc56351908dd45",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_add9.htm": [
-     "5babf368cbc23db7a1b18a5ec5c7ee1ad4bfe0ac",
+     "27061afd9c228abf30aadac28d3837e06897977e",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_batchGetAll.tentative.any.js": [
-     "aaef2868d832678d8596abefb3c1751442dc3d4b",
+     "3aeb8553598692f6fd418cb729deb5bd4af1ac32",
      [
       "IndexedDB/idbobjectstore_batchGetAll.tentative.any.html",
       {
@@ -339574,7 +339644,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339589,14 +339659,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_batchGetAll_largeValue.tentative.any.js": [
-     "4d23620672ac26ee0a163688da753a317647f90f",
+     "497196e642f313070e26371c79aab6769e64bf00",
      [
       "IndexedDB/idbobjectstore_batchGetAll_largeValue.tentative.any.html",
       {
@@ -339607,11 +339677,11 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
@@ -339626,116 +339696,116 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_clear.htm": [
-     "d9c3fb2a18954ad467126b8f5463ffc8790f169e",
+     "c9029587cb75afc51a23bab7f37f32b5e122971c",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_clear2.htm": [
-     "ac1fdff4cac27cecf12174b9511dc8ab496ff70c",
+     "6d7eb6ad74366a0f3b52248d98378795c7972b68",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_clear3.htm": [
-     "41e6566b6c2625d6bf3fba9961250ef45637d881",
+     "70f03c696f598683627b6ede11afa6f40cf8e2be",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_clear4.htm": [
-     "9812c3d33b1a57aa4cb9d844c1303fb59cc8d385",
+     "f5e1cad563e1a8859a85719ca17a640dc007ee3e",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_count.htm": [
-     "a54d16e435dd8df9327f0d089012699b711482fd",
+     "982fa6d46674888c1684102a6f728fca35e9fa00",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_count2.htm": [
-     "b92715a2d998fd28e25682d0e9a7b6971119c021",
+     "28fbf2b3632dd888c4d22722972a94fd3cd27415",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_count3.htm": [
-     "970b87a3d843a6488a850e90f313b23929f3f483",
+     "3d5fd17a2267948d5c7d647361bad35deb552b35",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_count4.htm": [
-     "8c9170e7e3bc5c77c3b2d70bda0f85bfde183036",
+     "c328a91e33c193850973661b24e0a1393199d8bd",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex.htm": [
-     "8f0327c1a78c307658478f33c5e95349144df812",
+     "ebd6377e492a3844a0ca8bbac4f194fcae7ceb18",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex10.htm": [
-     "bb91b7c17bc300390f5491c06c0925c53a3da703",
+     "46678b1b6c7b66bb433423520b836c7dd40c454a",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex11.htm": [
-     "47f06c3e1e4a3d9900fb243dc65b1a1e6d229092",
+     "e458977212ab3dbc2fa07b190b6fd3b1f37a721a",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex12.htm": [
-     "68214e54e941c78f6c951eb05bffa99bb87a97b1",
+     "a74ac6f5a1f97bf4d5a3bb070eeb5c2648c4c8ef",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex13.htm": [
-     "839abdb009e9bf1bc368ca0943556676b73e0b59",
+     "2e6309259b788b9819273dcf96538b9a66db5347",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex14-exception_order.htm": [
-     "c0e6c6f838743ca8cafbd2db4cbe708e6cbdba19",
+     "ad37351c8a84e0a6a96622c359d84841d5e01f4a",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex15-autoincrement.htm": [
-     "c66b81548adb1ef287b2ba075e66d6dbb8e6360b",
+     "6b88b0a208db322036d3beb7f91624f52b3e5ad9",
      [
       null,
       {
@@ -339744,14 +339814,14 @@
      ]
     ],
     "idbobjectstore_createIndex2.htm": [
-     "9dc1686b1866e095596c56b60ac491e86755c404",
+     "cac6c7996784d0b9da0f4d6d3dbed8dd8358433c",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex3-usable-right-away.htm": [
-     "727ddd2f084acc402b37f417b703e617f2638f4a",
+     "510f17f173c9fd405f76755841e20f8c1f68e9c3",
      [
       null,
       {
@@ -339760,35 +339830,35 @@
      ]
     ],
     "idbobjectstore_createIndex4-deleteIndex-event_order.htm": [
-     "5d6d7b4cb5cb3ed0f8777c9841bbe9631c0d04b7",
+     "bc5915f54a0587f810057f3513eb39fec8aea424",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex5-emptykeypath.htm": [
-     "f8fa9ee272b77564acfa67173366c6b989045368",
+     "b004a218ffba0870513323ddeccdcc6a174ff101",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex6-event_order.htm": [
-     "302bb86c2b39306c31674bbe0dcd7b1b742dc85b",
+     "db7398d3604ea00a43e403b879ad86a37460fc2d",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex7-event_order.htm": [
-     "b8bc9c515cb198d6dea3305e52292c1d4e7397ea",
+     "9be4c563f437ef37c61d1e7c27cd82ba2e88451d",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_createIndex8-valid_keys.htm": [
-     "25841f19dac6f86325d913fe7fb7a44e8b966b6c",
+     "10c2b29c57d2b7787619f3bb2a244134f3a684d7",
      [
       null,
       {
@@ -339797,77 +339867,77 @@
      ]
     ],
     "idbobjectstore_createIndex9-emptyname.htm": [
-     "3d04357c972baa3a78fed0fe8cf8797e816ed610",
+     "52fb94fec0f26e990d3ad576aef3e35b43c91d42",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete.htm": [
-     "337289296230831e03e44bcafec05123330ebc6e",
+     "264da9677dcd60d44df31747f99e495396f2fe84",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete2.htm": [
-     "f7e46846025b81ae12303e50862e031b8bc10c90",
+     "eb71169905791318549aca77de7806bde40d0cce",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete3.htm": [
-     "b72b1072d78e7b02831b5bbc49a1ac7b666bee31",
+     "9d4b886322808f57e3d99864b33781050f966aa9",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete4.htm": [
-     "3d36b7962eeac8613dad60c2ce8a0aa17d0ec940",
+     "05a8a87216eabcea100c1efef27aa8e11da4a5c4",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete5.htm": [
-     "9e8ac80a1238ad0baf23a096d45fb286997aeba0",
+     "6ae2edc21ebca3e3873c350a6daef73af88daa1d",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete6.htm": [
-     "4481387ccfd191102f2bad1ca754f186a3b55e78",
+     "8d660e33f2b6188aebe9337d40468985eb5833f5",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_delete7.htm": [
-     "aa7eb1ac6a255a4e777f457b5e01ba9d8c9e23f6",
+     "a65885cc2b43bdb4e17e82bea06d9d439716ec07",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_deleteIndex.htm": [
-     "f4fccd61309641ca97b5a5f5cfd4c11d67b0fb4f",
+     "061d106b91abd2bd2ad489a805feb7b4ef87523f",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_deleted.htm": [
-     "f5a383e75cbc4dd292dbe93299ce388c55449266",
+     "5ccc8fdb1b683896dd855aff38b60cbfa4b6f952",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_get.any.js": [
-     "d8f3422a646b5d8f1a673e2592b9adf86fe8fecf",
+     "cc4f21519e77e9b78a7810ff3e46a5f9fd17e196",
      [
       "IndexedDB/idbobjectstore_get.any.html",
       {
@@ -339878,7 +339948,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339893,14 +339963,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get2.any.js": [
-     "891d4f5497da59454ed16b809a318ae9ea67f7b3",
+     "a1589ca14b67d10ecf50a9e756a001822af505dd",
      [
       "IndexedDB/idbobjectstore_get2.any.html",
       {
@@ -339911,7 +339981,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339926,14 +339996,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get3.any.js": [
-     "f70054519c72b91a7fe59031660c2a38d711ab06",
+     "46cbb5cbc16f8773d9db66e4f251e03f354ab2e9",
      [
       "IndexedDB/idbobjectstore_get3.any.html",
       {
@@ -339944,7 +340014,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339959,14 +340029,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get4.any.js": [
-     "3c3cb784281efeeb4b4e89350577f843787aa048",
+     "a69717ce4ef08386c561437c8e544dabd767aed5",
      [
       "IndexedDB/idbobjectstore_get4.any.html",
       {
@@ -339977,7 +340047,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -339992,14 +340062,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get5.any.js": [
-     "2cea83b7647e725cbbfe9de69c4a8bdd2ef69dfc",
+     "cc10c50553e1296442724149d6be30d15b4d87de",
      [
       "IndexedDB/idbobjectstore_get5.any.html",
       {
@@ -340010,7 +340080,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340025,14 +340095,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get6.any.js": [
-     "9939eb6846c127f4bb4deef5bb2f964335acac79",
+     "c56e64e5cf82c4c0be9fb8e846b8aca18ff111e9",
      [
       "IndexedDB/idbobjectstore_get6.any.html",
       {
@@ -340043,7 +340113,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340058,14 +340128,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_get7.any.js": [
-     "e66c1d95761e4425209e0c7275dad6aceedcf452",
+     "8e1edbc556c388c5efade38752c609104d58a13e",
      [
       "IndexedDB/idbobjectstore_get7.any.html",
       {
@@ -340076,7 +340146,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340091,14 +340161,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_getAll.any.js": [
-     "f34dbcfb380f22ef7ee303fa591dfd3ec88ee67e",
+     "db7098f71e80b214b25bf3f0d42563c937f29918",
      [
       "IndexedDB/idbobjectstore_getAll.any.html",
       {
@@ -340109,7 +340179,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340124,14 +340194,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_getAllKeys.any.js": [
-     "80f64ca222cf77daf5a15856b56ec34d58cddae7",
+     "951c479873fa9684a3b1d648762e58be66837cd3",
      [
       "IndexedDB/idbobjectstore_getAllKeys.any.html",
       {
@@ -340142,7 +340212,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340157,14 +340227,14 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_getKey.any.js": [
-     "7397747f3ff816660c80028ae45a854b310e58da",
+     "57c8618c38dd61b66d09c1af34a423770876aa92",
      [
       "IndexedDB/idbobjectstore_getKey.any.html",
       {
@@ -340175,7 +340245,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340190,21 +340260,21 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_index.htm": [
-     "f01474af5bbfaefa61010c845dc3c2b3402370da",
+     "2a82079bd4b2345898b170425b62ffdb8baf57cc",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_keyPath.any.js": [
-     "91c3674c312aaaf0235b1bcda5d776137c2ee9b1",
+     "68626617950a1617dfabfd5bbb2cf1ba8d61b146",
      [
       "IndexedDB/idbobjectstore_keyPath.any.html",
       {
@@ -340215,7 +340285,7 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -340230,140 +340300,140 @@
         ],
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "idbobjectstore_openCursor.htm": [
-     "c54760a7cd7a0dcd47c6bf150fa53e290076fba6",
+     "44e8648ce0628aaa2b4f3fce48f6e25d32cb42b9",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_openCursor_invalid.htm": [
-     "5911686d3528da68ad548a79b5e4533225f306fa",
+     "0434b2961934df6d882367f4a4681333c957ed0c",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_openKeyCursor.htm": [
-     "0880a23c37d930bd526bf30da01bff67443d743f",
+     "108650425c9e34baf70a9c9ce6829b443b17938b",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put.htm": [
-     "6a0fed4b7fee690d189348c0999cda2343a93212",
+     "942943db8854c005c51db0189cb975757d6b0b85",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put10.htm": [
-     "cc8770ef9b52323e589e699b477964ed1bc2712d",
+     "6882e8e4b5c5bc0404bff41816dee36580abf2a5",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put11.htm": [
-     "d9802aa01745eb88ae72384307716492eace6173",
+     "a5ed2db357b56f1d690e61b8c2fda58020d2e8a6",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put12.htm": [
-     "5d4f544cdbd318a2a6196dc92bbc8a87ad066f20",
+     "0693980277dd66d6d5e137bdc0ed5dcc2d8c1718",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put13.htm": [
-     "ecd0515b87129759638f22fbbfe93f99fad6a4d0",
+     "8ae6561fc5c61765310d2cc12752ba77095076c5",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put14.htm": [
-     "c6896964592b53e8df0137e0b9516f2a0aeb630b",
+     "bc5647f4c11a87140f87d09582b10e2d353af376",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put15.htm": [
-     "5d1b8d409167b66545af086e4858248b1021380f",
+     "903ebbc95c6a15174d486e90f5bab781a2f48d9c",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put16.htm": [
-     "fe187e5508f607e1c357a229462656ff91c42450",
+     "e298ba88493f322c611ad964f6804d46584d8239",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put2.htm": [
-     "3b9fc30a8119218351783095fc936732cd7a6f05",
+     "c0813323bdc8f4963809ba3796ba0b4804490447",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put3.htm": [
-     "79097a283e5fd45986fe31ac8d59951fcfd4c1d3",
+     "7c4bf41f4ebb0a360085862a3670702d1d9b464f",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put4.htm": [
-     "c1335b27d002dfe31f9cca023f15c102398d379f",
+     "4a59836eb6313ed6bd213049c98d0f241c2a1f2b",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put5.htm": [
-     "a4d9abefff617866125c9ff8e0ad9fa9de975191",
+     "bce0687a6bebe6d49ad37f2aa01137210b588296",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put6.htm": [
-     "bcf7e7d19345b5da9bbc204670e17499fef2b710",
+     "ec89368aed5d81190c758292cb818f0affe8606f",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put7.htm": [
-     "6765b0a84ae8ccecfd00e62f6e1acc41a0a4babd",
+     "58061a6d951f4ee36b26618197ddb6d7baf240d3",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put8.htm": [
-     "3bf284eacab264b678aedf42a64e265367e80d54",
+     "44c8eb22a84ba6452268ecd81d5224665a2d9755",
      [
       null,
       {}
      ]
     ],
     "idbobjectstore_put9.htm": [
-     "0fa6dc75797c2b522d329946a8a9136bab98ab44",
+     "dff9415d691c4316f03787fd97076786bbdbbbe9",
      [
       null,
       {}
@@ -340377,70 +340447,70 @@
      ]
     ],
     "idbrequest_error.html": [
-     "c140c59e2de9b2bd1343fb6720e66db143b106f7",
+     "c9dbc3d13d831718a698648587fa6f2650df8c5d",
      [
       null,
       {}
      ]
     ],
     "idbrequest_result.html": [
-     "e7516d52e8f0d7259db255657ae7adffce722a0a",
+     "d396532da12fe724165c91fcaf61d24995e73ad1",
      [
       null,
       {}
      ]
     ],
     "idbtransaction-db-SameObject.html": [
-     "9c086068b7f6b7c5367d63309a70e7cc76f5ce3f",
+     "726e8fd23a6f259b81254f6b3954aa99d7ace23b",
      [
       null,
       {}
      ]
     ],
     "idbtransaction-objectStore-exception-order.html": [
-     "bc0357a13115d0398668b88c62284feff5455a9d",
+     "74673f952b91d18c9f035090228f976301700267",
      [
       null,
       {}
      ]
     ],
     "idbtransaction-objectStore-finished.html": [
-     "78d2777e63cd2734c48681562cc23fed7fecc3e2",
+     "fdea8a6ee945769fe029e5a97dd45c959b58186b",
      [
       null,
       {}
      ]
     ],
     "idbtransaction-oncomplete.htm": [
-     "647678a5fbb1ce1dbe3a5d7a28aa630dc668218f",
+     "475a2764f3670d14679e15f7231b202df0aa2a77",
      [
       null,
       {}
      ]
     ],
     "idbtransaction.htm": [
-     "d5bafda1cab078afbb810e2d3efa258e4139c5e2",
+     "d08e170eb6e140be562458888554bb5c1920d9af",
      [
       null,
       {}
      ]
     ],
     "idbtransaction_abort.htm": [
-     "8f19bc7993f468836158a736a487b1813fd35c6f",
+     "3c64352b08dbb3c6d8e6319d53755d741a48c34f",
      [
       null,
       {}
      ]
     ],
     "idbtransaction_objectStoreNames.html": [
-     "da0b9aba36e0b41da24bd2f86db2f6fe7242fcfe",
+     "acaec9cca2a73ed3f5ec51c55ec5139f6aec8fa3",
      [
       null,
       {}
      ]
     ],
     "idbversionchangeevent.htm": [
-     "fc4cd9a2f8765d331e43c3989f2b7c735f6dc444",
+     "9ea7e6d491426c414d5a6f138c67f6a4689a8a7e",
      [
       null,
       {}
@@ -340546,14 +340616,14 @@
      ]
     ],
     "index_sort_order.htm": [
-     "6249c4204897ffd9f292908ca50dae6f8655c02e",
+     "8f1021d060ac8e324ce124f0927d1c82838d4400",
      [
       null,
       {}
      ]
     ],
     "interleaved-cursors-large.html": [
-     "6f4e440e1dac8c6389d0882b314a10ea84ad9af8",
+     "9e17f9e11249a68eb846a3d0474785cda7010bf6",
      [
       null,
       {
@@ -340562,7 +340632,7 @@
      ]
     ],
     "interleaved-cursors-small.html": [
-     "a4c47771782f61c8ef17398e66d57e8d03db5830",
+     "2751113f5f73ea2607b3e8d6fd13254d95cb1711",
      [
       null,
       {
@@ -340571,7 +340641,7 @@
      ]
     ],
     "key-conversion-exceptions.htm": [
-     "36d67d8f07dcaf8becc68d1e96711c6d98534a18",
+     "9fdab58eb1212f911203177aac04d57440245d94",
      [
       null,
       {
@@ -340579,333 +340649,15 @@
       }
      ]
     ],
-    "key-generators": {
-     "reading-autoincrement-indexes-cursors.any.js": [
-      "f8f778428c98f4e189ce53b133133c5b784e1d38",
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.serviceworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.sharedworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.worker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ]
-     ],
-     "reading-autoincrement-indexes.any.js": [
-      "d945b78bf3743bccd632dabdcb846af52c183110",
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes.any.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes.any.serviceworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes.any.sharedworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-indexes.any.worker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ]
-     ],
-     "reading-autoincrement-store-cursors.any.js": [
-      "a07e5da3b0181360584f720f09f20674a13efa6f",
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.serviceworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.sharedworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.worker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ]
-     ],
-     "reading-autoincrement-store.any.js": [
-      "06c4e5c6ea0970fb0ccf1e9f23ee97a00a2e1d3a",
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store.any.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store.any.serviceworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store.any.sharedworker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ],
-      [
-       "IndexedDB/key-generators/reading-autoincrement-store.any.worker.html",
-       {
-        "script_metadata": [
-         [
-          "global",
-          "window,dedicatedworker,sharedworker,serviceworker"
-         ],
-         [
-          "script",
-          "../support-promises.js"
-         ],
-         [
-          "script",
-          "./reading-autoincrement-common.js"
-         ]
-        ]
-       }
-      ]
-     ]
-    },
     "key_invalid.htm": [
-     "c3c61ead23cf434a8a9806cc3d5f5489833d8280",
+     "cf649b07d0572cb6543f7ea081ac8db9b0a95e58",
      [
       null,
       {}
      ]
     ],
     "key_valid.html": [
-     "3bac0732cd4c838b9fd2cea192854eee0f4151f6",
+     "caafcce42a0f61ae1f2e3136b7bf4772858f6932",
      [
       null,
       {
@@ -340914,77 +340666,77 @@
      ]
     ],
     "keygenerator-constrainterror.htm": [
-     "2caad10a5bc901f58194998c84348b4476601121",
+     "edb7d6f5bb72d4e1a8fde91cbd98f78ea0e850a0",
      [
       null,
       {}
      ]
     ],
     "keygenerator-explicit.html": [
-     "1add18c0c61cf7d3cf2d55e69956438a7fbfebdd",
+     "32a7b20df2495e3f03a609c86dab2eee2ed9116a",
      [
       null,
       {}
      ]
     ],
     "keygenerator-inject.html": [
-     "301e92304370591237a5ab50ca0e260f37234c2a",
+     "4aefa40a7b66ff958754c5b1339a42eb567315cb",
      [
       null,
       {}
      ]
     ],
     "keygenerator-overflow.htm": [
-     "67f809d78f293461b80784e0438f92e93d25d7b5",
+     "2d9e4c88fb8cbd747e16e88b24c06b51696c6b23",
      [
       null,
       {}
      ]
     ],
     "keygenerator.htm": [
-     "7e5961382c517836f77ff2b0bb45cf317be6cd8c",
+     "567c3cf98a7328dbae70e7f642ad26d82d3569cb",
      [
       null,
       {}
      ]
     ],
     "keyorder.htm": [
-     "7f073ddb9a24e141bc26d9342caf38255b60041d",
+     "7e8b3d412648e739fc121d99797c8c62a5301d95",
      [
       null,
       {}
      ]
     ],
     "keypath-exceptions.htm": [
-     "62fce352baffd1c183a36376b50234b6bf1b5822",
+     "b0569f9294e2079d5c11bc3d6b5a6a2568302cba",
      [
       null,
       {}
      ]
     ],
     "keypath-special-identifiers.htm": [
-     "0692bed32ce54b4dc666fd76d5fa06c523a06a5a",
+     "a521ed8bb89c4357fe5bbc0ec1c0737f6ac0c7cf",
      [
       null,
       {}
      ]
     ],
     "keypath.htm": [
-     "4985712a215c28b6a798e789a7a384a4719760b5",
+     "be896b5d233fbe765b6fe64bab276f28ce193b44",
      [
       null,
       {}
      ]
     ],
     "keypath_invalid.htm": [
-     "470ff2681b343b9c32be94fb5bf2bd5709c46c48",
+     "6aa33c854ac14447ca922dfab2005a7342a9ac1c",
      [
       null,
       {}
      ]
     ],
     "keypath_maxsize.htm": [
-     "83bd9cc3138e4cc3a637adfebc45e26bda912e81",
+     "3ff7d6a521f7883c6cb436aea3bd6f5b562fc36a",
      [
       null,
       {
@@ -340993,7 +340745,7 @@
      ]
     ],
     "large-requests-abort.html": [
-     "9f30281e9fa59b623299e1b23ab1b9a577899ca1",
+     "38c73ff40694f2473e1db7dfa8df0792a89b1bb5",
      [
       null,
       {
@@ -341002,21 +340754,21 @@
      ]
     ],
     "list_ordering.htm": [
-     "8349dbae79fe36a7896439482305016b84e36db7",
+     "a3c36de38918400cdee469747739d38c088ff270",
      [
       null,
       {}
      ]
     ],
     "name-scopes.html": [
-     "59404f646152f876bfc577dba78e86a349100cac",
+     "d92f706e0a7bc3f120c4fac5330d81dd6acb6ed6",
      [
       null,
       {}
      ]
     ],
     "nested-cloning-large-multiple.html": [
-     "f263efbcf6d8f1601e623690ba0de799edce406b",
+     "97bcaddfb2d64bfe89aaf0e7df574a654e009153",
      [
       null,
       {
@@ -341025,7 +340777,7 @@
      ]
     ],
     "nested-cloning-large.html": [
-     "6e4f9be2ee6ce57605ad0248f37f794f6d8a70a2",
+     "8b3cbc57266527548c5797ab36327a2d5e05d54a",
      [
       null,
       {
@@ -341034,7 +340786,7 @@
      ]
     ],
     "nested-cloning-small.html": [
-     "558415f2342038eb079b4267fdcb0b133fbb9da8",
+     "e92251410afad12e244dfe14824ed611050d9e59",
      [
       null,
       {
@@ -341043,21 +340795,21 @@
      ]
     ],
     "objectstore_keyorder.htm": [
-     "69c281fd02ab9c181aa7b88ceab074bfc920e2e4",
+     "62faa63bc489de49f4fbb73b92ad1d9599711bc6",
      [
       null,
       {}
      ]
     ],
     "open-request-queue.html": [
-     "3a77adbdf8cdd6a463603c6e650b1918c3f05115",
+     "b4371f2a2eeb18940984c5a597f532031c3c2501",
      [
       null,
       {}
      ]
     ],
     "parallel-cursors-upgrade.html": [
-     "55d7963217f0d99b479d87f7af679b6c16e248c1",
+     "99ea65d9d60d2c8d4d6429b3d51693e98f22a5f6",
      [
       null,
       {
@@ -341065,15 +340817,331 @@
       }
      ]
     ],
+    "reading-autoincrement-indexes-cursors.any.js": [
+     "ff71000683c65e92e19c06a4cc567f1c1a807d93",
+     [
+      "IndexedDB/reading-autoincrement-indexes-cursors.any.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes-cursors.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes-cursors.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes-cursors.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ]
+    ],
+    "reading-autoincrement-indexes.any.js": [
+     "abff3dd8b5f4f5ae95afc9f18a4e390af1216149",
+     [
+      "IndexedDB/reading-autoincrement-indexes.any.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-indexes.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ]
+    ],
+    "reading-autoincrement-store-cursors.any.js": [
+     "da02057e898fe903771f51660e96017854a2006a",
+     [
+      "IndexedDB/reading-autoincrement-store-cursors.any.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store-cursors.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store-cursors.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store-cursors.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ]
+    ],
+    "reading-autoincrement-store.any.js": [
+     "531d5417bb18750d4798e3838c32f7b2048753f3",
+     [
+      "IndexedDB/reading-autoincrement-store.any.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/reading-autoincrement-store.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window,dedicatedworker,sharedworker,serviceworker"
+        ],
+        [
+         "script",
+         "resources/support-promises.js"
+        ],
+        [
+         "script",
+         "resources/reading-autoincrement-common.js"
+        ]
+       ]
+      }
+     ]
+    ],
     "ready-state-destroyed-execution-context.html": [
-     "dab25ef0ee066450694cb71c6dad398ceafa267e",
+     "8194052391a7795b9310fd43cbef74571bfdd4cf",
      [
       null,
       {}
      ]
     ],
     "request-abort-ordering.html": [
-     "1abf70b133500fd2f26ecbc98e636ae56515a4c5",
+     "4374d8de7089375e312fe8c40efe4176fc71776f",
      [
       null,
       {
@@ -341082,7 +341150,7 @@
      ]
     ],
     "request-event-ordering.html": [
-     "5185ecbaa15aeab1012cc3fb5e94c2e26e9b4e8e",
+     "71eda0dd1dfdc5a54fab4ed764e063936ac0905d",
      [
       null,
       {
@@ -341091,35 +341159,35 @@
      ]
     ],
     "request_bubble-and-capture.htm": [
-     "21d72d75a6fa9389c05e968f3e9eebc386063e51",
+     "8238e2c9ca140513e365f1619c96c86706d01397",
      [
       null,
       {}
      ]
     ],
     "serialize-sharedarraybuffer-throws.https.html": [
-     "6900759f441225f47b6f338f470883da6b9c3c12",
+     "613ddfe99d81704defe853466107065011819a69",
      [
       null,
       {}
      ]
     ],
     "string-list-ordering.htm": [
-     "cc905e56ecf83ea4cd4f1fe2ccfac425cdc5f9d0",
+     "ddbbc3036fb0ade4ec2b9da1a219f1c5c689446e",
      [
       null,
       {}
      ]
     ],
     "structured-clone-transaction-state.any.js": [
-     "5494bc51eb02848a8cbe9cf1a07fca4839edd3d9",
+     "adf3be2f70aa892bfe8213f7b31d4d3169c6a9b1",
      [
       "IndexedDB/structured-clone-transaction-state.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "title",
@@ -341139,7 +341207,7 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "title",
@@ -341155,7 +341223,7 @@
      ]
     ],
     "structured-clone.any.js": [
-     "d66de1da5ce65a95b79200d2c618f1568cfe1d21",
+     "f1bcd66ca81a35865ce6b97208e7c2501bfa328e",
      [
       "IndexedDB/structured-clone.any.html?1-20",
       {
@@ -341170,7 +341238,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341218,7 +341286,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341266,7 +341334,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341314,7 +341382,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341362,7 +341430,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341410,7 +341478,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341458,7 +341526,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341506,7 +341574,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341554,7 +341622,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341602,7 +341670,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341650,7 +341718,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341698,7 +341766,7 @@
         ],
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "script",
@@ -341734,84 +341802,84 @@
      ]
     ],
     "transaction-abort-generator-revert.html": [
-     "c916a91771fcb1111fb278e4c6caa86c79b08bd9",
+     "bbe0338c3acdc8791e308d8411c986048096f36c",
      [
       null,
       {}
      ]
     ],
     "transaction-abort-index-metadata-revert.html": [
-     "355fbbc31feb6218b2ffd08f7b54cff34cd89ce1",
+     "54a873d8758c6a906c1899ee0c15e990a8798444",
      [
       null,
       {}
      ]
     ],
     "transaction-abort-multiple-metadata-revert.html": [
-     "ca63eaaad3714a4a7bf4ae5942a094cfb9f3614a",
+     "18abd0588c4197e22976644a706f1df4731aad5d",
      [
       null,
       {}
      ]
     ],
     "transaction-abort-object-store-metadata-revert.html": [
-     "bcdcd1a22fd79791c212c4cc9eabe74b595316d7",
+     "c31537bc5cda382fdf87608f55af434129e2710a",
      [
       null,
       {}
      ]
     ],
     "transaction-abort-request-error.html": [
-     "ef3c097290b016812f1a9c918c6e0c11d5ae27c5",
+     "1690dc00434ac958beaa428811115df456b5165a",
      [
       null,
       {}
      ]
     ],
     "transaction-create_in_versionchange.htm": [
-     "0bfb4a87b911b841cdb7efd25c20f1d203ba07e2",
+     "f2facc8790d99aea69d78ba8cd3aaab2a3f8538d",
      [
       null,
       {}
      ]
     ],
     "transaction-deactivation-timing.html": [
-     "e3b4a968e877888d9dcf6ae05afdd1065cb69b95",
+     "674b1668f3e4a826e0681c2c60d139120e5ddcf2",
      [
       null,
       {}
      ]
     ],
     "transaction-lifetime-blocked.htm": [
-     "82c3ae032e8523d7da4ea8422588600373389411",
+     "760b6b9bdbe91b987b02495a2cd7af4328520c90",
      [
       null,
       {}
      ]
     ],
     "transaction-lifetime-empty.html": [
-     "7d4b0d7f7c7c8c41be52434ea530f0358b5e6fcb",
+     "ba299fdcd041802b49e41cb87cf4d52a577bab81",
      [
       null,
       {}
      ]
     ],
     "transaction-lifetime.htm": [
-     "2c8fd2f58089bf8752868bd3ceb7a5180fc79cf2",
+     "996f62937f76fa2b97fd3b66ead3993d234773f5",
      [
       null,
       {}
      ]
     ],
     "transaction-relaxed-durability.tentative.any.js": [
-     "7e17403eb0c202c5cccbee19b8cffd0d9de98ac2",
+     "9197389a24425483912249634b8954bab2e1b5a6",
      [
       "IndexedDB/transaction-relaxed-durability.tentative.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "timeout",
@@ -341827,7 +341895,7 @@
        "script_metadata": [
         [
          "script",
-         "support-promises.js"
+         "resources/support-promises.js"
         ],
         [
          "timeout",
@@ -341839,21 +341907,21 @@
      ]
     ],
     "transaction-requestqueue.htm": [
-     "9f28e81ea8a65013f4ba9a1992aaff8598418f5f",
+     "cef8699df42dfc6f6fd349de06a28fe87a35a030",
      [
       null,
       {}
      ]
     ],
     "transaction-scheduling-across-connections.any.js": [
-     "92d098d29c937c84b7bc9dd1219f126db0b7e585",
+     "84223a17338224de1e226156dc42efbb3c20fadd",
      [
       "IndexedDB/transaction-scheduling-across-connections.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341864,21 +341932,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-across-databases.any.js": [
-     "064444175867ca528d0d90ea0be40d573561ca88",
+     "eada0f7e839cc3de7d089b1c52b2a3f283b183b9",
      [
       "IndexedDB/transaction-scheduling-across-databases.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341889,21 +341957,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-mixed-scopes.any.js": [
-     "5f04a6a288d23c29a7663ccfcdb32c932d573831",
+     "6f550c58a55411e93e1c3325a422e7a20e7c2550",
      [
       "IndexedDB/transaction-scheduling-mixed-scopes.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341914,21 +341982,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-ordering.any.js": [
-     "9f47e5c58ca3961d83263c7d90da597b83e06ceb",
+     "95c9bbf3a7689d603b511c7120d87a4a65e1aa0d",
      [
       "IndexedDB/transaction-scheduling-ordering.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341939,21 +342007,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-ro-waits-for-rw.any.js": [
-     "dca08b820888f13c00cdb5a8a61badac884fac21",
+     "6457abe802726fe2b2b8caa837d2fbf4ec1ab936",
      [
       "IndexedDB/transaction-scheduling-ro-waits-for-rw.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341964,21 +342032,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-rw-scopes.any.js": [
-     "7c6f61614b0689d3090222872379c1269559ec4c",
+     "7296fef3b073b5ad4b6fa8f8159129f9970a6387",
      [
       "IndexedDB/transaction-scheduling-rw-scopes.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -341989,21 +342057,21 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction-scheduling-within-database.any.js": [
-     "10dd8b6d7ac5ed9dd4399a04dada2f5e88b827d8",
+     "552b4e4b2638bfe751e04c5a699d7a5d275cf429",
      [
       "IndexedDB/transaction-scheduling-within-database.any.html",
       {
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
@@ -342014,63 +342082,63 @@
        "script_metadata": [
         [
          "script",
-         "support.js"
+         "resources/support.js"
         ]
        ]
       }
      ]
     ],
     "transaction_bubble-and-capture.htm": [
-     "bffa9307ccf3c7738639eb243cbf2d3ae984cb5d",
+     "9b6694b980c579d068c5c93a13ef5b61985a6a85",
      [
       null,
       {}
      ]
     ],
     "upgrade-transaction-deactivation-timing.html": [
-     "f941f219e563bcd3fd3f1ae5d6a718e4bb7e17e5",
+     "8119c9ab261ee632b3ee4f9c08a4ce25ea626adc",
      [
       null,
       {}
      ]
     ],
     "upgrade-transaction-lifecycle-backend-aborted.html": [
-     "b516788e0959380ce30a7635a1fa9ee438d57aac",
+     "862e85144d64a12eda04e0b48c6954ff996486a0",
      [
       null,
       {}
      ]
     ],
     "upgrade-transaction-lifecycle-committed.html": [
-     "53afc13259ed654f6db345ecfa78c898f56db821",
+     "347d940aeefae01f9a41c8c460ae29135ccee4d0",
      [
       null,
       {}
      ]
     ],
     "upgrade-transaction-lifecycle-user-aborted.html": [
-     "8dff86196cf5db54f6148d4e9876ba9beb5828cf",
+     "4094ce34f34aa06d8ce4433b963819cf4f39f6b6",
      [
       null,
       {}
      ]
     ],
     "value.htm": [
-     "36e8339524852590d52ce2275a9f0c0f372f6d31",
+     "cc58528e4d93fad72587e42a39abd24997d97051",
      [
       null,
       {}
      ]
     ],
     "value_recursive.htm": [
-     "f49a1ccbc59ae14eb5ba74e37dccf8d6e56aa8b5",
+     "ef52aca221e487eb2c0dccbcac2bd80df4fc432c",
      [
       null,
       {}
      ]
     ],
     "writer-starvation.htm": [
-     "cdc7b1e8774f8e4d486d220f5c4ee1996ab7a901",
+     "3b15089307d2565d5b076c1a49597dc41222f03f",
      [
       null,
       {
@@ -370239,10 +370307,12 @@
       ]
      ],
      "all-prop-revert-noop.html": [
-      "696f498421e54d469f8304d46f34d9c39f81a4ef",
+      "d70fa53022e16e2fc01f9035e13f1f4eb9f118bf",
       [
        null,
-       {}
+       {
+        "timeout": "long"
+       }
       ]
      ],
      "at-scope-parsing.html": [
@@ -371406,6 +371476,13 @@
         {}
        ]
       ],
+      "svg-foreignobject-child-container.html": [
+       "898fc22c2ba038a07b0907517d3e5e1cb421500a",
+       [
+        null,
+        {}
+       ]
+      ],
       "svg-root-size-container.html": [
        "70ce40c0bcefc595a7afedadf945ac6c8b19b2fc",
        [
@@ -399441,7 +399518,7 @@
       ]
      ],
      "Event-constructors.any.js": [
-      "aced2f3c2cda6112541c49fad40b85a3deac56cf",
+      "faa623ea92991b72742477a18471449f5382f1a8",
       [
        "dom/events/Event-constructors.any.html",
        {
@@ -423990,7 +424067,7 @@
        ]
       ],
       "request-error.any.js": [
-       "67ed70c5db2f09aaed3a97fc249022b20d4b941e",
+       "9ec8015198daddf55d61fbd98a9d093da0f6a76d",
        [
         "fetch/api/request/request-error.any.html",
         {
@@ -430436,7 +430513,7 @@
    },
    "fs": {
     "FileSystemBaseHandle-IndexedDB.https.any.js": [
-     "7f0fc4a7212db3c4bc19f59d0ce265ccf5536bae",
+     "9e67fe88028210eba24cbc18ddcd40027acca492",
      [
       "fs/FileSystemBaseHandle-IndexedDB.https.any.html",
       {
@@ -430459,7 +430536,7 @@
         ],
         [
          "script",
-         "/IndexedDB/support-promises.js"
+         "/IndexedDB/resources/support-promises.js"
         ],
         [
          "script",
@@ -430490,7 +430567,7 @@
         ],
         [
          "script",
-         "/IndexedDB/support-promises.js"
+         "/IndexedDB/resources/support-promises.js"
         ],
         [
          "script",
@@ -457324,6 +457401,39 @@
        }
       ]
      ],
+     "reflection-credentialless.tentative.https.any.js": [
+      "82d4223039d821f12370ee968cd1797d82ed8116",
+      [
+       "html/cross-origin-embedder-policy/reflection-credentialless.tentative.https.any.html",
+       {}
+      ],
+      [
+       "html/cross-origin-embedder-policy/reflection-credentialless.tentative.https.any.worker.html",
+       {}
+      ]
+     ],
+     "reflection-require-corp.tentative.https.any.js": [
+      "c96b8f3b5deef700266d0d74d818d760432ac9bb",
+      [
+       "html/cross-origin-embedder-policy/reflection-require-corp.tentative.https.any.html",
+       {}
+      ],
+      [
+       "html/cross-origin-embedder-policy/reflection-require-corp.tentative.https.any.worker.html",
+       {}
+      ]
+     ],
+     "reflection-unsafe-none.tentative.https.any.js": [
+      "4694f9110ec93012f8a25d120ab6ecc456cd070f",
+      [
+       "html/cross-origin-embedder-policy/reflection-unsafe-none.tentative.https.any.html",
+       {}
+      ],
+      [
+       "html/cross-origin-embedder-policy/reflection-unsafe-none.tentative.https.any.worker.html",
+       {}
+      ]
+     ],
      "report-only-require-corp.https.html": [
       "ff9e5b64a084eb2d2d990c3a7660633468772ff8",
       [
@@ -459990,14 +460100,14 @@
         ]
        ],
        "serialization-via-idb.any.js": [
-        "2917013ee2536507ee3a5a3cbd03e93987b51351",
+        "e317b150cc9457c60084a45eebbc85fdbf7017f3",
         [
          "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.html",
          {
           "script_metadata": [
            [
             "script",
-            "/IndexedDB/support.js"
+            "/IndexedDB/resources/support.js"
            ]
           ]
          }
@@ -460008,7 +460118,7 @@
           "script_metadata": [
            [
             "script",
-            "/IndexedDB/support.js"
+            "/IndexedDB/resources/support.js"
            ]
           ]
          }
@@ -467756,7 +467866,7 @@
         ]
        ],
        "SubmitEvent.window.js": [
-        "5f98fe05155fa4bb1bf14413b14f1146fcc2cad1",
+        "382181551544072f8ee24f0a6dba89ea3e529558",
         [
          "html/semantics/forms/form-submission-0/SubmitEvent.window.html",
          {}
@@ -481743,7 +481853,7 @@
      ]
     ],
     "zero-area-element-visible.html": [
-     "5431750485fddca7f6ebc97b0a8a1dda498ab4e2",
+     "b012b65c1894b4fcaaf101af95d3d2b7fe7dd1f9",
      [
       null,
       {}
@@ -521219,7 +521329,7 @@
      ]
     ],
     "estimate-usage-details-indexeddb.https.tentative.any.js": [
-     "c854d5b8848638d11563a48348e7c3393ff58459",
+     "551cede9c6d1dce91b2323f9f6953d6f0142760b",
      [
       "storage/estimate-usage-details-indexeddb.https.tentative.any.html",
       {
@@ -521234,7 +521344,7 @@
         ],
         [
          "script",
-         "../IndexedDB/support-promises.js"
+         "../IndexedDB/resources/support-promises.js"
         ]
        ]
       }
@@ -521253,7 +521363,7 @@
         ],
         [
          "script",
-         "../IndexedDB/support-promises.js"
+         "../IndexedDB/resources/support-promises.js"
         ]
        ]
       }
@@ -521363,7 +521473,7 @@
      ]
     ],
     "partitioned-estimate-usage-details-indexeddb.tentative.https.sub.html": [
-     "101ff6f0c6f37ac196621fdf9a1203431a4426a2",
+     "a58d5426543be328521bcb8a5fd3e7524857d2d5",
      [
       null,
       {}
@@ -536688,14 +536798,14 @@
        ]
       ],
       "serialization-via-idb.any.js": [
-       "10c99c4d31cb4cc57a3435a2490e0cb3a0e1d081",
+       "2591d2fe7478adf4628a1ca9b39a2fc0541fba16",
        [
         "wasm/serialization/module/serialization-via-idb.any.html",
         {
          "script_metadata": [
           [
            "script",
-           "/IndexedDB/support.js"
+           "/IndexedDB/resources/support.js"
           ]
          ]
         }
@@ -536706,7 +536816,7 @@
          "script_metadata": [
           [
            "script",
-           "/IndexedDB/support.js"
+           "/IndexedDB/resources/support.js"
           ]
          ]
         }
@@ -546068,7 +546178,7 @@
       ]
      ],
      "opaque-origin.html": [
-      "7f2f443c52fb0c1af95abccc3d78c3ed81232887",
+      "c1762299dbf668aab5844862734869d71363234c",
       [
        null,
        {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-inline-size-intrinsic.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-inline-size-intrinsic.html
new file mode 100644
index 0000000..5d59b6b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-inline-size-intrinsic.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>contain:inline-size with contain-intrinsic-size</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#containment-inline-size">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#propdef-contain-intrinsic-size">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="background:green; contain:inline-size; height:50px; width:fit-content; contain-intrinsic-inline-size:100px">
+  <div style="display:inline-block; width:75px;"></div>
+  <div style="display:inline-block; width:75px;"></div>
+</div>
+<div style="background:green; contain:inline-size; height:fit-content; width:100px; contain-intrinsic-inline-size:50px; writing-mode: vertical-rl;">
+  <div style="display:inline-block; height:35px;"></div>
+  <div style="display:inline-block; height:35px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container.html
new file mode 100644
index 0000000..898fc22
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>CSS Container Queries Test: size query container inside foreignObject</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/cq-testcommon.js"></script>
+<style>
+  svg {
+    display: block;
+    width: 200px;
+    height: 200px;
+    container-type: size;
+  }
+  #container {
+    width: 100px;
+    height: 100px;
+    container-type: size;
+  }
+  @container (width = 100px) {
+    #inner { color: green; }
+  }
+</style>
+<svg>
+  <foreignObject>
+    <div id="container">
+      <div id="inner">Green</div>
+    </div>
+  </foreignObject>
+</svg>
+<script>
+  setup(() => assert_implements_container_queries());
+
+  const green = "rgb(0, 128, 0)";
+
+  test(() => {
+    assert_equals(getComputedStyle(inner).color, green);
+  }, "#inner querying #container inside foreignObject");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002-ref.html
index 84110e57..412602ad 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002-ref.html
@@ -8,6 +8,8 @@
       overflow: auto;
       width: 100px;
       height: 100px;
+      /* Avoids some fuzz on scrollbar corners */
+      scrollbar-color: blue blue;
   }
   .child {
       position: relative;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002.html
index 79dcaad6..5f6d740 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-002.html
@@ -9,6 +9,8 @@
       overflow: auto;
       width: 100px;
       height: 100px;
+      /* Avoids some fuzz on scrollbar corners */
+      scrollbar-color: blue blue;
   }
   .parent {
       width: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005-ref.html
index 84110e57..412602ad 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005-ref.html
@@ -8,6 +8,8 @@
       overflow: auto;
       width: 100px;
       height: 100px;
+      /* Avoids some fuzz on scrollbar corners */
+      scrollbar-color: blue blue;
   }
   .child {
       position: relative;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005.html
index 2d03a96..1b4b4aa9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-clip-margin-005.html
@@ -9,6 +9,8 @@
       overflow: auto;
       width: 100px;
       height: 100px;
+      /* Avoids some fuzz on scrollbar corners */
+      scrollbar-color: blue blue;
   }
   .parent {
       width: 100px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-table-caption.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-table-caption.html
new file mode 100644
index 0000000..20ff6288
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-table-caption.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<title>position:relative should work on table captions</title>
+<link rel="match" href="position-relative-table-top-ref.html" />
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#rel-pos" />
+<meta name="assert" content="This test checks that the position:relative top constraint behaves correctly for &lt;caption&gt; elements">
+<style>
+table {
+  border-collapse:collapse;
+}
+
+caption {
+  width: 50px;
+  height: 50px;
+  position: relative;
+  top: 100px;
+  background-color: green;
+}
+
+.group {
+  position: relative;
+  display: inline-block;
+  height: 200px;
+}
+
+.indicator {
+  position: absolute;
+  background-color: red;
+  left: 0;
+  top: 100px;
+  height: 50px;
+  width: 50px;
+}
+</style>
+
+<div class="group">
+  <div class="indicator"></div>
+  <table>
+    <caption></caption>
+  </table>
+</div>
+
+<div>You should see a green box above. No red should be visible.</div>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-each-line-hanging-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-each-line-hanging-ref.html
new file mode 100644
index 0000000..3357d7d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-each-line-hanging-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>text-indent 'each-line' and 'hanging' modifiers</title>
+
+    <link rel="stylesheet" href="/fonts/ahem.css" />
+    <style>
+    div { width:80px; font: 10px Ahem; background-color:lightgray; }
+    .indent { color: blue; padding-left:4em; }
+    </style>
+</head>
+<body>
+All black boxes should be left-aligned. All blue boxes should be right-aligned.
+
+<div>
+<span class="indent">xxxx</span><br>xxxx<br>xxxx
+</div>
+<br>
+<div>
+<span class="indent">xxxx</span> xxxx xxxx
+</div>
+<br>
+<div>
+<span class="indent">xxxx</span><br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
+</div>
+<br>
+<div>
+<span class="indent">xxxx</span> xxxx<br><span class="indent">xxxx</span>
+</div>
+<br>
+<div>
+xxxx<br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
+</div>
+<br>
+<div>
+xxxx <span class="indent">xxxx</span> <span class="indent">xxxx</span>
+</div>
+<br>
+<div>
+xxxx<br>xxxx<br>xxxx
+</div>
+<br>
+<div>
+xxxx <span class="indent">xxxx</span><br>xxxx
+</div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-with-absolute-pos-child-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-with-absolute-pos-child-ref.html
new file mode 100644
index 0000000..e5feb2c7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/reference/text-indent-with-absolute-pos-child-ref.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>This tests that first line text-indent is applied properly when the child is a statically positioned out-of-flow renderer.</title>
+
+<link rel="stylesheet" href="/fonts/ahem.css" />
+<style>
+ body {
+  margin: 40px;
+ }
+
+.container {
+  display: block;
+  background-color: green;
+  width: 100px;
+  height: 20px;
+  color: green;
+  font-family: Ahem;
+  font-size: 10px;
+}
+
+.inner {
+  display: block;
+  background-color: blue;
+  width: 20px;
+  height: 20px;
+}
+</style>
+</head>
+<body>
+<div>
+<div class=container><div class=inner style="margin-left: 20px;"></div></div>
+<div class=container><div class=inner style="margin-left: 20px;"></div></div>
+<div class=container><div class=inner style="margin-left: 20px;"></div></div>
+<div class=container><div class=inner style="margin-left: 20px;"></div></div>
+<div class=container><div class=inner style="position: relative; left: 70px;"></div></div>
+<div class=container><div class=inner style="margin-left: -20px;"></div></div>
+<div class=container><div class=inner style="left: 40px;"></div></div>
+<div class=container><div class=inner></div></div>
+<div class=container><div class=inner></div></div>
+<div class=container><div class=inner style="position: relative; top: 10px"></div></div>
+<div class=container><div class=inner></div></div>
+</div>
+
+<div style="direction: rtl;">
+<div class=container><div class=inner style="margin-right: 20px;"></div></div>
+<div class=container><div class=inner style="margin-right: 20px;"></div></div>
+<div class=container><div class=inner style="margin-right: 20px;"></div></div>
+<div class=container><div class=inner style="margin-right: 20px;"></div></div>
+<div class=container><div class=inner style="position: relative; right: 70px;"></div></div>
+<div class=container><div class=inner style="margin-right: -20px;"></div></div>
+<div class=container><div class=inner style="right: 40px;"></div></div>
+<div class=container><div class=inner></div></div>
+<div class=container><div class=inner></div></div>
+<div class=container><div class=inner style="position: relative; top: 10px"></div></div>
+<div class=container><div class=inner></div></div>
+</div>
+
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-each-line-hanging.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-each-line-hanging.html
new file mode 100644
index 0000000..2c3ac08
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-each-line-hanging.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>text-indent 'each-line' and 'hanging' modifiers</title>
+    <link rel="author" title="Jaehun Lim" href="mailto:ljaehun.lim@samsung.com">
+    <link rel="help" href="https://drafts.csswg.org/css-text-3/#text-indent-property">
+    <link rel="match" href="reference/text-indent-each-line-hanging-ref.html">
+    <meta name="assert" content="'each-line' and 'hanging' properly works">
+
+    <link rel="stylesheet" href="/fonts/ahem.css" />
+    <style>
+    div { width:80px; font: 10px Ahem; background-color:lightgray; }
+    .normal { text-indent: 4em; }
+    .eachline { text-indent: 4em each-line; }
+    .hanging { text-indent: 4em hanging; }
+    .eachlinehanging { text-indent: 4em each-line hanging; }
+    .indent { color: blue; }
+    </style>
+</head>
+<body>
+All black boxes should be left-aligned. All blue boxes should be right-aligned.
+
+<!-- normal text-indent -->
+<div class="normal">
+<span class="indent">xxxx</span> xxxx<br>xxxx
+</div>
+<br>
+<!-- each-line with a soft wrap break -->
+<div class="eachline">
+<span class="indent">xxxx</span> xxxx xxxx
+</div>
+<br>
+<!-- each-line with a forced line break -->
+<div class="eachline">
+<span class="indent">xxxx</span><br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
+</div>
+<br>
+<!-- each-line with a soft wrap break and a forced line break -->
+<div class="eachline">
+<span class="indent">xxxx</span> xxxx<br><span class="indent">xxxx</span>
+</div>
+<br>
+<!-- normal text-indent with hanging -->
+<div class="hanging">
+xxxx <span class="indent">xxxx</span><br><span class="indent">xxxx</span>
+</div>
+<br>
+<!-- each-line and hanging with a soft wrap break -->
+<div class="eachlinehanging">
+xxxx <span class="indent">xxxx</span> <span class="indent">xxxx</span>
+</div>
+<br>
+<!-- each-line and hanging with a forced line break -->
+<div class="eachlinehanging">
+xxxx<br>xxxx<br>xxxx
+</div>
+<br>
+<!-- each-line and hanging with a soft wrap break and a forced line break -->
+<div class="eachlinehanging">
+xxxx <span class="indent">xxxx</span><br>xxxx
+</div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-with-absolute-pos-child.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-with-absolute-pos-child.html
new file mode 100644
index 0000000..16a6deb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-indent/text-indent-with-absolute-pos-child.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>This tests that first line text-indent is applied properly when the child is a statically positioned out-of-flow renderer.</title>
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-indent-property">
+<link rel="match" href="reference/text-indent-with-absolute-pos-child-ref.html">
+<meta name="assert" content="First line text-indent is applied properly when the child is a statically positioned out-of-flow renderer.">
+
+<link rel="stylesheet" href="/fonts/ahem.css" />
+<style>
+  body {
+    margin: 40px;
+  }
+
+  .container {
+    display: block;
+    background-color: green;
+    width: 100px;
+    height: 20px;
+    color: green;
+    font-family: Ahem;
+    font-size: 10px;
+  }
+
+  .inner {
+    display: inline;
+    position: absolute;
+    background-color: blue;
+    width: 20px;
+    height: 20px;
+  }
+</style>
+</head>
+<body>
+<div>
+<div class=container style="text-indent: 20px"><div class=inner></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="display: inline-block;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner></div>foobar</div>
+<div class=container style="text-indent: 20px"><div class=inner style="text-indent: 20px;">f</div></div>
+<div class=container style="text-indent: 10px">foobar<div class=inner></div></div>
+<div class=container style="text-indent: -20px"><div class=inner></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="left: 40px;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="display: block;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="position: relative; display: block;"></div></div>
+<div class=container style="text-indent: 20px">foobar<br><div class=inner></div></div>
+<div class=container><div class=inner></div></div>
+</div>
+
+<div style="direction: rtl;">
+<div class=container style="text-indent: 20px"><div class=inner></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="display: inline-block;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner></div>foobar</div>
+<div class=container style="text-indent: 20px"><div class=inner style="text-indent: 20px;">f</div></div>
+<div class=container style="text-indent: 10px">foobar<div class=inner></div></div>
+<div class=container style="text-indent: -20px"><div class=inner></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="right: 40px;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="display: block;"></div></div>
+<div class=container style="text-indent: 20px"><div class=inner style="position: relative; display: block;"></div></div>
+<div class=container style="text-indent: 20px">foobar<br><div class=inner></div></div>
+<div class=container><div class=inner></div></div>
+</div>
+
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-constructors.any.js b/third_party/blink/web_tests/external/wpt/dom/events/Event-constructors.any.js
index aced2f3..faa623e 100644
--- a/third_party/blink/web_tests/external/wpt/dom/events/Event-constructors.any.js
+++ b/third_party/blink/web_tests/external/wpt/dom/events/Event-constructors.any.js
@@ -1,6 +1,12 @@
 // META: title=Event constructors
 
 test(function() {
+  assert_throws_js(
+    TypeError,
+    () => Event(""),
+    "Calling Event constructor without 'new' must throw")
+})
+test(function() {
   assert_throws_js(TypeError, function() {
     new Event()
   })
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-error.any.js b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-error.any.js
index 67ed70c..9ec80151 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-error.any.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-error.any.js
@@ -14,6 +14,14 @@
 }
 
 test(function() {
+  assert_throws_js(
+      TypeError,
+      () => Request("about:blank"),
+      "Calling Request constructor without 'new' must throw"
+    );
+});
+
+test(function() {
   var initialHeaders = new Headers([["Content-Type", "potato"]]);
   var initialRequest = new Request("", {"headers" : initialHeaders});
   var request = new Request(initialRequest);
diff --git a/third_party/blink/web_tests/external/wpt/html/anonymous-iframe/resources/embedding-test.js b/third_party/blink/web_tests/external/wpt/html/anonymous-iframe/resources/embedding-test.js
index a21cee52..414d9cfc 100644
--- a/third_party/blink/web_tests/external/wpt/html/anonymous-iframe/resources/embedding-test.js
+++ b/third_party/blink/web_tests/external/wpt/html/anonymous-iframe/resources/embedding-test.js
@@ -1,6 +1,12 @@
 // One document embeds another in an iframe. Both are loaded from the network.
 // Check whether or not the child can load.
 
+// There are no interoperable ways to check an iframe failed to load. So a
+// timeout is being used. See https://github.com/whatwg/html/issues/125
+// Moreover, we want to track progress, managing timeout explicitly allows to
+// get a per-test results, even in case of failure of one.
+setup({ explicit_timeout: true });
+
 const EXPECT_LOAD = "load";
 const EXPECT_BLOCK = "block";
 
@@ -47,8 +53,19 @@
     `);
 
     // There are no interoperable ways to check an iframe failed to load. So a
-    // timeout is being used. See https://github.com/whatwg/html/issues/125
-    step_timeout(() => send(reply_token, "block"), 4000)
+    // timeout is being used.
+    // See https://github.com/whatwg/html/issues/125
+    // Use a shorter timeout when it is expected to be reached.
+    // - The long delay reduces the false-positive rate. False-positive causes
+    //   stability problems on bot, so a big delay is used to vanish them.
+    //   https://crbug.com/1215956.
+    // - The short delay avoids delaying too much the test(s) for nothing and
+    //   timing out. False-negative are not a problem, they just need not to
+    //   overwhelm the true-negative, which is trivial to get.
+    step_timeout(() => send(reply_token, "block"), expectation == EXPECT_BLOCK
+      ? 2000
+      : 6000
+    );
 
     assert_equals(await receive(reply_token), expectation);
   }, description);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/SubmitEvent.window.js b/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/SubmitEvent.window.js
index 5f98fe0..3821815 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/SubmitEvent.window.js
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/SubmitEvent.window.js
@@ -1,7 +1,7 @@
 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-submitevent-interface
 
 test(() => {
-  let button = document.createElement('button');
+  assert_throws_js(TypeError, () => SubmitEvent(""), "Calling SubmitEvent constructor without 'new' must throw");
   assert_throws_js(TypeError, () => { new SubmitEvent() }, '0 arguments');
   assert_throws_js(TypeError, () => { new SubmitEvent('foo', { submitter: 'bar' }) }, 'Wrong type of submitter');
 }, 'Failing SubmitEvent constructor');
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/zero-area-element-visible.html b/third_party/blink/web_tests/external/wpt/intersection-observer/zero-area-element-visible.html
index 54317504..b012b65 100644
--- a/third_party/blink/web_tests/external/wpt/intersection-observer/zero-area-element-visible.html
+++ b/third_party/blink/web_tests/external/wpt/intersection-observer/zero-area-element-visible.html
@@ -14,9 +14,14 @@
   width: 0px;
   height: 0px;
 }
+#container {
+  overflow: clip;
+}
 </style>
 
-<div id='target'></div>
+<div id="container">
+  <div id='target'></div>
+</div>
 
 <script>
 var entries = [];
diff --git a/third_party/blink/web_tests/fast/mediastream/getusermedia-constraints.html b/third_party/blink/web_tests/fast/mediastream/getusermedia-constraints.html
index b6335fa..854a7a5 100644
--- a/third_party/blink/web_tests/fast/mediastream/getusermedia-constraints.html
+++ b/third_party/blink/web_tests/fast/mediastream/getusermedia-constraints.html
@@ -30,17 +30,10 @@
       });
 }, 'getUserMedia() with audio=true should succeed');
 
-promise_test(function() {
-  return navigator.mediaDevices.getUserMedia(
-      {audio: {'mandatory': { 'valid_but_unsupported_1': 0}}})
-    .then(function(s) {
-        assert_unreached('getUserMedia should have failed');
-      })
-    .catch(function(e) {
-        assert_equals(e.name, 'OverconstrainedError');
-        assert_equals(e.constraint, 'valid_but_unsupported_1');
-      });
-}, 'getUserMedia() with unsupported mandatory constraint should fail');
+promise_test(async () => {
+  await navigator.mediaDevices.getUserMedia(
+      {audio: {'mandatory': { 'valid_but_unsupported_1': 0}}});
+}, 'getUserMedia() with unsupported mandatory constraint should succeed');
 
 // The next tests document existing behavior. They seem non-conformant
 // with the specs.
diff --git a/third_party/blink/web_tests/fast/mediastream/getusermedia-promise.html b/third_party/blink/web_tests/fast/mediastream/getusermedia-promise.html
index 89831c46..13bb9e1f 100644
--- a/third_party/blink/web_tests/fast/mediastream/getusermedia-promise.html
+++ b/third_party/blink/web_tests/fast/mediastream/getusermedia-promise.html
@@ -28,16 +28,10 @@
   });
 }, 'getUserMedia() audio and video tracks');
 
-promise_test(function() {
-  return navigator.mediaDevices.getUserMedia(
-      {audio: {'mandatory': { 'valid_but_unsupported_1': 0}}})
-  .then(function(s) {
-    fail('getUserMedia should have failed');
-  }).catch(function(e) {
-    assert_equals(e.name, 'OverconstrainedError');
-    assert_equals(e.constraint, 'valid_but_unsupported_1');
-  });
-}, 'getUserMedia() with unsupported mandatory constraint');
+promise_test(async () => {
+  await navigator.mediaDevices.getUserMedia(
+      {audio: {'mandatory': { 'valid_but_unsupported_1': 0}}});
+}, 'getUserMedia() with unsupported mandatory constraint does not throw');
 
 
 </script>
diff --git a/third_party/blink/web_tests/fast/mediastream/getusermedia.html b/third_party/blink/web_tests/fast/mediastream/getusermedia.html
index 97b4a00..1337024 100644
--- a/third_party/blink/web_tests/fast/mediastream/getusermedia.html
+++ b/third_party/blink/web_tests/fast/mediastream/getusermedia.html
@@ -17,8 +17,12 @@
     finishJSTest();
 }
 
-function gotStreamInError(s) {
-    testFailed('Stream generated.');
+function gotStream6(s) {
+    stream = s;
+    testPassed('Stream generated.');
+    shouldBe('stream.getAudioTracks().length', '1');
+    shouldBe('stream.getVideoTracks().length', '1');
+
     finishJSTest();
 }
 
@@ -28,16 +32,7 @@
     shouldBe('stream.getAudioTracks().length', '1');
     shouldBe('stream.getVideoTracks().length', '1');
 
-    finishJSTest();
-}
-
-function error1(e) {
-    errorArg = e;
-    testPassed('Error callback called.');
-    shouldBeEqualToString('errorArg.name', 'OverconstrainedError');
-    shouldBeEqualToString('errorArg.constraint', 'valid_but_unsupported_1');
-
-    shouldNotThrow("navigator.getUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, error);");
+    shouldNotThrow("navigator.getUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream6, error);");
 }
 
 function gotStream4(s) {
@@ -46,7 +41,7 @@
     shouldBe('stream.getAudioTracks().length', '1');
     shouldBe('stream.getVideoTracks().length', '1');
 
-    shouldNotThrow("navigator.getUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1);");
+    shouldNotThrow("navigator.getUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStream5, error);");
 }
 
 function gotStream3(s) {
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection.html b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection.html
index d897686..a33dc50 100644
--- a/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection.html
+++ b/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection.html
@@ -66,9 +66,9 @@
 shouldNotThrow("new RTCPeerConnection(null, {optional:[{valid_and_supported_1:0},{valid_and_supported_2:0}]});");
 shouldNotThrow("new RTCPeerConnection(null, {optional:[{valid_but_unsupported_1:0},{valid_but_unsupported_2:0}]});");
 shouldThrow("new RTCPeerConnection(null, {mandatory:{valid_and_supported_1:66}});");
-shouldThrow("new RTCPeerConnection(null, {mandatory:{invalid:1}});");
-shouldThrow("new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1}});");
-shouldThrow("new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1, valid_and_supported_1:1}});");
+shouldNotThrow("new RTCPeerConnection(null, {mandatory:{invalid:1}});");
+shouldNotThrow("new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1}});");
+shouldNotThrow("new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1, valid_and_supported_1:1}});");
 shouldThrow("new RTCPeerConnection(null, {optional:{valid_and_supported_1:0}});");
 shouldThrow("new RTCPeerConnection(null, {optional:[{valid_and_supported_1:0,valid_and_supported_2:0}]});");
 // Optional constraints are ignored even if they are invalid.
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https.js
new file mode 100644
index 0000000..f7da56d
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https.js
@@ -0,0 +1,30 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startURL(
+      'resources/page-with-fenced-frame.php',
+      'Tests that Page.handleJavaScriptDialog() in a fenced frame is not allowed.');
+  await dp.Page.enable();
+  await dp.Runtime.enable();
+
+  dp.Target.setAutoAttach(
+      {autoAttach: true, waitForDebuggerOnStart: false, flatten: true});
+  let {sessionId} = (await dp.Target.onceAttachedToTarget()).params;
+
+  let childSession = session.createChild(sessionId);
+  let ffdp = childSession.protocol;
+
+  // Wait for FF to finish loading.
+  await ffdp.Page.enable();
+  ffdp.Page.setLifecycleEventsEnabled({enabled: true});
+  await ffdp.Page.onceLifecycleEvent(event => event.params.name === 'load');
+
+  // As a page in a fenced frame can't open a dialog, handleJavaScriptDialog()
+  // should return an error.
+  const result = await ffdp.Page.handleJavaScriptDialog({
+    accept: false,
+  });
+  testRunner.log(
+      'Page.handleJavaScriptDialog() from a fenced frame:\n' +
+      (result.error ? 'PASS: ' + result.error.message : 'FAIL: no error'));
+
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror.js b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror.js
new file mode 100644
index 0000000..615c9424
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror.js
@@ -0,0 +1,27 @@
+(async function(testRunner) {
+  const {dp, session} = await testRunner.startBlank(
+      `Tests that side-effect free Runtime.evaluate does not trigger window.onerror.`);
+
+  session.evaluate(`
+    window.onerrorCalled = false;
+    window.onerror = event => {
+      window.onerrorCalled = true;
+      event.preventDefault();
+    }
+  `);
+
+  await dp.Runtime.evaluate({
+    expression: 'nonexistent',
+    replMode: true,
+    throwOnSideEffect: true,
+  });
+
+  const onerrorCalled =
+      await dp.Runtime.evaluate({expression: 'window.onerrorCalled'});
+
+  testRunner.log(
+      onerrorCalled ?
+          'Side-effect free Runtime.evaluate error didn\'t trigger window.onerror' :
+          '[FAIL] Side-effect free Runtime.evaluate triggered window.onerror');
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container-expected.txt
new file mode 100644
index 0000000..3953eec2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/svg-foreignobject-child-container-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL #inner querying #container inside foreignObject assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/dom/events/Event-constructors.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/dom/events/Event-constructors.any.worker-expected.txt
index 94a22a4..f294a8c 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/dom/events/Event-constructors.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/dom/events/Event-constructors.any.worker-expected.txt
@@ -1,9 +1,9 @@
 This is a testharness.js-based test.
 PASS Event constructors
 PASS Event constructors 1
-FAIL Event constructors 2 assert_true: expected true got false
+PASS Event constructors 2
 FAIL Event constructors 3 assert_true: expected true got false
-PASS Event constructors 4
+FAIL Event constructors 4 assert_true: expected true got false
 PASS Event constructors 5
 PASS Event constructors 6
 PASS Event constructors 7
@@ -12,5 +12,6 @@
 PASS Event constructors 10
 PASS Event constructors 11
 PASS Event constructors 12
+PASS Event constructors 13
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any-expected.txt
index f3363b8..75d1889 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any-expected.txt
@@ -15,6 +15,7 @@
 PASS Bad credentials init parameter value
 PASS Bad cache init parameter value
 PASS Bad redirect init parameter value
+PASS Request error
 PASS Request should get its content-type from the init request
 PASS Request should not get its content-type from the init request if init headers are provided
 PASS Request should get its content-type from the body if none is provided
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
index f3363b8..75d1889 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
@@ -15,6 +15,7 @@
 PASS Bad credentials init parameter value
 PASS Bad cache init parameter value
 PASS Bad redirect init parameter value
+PASS Request error
 PASS Request should get its content-type from the init request
 PASS Request should not get its content-type from the init request if init headers are provided
 PASS Request should get its content-type from the body if none is provided
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
index f3363b8..75d1889 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
@@ -15,6 +15,7 @@
 PASS Bad credentials init parameter value
 PASS Bad cache init parameter value
 PASS Bad redirect init parameter value
+PASS Request error
 PASS Request should get its content-type from the init request
 PASS Request should not get its content-type from the init request if init headers are provided
 PASS Request should get its content-type from the body if none is provided
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
index f3363b8..75d1889 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
@@ -15,6 +15,7 @@
 PASS Bad credentials init parameter value
 PASS Bad cache init parameter value
 PASS Bad redirect init parameter value
+PASS Request error
 PASS Request should get its content-type from the init request
 PASS Request should not get its content-type from the init request if init headers are provided
 PASS Request should get its content-type from the body if none is provided
diff --git a/third_party/blink/web_tests/platform/generic/fast/mediastream/getusermedia-expected.txt b/third_party/blink/web_tests/platform/generic/fast/mediastream/getusermedia-expected.txt
index 419bbd6..cfb00e3 100644
--- a/third_party/blink/web_tests/platform/generic/fast/mediastream/getusermedia-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/fast/mediastream/getusermedia-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: Unknown constraint named valid_but_unsupported_1 rejected
 Tests webkitGetUserMedia.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -30,11 +29,11 @@
 PASS Stream generated.
 PASS stream.getAudioTracks().length is 1
 PASS stream.getVideoTracks().length is 1
-PASS Error callback called.
-PASS errorArg.name is "OverconstrainedError"
-PASS errorArg.constraint is "valid_but_unsupported_1"
-PASS navigator.getUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, error); did not throw exception.
-PASS navigator.getUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1); did not throw exception.
+PASS navigator.getUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStream5, error); did not throw exception.
+PASS Stream generated.
+PASS stream.getAudioTracks().length is 1
+PASS stream.getVideoTracks().length is 1
+PASS navigator.getUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream6, error); did not throw exception.
 PASS Stream generated.
 PASS stream.getAudioTracks().length is 1
 PASS stream.getVideoTracks().length is 1
diff --git a/third_party/blink/web_tests/platform/generic/fast/peerconnection/RTCPeerConnection-expected.txt b/third_party/blink/web_tests/platform/generic/fast/peerconnection/RTCPeerConnection-expected.txt
index ff24542..d7488e6 100644
--- a/third_party/blink/web_tests/platform/generic/fast/peerconnection/RTCPeerConnection-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/fast/peerconnection/RTCPeerConnection-expected.txt
@@ -1,6 +1,3 @@
-CONSOLE WARNING: Unknown constraint named invalid rejected
-CONSOLE WARNING: Unknown constraint named valid_but_unsupported_1 rejected
-CONSOLE WARNING: Unknown constraint named valid_but_unsupported_1 rejected
 Tests the RTCPeerConnection constructor.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -53,9 +50,9 @@
 PASS new RTCPeerConnection(null, {optional:[{valid_and_supported_1:0},{valid_and_supported_2:0}]}); did not throw exception.
 PASS new RTCPeerConnection(null, {optional:[{valid_but_unsupported_1:0},{valid_but_unsupported_2:0}]}); did not throw exception.
 PASS new RTCPeerConnection(null, {mandatory:{valid_and_supported_1:66}}); threw exception NotSupportedError: Failed to construct 'RTCPeerConnection': Unsatisfiable constraint valid_and_supported_1.
-PASS new RTCPeerConnection(null, {mandatory:{invalid:1}}); threw exception NotSupportedError: Failed to construct 'RTCPeerConnection': Unsatisfiable constraint invalid.
-PASS new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1}}); threw exception NotSupportedError: Failed to construct 'RTCPeerConnection': Unsatisfiable constraint valid_but_unsupported_1.
-PASS new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1, valid_and_supported_1:1}}); threw exception NotSupportedError: Failed to construct 'RTCPeerConnection': Unsatisfiable constraint valid_but_unsupported_1.
+PASS new RTCPeerConnection(null, {mandatory:{invalid:1}}); did not throw exception.
+PASS new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1}}); did not throw exception.
+PASS new RTCPeerConnection(null, {mandatory:{valid_but_unsupported_1:1, valid_and_supported_1:1}}); did not throw exception.
 PASS new RTCPeerConnection(null, {optional:{valid_and_supported_1:0}}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object..
 PASS new RTCPeerConnection(null, {optional:[{valid_and_supported_1:0,valid_and_supported_2:0}]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object..
 PASS new RTCPeerConnection(null, {optional:[{invalid:0}]}); did not throw exception.
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
index 5e1018e..d8aa34f0 100644
--- a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
@@ -4,7 +4,7 @@
 Script execution paused.
 
 Scope variables sidebar pane:
-Catch
+Catch block
     e: Error: An exception
     at innerFunction (...)
     at testFunction (...)
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
index 886a2cc..62764a2 100644
--- a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
@@ -7,7 +7,7 @@
 Block
     block2: "catch(e) {...}"
     const2: 2
-Catch
+Catch block
     e: Error: An exception
     at innerFunction (...)
     at testFunction (...)
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
index 313d1918..dc7fe54 100644
--- a/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
@@ -4,7 +4,7 @@
 Script execution paused.
 
 Scope variables sidebar pane:
-Catch
+Catch block
     error: "boom!"
 Local
     this: Window
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https-expected.txt
new file mode 100644
index 0000000..13a764a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/handleJavaScriptDialog-fenced-frame.https-expected.txt
@@ -0,0 +1,4 @@
+Tests that Page.handleJavaScriptDialog() in a fenced frame is not allowed.
+Page.handleJavaScriptDialog() from a fenced frame:
+PASS: This is only supported for top-level frames
+
diff --git a/third_party/blink/web_tests/platform/generic/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror-expected.txt b/third_party/blink/web_tests/platform/generic/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror-expected.txt
new file mode 100644
index 0000000..b50e3b1
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/inspector-protocol/runtime/runtime-evaluate-side-effect-free-onerror-expected.txt
@@ -0,0 +1,3 @@
+Tests that side-effect free Runtime.evaluate does not trigger window.onerror.
+Side-effect free Runtime.evaluate error didn't trigger window.onerror
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any-expected.txt
new file mode 100644
index 0000000..75d1889
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any-expected.txt
@@ -0,0 +1,25 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request error
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
new file mode 100644
index 0000000..75d1889
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
@@ -0,0 +1,25 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request error
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
new file mode 100644
index 0000000..75d1889
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
@@ -0,0 +1,25 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request error
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
new file mode 100644
index 0000000..75d1889
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/plz-dedicated-worker/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
@@ -0,0 +1,25 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request error
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/dom/events/Event-constructors.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/dom/events/Event-constructors.any.worker-expected.txt
new file mode 100644
index 0000000..94a22a4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/dom/events/Event-constructors.any.worker-expected.txt
@@ -0,0 +1,16 @@
+This is a testharness.js-based test.
+PASS Event constructors
+PASS Event constructors 1
+FAIL Event constructors 2 assert_true: expected true got false
+FAIL Event constructors 3 assert_true: expected true got false
+PASS Event constructors 4
+PASS Event constructors 5
+PASS Event constructors 6
+PASS Event constructors 7
+PASS Event constructors 8
+PASS Event constructors 9
+PASS Event constructors 10
+PASS Event constructors 11
+PASS Event constructors 12
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any-expected.txt
new file mode 100644
index 0000000..f3363b8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
new file mode 100644
index 0000000..f3363b8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.serviceworker-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
new file mode 100644
index 0000000..f3363b8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.sharedworker-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
new file mode 100644
index 0000000..f3363b8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/fetch/api/request/request-error.any.worker-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+FAIL RequestInit's window is not null assert_throws_js: Expect TypeError exception function "() => new Request(...args)" did not throw
+PASS Input URL is not valid
+PASS Input URL has credentials
+PASS RequestInit's mode is navigate
+PASS RequestInit's referrer is invalid
+PASS RequestInit's method is invalid
+PASS RequestInit's method is forbidden
+PASS RequestInit's mode is no-cors and method is not simple
+PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
+PASS Request with cache mode: only-if-cached and fetch mode cors
+PASS Request with cache mode: only-if-cached and fetch mode no-cors
+PASS Bad referrerPolicy init parameter value
+PASS Bad mode init parameter value
+PASS Bad credentials init parameter value
+PASS Bad cache init parameter value
+PASS Bad redirect init parameter value
+PASS Request should get its content-type from the init request
+PASS Request should not get its content-type from the init request if init headers are provided
+PASS Request should get its content-type from the body if none is provided
+PASS Request should get its content-type from init headers if one is provided
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+Harness: the test ran to completion.
+
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 71f12f192..a258a81 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4031,6 +4031,9 @@
 </enum>
 
 <enum name="ArcCustomTabsSessionEndReason">
+  <obsolete>
+    Removed as of 05/2022
+  </obsolete>
   <int value="0" label="Closed"/>
   <int value="1" label="Forwarded to a normal tab"/>
 </enum>
@@ -39216,8 +39219,8 @@
   <int value="3341" label="V8Window_ShowSaveFilePicker_Method"/>
   <int value="3342" label="V8Window_ShowDirectoryPicker_Method"/>
   <int value="3343" label="V8Window_GetOriginPrivateDirectory_Method"/>
-  <int value="3344" label="RTCConstraintEnableRtpDataChannelsTrue"/>
-  <int value="3345" label="RTCConstraintEnableRtpDataChannelsFalse"/>
+  <int value="3344" label="OBSOLETE_RTCConstraintEnableRtpDataChannelsTrue"/>
+  <int value="3345" label="OBSOLETE_RTCConstraintEnableRtpDataChannelsFalse"/>
   <int value="3346" label="FileSystemAccessDragAndDrop"/>
   <int value="3347" label="RTCAdaptivePtime"/>
   <int value="3348"
@@ -40102,9 +40105,9 @@
   <int value="4195" label="NavigatorUAData_Platform"/>
   <int value="4196" label="NavigatorUAData_Brands"/>
   <int value="4197" label="OldConstraintsParsed"/>
-  <int value="4198" label="OldConstraintNotReported"/>
-  <int value="4199" label="OldConstraintRejected"/>
-  <int value="4200" label="OldConstraintIgnored"/>
+  <int value="4198" label="OBSOLETE_OldConstraintNotReported"/>
+  <int value="4199" label="OBSOLETE_OldConstraintRejected"/>
+  <int value="4200" label="OBSOLETE_OldConstraintIgnored"/>
   <int value="4201" label="ExplicitOverflowVisibleOnReplacedElement"/>
   <int value="4202"
       label="ExplicitOverflowVisibleOnReplacedElementWithObjectProp"/>
@@ -59450,6 +59453,7 @@
   <int value="1140776731" label="WebViewForceDarkModeMatchTheme:disabled"/>
   <int value="1140903063" label="FuseBox:enabled"/>
   <int value="1141918949" label="ContextualSearchLongpressPanelHelp:enabled"/>
+  <int value="1142147693" label="webview-enable-app-recovery"/>
   <int value="1142515376" label="enable-nacl"/>
   <int value="1142752111" label="CellularUseAttachApn:disabled"/>
   <int value="1142788238" label="FontCacheScaling:disabled"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 0f592c52..5d94142 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -368,7 +368,7 @@
 
 <histogram name="Android.AutofillAssistant.FeatureModuleInstallation"
     enum="AutofillAssistantFeatureModuleInstallation"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mcarlen@chromium.org</owner>
   <owner>autofill_assistant+watch@google.com</owner>
   <summary>
@@ -1310,7 +1310,7 @@
 </histogram>
 
 <histogram name="Android.DragDrop.Image.Size" units="KB"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>shuyng@google.com</owner>
   <owner>clank-large-form-factors@google.com</owner>
   <summary>
@@ -1712,7 +1712,7 @@
 </histogram>
 
 <histogram name="Android.Intent.IntentUriWithSelector" enum="Boolean"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mthiesse@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index dfaecd1..f3bd20d 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -989,7 +989,7 @@
 </histogram>
 
 <histogram
-    name="Apps.AppList.SortDiscoveryDurationAfterEducationNudgeV2{TabletOrClamshell}"
+    name="Apps.AppList.SortDiscoveryDurationAfterEducationNudgeV2.{TabletOrClamshell}"
     units="ms" expires_after="M107">
   <owner>andrewxu@chromium.org</owner>
   <owner>tbarzic@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index 963d81ec..8cef64e 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -815,8 +815,11 @@
 
 <histogram name="Arc.CustomTabs.SessionEndReason"
     enum="ArcCustomTabsSessionEndReason" expires_after="2020-08-23">
+  <obsolete>
+    Removed as of 05/2022
+  </obsolete>
   <owner>hashimoto@google.com</owner>
-  <owner>shihuis@google.com</owner>
+  <owner>shiihuis@google.com</owner>
   <summary>
     Reason why a custom tab session ended. Recorded when a session ends.
   </summary>
@@ -824,12 +827,18 @@
 
 <histogram name="Arc.CustomTabs.SessionLifetime2.All" units="ms"
     expires_after="2020-10-04">
+  <obsolete>
+    Removed as of 05/2022
+  </obsolete>
   <owner>hashimoto@google.com</owner>
   <summary>Lifetime of each session. Recorded when a session ends.</summary>
 </histogram>
 
 <histogram name="Arc.CustomTabs.SessionLifetime2.Closed" units="ms"
     expires_after="2020-05-31">
+  <obsolete>
+    Removed as of 05/2022
+  </obsolete>
   <owner>hashimoto@google.com</owner>
   <summary>
     Lifetime of each session. Recorded when a session is closed.
@@ -838,6 +847,9 @@
 
 <histogram name="Arc.CustomTabs.SessionLifetime2.ForwardedToNormalTab"
     units="ms" expires_after="2020-05-31">
+  <obsolete>
+    Removed as of 05/2022
+  </obsolete>
   <owner>hashimoto@google.com</owner>
   <summary>
     Lifetime of each session. Recorded when a session ends because the tab was
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 6f25d29..b90c11c 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2682,7 +2682,7 @@
 </histogram>
 
 <histogram name="Ash.Notification.ExpandOrCollapse.AnimationSmoothness"
-    units="%" expires_after="2022-09-18">
+    units="%" expires_after="2022-11-20">
   <owner>leandre@chromium.org</owner>
   <owner>cros-status-area-eng@google.com</owner>
   <summary>
@@ -2693,6 +2693,18 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Ash.Notification.GroupNotification.SlideOut.AnimationSmoothness"
+    units="%" expires_after="2023-03-03">
+  <owner>amehfooz@chromium.org</owner>
+  <owner>cros-status-area-eng@google.com</owner>
+  <summary>
+    Animation smoothness of the slide out part of the animation when a grouped
+    notification is removed. Emmitted when a grouped notification is removed by
+    clicking on it's close button.
+  </summary>
+</histogram>
+
 <histogram name="Ash.Notification.GroupNotificationAdded"
     enum="GroupNotificationType" expires_after="2023-03-03">
   <owner>leandre@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 7732c62..e6d8255 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -49,7 +49,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.Accessibility.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -528,7 +528,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.CompositingCommit.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -547,7 +547,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.CompositingInputs.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -566,7 +566,7 @@
 </histogram>
 
 <histogram name="Blink.Compression.CompressionStream.Format"
-    enum="CompressionStreamsFormat" expires_after="2022-09-18">
+    enum="CompressionStreamsFormat" expires_after="2022-11-20">
   <owner>ricea@chromium.org</owner>
   <owner>yhirano@chromium.org</owner>
   <summary>
@@ -578,7 +578,7 @@
 </histogram>
 
 <histogram name="Blink.Compression.DecompressionStream.Format"
-    enum="CompressionStreamsFormat" expires_after="2022-09-18">
+    enum="CompressionStreamsFormat" expires_after="2022-11-20">
   <owner>ricea@chromium.org</owner>
   <owner>yhirano@chromium.org</owner>
   <summary>
@@ -590,7 +590,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ContentDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1242,7 +1242,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.HitTestDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1562,7 +1562,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ImplCompositorCommit.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1702,7 +1702,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.Layout.UpdateTime" units="microseconds"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1978,7 +1978,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ParseStyleSheet.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -2773,7 +2773,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.UserAgentOverride" enum="UserAgentOverride"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>aarontag@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -2827,7 +2827,7 @@
 </histogram>
 
 <histogram name="Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold"
-    enum="NQEEffectiveConnectionType" expires_after="2022-09-18">
+    enum="NQEEffectiveConnectionType" expires_after="2022-11-20">
   <owner>sclittle@chromium.org</owner>
   <owner>rajendrant@chromium.org</owner>
   <summary>
@@ -2897,7 +2897,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.WaitForCommit.UpdateTime"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index a6dd7447..ac989e85 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-09-20">
+    enum="BooleanSuccess" expires_after="2022-11-20">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -283,7 +283,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.Discovered.Version"
-    enum="FastPairVersion" expires_after="2022-09-20">
+    enum="FastPairVersion" expires_after="2022-11-20">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -722,7 +722,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.PairingMethod"
-    enum="FastPairPairingMethod" expires_after="2022-09-20">
+    enum="FastPairPairingMethod" expires_after="2022-11-20">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -839,7 +839,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.RetroactiveEngagementFunnel.Steps"
-    enum="FastPairRetroactiveEngagementFlowEvent" expires_after="2022-09-20">
+    enum="FastPairRetroactiveEngagementFlowEvent" expires_after="2022-11-20">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -853,7 +853,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.FastPair.RetroactivePairing.Result"
-    enum="BooleanSuccess" expires_after="2022-09-20">
+    enum="BooleanSuccess" expires_after="2022-11-20">
   <owner>shanefitz@google.com</owner>
   <owner>julietlevesque@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -1024,7 +1024,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.PoweredState" enum="BooleanEnabled"
-    expires_after="2022-11-13">
+    expires_after="2022-11-20">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index bdba3054..9cce694 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -758,7 +758,7 @@
 
 <histogram
     name="BrowserRenderProcessHost.SuspendedChild.KernelExecutionRecorded"
-    enum="BooleanRecorded" expires_after="2022-09-01">
+    enum="BooleanRecorded" expires_after="2022-11-20">
   <owner>wfh@chromium.org</owner>
   <owner>chrome-stability-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index 3185a97e..7216ca2 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1399,7 +1399,7 @@
 </histogram>
 
 <histogram name="ChromeOS.SAML.Scraping.PasswordCountAll" units="passwords"
-    expires_after="2022-09-21">
+    expires_after="2022-11-20">
   <owner>mslus@chromium.org</owner>
   <owner>emaxx@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
index 0ad3a792..8f933be 100644
--- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -408,7 +408,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.WindowOpenDuration" units="ms"
-    expires_after="2022-09-01">
+    expires_after="2022-11-20">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-customization@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml
index 0551ba7..0e61dc7 100644
--- a/tools/metrics/histograms/metadata/commerce/histograms.xml
+++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -169,7 +169,7 @@
 
 <histogram
     name="Commerce.PowerBookmarks.ShoppingDataProvider.FallbackDataContent"
-    enum="ShoppingDataProviderFallback" expires_after="2022-09-18">
+    enum="ShoppingDataProviderFallback" expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
@@ -181,7 +181,7 @@
 </histogram>
 
 <histogram name="Commerce.PowerBookmarks.ShoppingDataProvider.FallbackDataUsed"
-    enum="Boolean" expires_after="2022-09-18">
+    enum="Boolean" expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
@@ -454,7 +454,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.Message.ClearReason"
-    enum="MerchantTrustMessageClearReason" expires_after="2022-09-18">
+    enum="MerchantTrustMessageClearReason" expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <summary>
@@ -466,7 +466,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.Message.DismissReason"
-    enum="MessageDismissReason" expires_after="2022-09-18">
+    enum="MessageDismissReason" expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <summary>
@@ -476,7 +476,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.Message.DurationPrepared" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <summary>
@@ -486,7 +486,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.Message.DurationShown" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <summary>
@@ -496,7 +496,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.MessageImpact.BrowsingTime" units="ms"
-    expires_after="2022-11-13">
+    expires_after="2022-11-20">
   <owner>zhiyuancai@chromium.org</owner>
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -523,7 +523,7 @@
 </histogram>
 
 <histogram name="MerchantTrust.MessageImpact.NavigationCount"
-    units="navigations" expires_after="2022-11-13">
+    units="navigations" expires_after="2022-11-20">
   <owner>zhiyuancai@chromium.org</owner>
   <owner>ayman@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 0cce5fa..214e5b89 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -377,7 +377,7 @@
 
 <histogram
     name="Compositing.Display.OverlayProcessorUsingStrategy.CheckOverlaySupportCallCount"
-    units="units" expires_after="2022-09-18">
+    units="units" expires_after="2022-11-20">
   <owner>khaslett@chromium.org</owner>
   <owner>kylechar@chromium.org</owner>
   <summary>
@@ -388,7 +388,7 @@
 
 <histogram
     name="Compositing.Display.OverlayProcessorUsingStrategy.CheckOverlaySupportUs"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
   <owner>khaslett@chromium.org</owner>
   <owner>kylechar@chromium.org</owner>
   <summary>
@@ -486,7 +486,7 @@
 </histogram>
 
 <histogram name="Compositing.Renderer.CALayer.OddOffsetVideo" enum="OddOffset"
-    expires_after="2022-09-17">
+    expires_after="2022-11-20">
   <owner>magchen@chromium.org</owner>
   <owner>ccameron@chromium.org</owner>
   <summary>
@@ -496,7 +496,7 @@
 </histogram>
 
 <histogram name="Compositing.Renderer.CALayer.OddSizedVideo" enum="OddSize"
-    expires_after="2022-09-17">
+    expires_after="2022-11-20">
   <owner>magchen@chromium.org</owner>
   <owner>ccameron@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index a2f92c7..930a7c7e 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -519,7 +519,7 @@
 </histogram>
 
 <histogram name="ContentSettings.Popups.BlockerActions"
-    enum="PopupBlockerAction" expires_after="2022-09-18">
+    enum="PopupBlockerAction" expires_after="2022-11-20">
   <owner>csharrison@chromium.org</owner>
   <owner>lazzzis@google.com</owner>
   <owner>src/components/blocked_content/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/content_creation/histograms.xml b/tools/metrics/histograms/metadata/content_creation/histograms.xml
index 8058506..d991273 100644
--- a/tools/metrics/histograms/metadata/content_creation/histograms.xml
+++ b/tools/metrics/histograms/metadata/content_creation/histograms.xml
@@ -353,7 +353,7 @@
 </histogram>
 
 <histogram name="SharedHighlights.AsyncTask.SearchDuration" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>gayane@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 5d87c027..601b2e4f 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -398,7 +398,7 @@
 </histogram>
 
 <histogram name="Cookie.IncludedResponseEffectiveSameSite"
-    enum="CookieEffectiveSameSite" expires_after="2022-09-18">
+    enum="CookieEffectiveSameSite" expires_after="2022-11-20">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml
index 897cc9b6..a36849f 100644
--- a/tools/metrics/histograms/metadata/cras/histograms.xml
+++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -34,7 +34,7 @@
 </histogram>
 
 <histogram name="Cras.A2dp20msFailureOverStream" units="units"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -45,7 +45,7 @@
 </histogram>
 
 <histogram name="Cras.A2dpExitCode" enum="CrasA2dpExitCode"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -55,7 +55,7 @@
   </summary>
 </histogram>
 
-<histogram name="Cras.Busyloop" units="units" expires_after="2022-09-20">
+<histogram name="Cras.Busyloop" units="units" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.TimePeriod" -->
 
@@ -80,7 +80,7 @@
   </summary>
 </histogram>
 
-<histogram name="Cras.DeviceGain" units="level" expires_after="2022-09-20">
+<histogram name="Cras.DeviceGain" units="level" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.DeviceType" -->
 
@@ -163,7 +163,7 @@
 </histogram>
 
 <histogram name="Cras.DeviceTypeInput" enum="CrasDeviceType"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -174,7 +174,7 @@
 </histogram>
 
 <histogram name="Cras.DeviceTypeOutput" enum="CrasDeviceType"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -196,7 +196,7 @@
 </histogram>
 
 <histogram name="Cras.FetchDelayMilliSeconds" units="ms"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.ClientType" and
      name="Cras.StreamType" -->
@@ -243,7 +243,7 @@
 </histogram>
 
 <histogram name="Cras.HfpWidebandSpeechPacketLoss" units="units"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>enshuo@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -254,7 +254,7 @@
 </histogram>
 
 <histogram name="Cras.HfpWidebandSpeechSupported" units="BooleanSupported"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -290,7 +290,7 @@
 </histogram>
 
 <histogram name="Cras.HighestInputHardwareLevel" units="frames"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -334,7 +334,7 @@
 </histogram>
 
 <histogram name="Cras.InputDeviceBluetoothNarrowBandMicRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -434,7 +434,7 @@
 </histogram>
 
 <histogram name="Cras.InputDeviceMicRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -511,7 +511,7 @@
 </histogram>
 
 <histogram name="Cras.InputDeviceUSBRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -532,7 +532,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFirstTimeInput" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -546,7 +546,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFirstTimeOutput" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -560,7 +560,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFrequencyAfterReschedulingInput"
-    units="count" expires_after="2022-09-20">
+    units="count" expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -571,7 +571,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFrequencyAfterReschedulingOutput"
-    units="count" expires_after="2022-09-20">
+    units="count" expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -583,7 +583,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFrequencyInput" units="count"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -594,7 +594,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackFrequencyOutput" units="count"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -605,7 +605,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackSecondTimeInput" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -616,7 +616,7 @@
 </histogram>
 
 <histogram name="Cras.MissedCallbackSecondTimeOutput" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -627,7 +627,7 @@
 </histogram>
 
 <histogram name="Cras.OutputDeviceA2DPRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -672,7 +672,7 @@
 </histogram>
 
 <histogram name="Cras.OutputDeviceHDMIRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -683,7 +683,7 @@
 </histogram>
 
 <histogram name="Cras.OutputDeviceHeadphoneRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -716,7 +716,7 @@
 </histogram>
 
 <histogram name="Cras.OutputDeviceInternalSpeakerRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -760,7 +760,7 @@
 </histogram>
 
 <histogram name="Cras.OutputDeviceUSBRuntime" units="seconds"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -771,7 +771,7 @@
 </histogram>
 
 <histogram name="Cras.RtcDevicePair" enum="CrasDevicePair"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -858,7 +858,7 @@
 </histogram>
 
 <histogram name="Cras.StreamAddError" enum="CrasStreamAddError"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -867,7 +867,7 @@
 </histogram>
 
 <histogram name="Cras.StreamCallbackThreshold" units="frames"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.Direction" and
      name="Cras.ClientType" -->
@@ -902,7 +902,7 @@
 </histogram>
 
 <histogram name="Cras.StreamConnectError" enum="CrasStreamConnectError"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -912,7 +912,7 @@
 </histogram>
 
 <histogram name="Cras.StreamCreateError" enum="CrasStreamCreateError"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>Record the errors happen when CRAS server creats a stream.</summary>
@@ -944,7 +944,7 @@
   </summary>
 </histogram>
 
-<histogram name="Cras.StreamRuntime" units="seconds" expires_after="2022-09-20">
+<histogram name="Cras.StreamRuntime" units="seconds" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.Direction" and
      name="Cras.ClientType" and
@@ -974,7 +974,7 @@
 </histogram>
 
 <histogram name="Cras.StreamSamplingRate" units="bps"
-    expires_after="2022-09-20">
+    expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes
      name="Cras.Direction" and
      name="Cras.ClientType" -->
@@ -999,7 +999,7 @@
 </histogram>
 
 <histogram name="Cras.WebRTC.Audio.ApmCaptureInputLevelAverageRms"
-    units="dBFS (negated)" expires_after="2022-09-20">
+    units="dBFS (negated)" expires_after="2022-11-20">
   <owner>hychao@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/crostini/histograms.xml b/tools/metrics/histograms/metadata/crostini/histograms.xml
index f85b6a22..834051980 100644
--- a/tools/metrics/histograms/metadata/crostini/histograms.xml
+++ b/tools/metrics/histograms/metadata/crostini/histograms.xml
@@ -103,7 +103,7 @@
 </histogram>
 
 <histogram name="Crostini.Backup" enum="CrostiniExportContainerResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>Result of crostini backup.</summary>
@@ -180,7 +180,7 @@
 </histogram>
 
 <histogram name="Crostini.DiskResize.Result" enum="CrostiniDiskImageStatus"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -247,7 +247,7 @@
 </histogram>
 
 <histogram name="Crostini.FilesystemCorruption" enum="CorruptionStates"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>sidereal@google.com</owner>
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
@@ -302,7 +302,7 @@
 </histogram>
 
 <histogram name="Crostini.RestarterResult" enum="CrostiniResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -378,7 +378,7 @@
 </histogram>
 
 <histogram name="Crostini.SetupResult" enum="CrostiniSetupResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -447,7 +447,7 @@
 </histogram>
 
 <histogram name="Crostini.Stability" enum="GuestOsFailureClasses"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -479,7 +479,7 @@
 </histogram>
 
 <histogram name="Crostini.TimeToInstallCancel" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -502,7 +502,7 @@
 </histogram>
 
 <histogram name="Crostini.TimeToInstallSuccess" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
@@ -527,7 +527,7 @@
 </histogram>
 
 <histogram name="Crostini.UninstallResult" enum="CrostiniUninstallResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
index a0a5b9a..d7ab447 100644
--- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml
+++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -287,7 +287,7 @@
 </histogram>
 
 <histogram base="true" name="Cryptohome.LECredential"
-    enum="CryptohomeLECredError" expires_after="2022-09-18">
+    enum="CryptohomeLECredError" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="LECredentialOps" -->
 
   <owner>pmalani@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index 2f1b752..72470bf 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -337,7 +337,7 @@
 </histogram>
 
 <histogram name="CustomTabs.WarmupStateOnLaunch" enum="WarmupStateOnLaunch"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>lizeb@chromium.org</owner>
   <summary>
     Recorded only on Android. Reports whether warmup() has been called when a
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml
index f49fcd3..ea23efb 100644
--- a/tools/metrics/histograms/metadata/download/histograms.xml
+++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -149,7 +149,7 @@
 </histogram>
 
 <histogram name="Download.CancelReason" enum="DownloadCancelReason"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>qinmin@chromium.org</owner>
   <owner>clank-downloads@google.com</owner>
   <summary>Records why the download is canceled.</summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index 93b70e5..468a8ab 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -2153,7 +2153,7 @@
 </histogram>
 
 <histogram name="Enterprise.VpdUpdateStatus" units="units"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>igorcov@chromium.org</owner>
   <owner>tnagel@chromium.org</owner>
   <summary>
@@ -2304,7 +2304,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsManagedOrEnterpriseDevice"
-    enum="BooleanEnabled" expires_after="2022-08-21">
+    enum="BooleanEnabled" expires_after="2022-11-20">
   <owner>pastarmovj@chromium.org</owner>
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml
index 2751e8a3..ba1fc6b5 100644
--- a/tools/metrics/histograms/metadata/event/histograms.xml
+++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -979,7 +979,7 @@
 </histogram>
 
 <histogram name="Event.Latency.ScrollUpdate.JankyDurationPercentage" units="%"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ddrone@google.com</owner>
   <owner>chrometto-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index b9062fc..0f28b99 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -719,7 +719,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.RequestHeaderAdded"
-    enum="WebRequest.RequestHeader" expires_after="2022-09-18">
+    enum="WebRequest.RequestHeader" expires_after="2022-11-20">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
@@ -731,7 +731,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.RequestHeaderChanged"
-    enum="WebRequest.RequestHeader" expires_after="2022-09-18">
+    enum="WebRequest.RequestHeader" expires_after="2022-11-20">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
@@ -767,7 +767,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.ResponseHeaderChanged"
-    enum="WebRequest.ResponseHeader" expires_after="2022-09-18">
+    enum="WebRequest.ResponseHeader" expires_after="2022-11-20">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
@@ -779,7 +779,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.ResponseHeaderRemoved"
-    enum="WebRequest.ResponseHeader" expires_after="2022-09-18">
+    enum="WebRequest.ResponseHeader" expires_after="2022-11-20">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/geolocation/histograms.xml b/tools/metrics/histograms/metadata/geolocation/histograms.xml
index ae2068c..f653bfd5 100644
--- a/tools/metrics/histograms/metadata/geolocation/histograms.xml
+++ b/tools/metrics/histograms/metadata/geolocation/histograms.xml
@@ -77,7 +77,7 @@
 </histogram>
 
 <histogram name="Geolocation.LocationUpdate.ErrorCode"
-    enum="GeopositionErrorCode" expires_after="2022-09-11">
+    enum="GeopositionErrorCode" expires_after="2022-11-20">
   <owner>mattreynolds@chromium.org</owner>
   <owner>device-dev@chromium.org</owner>
   <summary>Error code for the geoposition sent to the renderers.</summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index 6f16f56..0326a70 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -634,7 +634,7 @@
 </histogram>
 
 <histogram base="true" name="GPU.DirectComposition.DCLayerResult.Video"
-    enum="DCLayerResult" expires_after="2022-09-18">
+    enum="DCLayerResult" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="GPU.ProtectedVideoType" -->
 
   <owner>magchen@chromium.org</owner>
@@ -835,7 +835,7 @@
 </histogram>
 
 <histogram name="GPU.EstablishGpuChannelSyncTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>cduvall@chromium.org</owner>
   <owner>jam@chromium.org</owner>
   <summary>
@@ -1203,7 +1203,7 @@
 </histogram>
 
 <histogram name="GPU.PaintOpReader.DeserializationError"
-    enum="PaintOpDeserializationError" expires_after="2022-09-15">
+    enum="PaintOpDeserializationError" expires_after="2022-11-20">
   <owner>junov@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -1308,7 +1308,7 @@
 </histogram>
 
 <histogram name="Gpu.Rasterization.Raster.MSAASampleCountLog2" units="count"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>penghuang@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -1319,14 +1319,14 @@
 </histogram>
 
 <histogram name="Gpu.Rasterization.Raster.NumPaintOps" units="count"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>penghuang@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>Number of paint ops in a raster task.</summary>
 </histogram>
 
 <histogram name="Gpu.Rasterization.Raster.NumSlowPaths" units="count"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>penghuang@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>Number of slow paths in a raster task.</summary>
@@ -1562,7 +1562,7 @@
 </histogram>
 
 <histogram name="GPU.Vulkan.PipelineCache.vkCreateGraphicsPipelines"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
   <owner>backer@chromium.org</owner>
   <owner>penghuang@chromium.org</owner>
   <owner>vasilyt@chromium.org</owner>
@@ -1746,7 +1746,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayStrategy"
-    enum="OverlayStrategies" expires_after="2022-09-18">
+    enum="OverlayStrategies" expires_after="2022-11-20">
   <owner>dcastagna@chromium.org</owner>
   <owner>hoegsberg@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml
index 858967e..1e6c2fd 100644
--- a/tools/metrics/histograms/metadata/history/histograms.xml
+++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="History.AttemptedToFixProfileError" units="units"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>sky@chromium.org</owner>
   <owner>sdefresne@chromium.org</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -500,7 +500,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Actions.FinalState"
-    enum="HistoryClustersFinalState" expires_after="2022-09-18">
+    enum="HistoryClustersFinalState" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -520,7 +520,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Actions.InitialState"
-    enum="HistoryClustersInitialState" expires_after="2022-09-18">
+    enum="HistoryClustersInitialState" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -533,7 +533,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Actions.LinksOpened" units="links opened"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>manukh@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -545,7 +545,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Actions.NumQueries"
-    units="number queries made" expires_after="2022-09-18">
+    units="number queries made" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -576,7 +576,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.BatchEntityLookupLatency2" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -590,7 +590,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.BatchEntityLookupSize" units="count"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -622,7 +622,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.ComputeClusters.ThreadTime"
-    units="ms" expires_after="2022-09-18">
+    units="ms" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -637,7 +637,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.EntityIdGathering.ThreadTime"
-    units="ms" expires_after="2022-09-18">
+    units="ms" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -652,7 +652,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.GetClustersLatency" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -754,7 +754,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.NumClustersReturned"
-    units="number clusters returned" expires_after="2022-09-18">
+    units="number clusters returned" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -785,7 +785,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.NumVisitsToCluster"
-    units="number visits" expires_after="2022-09-18">
+    units="number visits" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -815,7 +815,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.ProcessBatchOfVisits.ThreadTime"
-    units="ms" expires_after="2022-09-18">
+    units="ms" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -929,7 +929,7 @@
 </histogram>
 
 <histogram name="History.Clusters.ServiceLatency" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>tommycli@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;History</component>
@@ -1317,7 +1317,7 @@
 </histogram>
 
 <histogram name="History.InitializationFailureStep" enum="HistoryInitStep"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>sky@chromium.org</owner>
   <owner>sdefresne@chromium.org</owner>
   <component>UI&gt;Browser&gt;History</component>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 5272fb8..77c6a40 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -919,7 +919,7 @@
 </histogram>
 
 <histogram name="IOS.MetricKit.BackgroundTimePerDay" units="ms"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -962,7 +962,7 @@
 </histogram>
 
 <histogram name="IOS.MetricKit.ForegroundTimePerDay" units="s"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -1469,7 +1469,7 @@
 </histogram>
 
 <histogram name="IOS.Spotlight.Availability" enum="IOSSpotlightAvailability"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>rohitrao@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -1480,7 +1480,7 @@
 </histogram>
 
 <histogram name="IOS.Spotlight.BookmarksIndexingDuration" units="ms"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>olivierrobin@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>Time spent in Spotlight initial indexation of bookmarks.</summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index c999cc3..44fc427 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -215,7 +215,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.FramesProvided" units="frames"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
   <summary>
@@ -620,7 +620,7 @@
 </histogram>
 
 <histogram name="Media.Audio.InputStartupSuccessMac" enum="BooleanSuccess"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>henrika@chromium.org</owner>
   <owner>webrtc-audio@google.com</owner>
   <summary>
@@ -1777,7 +1777,7 @@
 </histogram>
 
 <histogram name="Media.Controls.CTR" enum="MediaControlsCTREvent"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>steimel@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -2692,7 +2692,7 @@
 </histogram>
 
 <histogram name="Media.GpuArcVideoDecodeAccelerator.InstanceCount.All"
-    units="instances" expires_after="2022-09-15">
+    units="instances" expires_after="2022-11-20">
   <owner>andrescj@chromium.org</owner>
   <owner>chromeos-gfx-video@google.com</owner>
   <summary>
@@ -2702,7 +2702,7 @@
 </histogram>
 
 <histogram name="Media.GpuArcVideoDecodeAccelerator.InstanceCount.Initialized"
-    units="instances" expires_after="2022-09-15">
+    units="instances" expires_after="2022-11-20">
   <owner>andrescj@chromium.org</owner>
   <owner>chromeos-gfx-video@google.com</owner>
   <summary>
@@ -2715,7 +2715,7 @@
 </histogram>
 
 <histogram name="Media.GpuMemoryBufferVideoFramePool.OddOffset.Mappable"
-    enum="Boolean" expires_after="2022-09-17">
+    enum="Boolean" expires_after="2022-11-20">
   <owner>magchen@chromium.org</owner>
   <owner>ccameron@chromium.org</owner>
   <summary>
@@ -2765,7 +2765,7 @@
 </histogram>
 
 <histogram name="Media.GpuMemoryBufferVideoFramePool.UnsupportedFormat"
-    enum="VideoPixelFormatUnion" expires_after="2022-09-17">
+    enum="VideoPixelFormatUnion" expires_after="2022-11-20">
   <owner>magchen@chromium.org</owner>
   <owner>mcasas@chromium.org</owner>
   <summary>
@@ -4238,7 +4238,7 @@
 </histogram>
 
 <histogram name="Media.Session.ActiveTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>steimel@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -4972,7 +4972,7 @@
 
 <histogram
     name="Media.VideoCapture.Windows.NumberOfRetriesNeededForMFGetDeviceStreamCategory"
-    units="retries" expires_after="2022-09-18">
+    units="retries" expires_after="2022-11-20">
   <owner>guidou@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -5698,7 +5698,7 @@
 </histogram>
 
 <histogram name="MediaRouter.CastStreaming.Session.Launch" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Total time to launch a Cast Streaming mirror session.</summary>
@@ -6091,7 +6091,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Ui.Android.DialogAction"
-    enum="MediaRouterAndroidDialogAction" expires_after="2022-09-15">
+    enum="MediaRouterAndroidDialogAction" expires_after="2022-11-20">
   <owner>muyaoxu@google.com</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
@@ -6103,7 +6103,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Ui.Android.DialogType"
-    enum="MediaRouterAndroidDialogType" expires_after="2022-09-15">
+    enum="MediaRouterAndroidDialogType" expires_after="2022-11-20">
   <owner>muyaoxu@google.com</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml
index e3172b3..dbe188b6 100644
--- a/tools/metrics/histograms/metadata/memory/histograms.xml
+++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -269,7 +269,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Active" units="MB"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -280,7 +280,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Active.Over200MBWatermark"
-    enum="BooleanGreaterOrEqualThan200MB" expires_after="2022-09-12">
+    enum="BooleanGreaterOrEqualThan200MB" expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -296,7 +296,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Background" units="MB"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -312,7 +312,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Inactive" units="MB"
-    expires_after="2022-09-12">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -2174,7 +2174,7 @@
 </histogram>
 
 <histogram name="Memory.ParkableString.OnDiskSizeKb.5min" units="KB"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>lizeb@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index c69de2758..a48fc9f 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1223,7 +1223,7 @@
 </histogram>
 
 <histogram name="Navigation.TimeToActivatePrerender{PrerenderTriggerType}"
-    units="ms" expires_after="2022-07-01">
+    units="ms" expires_after="2022-11-27">
   <owner>sreejakshetty@chromium.org</owner>
   <owner>altimin@chromium.org</owner>
   <owner>asamidoi@chromium.org</owner>
@@ -1261,7 +1261,7 @@
 </histogram>
 
 <histogram name="Navigation.UrlParamFilter.ClassificationListValidationResult"
-    enum="ClassificationListValidationResult" expires_after="2022-09-18">
+    enum="ClassificationListValidationResult" expires_after="2022-11-20">
   <owner>kaklilu@chromium.org</owner>
   <owner>src/chrome/browser/url_param_filter/OWNERS</owner>
   <summary>
@@ -1438,7 +1438,7 @@
 </histogram>
 
 <histogram name="Prerender.Experimental.PredictionStatus.DefaultSearchEngine"
-    enum="PrerenderPredictionStatus" expires_after="2022-11-06">
+    enum="PrerenderPredictionStatus" expires_after="2022-11-27">
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-prerendering@google.com</owner>
   <summary>
@@ -1450,7 +1450,7 @@
 </histogram>
 
 <histogram name="Prerender.Experimental.PredictionStatus.DirectUrlInput"
-    enum="PrerenderPredictionStatus" expires_after="2022-11-06">
+    enum="PrerenderPredictionStatus" expires_after="2022-11-27">
   <owner>asamidoi@chromium.org</owner>
   <owner>chrome-prerendering@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index dc05c11..bd2b3eb 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -2855,7 +2855,7 @@
 </histogram>
 
 <histogram name="NetworkService.DeletedOldCacheData" enum="Boolean"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>wfh@chromium.org</owner>
   <owner>mmenke@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 7553270..527e3c0 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -129,7 +129,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.DataRequest" enum="CartDiscountDataType"
-    expires_after="2022-09-11">
+    expires_after="2022-11-20">
   <owner>meiliang@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -172,7 +172,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.DiscountConsentStatusAtLoad"
-    enum="CartDiscountConsentStatus" expires_after="2022-11-13">
+    enum="CartDiscountConsentStatus" expires_after="2022-11-20">
   <owner>yuezhanggg@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -1035,7 +1035,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.Dismissed" units="count"
-    expires_after="2022-09-11">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>mahmadi@chromium.org</owner>
   <owner>tiborg@chromium.org</owner>
@@ -1080,7 +1080,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.FreExplicitOptIn" units="count"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1093,7 +1093,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.FreImplicitOptIn" enum="BooleanEnabled"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1106,7 +1106,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.FreImpression" enum="BooleanEnabled"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1119,7 +1119,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.FreLoaded" enum="BooleanEnabled"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1132,7 +1132,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.FreOptOut" units="count"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index 536986f..1b50a48c4 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -168,7 +168,7 @@
 
 <histogram
     name="OptimizationGuide.EntityAnnotatorNativeLibrary.InitiatedSuccessfully"
-    enum="BooleanSuccess" expires_after="M106">
+    enum="BooleanSuccess" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -588,7 +588,7 @@
 
 <histogram
     name="OptimizationGuide.PageContentAnnotations.AnnotateVisitResultCached"
-    enum="BooleanCacheHit" expires_after="M106">
+    enum="BooleanCacheHit" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -673,7 +673,7 @@
 
 <histogram
     name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageMinMagnitudeForVisitNotFound"
-    units="ms" expires_after="M106">
+    units="ms" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -705,7 +705,7 @@
 <histogram
     name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageStatus"
     enum="OptimizationGuidePageContentAnnotationsStorageStatus"
-    expires_after="2022-10-30">
+    expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -748,7 +748,7 @@
 
 <histogram
     name="OptimizationGuide.PageContentAnnotationsService.ModelExecutionLatency.PageEntities"
-    units="ms" expires_after="M106">
+    units="ms" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -760,7 +760,7 @@
 
 <histogram
     name="OptimizationGuide.PageContentAnnotationsService.ModelThreadExecutionLatency.PageEntities"
-    units="ms" expires_after="M106">
+    units="ms" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -802,7 +802,7 @@
 
 <histogram
     name="OptimizationGuide.PageEntitiesModelExecutor.CreatedSuccessfully"
-    enum="BooleanSuccess" expires_after="M106">
+    enum="BooleanSuccess" expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -813,7 +813,8 @@
 </histogram>
 
 <histogram name="OptimizationGuide.PageEntitiesModelExecutor.CreationStatus"
-    enum="OptimizationGuideEntityAnnotatorCreationStatus" expires_after="M106">
+    enum="OptimizationGuideEntityAnnotatorCreationStatus"
+    expires_after="2022-11-20">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -885,7 +886,7 @@
 
 <histogram name="OptimizationGuide.PageTopicsOverrideList.FileLoadResult"
     enum="OptimizationGuidePageTopicsOverrideListFileLoadResult"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>robertogden@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -898,7 +899,7 @@
 </histogram>
 
 <histogram name="OptimizationGuide.PageTopicsOverrideList.GotFile"
-    enum="Boolean" expires_after="M106">
+    enum="Boolean" expires_after="2022-11-20">
   <owner>robertogden@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
@@ -1116,7 +1117,7 @@
 
 <histogram
     name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.NetErrorCode"
-    enum="NetErrorCodes" expires_after="2022-10-30">
+    enum="NetErrorCodes" expires_after="2022-11-20">
   <owner>mcrouse@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -1146,7 +1147,7 @@
 
 <histogram
     name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.Status"
-    enum="HttpResponseCode" expires_after="2022-10-30">
+    enum="HttpResponseCode" expires_after="2022-11-20">
   <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 cbc9cff5f..038bd86e 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -3794,7 +3794,7 @@
 </histogram>
 
 <histogram name="Conversions.TriggerQueueEvents"
-    enum="ConversionTriggerQueueEvent" expires_after="2022-09-17">
+    enum="ConversionTriggerQueueEvent" expires_after="2022-11-20">
   <owner>apaseltiner@chromium.org</owner>
   <owner>johnidel@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
@@ -5523,7 +5523,7 @@
 
 <histogram name="Feedback.HappinessTrackingSurvey.ShouldShowSurveyReason"
     enum="HappinessTrackingSurveyShouldShowSurveyReasons"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>sauski@google.com</owner>
   <owner>msramek@chromium.org</owner>
   <summary>
@@ -6438,7 +6438,7 @@
 </histogram>
 
 <histogram name="ImportantFile.FileReplaceRetryCount" units="attempt count"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>brucedawson@chromium.org</owner>
   <owner>grt@chromium.org</owner>
   <summary>
@@ -7364,7 +7364,7 @@
 </histogram>
 
 <histogram name="Linux.SandboxStatus" enum="LinuxSandboxStatus"
-    expires_after="2022-09-19">
+    expires_after="2022-11-20">
   <owner>mpdenton@google.com</owner>
   <owner>src/sandbox/linux/OWNERS</owner>
   <summary>
@@ -10423,7 +10423,7 @@
 </histogram>
 
 <histogram name="RenderTextHarfBuzz.GetFallbackFontsTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
@@ -10434,7 +10434,7 @@
 </histogram>
 
 <histogram name="RenderTextHarfBuzz.GetFallbackFontTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
@@ -10445,7 +10445,7 @@
 </histogram>
 
 <histogram name="RenderTextHarfBuzz.ShapeRunsFallback" enum="ShapeRunFallback"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
@@ -10455,7 +10455,7 @@
 </histogram>
 
 <histogram name="RenderTextHarfBuzz.ShapeRunsWithFallbackFontsTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ccameron@chromium.org</owner>
   <owner>etienneb@chromium.org</owner>
   <summary>
@@ -11046,7 +11046,7 @@
   </summary>
 </histogram>
 
-<histogram name="SB2.RemoteCall.Elapsed" units="ms" expires_after="2022-09-18">
+<histogram name="SB2.RemoteCall.Elapsed" units="ms" expires_after="2022-11-20">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -11288,7 +11288,7 @@
 </histogram>
 
 <histogram name="SBIRS.UploadResult" enum="ReportProcessingResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>caitkp@google.com</owner>
   <summary>
     The result of an attempted report upload by the safe browsing incident
@@ -11807,7 +11807,7 @@
 </histogram>
 
 <histogram name="SignedExchange.LoadResult2" enum="SignedExchangeLoadResult"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ksakamoto@chromium.org</owner>
   <owner>webpackage-dev@chromium.org</owner>
   <summary>
@@ -12075,7 +12075,7 @@
 </histogram>
 
 <histogram name="Skia.VulkanMemoryAllocator.AmountAllocated" units="KB"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>egdaniel@google.com</owner>
   <owner>bsalomon@google.com</owner>
   <summary>
@@ -14344,7 +14344,7 @@
 </histogram>
 
 <histogram name="WebFont.HadBlankText" enum="BooleanHadBlankText"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 6069af3..fb1569b 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -112,7 +112,7 @@
 </histogram>
 
 <histogram name="KeyboardAccessory.AccessorySheetSuggestionsSelected"
-    enum="AccessorySuggestionType" expires_after="2022-09-18">
+    enum="AccessorySuggestionType" expires_after="2022-11-20">
   <owner>fhorschig@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -328,7 +328,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AccountChooserDialogMultipleAccounts"
-    enum="AccountChooserDismissalReason" expires_after="2022-09-18">
+    enum="AccountChooserDismissalReason" expires_after="2022-11-20">
   <owner>vasilii@chromium.org</owner>
   <owner>kazinova@google.com</owner>
   <summary>
@@ -338,7 +338,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AccountChooserDialogOneAccount"
-    enum="AccountChooserDismissalReason" expires_after="2022-09-18">
+    enum="AccountChooserDismissalReason" expires_after="2022-11-20">
   <owner>vasilii@chromium.org</owner>
   <owner>kazinova@google.com</owner>
   <summary>
@@ -397,6 +397,9 @@
 <histogram
     name="PasswordManager.AccountStorage.MoveToAccountStorePasswordsCount"
     units="credentials" expires_after="2022-05-31">
+  <obsolete>
+    Obsolete since M104.
+  </obsolete>
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -544,7 +547,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AccountStoreVsProfileStore3.{DifferenceType}"
-    units="accounts" expires_after="2022-05-31">
+    units="accounts" expires_after="2022-10-31">
   <owner>mamir@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -857,7 +860,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AutomaticChange.ForSitesWithScripts"
-    enum="PasswordCheckResolutionAction" expires_after="2022-09-18">
+    enum="PasswordCheckResolutionAction" expires_after="2022-11-20">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -1347,7 +1350,7 @@
 </histogram>
 
 <histogram name="PasswordManager.DynamicFormChanges" units="units"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -1527,7 +1530,7 @@
 </histogram>
 
 <histogram name="PasswordManager.HttpCredentials"
-    enum="PasswordManagerHttpCredentialType" expires_after="2022-09-18">
+    enum="PasswordManagerHttpCredentialType" expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1549,7 +1552,7 @@
 </histogram>
 
 <histogram name="PasswordManager.HttpPasswordMigrationMode"
-    enum="HttpPasswordMigrationMode" expires_after="2022-09-18">
+    enum="HttpPasswordMigrationMode" expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2003,7 +2006,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordDropdownShown"
-    enum="PasswordDropdownState" expires_after="2022-09-18">
+    enum="PasswordDropdownState" expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>Logs the state of the password dropdown when it's shown.</summary>
@@ -2020,7 +2023,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordExport.Event"
-    enum="PasswordExportEvent" expires_after="M106">
+    enum="PasswordExportEvent" expires_after="2022-11-20">
   <owner>ioanap@chromium.org</owner>
   <owner>kazinova@google.com</owner>
   <summary>
@@ -2522,7 +2525,7 @@
 </histogram>
 
 <histogram name="PasswordManager.RequirementsSpecFetcher.HttpResponseCode"
-    enum="HttpResponseCode" expires_after="2022-09-18">
+    enum="HttpResponseCode" expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -2570,7 +2573,7 @@
 </histogram>
 
 <histogram name="PasswordManager.SavedGaiaPasswordHashCount" units="count"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>vsemeniuk@google.com</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2877,6 +2880,26 @@
   <summary>The number of credentials shown in the Touch To Fill sheet.</summary>
 </histogram>
 
+<histogram name="PasswordManager.TouchToFill.ObservedSuccessfulSubmission"
+    units="Boolean" expires_after="2022-10-30">
+  <owner>ioanap@chromium.org</owner>
+  <owner>fhorschig@chromium.org</owner>
+  <owner>kolos@chromium.org</owner>
+  <summary>
+    Measures whether a credential filling by Touch To Fill leads to a successful
+    submission or not (submission failed, or the submission could not be
+    associated with filling by Touch To Fill). A submission after filling is
+    considered successful iff the filled and submitted usernames coincide, the
+    timestamps are within one minute and a user hasn't modified any field after
+    filling. Otherwise, it is reported as 'no successful submission observed'.
+    The metric is used to compare a login success rate when automated submission
+    is enabled and disabled. Due to stale or wrong credentials, the success rate
+    will be degraded independently of automated submission. Recorded when the
+    password manager has classified a login submission (succeeded or failed) or
+    a user has modified a field after Touch-To-Fill.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.TouchToFill.Outcome"
     enum="TouchToFill.Outcome" expires_after="2022-10-23">
   <owner>ioanap@chromium.org</owner>
@@ -2996,7 +3019,7 @@
 </histogram>
 
 <histogram name="PasswordManager.UsernameDetectionMethod"
-    enum="UsernameDetectionMethod" expires_after="2022-09-18">
+    enum="UsernameDetectionMethod" expires_after="2022-11-20">
   <owner>kazinova@google.com</owner>
   <owner>kolos@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/payment/histograms.xml b/tools/metrics/histograms/metadata/payment/histograms.xml
index 5ce44e5..0aabfb5 100644
--- a/tools/metrics/histograms/metadata/payment/histograms.xml
+++ b/tools/metrics/histograms/metadata/payment/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="DigitalGoods.CrossSite" enum="Boolean"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>glenrob@chromium.org</owner>
   <owner>dominickn@chromium.org</owner>
   <owner>rouslan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index 10991bd9..e29905d 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -913,7 +913,7 @@
 </histogram>
 
 <histogram name="Power.CpuTimeSecondsPerProcessType" enum="ProcessType2"
-    expires_after="2022-11-13">
+    expires_after="2022-11-20">
   <owner>eseckler@chromium.org</owner>
   <owner>skyostil@chromium.org</owner>
   <owner>woa-performance@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml
index 214fabc1..4839a287 100644
--- a/tools/metrics/histograms/metadata/profile/histograms.xml
+++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -53,7 +53,7 @@
 </histogram>
 
 <histogram name="Profile.AllAccounts.Names" enum="ProfileAllAccountsNames"
-    expires_after="2022-08-21">
+    expires_after="2022-11-20">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
@@ -91,7 +91,7 @@
   <summary>The frequency of selection of each avatar.</summary>
 </histogram>
 
-<histogram name="Profile.BookmarksSize" units="MB" expires_after="2022-09-18">
+<histogram name="Profile.BookmarksSize" units="MB" expires_after="2022-11-20">
   <owner>etienneb@chromium.org</owner>
   <owner>gab@chromium.org</owner>
   <summary>Size of the bookmarks database.</summary>
@@ -250,7 +250,7 @@
 </histogram>
 
 <histogram name="Profile.Incognito.MainFrameNavigationsPerSession"
-    units="navigations" expires_after="2022-09-18">
+    units="navigations" expires_after="2022-11-20">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-incognito@google.com</owner>
   <summary>
@@ -434,7 +434,7 @@
 </histogram>
 
 <histogram name="Profile.NumberOfProfilesAtProfileSwitch" units="profiles"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
@@ -479,7 +479,7 @@
 </histogram>
 
 <histogram name="Profile.SessionDuration.PerProfile" enum="Profile"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>msarda@chromium.org</owner>
   <owner>alexilin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/renderer/histograms.xml b/tools/metrics/histograms/metadata/renderer/histograms.xml
index 1ca956f..96bd792 100644
--- a/tools/metrics/histograms/metadata/renderer/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer/histograms.xml
@@ -319,7 +319,7 @@
 </histogram>
 
 <histogram name="Renderer.Font.SystemFallback.DomContentLoaded" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>kojii@chromium.org</owner>
   <owner>tkent@chromium.org</owner>
   <owner>yosin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index 5e3bbca..d8b20d7 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -185,7 +185,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.CheckBrowseUrl.HasLocalMatch"
-    enum="BooleanMatched" expires_after="2022-08-21">
+    enum="BooleanMatched" expires_after="2022-11-20">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -923,6 +923,9 @@
 
 <histogram name="SafeBrowsing.DelayedWarnings.Event"
     enum="SafeBrowsingDelayedWarningEvent" expires_after="2021-08-22">
+  <obsolete>
+    Removed in M103 as this histogram is no longer needed.
+  </obsolete>
   <owner>meacer@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1287,7 +1290,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.NavigationObserver.AppendRecentNavigationsTime"
-    units="ms" expires_after="2022-09-18">
+    units="ms" expires_after="2022-11-20">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1778,7 +1781,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.LocalMatch.Result"
-    enum="SafeBrowsingAllowlistAsyncMatch" expires_after="2022-11-13">
+    enum="SafeBrowsingAllowlistAsyncMatch" expires_after="2022-11-20">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1854,7 +1857,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.Request.Size" units="bytes"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2099,7 +2102,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4Database.Size" units="KB"
-    expires_after="2022-11-13">
+    expires_after="2022-11-20">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/scanning/histograms.xml b/tools/metrics/histograms/metadata/scanning/histograms.xml
index fb1bb81..8031bb6 100644
--- a/tools/metrics/histograms/metadata/scanning/histograms.xml
+++ b/tools/metrics/histograms/metadata/scanning/histograms.xml
@@ -84,7 +84,7 @@
 </histogram>
 
 <histogram name="Scanning.MultiPageScan.ToolbarAction"
-    enum="ScanMultiPageToolbarAction" expires_after="2022-09-03">
+    enum="ScanMultiPageToolbarAction" expires_after="2022-11-20">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index 1a1a261..20ca8d3 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -779,7 +779,7 @@
 </histogram>
 
 <histogram name="SiteIsolation.ORB.BlockingReason"
-    enum="OrbBlockingDecisionReason" expires_after="M106">
+    enum="OrbBlockingDecisionReason" expires_after="2022-11-20">
   <owner>creis@chromium.org</owner>
   <owner>lukasza@chromium.org</owner>
   <summary>
@@ -790,7 +790,7 @@
 </histogram>
 
 <histogram name="SiteIsolation.ORB.CorbVsOrb" enum="CorbVsOrb"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>creis@chromium.org</owner>
   <owner>lukasza@chromium.org</owner>
   <summary>
@@ -804,7 +804,7 @@
 </histogram>
 
 <histogram name="SiteIsolation.ORB.CorbVsOrb.OrbBlockedAndCorbDidnt.Reason"
-    enum="OrbBlockingDecisionReason" expires_after="M106">
+    enum="OrbBlockingDecisionReason" expires_after="2022-11-20">
   <owner>creis@chromium.org</owner>
   <owner>lukasza@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml b/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml
index c87e547f..ae873eb6 100644
--- a/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml
+++ b/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml
@@ -90,7 +90,7 @@
 
 <histogram
     name="SegmentationPlatform.AdaptiveToolbar.SegmentSelection.Computed"
-    enum="AdaptiveToolbarButtonVariant" expires_after="2022-11-13">
+    enum="AdaptiveToolbarButtonVariant" expires_after="2022-11-20">
   <owner>shaktisahu@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
@@ -431,7 +431,7 @@
 </histogram>
 
 <histogram name="SegmentationPlatform.SelectionFailedReason"
-    enum="SegmentationSelectionFailureReason" expires_after="2022-11-13">
+    enum="SegmentationSelectionFailureReason" expires_after="2022-11-20">
   <owner>ssid@chromium.org</owner>
   <owner>chrome-segmentation-platform@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index 94cfe4f..67759b6 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -501,7 +501,7 @@
 
 <histogram
     name="ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted2"
-    units="ms" expires_after="2022-09-20">
+    units="ms" expires_after="2022-11-20">
   <owner>bashi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -517,7 +517,7 @@
 
 <histogram
     name="ServiceWorker.LoadTiming.MainFrame.MainResource.StartToForwardServiceWorker"
-    units="ms" expires_after="2022-09-20">
+    units="ms" expires_after="2022-11-20">
   <owner>bashi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -533,7 +533,7 @@
 
 <histogram
     name="ServiceWorker.LoadTiming.MainFrame.MainResource.WorkerReadyToFetchHandlerStart"
-    units="ms" expires_after="2022-09-20">
+    units="ms" expires_after="2022-11-20">
   <owner>bashi@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -901,7 +901,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Status"
-    enum="ServiceWorkerStatusCode" expires_after="2022-11-13">
+    enum="ServiceWorkerStatusCode" expires_after="2022-11-20">
   <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 62a653b..6feb147 100644
--- a/tools/metrics/histograms/metadata/session/histograms.xml
+++ b/tools/metrics/histograms/metadata/session/histograms.xml
@@ -496,7 +496,7 @@
 </histogram>
 
 <histogram name="Session.WebState.CustomWebViewSerializedSize" units="KB"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -584,7 +584,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.SerializedSize" units="KB"
-    expires_after="2022-09-15">
+    expires_after="2022-11-20">
   <owner>justincohen@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index 25aaf64..0b36488 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -295,7 +295,7 @@
 </histogram>
 
 <histogram base="true" name="Signin.CookieJar.SignedInCountWithPrimary"
-    units="accounts" expires_after="2022-09-18">
+    units="accounts" expires_after="2022-11-20">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
 <!-- Name completed by histogram_suffixes name="UnconsentedPrimaryAccountType" -->
@@ -410,7 +410,7 @@
 </histogram>
 
 <histogram name="Signin.Extensions.GetAuthTokenResult"
-    enum="GetAuthTokenResult" expires_after="2022-09-18">
+    enum="GetAuthTokenResult" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="GetAuthTokenType" -->
 
   <owner>alexilin@chromium.org</owner>
@@ -472,7 +472,7 @@
 </histogram>
 
 <histogram name="Signin.Intercept.HeuristicOutcome"
-    enum="SigninInterceptHeuristicOutcome" expires_after="M106">
+    enum="SigninInterceptHeuristicOutcome" expires_after="2022-11-20">
   <owner>droger@chromium.org</owner>
   <owner>alexilin@chromium.org</owner>
   <summary>
@@ -502,7 +502,7 @@
 </histogram>
 
 <histogram base="true" name="Signin.InterceptResult"
-    enum="SigninInterceptResult" expires_after="M106">
+    enum="SigninInterceptResult" expires_after="2022-11-20">
 <!-- Name completed by histogram_suffixes name="SigninInterceptType" -->
 
   <owner>alexilin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml
index c8bdbbf..711f3117 100644
--- a/tools/metrics/histograms/metadata/stability/histograms.xml
+++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -242,7 +242,7 @@
 </histogram>
 
 <histogram name="Stability.ChildFrameCrash.TabMarkedForReload.Visibility"
-    enum="FrameVisibility" expires_after="2022-08-18">
+    enum="FrameVisibility" expires_after="2022-11-20">
   <owner>alexmos@chromium.org</owner>
   <owner>boliu@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 810df945..1249386 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -764,7 +764,7 @@
 </histogram>
 
 <histogram name="Startup.MobileSessionStartAction"
-    enum="MobileSessionStartAction" expires_after="2022-09-18">
+    enum="MobileSessionStartAction" expires_after="2022-11-20">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -844,7 +844,7 @@
 </histogram>
 
 <histogram name="Startup.PreMainMessageLoopRunImplLongTime" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>rkaplow@chromium.org</owner>
   <summary>
     The amount of time that elapsed during
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml
index cb8fbb4..2265d7f 100644
--- a/tools/metrics/histograms/metadata/sync/histograms.xml
+++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -870,7 +870,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessageLatency" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mastiz@chromium.org</owner>
   <component>Services&gt;Sync</component>
   <summary>
@@ -908,7 +908,7 @@
 </histogram>
 
 <histogram name="Sync.PostedGetUpdatesOrigin" enum="SyncGetUpdatesOrigin"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>mastiz@chromium.org</owner>
   <owner>rushans@google.com</owner>
   <component>Services&gt;Sync</component>
@@ -1191,7 +1191,7 @@
 </histogram>
 
 <histogram name="Sync.TrustedVaultKeyRetrievalTrigger"
-    enum="TrustedVaultUserActionTrigger" expires_after="2022-09-11">
+    enum="TrustedVaultUserActionTrigger" expires_after="2022-11-20">
   <owner>mmoskvitin@google.com</owner>
   <owner>mastiz@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 d6e2aed..d0c6fd2 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -499,7 +499,7 @@
 </histogram>
 
 <histogram name="Tab.Preview.MemoryUsage.CompressedData.TotalKiB" units="KB"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>dfried@chromium.org</owner>
   <owner>collinbaker@chromium.org</owner>
   <summary>
@@ -1914,7 +1914,7 @@
 
 <histogram
     name="Tabs.PersistedTabData.Storage.Save.File.FirstStorageRequestType"
-    enum="FileStorageRequestType" expires_after="2022-09-18">
+    enum="FileStorageRequestType" expires_after="2022-11-20">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/translate/histograms.xml b/tools/metrics/histograms/metadata/translate/histograms.xml
index b34cb3c..b04aec0 100644
--- a/tools/metrics/histograms/metadata/translate/histograms.xml
+++ b/tools/metrics/histograms/metadata/translate/histograms.xml
@@ -477,7 +477,7 @@
 </histogram>
 
 <histogram name="Translate.PageLoad.FinalTargetLanguage"
-    enum="LocaleCodeISO639" expires_after="2022-09-11">
+    enum="LocaleCodeISO639" expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -532,7 +532,7 @@
 </histogram>
 
 <histogram name="Translate.PageLoad.InitialTargetLanguage"
-    enum="LocaleCodeISO639" expires_after="2022-09-11">
+    enum="LocaleCodeISO639" expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -641,7 +641,7 @@
 </histogram>
 
 <histogram name="Translate.PageLoad.Ranker.Version" units="version"
-    expires_after="2022-09-11">
+    expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -679,7 +679,7 @@
 </histogram>
 
 <histogram name="Translate.Ranker.Model.Status" enum="RankerModelStatus"
-    expires_after="2022-09-11">
+    expires_after="2022-11-20">
   <owner>rogerm@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -936,7 +936,7 @@
 </histogram>
 
 <histogram name="Translate.Translation.TargetLanguage" enum="LocaleCodeISO639"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -961,7 +961,7 @@
 </histogram>
 
 <histogram name="Translate.Translation.TimeToBeReady" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -974,7 +974,7 @@
 </histogram>
 
 <histogram name="Translate.Translation.TimeToLoad" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>curranmax@google.com</owner>
   <owner>megjablon@google.com</owner>
   <owner>chrome-language@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index 2245829..8370b4061 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -851,7 +851,7 @@
 </histogram>
 
 <histogram name="UMA.TruncatedEvents.UserAction" units="events"
-    expires_after="2022-11-13">
+    expires_after="2022-11-20">
   <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 9507bb5..f7682ea6 100644
--- a/tools/metrics/histograms/metadata/v8/histograms.xml
+++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -137,7 +137,7 @@
 </histogram>
 
 <histogram name="V8.CompileMicroSeconds" units="microseconds"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>yangguo@chromium.org</owner>
   <summary>
     Time spent in V8 compiler (full codegen) excluding parser.
@@ -306,7 +306,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds.ProduceCache"
-    units="microseconds" expires_after="2022-09-18">
+    units="microseconds" expires_after="2022-11-20">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -1004,7 +1004,7 @@
   </summary>
 </histogram>
 
-<histogram name="V8.GCCompactor" units="ms" expires_after="M106">
+<histogram name="V8.GCCompactor" units="ms" expires_after="2022-11-20">
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>Time spent in mark-sweep phase of GC.</summary>
@@ -1026,7 +1026,7 @@
   </summary>
 </histogram>
 
-<histogram name="V8.GCFinalizeMC" units="ms" expires_after="M106">
+<histogram name="V8.GCFinalizeMC" units="ms" expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
@@ -1076,7 +1076,7 @@
   </summary>
 </histogram>
 
-<histogram name="V8.GCFinalizeMC.Mark" units="ms" expires_after="M106">
+<histogram name="V8.GCFinalizeMC.Mark" units="ms" expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
@@ -1125,7 +1125,8 @@
   </summary>
 </histogram>
 
-<histogram name="V8.GCFinalizeMCReduceMemory" units="ms" expires_after="M106">
+<histogram name="V8.GCFinalizeMCReduceMemory" units="ms"
+    expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
@@ -1165,26 +1166,28 @@
 </histogram>
 
 <histogram name="V8.GCIncrementalMarkingFinalize" units="ms"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>Time spent in finalizing incremental marking.</summary>
 </histogram>
 
 <histogram name="V8.GCIncrementalMarkingReason" enum="GarbageCollectionReason"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>Reason an incremental marking was started in V8.</summary>
 </histogram>
 
-<histogram name="V8.GCIncrementalMarkingStart" units="ms" expires_after="M106">
+<histogram name="V8.GCIncrementalMarkingStart" units="ms"
+    expires_after="2022-11-20">
   <owner>hpayer@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>Time spent in starting incremental marking.</summary>
 </histogram>
 
-<histogram name="V8.GCIncrementalMarkingSum" units="ms" expires_after="M106">
+<histogram name="V8.GCIncrementalMarkingSum" units="ms"
+    expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>
@@ -1194,7 +1197,7 @@
 </histogram>
 
 <histogram name="V8.GCMainThreadMarkingThroughput" units="MB/s"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>
@@ -1207,7 +1210,7 @@
 </histogram>
 
 <histogram name="V8.GCMarkCompactReason" enum="GarbageCollectionReason"
-    expires_after="M106">
+    expires_after="2022-11-20">
   <owner>mlippautz@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>Reason a mark-compact garbage collection was started in V8.</summary>
@@ -1749,7 +1752,7 @@
 </histogram>
 
 <histogram name="V8.WasmCompileModuleAsyncMicroSeconds" units="microseconds"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>ecmziegler@chromium.org</owner>
   <owner>adamk@chromium.org</owner>
   <owner>clemensb@chromium.org</owner>
@@ -2062,7 +2065,7 @@
   </summary>
 </histogram>
 
-<histogram name="V8.WasmThrowCount" units="count" expires_after="2022-09-01">
+<histogram name="V8.WasmThrowCount" units="count" expires_after="2022-11-20">
   <owner>thibaudm@chromium.org</owner>
   <owner>ecmziegler@chromium.org</owner>
   <owner>wasm-v8@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index a6a97b4..8741bf1 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -427,7 +427,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.AudioInterruptionMs" units="ms"
-    expires_after="2022-08-14">
+    expires_after="2022-11-20">
   <owner>hlundin@chromium.org</owner>
   <owner>ivoc@chromium.org</owner>
   <summary>
@@ -580,7 +580,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.Clockdrift" enum="ClockdriftLevel"
-    expires_after="2022-09-13">
+    expires_after="2022-11-20">
   <owner>gustaf@chromium.org</owner>
   <owner>peah@chromium.org</owner>
   <summary>
@@ -590,7 +590,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.DelayChanges"
-    enum="WebRTCEventFrequency" expires_after="2022-09-13">
+    enum="WebRTCEventFrequency" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>saza@chromium.org</owner>
   <summary>
@@ -660,7 +660,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.MaxCaptureJitter"
-    units="frames (10 ms)" expires_after="2022-09-13">
+    units="frames (10 ms)" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>gustaf@chromium.org</owner>
   <summary>
@@ -670,7 +670,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.MaxRenderJitter"
-    units="frames (10 ms)" expires_after="2022-09-13">
+    units="frames (10 ms)" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>gustaf@chromium.org</owner>
   <summary>
@@ -697,7 +697,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.MinCaptureJitter"
-    units="frames (10 ms)" expires_after="2022-09-13">
+    units="frames (10 ms)" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>gustaf@chromium.org</owner>
   <summary>
@@ -707,7 +707,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.MinRenderJitter"
-    units="frames (10 ms)" expires_after="2022-09-13">
+    units="frames (10 ms)" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>gustaf@chromium.org</owner>
   <summary>
@@ -755,7 +755,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.EchoCanceller.RenderOverruns"
-    enum="WebRTCEventFrequency" expires_after="2022-09-13">
+    enum="WebRTCEventFrequency" expires_after="2022-11-20">
   <owner>peah@chromium.org</owner>
   <owner>saza@chromium.org</owner>
   <summary>
@@ -790,7 +790,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Encoder.CodecType" enum="WebRtcAudioCodecs"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>aleloi@chromium.org</owner>
   <summary>
     Histogram of audio codec usage. Every sample corresponds to 5 seconds of
@@ -852,7 +852,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.TargetBitrateInKbps" units="kbps"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>hlundin@chromium.org</owner>
   <summary>
     The target bitrate in kbps that the audio codec should try to produce on
@@ -916,7 +916,7 @@
 </histogram>
 
 <histogram name="WebRTC.BWE.InitialBandwidthEstimate" units="kbps"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>holmer@chromium.org</owner>
   <summary>The bandwidth estimate 2 seconds into a WebRTC call.</summary>
 </histogram>
@@ -1208,7 +1208,7 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCapture.Win.DesktopCapturerImpl"
-    enum="WebRtcDesktopCapturerImpl" expires_after="2022-09-18">
+    enum="WebRtcDesktopCapturerImpl" expires_after="2022-11-20">
   <owner>jamiewalch@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
@@ -1265,7 +1265,7 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCaptureCounters" enum="DesktopCaptureCounters"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>toprice@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -2085,7 +2085,7 @@
 </histogram>
 
 <histogram name="WebRTC.SentVideoTrackDuration" units="ms"
-    expires_after="2022-09-18">
+    expires_after="2022-11-20">
   <owner>perkj@chromium.org</owner>
   <summary>
     Durations of video tracks sent over a PeerConnection. The stopwatch starts
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index ac66e7a..f0c956a0 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -687,7 +687,7 @@
 </histogram>
 
 <histogram name="WebApp.Shortcuts.Creation.Result"
-    enum="ShortcutsCreationResult" expires_after="2022-09-19">
+    enum="ShortcutsCreationResult" expires_after="2022-11-20">
   <owner>phillis@chromium.org</owner>
   <owner>dmurph@chromium.org</owner>
   <summary>Records the result of shortcut creation for PWA.</summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 52c6910..db5b060 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "e8dee31f0f1f3bd72c50043bb78a4b283e77e760",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/3aded8458ec316b21ef66cc9afd274ca2e4a604b/trace_processor_shell"
+            "hash": "45efb72815abd76eb15718005137798939be4e02",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/03376e559abfc2e993526197d9bd2198ca356959/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/events/keycodes/DEPS b/ui/events/keycodes/DEPS
index d974f6c..0186a15e 100644
--- a/ui/events/keycodes/DEPS
+++ b/ui/events/keycodes/DEPS
@@ -7,7 +7,6 @@
   "-third_party",
   "-ui",
 
-  "+third_party/abseil-cpp/absl",
   "+ui/base/buildflags.h",  # Doesn't bring in all of UI.
   "+ui/gfx/x",
   "+ui/events",
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js
index 827cc81..03112b3 100644
--- a/ui/file_manager/integration_tests/file_manager/background.js
+++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -64,6 +64,9 @@
 
 export {FILE_MANAGER_EXTENSIONS_ID};
 
+/**
+ * @type {!RemoteCallFilesApp}
+ */
 export let remoteCall;
 
 /**
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js
index 60b28ca..d8846aa 100644
--- a/ui/file_manager/integration_tests/file_manager/recents.js
+++ b/ui/file_manager/integration_tests/file_manager/recents.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 {addEntries, ENTRIES, EntryType, getDateWithinLastMonth, RootPath, sendTestMessage, TestEntryInfo} from '../test_util.js';
+import {addEntries, ENTRIES, getCaller, getDateWithinLastMonth, pending, repeatUntil, RootPath, sendTestMessage, TestEntryInfo, wait} from '../test_util.js';
 import {testcase} from '../testcase.js';
 
-import {mountCrostini, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
+import {mountCrostini, navigateWithDirectoryTree, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
 import {BASIC_CROSTINI_ENTRY_SET, BASIC_DRIVE_ENTRY_SET, BASIC_LOCAL_ENTRY_SET, NESTED_ENTRY_SET, RECENT_ENTRY_SET} from './test_data.js';
 
 // Test entry for a recently-modified video file.
@@ -217,24 +217,106 @@
 }
 
 /**
- * Opens given file's containing folder by choosing "Go to file location"
- * context menu item.
+ * Select a file and right click to show the context menu, then click the
+ * specified context menu item.
  *
  * @param {string} appId Files app windowId.
- * @param {string} itemName Name of the file to open containing folder.
+ * @param {string} fileName Name of the file to right click.
+ * @param {string} commandId The command id for the context menu item.
  */
-async function goToFileLocation(appId, itemName) {
+async function rightClickContextMenu(appId, fileName, commandId) {
   // Select the item.
   chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [itemName]));
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [fileName]));
 
   // Right-click the selected file.
   await remoteCall.waitAndRightClick(appId, '.table-row[selected]');
 
-  // Click 'Go to file location' menu command.
-  const goToLocationMenu = '#file-context-menu:not([hidden]) ' +
-      '[command="#go-to-file-location"]:not([hidden]):not([disabled])';
-  remoteCall.waitAndClickElement(appId, goToLocationMenu);
+  // Click the context menu item with the command id.
+  const contextMenuItem = '#file-context-menu:not([hidden]) ' +
+      `[command="#${commandId}"]:not([hidden]):not([disabled])`;
+  await remoteCall.waitAndClickElement(appId, contextMenuItem);
+}
+
+/**
+ * Opens given file's containing folder by choosing "Go to file location"
+ * context menu item.
+ *
+ * @param {string} appId Files app windowId.
+ * @param {string} fileName Name of the file to open containing folder.
+ */
+async function goToFileLocation(appId, fileName) {
+  await rightClickContextMenu(appId, fileName, 'go-to-file-location');
+}
+
+/**
+ * Delete a given file by choosing "Delete" context menu item.
+ *
+ * @param {string} appId Files app windowId.
+ * @param {string} fileName Name of the file to delete.
+ */
+async function deleteFile(appId, fileName) {
+  await rightClickContextMenu(appId, fileName, 'delete');
+  // Click "Delete" on the Delete confirm dialog.
+  await remoteCall.waitAndClickElement(
+      appId, '.files-confirm-dialog button.cr-dialog-ok');
+}
+
+/**
+ * Rename a given file by choosing "Rename" context menu item.
+ *
+ * @param {string} appId Files app windowId.
+ * @param {string} fileName Name of the file to rename.
+ * @param {string} newName The new file name.
+ */
+async function renameFile(appId, fileName, newName) {
+  await rightClickContextMenu(appId, fileName, 'rename');
+  // Wait for the rename input field.
+  await remoteCall.waitForElement(appId, 'input.rename');
+  // Input the new name.
+  await remoteCall.inputText(appId, 'input.rename', newName);
+  // Press Enter to commit rename.
+  const keyDown = ['input.rename', 'Enter', false, false, false];
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, keyDown));
+}
+
+/**
+ * Cut a given file by choosing "Cut" context menu item and paste the file
+ * to the new folder.
+ *
+ * @param {string} appId Files app windowId.
+ * @param {string} fileName Name of the file to cut.
+ * @param {string} newFolder Full breadcrumb path for the new folder to paste.
+ */
+async function cutFileAndPasteTo(appId, fileName, newFolder) {
+  await rightClickContextMenu(appId, fileName, 'cut');
+  // Go to the new folder to paste.
+  await navigateWithDirectoryTree(appId, newFolder);
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('execCommand', appId, ['paste']));
+  // Wait for the operation to be completed.
+  const caller = getCaller();
+  await repeatUntil(async () => {
+    const element = await remoteCall.waitForElement(
+        appId, ['#progress-panel', 'xf-panel-item']);
+    const expectedPrimaryText =
+        `Moving ${fileName} to ${newFolder.split('/').pop()}`;
+    const expectedSecondaryText = 'Complete';
+    const actualPrimaryText = element.attributes['primary-text'];
+    const actualSecondaryText = element.attributes['secondary-text'];
+
+    if (expectedPrimaryText === actualPrimaryText &&
+        actualSecondaryText === actualSecondaryText) {
+      return;
+    }
+
+    return pending(
+        caller,
+        `Expected feedback panel msg: "${expectedPrimaryText} - ${
+            expectedSecondaryText}", got "${actualPrimaryText} - ${
+            actualSecondaryText}"`);
+  });
 }
 
 /**
@@ -619,3 +701,233 @@
       'Videos filter is off. Filter is reset.',
       a11yMessages[a11yMessages.length - 1]);
 };
+
+/**
+ * Tests the read only flag on Recents view should be hidden.
+ */
+testcase.recentsReadOnlyHidden = async () => {
+  const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
+  await navigateToRecent(appId);
+  const readOnlyIndicator =
+      await remoteCall.waitForElement(appId, ['#read-only-indicator']);
+  chrome.test.assertTrue(
+      readOnlyIndicator.hidden, 'Read only indicator should be hidden');
+};
+
+/**
+ * Tests delete operation can be performed in Recents view on files from
+ * Downloads, Drive and Play Files.
+ */
+testcase.recentsAllowDeletion = async () => {
+  await addPlayFileEntries();
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, [ENTRIES.beautiful], [ENTRIES.desktop]);
+  await navigateToRecent(appId);
+  const files = TestEntryInfo.getExpectedRows([
+    ENTRIES.beautiful, ENTRIES.desktop, RECENT_MODIFIED_ANDROID_DOCUMENT,
+    RECENT_MODIFIED_ANDROID_IMAGE, RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Delete a file originated from Downloads.
+  await deleteFile(appId, ENTRIES.beautiful.nameText);
+  const files1 = TestEntryInfo.getExpectedRows([
+    ENTRIES.desktop, RECENT_MODIFIED_ANDROID_DOCUMENT,
+    RECENT_MODIFIED_ANDROID_IMAGE, RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  await remoteCall.waitForFiles(appId, files1);
+
+  // Delete a file originated from Drive.
+  await deleteFile(appId, ENTRIES.desktop.nameText);
+  const files2 = TestEntryInfo.getExpectedRows([
+    RECENT_MODIFIED_ANDROID_DOCUMENT, RECENT_MODIFIED_ANDROID_IMAGE,
+    RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  await remoteCall.waitForFiles(appId, files2);
+
+  // Delete a file originated from Play Files.
+  await deleteFile(appId, RECENT_MODIFIED_ANDROID_IMAGE.nameText);
+  const files3 = TestEntryInfo.getExpectedRows(
+      [RECENT_MODIFIED_ANDROID_DOCUMENT, RECENT_MODIFIED_ANDROID_VIDEO]);
+  await remoteCall.waitForFiles(appId, files3);
+};
+
+/**
+ * Tests delete operation can be performed in Recents view with multiple files
+ * from different sources including Downloads, Drive and Play Files.
+ */
+testcase.recentsAllowMultipleFilesDeletion = async () => {
+  await addPlayFileEntries();
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, [ENTRIES.beautiful], [ENTRIES.desktop]);
+  await navigateToRecent(appId);
+  const files = TestEntryInfo.getExpectedRows([
+    ENTRIES.beautiful, ENTRIES.desktop, RECENT_MODIFIED_ANDROID_DOCUMENT,
+    RECENT_MODIFIED_ANDROID_IMAGE, RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Select all files from the gear menu.
+  await remoteCall.waitAndClickElement(appId, '#gear-button');
+  const selectAllMenu = '#gear-menu:not([hidden]) ' +
+      `[command="#select-all"]:not([hidden]):not([disabled])`;
+  await remoteCall.waitAndClickElement(appId, selectAllMenu);
+  await remoteCall.waitForElement(appId, '.table-row[selected]');
+  // Wait for the files selection label.
+  const caller = getCaller();
+  await repeatUntil(async () => {
+    const element =
+        await remoteCall.waitForElement(appId, '#files-selected-label');
+    const expectedLabel = '5 files selected';
+
+    if (element.text === expectedLabel) {
+      return;
+    }
+
+    return pending(
+        caller,
+        `Expected files selection label: "${expectedLabel}", got "${
+            element.text}"`);
+  });
+  // Delete all selected files via action bar.
+  await remoteCall.waitAndClickElement(appId, '#delete-button');
+  // Click okay on the confirm dialog.
+  await remoteCall.waitAndClickElement(
+      appId, '.files-confirm-dialog button.cr-dialog-ok');
+
+  // Check all files should be deleted.
+  await remoteCall.waitForFiles(appId, []);
+};
+
+/**
+ * Tests rename operation can be performed in Recents view on files from
+ * Downloads, Drive.
+ */
+testcase.recentsAllowRename = async () => {
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, [ENTRIES.beautiful], [ENTRIES.desktop]);
+  await navigateToRecent(appId);
+  const files =
+      TestEntryInfo.getExpectedRows([ENTRIES.beautiful, ENTRIES.desktop]);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Rename a file originated from Downloads.
+  const newBeautiful = ENTRIES.beautiful.cloneWithNewName('new-beautiful.ogg');
+  await renameFile(appId, ENTRIES.beautiful.nameText, newBeautiful.nameText);
+  const files1 = TestEntryInfo.getExpectedRows([
+    newBeautiful,
+    ENTRIES.desktop,
+  ]);
+  await remoteCall.waitForFiles(appId, files1);
+
+  // Rename a file originated from Drive.
+  const newDesktop = ENTRIES.desktop.cloneWithNewName('new-desktop.png');
+  await renameFile(appId, ENTRIES.desktop.nameText, newDesktop.nameText);
+  const files2 = TestEntryInfo.getExpectedRows([
+    newDesktop,
+    newBeautiful,
+  ]);
+  await remoteCall.waitForFiles(appId, files2);
+};
+
+/**
+ * Tests rename operation is not allowed in Recents view for files from
+ * Play files.
+ */
+testcase.recentsNoRenameForPlayFiles = async () => {
+  await addPlayFileEntries();
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
+  await navigateToRecent(appId);
+  const files = TestEntryInfo.getExpectedRows([
+    ENTRIES.beautiful, RECENT_MODIFIED_ANDROID_DOCUMENT,
+    RECENT_MODIFIED_ANDROID_IMAGE, RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Select the item.
+  chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
+      'selectFile', appId, [RECENT_MODIFIED_ANDROID_DOCUMENT.nameText]));
+
+  // Right-click the selected file.
+  await remoteCall.waitAndRightClick(appId, '.table-row[selected]');
+
+  // Checks the rename menu should be disabled.
+  const renameMenu = '#file-context-menu:not([hidden]) ' +
+      '[command="#rename"][disabled]:not([hidden])';
+  await remoteCall.waitForElement(appId, renameMenu);
+};
+
+/**
+ * Tests cut operation can be performed in Recents view on files from
+ * Downloads, Drive and Play Files.
+ */
+testcase.recentsAllowCut = async () => {
+  await addPlayFileEntries();
+  const appId = await setupAndWaitUntilReady(
+      RootPath.DOWNLOADS, [ENTRIES.beautiful, ENTRIES.directoryA],
+      [ENTRIES.desktop]);
+  const files = TestEntryInfo.getExpectedRows([
+    ENTRIES.beautiful, ENTRIES.desktop, RECENT_MODIFIED_ANDROID_DOCUMENT,
+    RECENT_MODIFIED_ANDROID_IMAGE, RECENT_MODIFIED_ANDROID_VIDEO
+  ]);
+  const newFolderBreadcrumb =
+      `/My files/Downloads/${ENTRIES.directoryA.nameText}`;
+
+  // Cut/Paste a file originated from Downloads.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  await cutFileAndPasteTo(
+      appId, ENTRIES.beautiful.nameText, newFolderBreadcrumb);
+  // The file being cut should appear in the new directory.
+  const filesInNewDir1 = TestEntryInfo.getExpectedRows([ENTRIES.beautiful]);
+  await remoteCall.waitForFiles(appId, filesInNewDir1);
+  // Recents view still have the full file list because the file being cut just
+  // moves to a new directory, but it still belongs to Recent.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  // Use "go to location" to validate the file in Recents after cut is
+  // collected from the new folder.
+  await goToFileLocation(appId, ENTRIES.beautiful.nameText);
+  await remoteCall.waitForFiles(appId, filesInNewDir1);
+  await verifyBreadcrumbsPath(appId, newFolderBreadcrumb);
+
+  // Cut/Paste a file originated from Drive.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  await cutFileAndPasteTo(appId, ENTRIES.desktop.nameText, newFolderBreadcrumb);
+  // The file being cut should appear in the new directory.
+  const filesInNewDir2 = TestEntryInfo.getExpectedRows([
+    ENTRIES.beautiful,
+    ENTRIES.desktop,
+  ]);
+  await remoteCall.waitForFiles(appId, filesInNewDir2);
+  // Recents view still have the full file list because the file being cut just
+  // moves to a new directory, but it still belongs to Recent.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  // Use "go to location" to validate the file in Recents after cut is
+  // collected from the new folder.
+  await goToFileLocation(appId, ENTRIES.desktop.nameText);
+  await remoteCall.waitForFiles(appId, filesInNewDir2);
+  await verifyBreadcrumbsPath(appId, newFolderBreadcrumb);
+
+  // Cut/Paste a file originated from Play Files.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  await cutFileAndPasteTo(
+      appId, RECENT_MODIFIED_ANDROID_IMAGE.nameText, newFolderBreadcrumb);
+  // The file being cut should appear in the new directory.
+  const filesInNewDir3 = TestEntryInfo.getExpectedRows(
+      [ENTRIES.beautiful, ENTRIES.desktop, RECENT_MODIFIED_ANDROID_IMAGE]);
+  await remoteCall.waitForFiles(appId, filesInNewDir3);
+  // Recents view still have the full file list because the file being cut just
+  // moves to a new directory, but it still belongs to Recent.
+  await navigateToRecent(appId);
+  await remoteCall.waitForFiles(appId, files);
+  // Use "go to location" to validate the file in Recents after cut is
+  // collected from the new folder.
+  await goToFileLocation(appId, RECENT_MODIFIED_ANDROID_IMAGE.nameText);
+  await remoteCall.waitForFiles(appId, filesInNewDir3);
+  await verifyBreadcrumbsPath(appId, newFolderBreadcrumb);
+};
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index 53eaef6..37af31a2 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -471,6 +471,23 @@
         }));
     return new TestEntryInfo(updatedOptions);
   }
+
+  /**
+   * Clone the existing TestEntryInfo object to a new TestEntryInfo object but
+   * with modified targetPath field. This is especially useful for testing
+   * rename functionality.
+   *
+   * @param {string} newName the new modified name
+   * @return {!TestEntryInfo}
+   */
+  cloneWithNewName(newName) {
+    const updatedOptions =
+        /** @type {TestEntryInfoOptions} */ (Object.assign({}, this, {
+          targetPath: newName,
+          nameText: newName,
+        }));
+    return new TestEntryInfo(updatedOptions);
+  }
 }
 
 /**
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index 7e139ef2..41a5b502 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -276,7 +276,6 @@
   // MessageViewFactory parlance.
   bool is_nested_ = false;
 
-  bool is_grouped_ = false;
   // True if the slide is disabled forcibly.
   bool disable_slide_ = false;
 
diff --git a/weblayer/browser/autofill_assistant/weblayer_dependencies.cc b/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
index 362d52c..4acb240 100644
--- a/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
+++ b/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
@@ -97,9 +97,9 @@
 }
 
 std::string WebLayerDependencies::GetSignedInEmail(
-    content::WebContents* web_contents) const {
-  ProfileImpl* profile =
-      ProfileImpl::FromBrowserContext(web_contents->GetBrowserContext());
+    content::BrowserContext* browser_context) const {
+  DCHECK(browser_context);
+  ProfileImpl* profile = ProfileImpl::FromBrowserContext(browser_context);
   const ScopedJavaLocalRef<jstring> email =
       Java_WebLayerAssistantStaticDependencies_getEmailOrNull(
           AttachCurrentThread(), jstatic_dependencies_,
@@ -107,6 +107,12 @@
   return email.is_null() ? "" : ConvertJavaStringToUTF8(email);
 }
 
+bool WebLayerDependencies::IsSupervisedUser(
+    content::BrowserContext* browser_context) const {
+  // WebLayer does not support supervised users.
+  return false;
+}
+
 std::string WebLayerDependencies::GetLocale() const {
   return base::android::GetDefaultLocaleString();
 }
diff --git a/weblayer/browser/autofill_assistant/weblayer_dependencies.h b/weblayer/browser/autofill_assistant/weblayer_dependencies.h
index 3b3f8f2..940fbac 100644
--- a/weblayer/browser/autofill_assistant/weblayer_dependencies.h
+++ b/weblayer/browser/autofill_assistant/weblayer_dependencies.h
@@ -48,7 +48,9 @@
   std::string GetLocale() const override;
   std::string GetCountryCode() const override;
   std::string GetSignedInEmail(
-      content::WebContents* web_contents) const override;
+      content::BrowserContext* browser_context) const override;
+  bool IsSupervisedUser(
+      content::BrowserContext* browser_context) const override;
   ::autofill_assistant::AnnotateDomModelService*
   GetOrCreateAnnotateDomModelService(
       content::BrowserContext* browser_context) const override;